From a92c735c9b57049e8c4037d3490f7e10f8eef4d6 Mon Sep 17 00:00:00 2001 From: Dana Robinson Date: Thu, 16 Jan 2020 13:29:34 -0800 Subject: Squashed commit of the token_refactoring branch: --- .gitattributes | 6 +- MANIFEST | 8 +- bin/make_vers | 34 +- bin/trace | 13 +- c++/examples/h5group.cpp | 8 +- c++/src/C2Cppfunction_map.htm | 4 +- c++/src/H5Location.cpp | 157 +- c++/src/H5Location.h | 35 +- c++/src/H5Object.cpp | 28 +- c++/src/H5Object.h | 4 +- c++/test/dsets.cpp | 26 +- c++/test/tattr.cpp | 4 +- c++/test/tfile.cpp | 14 +- c++/test/titerate.cpp | 12 +- c++/test/tlinks.cpp | 4 +- c++/test/tobject.cpp | 2 +- c++/test/trefer.cpp | 2 +- examples/h5_attribute.c | 4 +- examples/h5_extlink.c | 48 +- examples/h5_group.c | 14 +- examples/testh5cc.sh.in | 5 +- fortran/src/H5Af.c | 4 +- fortran/src/H5Gf.c | 4 +- fortran/src/H5Lf.c | 28 +- fortran/src/H5Lff.F90 | 38 +- fortran/src/H5Of.c | 109 +- fortran/src/H5Off.F90 | 168 +- fortran/src/H5VLff.F90 | 56 +- fortran/src/H5_f.c | 301 +- fortran/src/H5f90.h | 3 + fortran/src/H5f90global.F90 | 7 +- fortran/src/H5f90i.h | 3 +- fortran/src/H5f90proto.h | 34 +- fortran/src/H5match_types.c | 10 +- fortran/src/README | 20 +- fortran/src/hdf5_fortrandll.def.in | 4 +- fortran/test/tH5G_1_8.F90 | 54 +- fortran/test/tH5O_F03.F90 | 156 +- fortran/test/vol_connector.F90 | 10 +- hl/src/H5DS.c | 171 +- hl/src/H5LT.c | 4 +- java/examples/groups/H5Ex_G_Intermediate.java | 14 +- java/examples/groups/H5Ex_G_Iterate.java | 5 +- java/examples/groups/H5Ex_G_Traverse.java | 32 +- java/examples/groups/H5Ex_G_Visit.java | 28 +- java/src/Makefile.am | 6 +- java/src/hdf/hdf5lib/CMakeLists.txt | 6 +- java/src/hdf/hdf5lib/H5.java | 245 +- java/src/hdf/hdf5lib/HDF5Constants.java | 21 +- java/src/hdf/hdf5lib/callbacks/H5L_iterate_cb.java | 21 - .../hdf5lib/callbacks/H5L_iterate_opdata_t.java | 18 + java/src/hdf/hdf5lib/callbacks/H5L_iterate_t.java | 9 +- java/src/hdf/hdf5lib/callbacks/H5O_iterate_cb.java | 21 - .../hdf5lib/callbacks/H5O_iterate_opdata_t.java | 18 + java/src/hdf/hdf5lib/callbacks/H5O_iterate_t.java | 9 +- java/src/hdf/hdf5lib/structs/H5L_info_t.java | 35 +- java/src/hdf/hdf5lib/structs/H5O_hdr_info_t.java | 36 +- java/src/hdf/hdf5lib/structs/H5O_info_t.java | 38 +- .../src/hdf/hdf5lib/structs/H5O_native_info_t.java | 52 + java/src/hdf/hdf5lib/structs/H5O_token_t.java | 45 + java/src/hdf/hdf5lib/structs/H5_ih_info_t.java | 18 + java/src/jni/exceptionImp.c | 2 +- java/src/jni/h5Constants.c | 18 +- java/src/jni/h5aImp.c | 43 +- java/src/jni/h5dImp.c | 26 +- java/src/jni/h5eImp.c | 18 +- java/src/jni/h5fImp.c | 4 +- java/src/jni/h5iImp.c | 4 +- java/src/jni/h5jni.h | 428 +- java/src/jni/h5lImp.c | 207 +- java/src/jni/h5oImp.c | 466 +- java/src/jni/h5oImp.h | 35 +- java/src/jni/h5pDAPLImp.c | 4 +- java/src/jni/h5pDCPLImp.c | 38 +- java/src/jni/h5pDXPLImp.c | 4 +- java/src/jni/h5pFAPLImp.c | 28 +- java/src/jni/h5pImp.c | 2 +- java/src/jni/h5pLAPLImp.c | 4 +- java/src/jni/h5plImp.c | 2 +- java/src/jni/h5rImp.c | 28 +- java/src/jni/h5sImp.c | 46 +- java/src/jni/h5tImp.c | 12 +- java/src/jni/h5util.c | 263 +- java/src/jni/h5util.h | 2 +- java/src/jni/h5vlImp.c | 32 +- java/src/jni/h5vlImp.h | 11 +- java/src/jni/nativeData.c | 20 +- java/test/TestH5E.java | 23 +- java/test/TestH5Edefault.java | 71 +- java/test/TestH5G.java | 27 +- java/test/TestH5Giterate.java | 5 +- java/test/TestH5Lbasic.java | 53 +- java/test/TestH5Lcreate.java | 34 +- java/test/TestH5Obasic.java | 328 +- java/test/TestH5Ocreate.java | 20 +- java/test/TestH5Oparams.java | 25 + java/test/TestH5VL.java | 48 +- java/test/testfiles/JUnit-TestH5Edefault.txt | 48 +- java/test/testfiles/JUnit-TestH5Obasic.txt | 20 +- java/test/testfiles/JUnit-TestH5Oparams.txt | 7 +- java/test/testfiles/JUnit-TestH5VL.txt | 3 +- src/CMakeLists.txt | 2 + src/H5A.c | 20 +- src/H5Adeprec.c | 20 +- src/H5Cpkg.h | 2 +- src/H5Ctest.c | 19 +- src/H5D.c | 10 +- src/H5Ddeprec.c | 8 +- src/H5Epkg.h | 2 +- src/H5Epublic.h | 8 +- src/H5Fint.c | 72 - src/H5Fpkg.h | 1 - src/H5G.c | 8 +- src/H5Gdeprec.c | 87 +- src/H5Gint.c | 14 +- src/H5Glink.c | 9 +- src/H5Gloc.c | 101 +- src/H5Gname.c | 64 +- src/H5Gprivate.h | 10 +- src/H5Gtraverse.c | 4 + src/H5I.c | 4 +- src/H5Itest.c | 2 +- src/H5L.c | 134 +- src/H5Ldeprec.c | 628 +++ src/H5Lexternal.c | 2 +- src/H5Lprivate.h | 9 +- src/H5Lpublic.h | 124 +- src/H5M.c | 10 +- src/H5O.c | 481 +- src/H5Oattribute.c | 22 - src/H5Ocopy.c | 8 +- src/H5Ocopy_ref.c | 31 +- src/H5Odeprec.c | 729 ++- src/H5Oflush.c | 4 +- src/H5Oint.c | 129 +- src/H5Opkg.h | 2 +- src/H5Oprivate.h | 3 +- src/H5Opublic.h | 137 +- src/H5R.c | 143 +- src/H5Rdeprec.c | 83 +- src/H5Rint.c | 326 +- src/H5Rpkg.h | 28 +- src/H5Rpublic.h | 15 +- src/H5Tcommit.c | 10 +- src/H5Tdeprec.c | 6 +- src/H5Tref.c | 6 +- src/H5VL.c | 40 +- src/H5VLcallback.c | 385 +- src/H5VLconnector.h | 24 +- src/H5VLconnector_passthru.h | 5 + src/H5VLint.c | 41 +- src/H5VLnative.c | 345 ++ src/H5VLnative.h | 28 +- src/H5VLnative_file.c | 6 +- src/H5VLnative_link.c | 18 +- src/H5VLnative_object.c | 174 +- src/H5VLnative_private.h | 15 +- src/H5VLnative_token.c | 157 + src/H5VLpassthru.c | 108 + src/H5VLpkg.h | 3 +- src/H5VLprivate.h | 8 + src/H5VLpublic.h | 3 +- src/H5public.h | 12 + src/H5system.c | 28 + src/H5trace.c | 28 +- src/H5vers.txt | 18 +- src/Makefile.am | 80 +- test/cache_tagging.c | 73 +- test/chunk_info.c | 2 +- test/cork.c | 174 +- test/direct_chunk.c | 12 +- test/dsets.c | 50 +- test/dtypes.c | 14 +- test/efc.c | 2 +- test/fillval.c | 4 +- test/flushrefresh.c | 65 +- test/genall5.c | 72 +- test/getname.c | 10 +- test/h5test.c | 4 +- test/links.c | 5254 ++++++++++++++++++-- test/mount.c | 119 +- test/mtime.c | 16 +- test/null_vol_connector.c | 5 + test/objcopy.c | 1052 ++-- test/objcopy_ref.c | 116 +- test/ohdr.c | 25 +- test/stab.c | 24 +- test/tattr.c | 177 +- test/tfile.c | 52 +- test/th5o.c | 475 +- test/titerate.c | 168 +- test/tmisc.c | 140 +- test/trefer.c | 14 +- test/trefer_deprec.c | 14 +- test/tsohm.c | 24 +- test/tvlstr.c | 5 +- test/unlink.c | 29 +- test/vds.c | 18 +- test/vol.c | 13 +- test/vol_plugin.c | 2 +- tools/lib/h5diff.c | 46 +- tools/lib/h5diff_array.c | 24 +- tools/lib/h5diff_attr.c | 11 +- tools/lib/h5tools.c | 22 +- tools/lib/h5tools_dump.c | 23 +- tools/lib/h5tools_ref.c | 148 +- tools/lib/h5tools_ref.h | 8 +- tools/lib/h5tools_str.c | 46 +- tools/lib/h5tools_str.h | 2 +- tools/lib/h5tools_utils.c | 73 +- tools/lib/h5tools_utils.h | 15 +- tools/lib/h5trav.c | 117 +- tools/lib/h5trav.h | 15 +- tools/src/h5dump/h5dump.c | 4 +- tools/src/h5dump/h5dump_ddl.c | 67 +- tools/src/h5dump/h5dump_xml.c | 171 +- tools/src/h5format_convert/h5format_convert.c | 2 +- tools/src/h5ls/h5ls.c | 32 +- tools/src/h5repack/h5repack.c | 36 +- tools/src/h5repack/h5repack.h | 2 +- tools/src/h5repack/h5repack_copy.c | 2 +- tools/src/h5repack/h5repack_refs.c | 15 +- tools/src/h5repack/h5repack_verify.c | 6 +- tools/src/h5stat/h5stat.c | 53 +- tools/test/h5dump/errfiles/tdset-2.err | 2 +- tools/test/h5dump/errfiles/tperror.err | 2 +- tools/test/h5dump/errfiles/tqmarkfile.err | 2 +- 227 files changed, 14156 insertions(+), 4829 deletions(-) delete mode 100644 java/src/hdf/hdf5lib/callbacks/H5L_iterate_cb.java create mode 100644 java/src/hdf/hdf5lib/callbacks/H5L_iterate_opdata_t.java delete mode 100644 java/src/hdf/hdf5lib/callbacks/H5O_iterate_cb.java create mode 100644 java/src/hdf/hdf5lib/callbacks/H5O_iterate_opdata_t.java create mode 100644 java/src/hdf/hdf5lib/structs/H5O_native_info_t.java create mode 100644 java/src/hdf/hdf5lib/structs/H5O_token_t.java create mode 100644 src/H5Ldeprec.c create mode 100644 src/H5VLnative_token.c diff --git a/.gitattributes b/.gitattributes index 1ca4739..2ad5b6e 100644 --- a/.gitattributes +++ b/.gitattributes @@ -216,10 +216,10 @@ java/src/hdf/hdf5lib/callbacks/H5D_iterate_cb.java -text java/src/hdf/hdf5lib/callbacks/H5D_iterate_t.java -text java/src/hdf/hdf5lib/callbacks/H5E_walk_cb.java -text java/src/hdf/hdf5lib/callbacks/H5E_walk_t.java -text -java/src/hdf/hdf5lib/callbacks/H5L_iterate_cb.java -text java/src/hdf/hdf5lib/callbacks/H5L_iterate_t.java -text -java/src/hdf/hdf5lib/callbacks/H5O_iterate_cb.java -text +java/src/hdf/hdf5lib/callbacks/H5L_iterate_opdata_t.java -text java/src/hdf/hdf5lib/callbacks/H5O_iterate_t.java -text +java/src/hdf/hdf5lib/callbacks/H5O_iterate_opdata_t.java -text java/src/hdf/hdf5lib/callbacks/H5P_cls_close_func_cb.java -text java/src/hdf/hdf5lib/callbacks/H5P_cls_close_func_t.java -text java/src/hdf/hdf5lib/callbacks/H5P_cls_copy_func_cb.java -text @@ -267,6 +267,8 @@ java/src/hdf/hdf5lib/structs/H5G_info_t.java -text java/src/hdf/hdf5lib/structs/H5L_info_t.java -text java/src/hdf/hdf5lib/structs/H5O_hdr_info_t.java -text java/src/hdf/hdf5lib/structs/H5O_info_t.java -text +java/src/hdf/hdf5lib/structs/H5O_native_info_t.java -text +java/src/hdf/hdf5lib/structs/H5O_token_t.java -text java/src/hdf/hdf5lib/structs/H5_ih_info_t.java -text java/src/hdf/overview.html -text java/src/jni/CMakeLists.txt -text diff --git a/MANIFEST b/MANIFEST index b1b8f07..f7fe208 100644 --- a/MANIFEST +++ b/MANIFEST @@ -748,6 +748,7 @@ ./src/H5Ipublic.h ./src/H5Itest.c ./src/H5L.c +./src/H5Ldeprec.c ./src/H5Lexternal.c ./src/H5Lmodule.h ./src/H5Lpkg.h @@ -938,6 +939,7 @@ ./src/H5VLnative_link.c ./src/H5VLnative_introspect.c ./src/H5VLnative_object.c +./src/H5VLnative_token.c ./src/H5VLnative_private.h ./src/H5VLpassthru.c ./src/H5VLpassthru.h @@ -3044,10 +3046,10 @@ ./java/src/hdf/hdf5lib/callbacks/H5D_append_t.java ./java/src/hdf/hdf5lib/callbacks/H5E_walk_cb.java ./java/src/hdf/hdf5lib/callbacks/H5E_walk_t.java -./java/src/hdf/hdf5lib/callbacks/H5L_iterate_cb.java ./java/src/hdf/hdf5lib/callbacks/H5L_iterate_t.java -./java/src/hdf/hdf5lib/callbacks/H5O_iterate_cb.java +./java/src/hdf/hdf5lib/callbacks/H5L_iterate_opdata_t.java ./java/src/hdf/hdf5lib/callbacks/H5O_iterate_t.java +./java/src/hdf/hdf5lib/callbacks/H5O_iterate_opdata_t.java ./java/src/hdf/hdf5lib/callbacks/H5P_cls_close_func_cb.java ./java/src/hdf/hdf5lib/callbacks/H5P_cls_close_func_t.java ./java/src/hdf/hdf5lib/callbacks/H5P_cls_copy_func_cb.java @@ -3100,6 +3102,8 @@ ./java/src/hdf/hdf5lib/structs/H5L_info_t.java ./java/src/hdf/hdf5lib/structs/H5O_hdr_info_t.java ./java/src/hdf/hdf5lib/structs/H5O_info_t.java +./java/src/hdf/hdf5lib/structs/H5O_native_info_t.java +./java/src/hdf/hdf5lib/structs/H5O_token_t.java ./java/src/hdf/hdf5lib/H5.java ./java/src/hdf/hdf5lib/HDF5Constants.java diff --git a/bin/make_vers b/bin/make_vers index c6d2c04..7154dfb 100755 --- a/bin/make_vers +++ b/bin/make_vers @@ -90,7 +90,8 @@ sub print_checkoptions ($) { my $curr_idx; # Current API version index # Print the option checking - print $fh "\n/* Issue error if contradicting macros have been defined. */\n"; + print $fh "\n\n/* Issue error if contradicting macros have been defined. */\n"; + print $fh "/* (Can't use an older (deprecated) API version if deprecated symbols have been disabled) */\n"; # Print the #ifdef print $fh "#if ("; @@ -119,26 +120,40 @@ sub print_checkoptions ($) { ############################################################################## # Print "global" API version macro settings # -sub print_globalapivers ($) { +sub print_globalapidefvers ($) { my $fh = shift; # File handle for output file my $curr_idx; # Current API version index # Print the descriptive comment - print $fh "\n\n/* If a particular \"global\" version of the library's interfaces is chosen,\n"; - print $fh " * set the versions for the API symbols affected.\n"; + print $fh "\n\n/* If a particular default \"global\" version of the library's interfaces is\n"; + print $fh " * chosen, set the corresponding version macro for API symbols.\n"; print $fh " *\n"; - print $fh " * Note: If an application has already chosen a particular version for an\n"; - print $fh " * API symbol, the individual API version macro takes priority.\n"; print $fh " */\n"; for $curr_idx ($min_sup_idx .. ($max_idx - 1)) { # Print API version ifdef - print $fh "#if defined(H5_USE_1", ($curr_idx * 2), "_API_DEFAULT) && !defined(H5_USE_1", ($curr_idx * 2), "_API)\n"; + print $fh "\n#if defined(H5_USE_1", ($curr_idx * 2), "_API_DEFAULT) && !defined(H5_USE_1", ($curr_idx * 2), "_API)\n"; # Print API version definition print $fh " " x $indent, "#define H5_USE_1", ($curr_idx * 2), "_API 1\n"; # Print API version endif - print $fh "#endif /* H5_USE_1", ($curr_idx * 2), "_API_DEFAULT && !H5_USE_1", ($curr_idx * 2), "_API */\n\n"; + print $fh "#endif /* H5_USE_1", ($curr_idx * 2), "_API_DEFAULT && !H5_USE_1", ($curr_idx * 2), "_API */\n"; } +} + +############################################################################## +# Print "global" API symbol version macro settings +# +sub print_globalapisymbolvers ($) { + my $fh = shift; # File handle for output file + my $curr_idx; # Current API version index + + # Print the descriptive comment + print $fh "\n\n/* If a particular \"global\" version of the library's interfaces is chosen,\n"; + print $fh " * set the versions for the API symbols affected.\n"; + print $fh " *\n"; + print $fh " * Note: If an application has already chosen a particular version for an\n"; + print $fh " * API symbol, the individual API version macro takes priority.\n"; + print $fh " */\n"; # Loop over supported older library APIs and define the appropriate macros for $curr_idx ($min_sup_idx .. ($max_idx - 1)) { @@ -444,8 +459,9 @@ sub create_public ($) { print_copyright(*HEADER); print_warning(*HEADER); print_startprotect(*HEADER, $file); + print_globalapidefvers(*HEADER); print_checkoptions(*HEADER); - print_globalapivers(*HEADER); + print_globalapisymbolvers(*HEADER); print_defaultapivers(*HEADER); print_endprotect(*HEADER, $file); diff --git a/bin/trace b/bin/trace index 50fd2f3..9e5730b 100755 --- a/bin/trace +++ b/bin/trace @@ -71,6 +71,7 @@ $Source = ""; "uint32_t" => "Iu", "uint64_t" => "UL", "H5I_type_t" => "It", + "H5O_token_t" => "k", "H5G_link_t" => "Ll", #Same as H5L_type_t now "H5L_type_t" => "Ll", "MPI_Comm" => "Mc", @@ -164,12 +165,18 @@ $Source = ""; "H5I_search_func_t" => "x", "H5L_class_t" => "x", "H5L_elink_traverse_t" => "x", - "H5L_iterate_t" => "x", + "H5L_info1_t" => "x", + "H5L_info2_t" => "x", + "H5L_iterate1_t" => "x", + "H5L_iterate2_t" => "x", "H5M_iterate_t" => 'x', "H5MM_allocate_t" => "x", "H5MM_free_t" => "x", - "H5O_info_t" => "x", - "H5O_iterate_t" => "x", + "H5O_info1_t" => "x", + "H5O_info2_t" => "x", + "H5O_native_info_t" => "x", + "H5O_iterate1_t" => "x", + "H5O_iterate2_t" => "x", "H5O_mcdt_search_cb_t" => "x", "H5P_cls_create_func_t" => "x", "H5P_cls_copy_func_t" => "x", diff --git a/c++/examples/h5group.cpp b/c++/examples/h5group.cpp index fab54cd..271c538 100644 --- a/c++/examples/h5group.cpp +++ b/c++/examples/h5group.cpp @@ -36,7 +36,7 @@ const H5std_string FILE_NAME( "Group.h5" ); const int RANK = 2; // Operator function -extern "C" herr_t file_info(hid_t loc_id, const char *name, const H5L_info_t *linfo, +extern "C" herr_t file_info(hid_t loc_id, const char *name, const H5L_info2_t *linfo, void *opdata); int main(void) @@ -157,7 +157,7 @@ int main(void) * root directory. */ cout << endl << "Iterating over elements in the file" << endl; - herr_t idx = H5Literate(file->getId(), H5_INDEX_NAME, H5_ITER_INC, NULL, file_info, NULL); + herr_t idx = H5Literate2(file->getId(), H5_INDEX_NAME, H5_ITER_INC, NULL, file_info, NULL); cout << endl; /* @@ -175,7 +175,7 @@ int main(void) cout << "\"Data\" is unlinked" << endl; cout << endl << "Iterating over elements in the file again" << endl; - idx = H5Literate(file->getId(), H5_INDEX_NAME, H5_ITER_INC, NULL, file_info, NULL); + idx = H5Literate2(file->getId(), H5_INDEX_NAME, H5_ITER_INC, NULL, file_info, NULL); cout << endl; /* @@ -219,7 +219,7 @@ int main(void) * Operator function. */ herr_t -file_info(hid_t loc_id, const char *name, const H5L_info_t *linfo, void *opdata) +file_info(hid_t loc_id, const char *name, const H5L_info2_t *linfo, void *opdata) { hid_t group; diff --git a/c++/src/C2Cppfunction_map.htm b/c++/src/C2Cppfunction_map.htm index 2d779a3..a9e0a27 100644 --- a/c++/src/C2Cppfunction_map.htm +++ b/c++/src/C2Cppfunction_map.htm @@ -11493,7 +11493,7 @@ normal'>

H5L_info_t getLinkInfo(const char* link_name,

+ normal'>H5L_info2_t getLinkInfo(const char* link_name,

const LinkAccPropList& lapl = LinkAccPropList::DEFAULT)

@@ -11526,7 +11526,7 @@ normal'>

H5L_info_t getLinkInfo(const H5std_string& link_name,

+ normal'>H5L_info2_t getLinkInfo(const H5std_string& link_name,

const LinkAccPropList& lapl = LinkAccPropList::DEFAULT)

diff --git a/c++/src/H5Location.cpp b/c++/src/H5Location.cpp index 2641960..764aa12 100644 --- a/c++/src/H5Location.cpp +++ b/c++/src/H5Location.cpp @@ -1404,6 +1404,121 @@ void H5Location::unlink(const H5std_string& name, const LinkAccPropList& lapl) c } //-------------------------------------------------------------------------- +// Function: H5Location::getNativeObjinfo +///\brief Retrieves native information about an HDF5 object. +///\param objinfo - OUT: Struct containing the native object info +///\param fields - IN: Indicates the group of information to be retrieved +///\par Description +/// Valid values of \a fields are as follows: +/// \li \c H5O_INFO_HDR (default) +/// \li \c H5O_INFO_META_SIZE +/// \li \c H5O_INFO_ALL +// July, 2018 +//-------------------------------------------------------------------------- +void H5Location::getNativeObjinfo(H5O_native_info_t& objinfo, unsigned fields) const +{ + + // Use C API to get information of the object + herr_t ret_value = H5Oget_native_info(getId(), &objinfo, fields); + + // Throw exception if C API returns failure + if (ret_value < 0) + throwException(inMemFunc("getNativeObjinfo"), "H5Oget_native_info failed"); +} + +//-------------------------------------------------------------------------- +// Function: H5Location::getNativeObjinfo +///\brief Retrieves native information about an HDF5 object given its name. +///\param name - IN: Name of the object to be queried - \c char * +///\param objinfo - OUT: Struct containing the native object info +///\param fields - IN: Indicates the group of information to be retrieved +/// - default to H5O_INFO_HDR +///\param lapl - IN: Link access property list +///\par Description +/// Valid values of \a fields are as follows: +/// \li \c H5O_INFO_HDR (default) +/// \li \c H5O_INFO_META_SIZE +/// \li \c H5O_INFO_ALL +// July, 2018 +//-------------------------------------------------------------------------- +void H5Location::getNativeObjinfo(const char* name, H5O_native_info_t& objinfo, unsigned fields, const LinkAccPropList& lapl) const +{ + // Use C API to get information of the object + herr_t ret_value = H5Oget_native_info_by_name(getId(), name, &objinfo, fields, lapl.getId()); + + // Throw exception if C API returns failure + if (ret_value < 0) + throwException(inMemFunc("getNativeObjinfo"), "H5Oget_native_info_by_name failed"); +} + +//-------------------------------------------------------------------------- +// Function: H5Location::getNativeObjinfo +///\brief This is an overloaded member function, provided for convenience. +/// It differs from the above function in that it takes +/// a reference to an \c H5std_string for \a name. +///\param name - IN: Name of the object to be queried - \c H5std_string +///\param objinfo - OUT: Struct containing the native object info +///\param fields - IN: Indicates the group of information to be retrieved +/// - default to H5O_INFO_HDR +///\param lapl - IN: Link access property list +// July, 2018 +//-------------------------------------------------------------------------- +void H5Location::getNativeObjinfo(const H5std_string& name, H5O_native_info_t& objinfo, unsigned fields, const LinkAccPropList& lapl) const +{ + getNativeObjinfo(name.c_str(), objinfo, fields, lapl); +} + +//-------------------------------------------------------------------------- +// Function: H5Location::getNativeObjinfo +///\brief Retrieves native information about an HDF5 object given its index. +///\param grp_name - IN: Group name where the object belongs - \c char * +///\param idx_type - IN: Type of index +///\param order - IN: Order to traverse +///\param idx - IN: Object position +///\param objinfo - OUT: Struct containing the native object info +///\param fields - IN: Indicates the group of information to be retrieved +/// - default to H5O_INFO_HDR +///\param lapl - IN: Link access property list +///\par Description +/// Valid values of \a fields are as follows: +/// \li \c H5O_INFO_HDR (default) +/// \li \c H5O_INFO_META_SIZE +/// \li \c H5O_INFO_ALL +// July, 2018 +//-------------------------------------------------------------------------- +void H5Location::getNativeObjinfo(const char* grp_name, H5_index_t idx_type, + H5_iter_order_t order, hsize_t idx, H5O_native_info_t& objinfo, unsigned fields, + const LinkAccPropList& lapl) const +{ + // Use C API to get information of the object + herr_t ret_value = H5Oget_native_info_by_idx(getId(), grp_name, idx_type, order, + idx, &objinfo, fields, lapl.getId()); + + // Throw exception if C API returns failure + if (ret_value < 0) + throwException(inMemFunc("getNativeObjinfo"), "H5Oget_native_info_by_idx failed"); +} + +//-------------------------------------------------------------------------- +// Function: H5Location::getObjinfo +///\brief This is an overloaded member function, provided for convenience. +/// It differs from the above function in that it takes +/// a reference to an \c H5std_string for \a name. +///\param name - IN: Name of the object to be queried - \c H5std_string +///\param objinfo - OUT: Struct containing the native object info +///\param fields - IN: Indicates a group of information to be retrieved +/// - default to H5O_INFO_HDR +///\param lapl - IN: Link access property list +// July, 2018 +//-------------------------------------------------------------------------- +void H5Location::getNativeObjinfo(const H5std_string& grp_name, H5_index_t idx_type, + H5_iter_order_t order, hsize_t idx, H5O_native_info_t& objinfo, unsigned fields, + const LinkAccPropList& lapl) const +{ + getNativeObjinfo(grp_name.c_str(), idx_type, order, idx, objinfo, fields, lapl); +} + +//-------------------------------------------------------------------------- // Function: H5Location::getObjinfo ///\brief Retrieves information about an HDF5 object. ///\param objinfo - OUT: Struct containing the object info @@ -1418,15 +1533,15 @@ void H5Location::unlink(const H5std_string& name, const LinkAccPropList& lapl) c /// \li \c H5O_INFO_ALL // July, 2018 //-------------------------------------------------------------------------- -void H5Location::getObjinfo(H5O_info_t& objinfo, unsigned fields) const +void H5Location::getObjinfo(H5O_info2_t& objinfo, unsigned fields) const { // Use C API to get information of the object - herr_t ret_value = H5Oget_info2(getId(), &objinfo, fields); + herr_t ret_value = H5Oget_info3(getId(), &objinfo, fields); // Throw exception if C API returns failure if (ret_value < 0) - throwException(inMemFunc("getObjinfo"), "H5Oget_info2 failed"); + throwException(inMemFunc("getObjinfo"), "H5Oget_info3 failed"); } //-------------------------------------------------------------------------- @@ -1447,10 +1562,10 @@ void H5Location::getObjinfo(H5O_info_t& objinfo, unsigned fields) const /// \li \c H5O_INFO_ALL // July, 2018 //-------------------------------------------------------------------------- -void H5Location::getObjinfo(const char* name, H5O_info_t& objinfo, unsigned fields, const LinkAccPropList& lapl) const +void H5Location::getObjinfo(const char* name, H5O_info2_t& objinfo, unsigned fields, const LinkAccPropList& lapl) const { // Use C API to get information of the object - herr_t ret_value = H5Oget_info_by_name2(getId(), name, &objinfo, fields, lapl.getId()); + herr_t ret_value = H5Oget_info_by_name3(getId(), name, &objinfo, fields, lapl.getId()); // Throw exception if C API returns failure if (ret_value < 0) @@ -1469,7 +1584,7 @@ void H5Location::getObjinfo(const char* name, H5O_info_t& objinfo, unsigned fiel ///\param lapl - IN: Link access property list // July, 2018 //-------------------------------------------------------------------------- -void H5Location::getObjinfo(const H5std_string& name, H5O_info_t& objinfo, unsigned fields, const LinkAccPropList& lapl) const +void H5Location::getObjinfo(const H5std_string& name, H5O_info2_t& objinfo, unsigned fields, const LinkAccPropList& lapl) const { getObjinfo(name.c_str(), objinfo, fields, lapl); } @@ -1496,11 +1611,11 @@ void H5Location::getObjinfo(const H5std_string& name, H5O_info_t& objinfo, unsig // July, 2018 //-------------------------------------------------------------------------- void H5Location::getObjinfo(const char* grp_name, H5_index_t idx_type, - H5_iter_order_t order, hsize_t idx, H5O_info_t& objinfo, unsigned fields, + H5_iter_order_t order, hsize_t idx, H5O_info2_t& objinfo, unsigned fields, const LinkAccPropList& lapl) const { // Use C API to get information of the object - herr_t ret_value = H5Oget_info_by_idx2(getId(), grp_name, idx_type, order, + herr_t ret_value = H5Oget_info_by_idx3(getId(), grp_name, idx_type, order, idx, &objinfo, fields, lapl.getId()); // Throw exception if C API returns failure @@ -1521,7 +1636,7 @@ void H5Location::getObjinfo(const char* grp_name, H5_index_t idx_type, // July, 2018 //-------------------------------------------------------------------------- void H5Location::getObjinfo(const H5std_string& grp_name, H5_index_t idx_type, - H5_iter_order_t order, hsize_t idx, H5O_info_t& objinfo, unsigned fields, + H5_iter_order_t order, hsize_t idx, H5O_info2_t& objinfo, unsigned fields, const LinkAccPropList& lapl) const { getObjinfo(grp_name.c_str(), idx_type, order, idx, objinfo, fields, lapl); @@ -1596,11 +1711,11 @@ void H5Location::getObjinfo(const H5std_string& name, H5G_stat_t& statbuf) const ///\exception H5::FileIException/H5::GroupIException/H5::LocationException // 2000 //-------------------------------------------------------------------------- -H5L_info_t H5Location::getLinkInfo(const char* link_name, const LinkAccPropList& lapl) const +H5L_info2_t H5Location::getLinkInfo(const char* link_name, const LinkAccPropList& lapl) const { - H5L_info_t linkinfo; // link info structure + H5L_info2_t linkinfo; // link info structure - herr_t ret_value = H5Lget_info(getId(), link_name, &linkinfo, lapl.getId()); + herr_t ret_value = H5Lget_info2(getId(), link_name, &linkinfo, lapl.getId()); if (ret_value < 0) throwException("getLinkInfo", "H5Lget_info to find buffer size failed"); @@ -1613,7 +1728,7 @@ H5L_info_t H5Location::getLinkInfo(const char* link_name, const LinkAccPropList& /// It differs from the above function in that it takes an /// \c H5std_string for \a link_name. //-------------------------------------------------------------------------- -H5L_info_t H5Location::getLinkInfo(const H5std_string& link_name, const LinkAccPropList& lapl) const +H5L_info2_t H5Location::getLinkInfo(const H5std_string& link_name, const LinkAccPropList& lapl) const { return(getLinkInfo(link_name.c_str(), lapl)); } @@ -1629,7 +1744,7 @@ H5L_info_t H5Location::getLinkInfo(const H5std_string& link_name, const LinkAccP //-------------------------------------------------------------------------- H5std_string H5Location::getLinkval(const char* name, size_t size) const { - H5L_info_t linkinfo; + H5L_info2_t linkinfo; char *value_C; // value in C string size_t val_size = size; H5std_string value = ""; @@ -1638,7 +1753,7 @@ H5std_string H5Location::getLinkval(const char* name, size_t size) const // if user doesn't provide buffer size, determine it if (size == 0) { - ret_value = H5Lget_info(getId(), name, &linkinfo, H5P_DEFAULT); + ret_value = H5Lget_info2(getId(), name, &linkinfo, H5P_DEFAULT); if (ret_value < 0) throwException("getLinkval", "H5Lget_info to find buffer size failed"); @@ -1941,11 +2056,11 @@ ssize_t H5Location::getObjnameByIdx(hsize_t idx, H5std_string& name, size_t size //-------------------------------------------------------------------------- H5O_type_t H5Location::childObjType(const char* objname) const { - H5O_info_t objinfo; + H5O_info2_t objinfo; H5O_type_t objtype = H5O_TYPE_UNKNOWN; // Use C API to get information of the object - herr_t ret_value = H5Oget_info_by_name2(getId(), objname, &objinfo, H5O_INFO_BASIC, H5P_DEFAULT); + herr_t ret_value = H5Oget_info_by_name3(getId(), objname, &objinfo, H5O_INFO_BASIC, H5P_DEFAULT); // Throw exception if C API returns failure if (ret_value < 0) @@ -2016,11 +2131,11 @@ H5O_type_t H5Location::childObjType(const H5std_string& objname) const H5O_type_t H5Location::childObjType(hsize_t index, H5_index_t index_type, H5_iter_order_t order, const char* objname) const { herr_t ret_value; - H5O_info_t objinfo; + H5O_info2_t objinfo; H5O_type_t objtype = H5O_TYPE_UNKNOWN; // Use C API to get information of the object - ret_value = H5Oget_info_by_idx2(getId(), objname, index_type, order, index, &objinfo, H5O_INFO_BASIC, H5P_DEFAULT); + ret_value = H5Oget_info_by_idx3(getId(), objname, index_type, order, index, &objinfo, H5O_INFO_BASIC, H5P_DEFAULT); // Throw exception if C API returns failure if (ret_value < 0) @@ -2058,11 +2173,11 @@ H5O_type_t H5Location::childObjType(hsize_t index, H5_index_t index_type, H5_ite //-------------------------------------------------------------------------- unsigned H5Location::childObjVersion(const char* objname) const { - H5O_info_t objinfo; + H5O_native_info_t objinfo; unsigned version = 0; // Use C API to get information of the object - herr_t ret_value = H5Oget_info_by_name2(getId(), objname, &objinfo, H5O_INFO_HDR, H5P_DEFAULT); + herr_t ret_value = H5Oget_native_info_by_name(getId(), objname, &objinfo, H5O_NATIVE_INFO_HDR, H5P_DEFAULT); // Throw exception if C API returns failure if (ret_value < 0) diff --git a/c++/src/H5Location.h b/c++/src/H5Location.h index dc3db75..3bad8bc 100644 --- a/c++/src/H5Location.h +++ b/c++/src/H5Location.h @@ -118,8 +118,8 @@ class H5_DLLCPP H5Location : public IdComponent { DataSet openDataSet(const char* name, const DSetAccPropList& dapl = DSetAccPropList::DEFAULT) const; DataSet openDataSet(const H5std_string& name, const DSetAccPropList& dapl = DSetAccPropList::DEFAULT) const; - H5L_info_t getLinkInfo(const char* link_name, const LinkAccPropList& lapl = LinkAccPropList::DEFAULT) const; - H5L_info_t getLinkInfo(const H5std_string& link_name, const LinkAccPropList& lapl = LinkAccPropList::DEFAULT) const; + H5L_info2_t getLinkInfo(const char* link_name, const LinkAccPropList& lapl = LinkAccPropList::DEFAULT) const; + H5L_info2_t getLinkInfo(const H5std_string& link_name, const LinkAccPropList& lapl = LinkAccPropList::DEFAULT) const; // Returns the value of a symbolic link. H5std_string getLinkval(const char* link_name, size_t size=0) const; @@ -147,26 +147,47 @@ class H5_DLLCPP H5Location : public IdComponent { unsigned childObjVersion(const H5std_string& objname) const; // Retrieves information about an HDF5 object. - void getObjinfo(H5O_info_t& objinfo, unsigned fields = H5O_INFO_BASIC) const; + void getObjinfo(H5O_info2_t& objinfo, unsigned fields = H5O_INFO_BASIC) const; // Retrieves information about an HDF5 object, given its name. - void getObjinfo(const char* name, H5O_info_t& objinfo, + void getObjinfo(const char* name, H5O_info2_t& objinfo, unsigned fields = H5O_INFO_BASIC, const LinkAccPropList& lapl = LinkAccPropList::DEFAULT) const; - void getObjinfo(const H5std_string& name, H5O_info_t& objinfo, + void getObjinfo(const H5std_string& name, H5O_info2_t& objinfo, unsigned fields = H5O_INFO_BASIC, const LinkAccPropList& lapl = LinkAccPropList::DEFAULT) const; // Retrieves information about an HDF5 object, given its index. void getObjinfo(const char* grp_name, H5_index_t idx_type, - H5_iter_order_t order, hsize_t idx, H5O_info_t& objinfo, + H5_iter_order_t order, hsize_t idx, H5O_info2_t& objinfo, unsigned fields = H5O_INFO_BASIC, const LinkAccPropList& lapl = LinkAccPropList::DEFAULT) const; void getObjinfo(const H5std_string& grp_name, H5_index_t idx_type, - H5_iter_order_t order, hsize_t idx, H5O_info_t& objinfo, + H5_iter_order_t order, hsize_t idx, H5O_info2_t& objinfo, unsigned fields = H5O_INFO_BASIC, const LinkAccPropList& lapl = LinkAccPropList::DEFAULT) const; + // Retrieves native native information about an HDF5 object. + void getNativeObjinfo(H5O_native_info_t& objinfo, unsigned fields = H5O_NATIVE_INFO_HDR) const; + + // Retrieves native information about an HDF5 object, given its name. + void getNativeObjinfo(const char* name, H5O_native_info_t& objinfo, + unsigned fields = H5O_NATIVE_INFO_HDR, + const LinkAccPropList& lapl = LinkAccPropList::DEFAULT) const; + void getNativeObjinfo(const H5std_string& name, H5O_native_info_t& objinfo, + unsigned fields = H5O_NATIVE_INFO_HDR, + const LinkAccPropList& lapl = LinkAccPropList::DEFAULT) const; + + // Retrieves native information about an HDF5 object, given its index. + void getNativeObjinfo(const char* grp_name, H5_index_t idx_type, + H5_iter_order_t order, hsize_t idx, H5O_native_info_t& objinfo, + unsigned fields = H5O_NATIVE_INFO_HDR, + const LinkAccPropList& lapl = LinkAccPropList::DEFAULT) const; + void getNativeObjinfo(const H5std_string& grp_name, H5_index_t idx_type, + H5_iter_order_t order, hsize_t idx, H5O_native_info_t& objinfo, + unsigned fields = H5O_NATIVE_INFO_HDR, + const LinkAccPropList& lapl = LinkAccPropList::DEFAULT) const; + #ifndef H5_NO_DEPRECATED_SYMBOLS // Returns the type of an object in this group, given the // object's index. diff --git a/c++/src/H5Object.cpp b/c++/src/H5Object.cpp index 8d3334b..081cab7 100644 --- a/c++/src/H5Object.cpp +++ b/c++/src/H5Object.cpp @@ -52,9 +52,9 @@ extern "C" herr_t userAttrOpWrpr(hid_t loc_id, const char *attr_name, } // userVisitOpWrpr interfaces between the user's function and the -// C library function H5Ovisit2 +// C library function H5Ovisit3 extern "C" herr_t userVisitOpWrpr(hid_t obj_id, const char *attr_name, - const H5O_info_t *obj_info, void *op_data) + const H5O_info2_t *obj_info, void *op_data) { H5std_string s_attr_name = H5std_string(attr_name); UserData4Visit* myData = reinterpret_cast (op_data); @@ -250,13 +250,11 @@ int H5Object::iterateAttrs(attr_operator_t user_op, unsigned *_idx, void *op_dat ///\param *op_data - IN: User-defined pointer to data required by the /// application for its processing of the object ///\param fields - IN: Flags specifying the fields to be retrieved -/// to the callback op via the H5O_info_t argument. +/// to the callback op via the H5O_info2_t argument. /// \li \c H5O_INFO_BASIC fileno, addr, type, and rc fields /// \li \c H5O_INFO_TIME atime, mtime, ctime, and btime fields /// \li \c H5O_INFO_NUM_ATTRS num_attrs field -/// \li \c H5O_INFO_HDR hdr field -/// \li \c H5O_INFO_META_SIZE meta_size field -/// \li \c H5O_INFO_ALL H5O_INFO_BASIC | H5O_INFO_TIME | H5O_INFO_NUM_ATTRS | H5O_INFO_HDR | H5O_INFO_META_SIZE +/// \li \c H5O_INFO_ALL H5O_INFO_BASIC | H5O_INFO_TIME | H5O_INFO_NUM_ATTRS ///\return /// \li On success: /// \li the return value of the first operator that returns a positive value @@ -266,7 +264,7 @@ int H5Object::iterateAttrs(attr_operator_t user_op, unsigned *_idx, void *op_dat /// wrong within the library or the operator failed ///\exception H5::Exception ///\par Description -/// For information, please refer to the H5Ovisit2 API in the HDF5 +/// For information, please refer to the H5Ovisit3 API in the HDF5 /// C Reference Manual. // Programmer Binh-Minh Ribler - Feb, 2019 //-------------------------------------------------------------------------- @@ -279,15 +277,15 @@ void H5Object::visit(H5_index_t idx_type, H5_iter_order_t order, visit_operator_ userData->obj = this; // Call the C API passing in op wrapper and info - herr_t ret_value = H5Ovisit2(getId(), idx_type, order, userVisitOpWrpr, static_cast(userData), fields); + herr_t ret_value = H5Ovisit3(getId(), idx_type, order, userVisitOpWrpr, static_cast(userData), fields); // Release memory delete userData; - // Throw exception if H5Ovisit2 failed, which could be a failure in + // Throw exception if H5Ovisit3 failed, which could be a failure in // the library or in the call back operator if (ret_value < 0) - throw Exception(inMemFunc("visit"), "H5Ovisit2 failed"); + throw Exception(inMemFunc("visit"), "H5Ovisit3 failed"); } //-------------------------------------------------------------------------- @@ -304,15 +302,15 @@ void H5Object::visit(H5_index_t idx_type, H5_iter_order_t order, visit_operator_ //-------------------------------------------------------------------------- unsigned H5Object::objVersion() const { - H5O_info_t objinfo; + H5O_native_info_t objinfo; unsigned version = 0; // Use C API to get information of the object - herr_t ret_value = H5Oget_info2(getId(), &objinfo, H5O_INFO_HDR); + herr_t ret_value = H5Oget_native_info(getId(), &objinfo, H5O_NATIVE_INFO_HDR); // Throw exception if C API returns failure if (ret_value < 0) - throw Exception(inMemFunc("objVersion"), "H5Oget_info failed"); + throw Exception(inMemFunc("objVersion"), "H5Oget_native_info failed"); // Return a valid version or throw an exception for invalid value else { @@ -332,9 +330,9 @@ unsigned H5Object::objVersion() const //-------------------------------------------------------------------------- int H5Object::getNumAttrs() const { - H5O_info_t oinfo; /* Object info */ + H5O_info2_t oinfo; /* Object info */ - if(H5Oget_info2(getId(), &oinfo, H5O_INFO_NUM_ATTRS) < 0) + if(H5Oget_info3(getId(), &oinfo, H5O_INFO_NUM_ATTRS) < 0) throw AttributeIException(inMemFunc("getNumAttrs"), "H5Oget_info failed"); else return(static_cast(oinfo.num_attrs)); diff --git a/c++/src/H5Object.h b/c++/src/H5Object.h index 4a4e909..033b1b7 100644 --- a/c++/src/H5Object.h +++ b/c++/src/H5Object.h @@ -44,10 +44,10 @@ typedef void (*attr_operator_t)(H5Object& loc, const H5std_string attr_name, void *operator_data); -// Define the operator function pointer for H5Ovisit2(). +// Define the operator function pointer for H5Ovisit3(). typedef int (*visit_operator_t)(H5Object& obj, const H5std_string attr_name, - const H5O_info_t *oinfo, + const H5O_info2_t *oinfo, void *operator_data); // User data for attribute iteration diff --git a/c++/test/dsets.cpp b/c++/test/dsets.cpp index 14f1bd4..fc29307 100644 --- a/c++/test/dsets.cpp +++ b/c++/test/dsets.cpp @@ -1116,9 +1116,9 @@ static herr_t test_types(H5File& file) /*------------------------------------------------------------------------- - * Function: test_getObjinfo + * Function: test_getNativeObjinfo * - * Purpose Tests getObjinfo() + * Purpose Tests getNativeObjinfo() * * Return Success: 0 * Failure: -1 @@ -1126,7 +1126,7 @@ static herr_t test_types(H5File& file) * July, 2018 *------------------------------------------------------------------------- */ -static herr_t test_getinfo(H5File& file) +static herr_t test_getnativeinfo(H5File& file) { SUBTEST("Getting object information"); @@ -1142,18 +1142,18 @@ static herr_t test_getinfo(H5File& file) DataSet dataset(file.openDataSet(DSET_CHUNKED_NAME)); // Get dataset header info - H5O_info_t oinfo; - HDmemset(&oinfo, 0, sizeof(oinfo)); - dataset.getObjinfo(oinfo, H5O_INFO_HDR); - verify_val(oinfo.hdr.nchunks, 1, "DataSet::getObjinfo", __LINE__, __FILE__); + H5O_native_info_t ninfo; + HDmemset(&ninfo, 0, sizeof(ninfo)); + dataset.getNativeObjinfo(ninfo, H5O_NATIVE_INFO_HDR); + verify_val(ninfo.hdr.nchunks, 1, "DataSet::getNativeObjinfo", __LINE__, __FILE__); dataset.close(); // Open the dataset we created above and then close it. This is one // way to open an existing dataset for accessing. dataset = file.openDataSet(DSET_DEFAULT_NAME); - HDmemset(&oinfo, 0, sizeof(oinfo)); - dataset.getObjinfo(oinfo, H5O_INFO_ALL); - verify_val(oinfo.hdr.nchunks, 1, "DataSet::getObjinfo", __LINE__, __FILE__); + HDmemset(&ninfo, 0, sizeof(ninfo)); + dataset.getNativeObjinfo(ninfo, H5O_NATIVE_INFO_ALL); + verify_val(ninfo.hdr.nchunks, 1, "DataSet::getNativeObjinfo", __LINE__, __FILE__); dataset.close(); PASSED(); @@ -1169,10 +1169,10 @@ static herr_t test_getinfo(H5File& file) // catch all other exceptions catch (Exception& E) { - issue_fail_msg("test_getinfo", __LINE__, __FILE__); + issue_fail_msg("test_getnativeinfo", __LINE__, __FILE__); return -1; } -} // test_getinfo +} // test_getnativeinfo /*------------------------------------------------------------------------- @@ -1408,7 +1408,7 @@ void test_dset() nerrors += test_create(file) < 0 ? 1:0; nerrors += test_simple_io(file) < 0 ? 1:0; - nerrors += test_getinfo(file) < 0 ? 1:0; + nerrors += test_getnativeinfo(file) < 0 ? 1:0; nerrors += test_tconv(file) < 0 ? 1:0; nerrors += test_compression(file) < 0 ? 1:0; nerrors += test_nbit_compression(file) < 0 ? 1:0; diff --git a/c++/test/tattr.cpp b/c++/test/tattr.cpp index 4734755..9485ec6 100644 --- a/c++/test/tattr.cpp +++ b/c++/test/tattr.cpp @@ -519,7 +519,7 @@ static void test_attr_basic_read() verify_val(num_attrs, 3, "DataSet::getNumAttrs", __LINE__, __FILE__); // Verify the correct number of attributes another way - H5O_info_t oinfo; + H5O_info2_t oinfo; HDmemset(&oinfo, 0, sizeof(oinfo)); dataset.getObjinfo(oinfo, H5O_INFO_NUM_ATTRS); verify_val(oinfo.num_attrs, 3, "DataSet::getObjinfo", __LINE__, __FILE__); @@ -670,7 +670,7 @@ static void test_attr_compound_read() verify_val(num_attrs, 1, "DataSet::getNumAttrs", __LINE__, __FILE__); // Verify the correct number of attributes another way - H5O_info_t oinfo; + H5O_info2_t oinfo; HDmemset(&oinfo, 0, sizeof(oinfo)); dataset.getObjinfo(oinfo, H5O_INFO_NUM_ATTRS); verify_val(oinfo.num_attrs, 1, "DataSet::getObjinfo", __LINE__, __FILE__); diff --git a/c++/test/tfile.cpp b/c++/test/tfile.cpp index 055cf23..a0231a6 100644 --- a/c++/test/tfile.cpp +++ b/c++/test/tfile.cpp @@ -716,10 +716,10 @@ static void test_libver_bounds_real( verify_val(obj_version, oh_vers_create, "H5File::childObjVersion", __LINE__, __FILE__); // Verify object header version another way - H5O_info_t oinfo; - HDmemset(&oinfo, 0, sizeof(oinfo)); - file.getObjinfo(oinfo, H5O_INFO_HDR); - verify_val(oinfo.hdr.version, oh_vers_create, "H5File::getObjinfo", __LINE__, __FILE__); + H5O_native_info_t ninfo; + HDmemset(&ninfo, 0, sizeof(ninfo)); + file.getNativeObjinfo(ninfo, H5O_NATIVE_INFO_HDR); + verify_val(ninfo.hdr.version, oh_vers_create, "H5File::getNativeObjinfo", __LINE__, __FILE__); /* * Reopen the file and make sure the root group still has the correct @@ -744,9 +744,9 @@ static void test_libver_bounds_real( verify_val(obj_version, oh_vers_mod, "Group::objVersion", __LINE__, __FILE__); // Verify object header version another way - HDmemset(&oinfo, 0, sizeof(oinfo)); - group.getObjinfo(oinfo, H5O_INFO_HDR); - verify_val(oinfo.hdr.version, oh_vers_mod, "Group::getObjinfo", __LINE__, __FILE__); + HDmemset(&ninfo, 0, sizeof(ninfo)); + group.getNativeObjinfo(ninfo, H5O_NATIVE_INFO_HDR); + verify_val(ninfo.hdr.version, oh_vers_mod, "Group::getNativeObjinfo", __LINE__, __FILE__); group.close(); // close "/G1" diff --git a/c++/test/titerate.cpp b/c++/test/titerate.cpp index e77ebcc..c689087 100644 --- a/c++/test/titerate.cpp +++ b/c++/test/titerate.cpp @@ -96,7 +96,7 @@ int iter_strcmp(const void *s1, const void *s2) * Purpose Custom link iteration callback routine *------------------------------------------------------------------------- */ -static herr_t liter_cb(hid_t H5_ATTR_UNUSED group, const char *name, const H5L_info_t H5_ATTR_UNUSED *link_info, void *op_data) +static herr_t liter_cb(hid_t H5_ATTR_UNUSED group, const char *name, const H5L_info2_t H5_ATTR_UNUSED *link_info, void *op_data) { iter_info *info = (iter_info *)op_data; static int count = 0; @@ -158,7 +158,7 @@ static void test_iter_group(FileAccPropList& fapl) /* Test iterating over empty group */ info.command = RET_ZERO; idx = 0; - ret = H5Literate(file.getId(), H5_INDEX_NAME, H5_ITER_INC, &idx, liter_cb, &info); + ret = H5Literate2(file.getId(), H5_INDEX_NAME, H5_ITER_INC, &idx, liter_cb, &info); verify_val(ret, SUCCEED, "H5Literate", __LINE__, __FILE__); DataType datatype(PredType::NATIVE_INT); @@ -207,7 +207,7 @@ static void test_iter_group(FileAccPropList& fapl) H5std_string obj_name; for (i = 0; i < nobjs; i++) { - //H5O_info_t oinfo; /* Object info */ + //H5O_info2_t oinfo; /* Object info */ obj_name = root_group.getObjnameByIdx(i); //ret = (herr_t)H5Lget_name_by_idx(root_group, ".", H5_INDEX_NAME, H5_ITER_INC, (hsize_t)i, dataset_name, (size_t)NAMELEN, H5P_DEFAULT); @@ -287,7 +287,7 @@ static void test_iter_group(FileAccPropList& fapl) /* Test all objects in group, when callback always returns 0 */ info.command = RET_ZERO; idx = 0; - if((ret = H5Literate(file, H5_INDEX_NAME, H5_ITER_INC, &idx, liter_cb, &info)) > 0) + if((ret = H5Literate2(file, H5_INDEX_NAME, H5_ITER_INC, &idx, liter_cb, &info)) > 0) TestErrPrintf("Group iteration function didn't return zero correctly!\n"); /* Test all objects in group, when callback always returns 1 */ @@ -295,7 +295,7 @@ static void test_iter_group(FileAccPropList& fapl) info.command = RET_TWO; i = 0; idx = 0; - while((ret = H5Literate(file, H5_INDEX_NAME, H5_ITER_INC, &idx, liter_cb, &info)) > 0) { + while((ret = H5Literate2(file, H5_INDEX_NAME, H5_ITER_INC, &idx, liter_cb, &info)) > 0) { /* Verify return value from iterator gets propagated correctly */ verify_val(ret, 2, "H5Literate", __LINE__, __FILE__); @@ -321,7 +321,7 @@ static void test_iter_group(FileAccPropList& fapl) info.command = new_format ? RET_CHANGE2 : RET_CHANGE; i = 0; idx = 0; - while((ret = H5Literate(file, H5_INDEX_NAME, H5_ITER_INC, &idx, liter_cb, &info)) >= 0) { + while((ret = H5Literate2(file, H5_INDEX_NAME, H5_ITER_INC, &idx, liter_cb, &info)) >= 0) { /* Verify return value from iterator gets propagated correctly */ verify_val(ret, 1, "H5Literate", __LINE__, __FILE__); diff --git a/c++/test/tlinks.cpp b/c++/test/tlinks.cpp index 491cd6a..1bdd442 100644 --- a/c++/test/tlinks.cpp +++ b/c++/test/tlinks.cpp @@ -190,7 +190,7 @@ const H5std_string GROUP2NAME("Second_group"); static void test_lcpl(hid_t fapl_id, hbool_t new_format) { - H5L_info_t linfo; + H5L_info2_t linfo; char filename[1024]; hsize_t dims[2]; @@ -604,7 +604,7 @@ const int RANK = 2; const int DIM1 = 2; // Operator function -static int visit_obj_cb(H5Object& obj, const H5std_string name, const H5O_info_t *oinfo, void *_op_data) +static int visit_obj_cb(H5Object& obj, const H5std_string name, const H5O_info2_t *oinfo, void *_op_data) { ovisit_ud_t *op_data = static_cast (_op_data); diff --git a/c++/test/tobject.cpp b/c++/test/tobject.cpp index 232ece2..fd0f5ce 100644 --- a/c++/test/tobject.cpp +++ b/c++/test/tobject.cpp @@ -542,7 +542,7 @@ const H5std_string GROUP1NAME("group1"); const H5std_string GROUP2NAME("group2"); static void test_getobjectinfo_same_file() { - H5O_info_t oinfo1, oinfo2; /* Object info structs */ + H5O_info2_t oinfo1, oinfo2; /* Object info structs */ // Output message about test being performed SUBTEST("Group::getObjinfo"); diff --git a/c++/test/trefer.cpp b/c++/test/trefer.cpp index 562b127..8a6fb51 100644 --- a/c++/test/trefer.cpp +++ b/c++/test/trefer.cpp @@ -482,7 +482,7 @@ static void test_reference_group() verify_val(fname, FILE1, "H5Group::getFileName",__LINE__,__FILE__); // Check object type using Group::getObjinfo() - H5O_info_t oinfo; + H5O_info2_t oinfo; HDmemset(&oinfo, 0, sizeof(oinfo)); group.getObjinfo(".", H5_INDEX_NAME, H5_ITER_INC, (hsize_t)0, oinfo); verify_val(oinfo.type, H5O_TYPE_DATASET, "Group::getObjinfo",__LINE__,__FILE__); diff --git a/examples/h5_attribute.c b/examples/h5_attribute.c index e3b5759..0e275c7 100644 --- a/examples/h5_attribute.c +++ b/examples/h5_attribute.c @@ -60,7 +60,7 @@ main (void) float matrix[ADIM1][ADIM2]; /* Attribute data */ herr_t ret; /* Return value */ - H5O_info_t oinfo; /* Object info */ + H5O_info2_t oinfo; /* Object info */ unsigned i, j; /* Counters */ char string_out[80]; /* Buffer to read string attribute back */ int point_out; /* Buffer to read scalar attribute back */ @@ -189,7 +189,7 @@ main (void) /* * Find string attribute by iterating through all attributes */ - ret = H5Oget_info2(dataset, &oinfo, H5O_INFO_ALL); + ret = H5Oget_info3(dataset, &oinfo, H5O_INFO_NUM_ATTRS); for(i = 0; i < (unsigned)oinfo.num_attrs; i++) { attr = H5Aopen_by_idx(dataset, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, (hsize_t)i, H5P_DEFAULT, H5P_DEFAULT); atype = H5Aget_type(attr); diff --git a/examples/h5_extlink.c b/examples/h5_extlink.c index 229e465..fea1fa2 100644 --- a/examples/h5_extlink.c +++ b/examples/h5_extlink.c @@ -316,7 +316,7 @@ static void hard_link_example(void) { hid_t file_id; hid_t group_id; - H5L_info_t li; + H5L_info2_t li; /* Define the link class that we'll use to register "user-defined hard * links" using the callbacks we defined above. * A link class can have NULL for any callback except its traverse @@ -361,13 +361,13 @@ static void hard_link_example(void) * the target group's address. We do this by calling H5Lget_info * on a hard link to the object. */ - H5Lget_info(file_id, TARGET_GROUP, &li, H5P_DEFAULT); + H5Lget_info2(file_id, TARGET_GROUP, &li, H5P_DEFAULT); /* Now create a user-defined link. We give it the group's address * as its udata. */ - H5Lcreate_ud(file_id, UD_HARD_LINK_NAME, (H5L_type_t)UD_HARD_CLASS, &(li.u.address), - sizeof(li.u.address), H5P_DEFAULT, H5P_DEFAULT); + H5Lcreate_ud(file_id, UD_HARD_LINK_NAME, (H5L_type_t)UD_HARD_CLASS, &(li.u.token), + sizeof(H5O_token_t), H5P_DEFAULT, H5P_DEFAULT); /* The UD hard link has now incremented the group's reference count * like a normal hard link would. This means that we can unlink the @@ -404,23 +404,23 @@ static void hard_link_example(void) static herr_t UD_hard_create(const char *link_name, hid_t loc_group, const void *udata, size_t udata_size, hid_t lcpl_id) { - haddr_t addr; - hid_t target_obj = -1; + H5O_token_t token; + hid_t target_obj = H5I_INVALID_HID; herr_t ret_value = 0; /* Make sure that the address passed in looks valid */ - if(udata_size != sizeof(haddr_t)) + if(udata_size != sizeof(H5O_token_t)) { ret_value = -1; goto done; } - addr = *((const haddr_t *) udata); + token = *((H5O_token_t *) udata); /* Open the object this link points to so that we can increment - * its reference count. This also ensures that the address passed + * its reference count. This also ensures that the token passed * in points to a real object (although this check is not perfect!) */ - target_obj= H5Oopen_by_addr(loc_group, addr); + target_obj = H5Oopen_by_token(loc_group, token); if(target_obj < 0) { ret_value = -1; @@ -448,23 +448,23 @@ done: static herr_t UD_hard_delete(const char *link_name, hid_t loc_group, const void *udata, size_t udata_size) { - haddr_t addr; - hid_t target_obj = -1; + H5O_token_t token; + hid_t target_obj = H5I_INVALID_HID; herr_t ret_value = 0; /* Sanity check; we have already verified the udata's size in the creation * callback. */ - if(udata_size != sizeof(haddr_t)) + if(udata_size != sizeof(H5O_token_t)) { ret_value = -1; goto done; } - addr = *((const haddr_t *) udata); + token = *((H5O_token_t *) udata); /* Open the object this link points to */ - target_obj= H5Oopen_by_addr(loc_group, addr); + target_obj = H5Oopen_by_token(loc_group, token); if(target_obj < 0) { ret_value = -1; @@ -492,21 +492,21 @@ done: static hid_t UD_hard_traverse(const char *link_name, hid_t cur_group, const void *udata, size_t udata_size, hid_t lapl_id, hid_t dxpl_id) { - haddr_t addr; - hid_t ret_value = -1; + H5O_token_t token; + hid_t ret_value = H5I_INVALID_HID; /* Sanity check; we have already verified the udata's size in the creation * callback. */ - if(udata_size != sizeof(haddr_t)) - return -1; + if(udata_size != sizeof(H5O_token_t)) + return H5I_INVALID_HID; - addr = *((const haddr_t *) udata); + token = *((H5O_token_t *) udata); - /* Open the object by address. If H5Oopen_by_addr fails, ret_value will + /* Open the object by token. If H5Oopen_by_token fails, ret_value will * be negative to indicate that the traversal function failed. */ - ret_value = H5Oopen_by_addr(cur_group, addr); + ret_value = H5Oopen_by_token(cur_group, token); return ret_value; } @@ -621,7 +621,7 @@ static hid_t UD_plist_traverse(const char *link_name, hid_t cur_group, const void *udata, size_t udata_size, hid_t lapl_id, hid_t dxpl_id) { char * path; - hid_t ret_value = -1; + hid_t ret_value = H5I_INVALID_HID; /* If the link property isn't set or can't be found, traversal fails. */ if(H5Pexist(lapl_id, PLIST_LINK_PROP) < 0) @@ -638,7 +638,7 @@ static hid_t UD_plist_traverse(const char *link_name, hid_t cur_group, return ret_value; error: - return -1; + return H5I_INVALID_HID; } diff --git a/examples/h5_group.c b/examples/h5_group.c index 8e89165..75bed91 100644 --- a/examples/h5_group.c +++ b/examples/h5_group.c @@ -26,9 +26,9 @@ #define H5FILE_NAME "group.h5" #define RANK 2 -static herr_t file_info(hid_t loc_id, const char *name, const H5L_info_t *linfo, +static herr_t file_info(hid_t loc_id, const char *name, const H5L_info2_t *linfo, void *opdata); /* Link iteration operator function */ -static herr_t group_info(hid_t loc_id, const char *name, const H5L_info_t *linfo, +static herr_t group_info(hid_t loc_id, const char *name, const H5L_info2_t *linfo, void *opdata); /* Link iteration operator function */ int main(void) @@ -135,7 +135,7 @@ main(void) /* * Use iterator to see the names of the objects in the root group. */ - idx_f = H5Literate(file, H5_INDEX_NAME, H5_ITER_INC, NULL, file_info, NULL); + idx_f = H5Literate2(file, H5_INDEX_NAME, H5_ITER_INC, NULL, file_info, NULL); /* * Unlink name "Data" and use iterator to see the names @@ -146,13 +146,13 @@ main(void) else printf("\"Data\" is unlinked \n"); - idx_f = H5Literate(file, H5_INDEX_NAME, H5_ITER_INC, NULL, file_info, NULL); + idx_f = H5Literate2(file, H5_INDEX_NAME, H5_ITER_INC, NULL, file_info, NULL); /* * Use iterator to see the names of the objects in the group * /Data_new. */ - idx_g = H5Literate_by_name(grp, "/Data_new", H5_INDEX_NAME, H5_ITER_INC, NULL, group_info, NULL, H5P_DEFAULT); + idx_g = H5Literate_by_name2(grp, "/Data_new", H5_INDEX_NAME, H5_ITER_INC, NULL, group_info, NULL, H5P_DEFAULT); /* * Close the file. @@ -168,7 +168,7 @@ main(void) * Operator function. */ static herr_t -file_info(hid_t loc_id, const char *name, const H5L_info_t *linfo, void *opdata) +file_info(hid_t loc_id, const char *name, const H5L_info2_t *linfo, void *opdata) { /* avoid compiler warnings */ loc_id = loc_id; @@ -189,7 +189,7 @@ file_info(hid_t loc_id, const char *name, const H5L_info_t *linfo, void *opdata) * Operator function. */ static herr_t -group_info(hid_t loc_id, const char *name, const H5L_info_t *linfo, void *opdata) +group_info(hid_t loc_id, const char *name, const H5L_info2_t *linfo, void *opdata) { hid_t did; /* dataset identifier */ hid_t tid; /* datatype identifier */ diff --git a/examples/testh5cc.sh.in b/examples/testh5cc.sh.in index 800d4d4..40ca466 100644 --- a/examples/testh5cc.sh.in +++ b/examples/testh5cc.sh.in @@ -308,8 +308,8 @@ echo "***"Version compatibility tests. # If H5_NO_DEPRECATED_SYMBOLS; # then only v18main works. # else if H5_USE_16_API_DEFAULT; -# then v16main works and -DH5_NO_DEPRECATED_SYMBOLS v18main also works. -# else v18main works and -DH5_USE_16_API_DEFAULT v16main also works. +# then v16main works. +# else v18main works and -DH5_USE_16_API_DEFAULT v16main also works. # if [ -n "$H5_USE_16_API_DEFAULT" ]; then echo "H5_USE_16_API_DEFAULT is defined." @@ -326,7 +326,6 @@ if [ -n "$H5_NO_DEPRECATED_SYMBOLS" ]; then TOOLTEST $v18main elif [ -n "$H5_USE_16_API_DEFAULT" ]; then TOOLTEST $v16main - TOOLTEST -DH5_NO_DEPRECATED_SYMBOLS $v18main else TOOLTEST -DH5_USE_16_API_DEFAULT $v16main TOOLTEST $v18main diff --git a/fortran/src/H5Af.c b/fortran/src/H5Af.c index 31a18fc..5e5bcc0 100644 --- a/fortran/src/H5Af.c +++ b/fortran/src/H5Af.c @@ -137,13 +137,13 @@ int_f h5aget_num_attrs_c (hid_t_f *obj_id, int_f *attr_num) /******/ { - H5O_info_t oinfo; /* Object info */ + H5O_info2_t oinfo; /* Object info */ int_f ret_value = 0; /* Return value */ /* * Call H5Oget_info function. */ - if(H5Oget_info2((hid_t)*obj_id, &oinfo, H5O_INFO_NUM_ATTRS) < 0) + if(H5Oget_info3((hid_t)*obj_id, &oinfo, H5O_INFO_NUM_ATTRS) < 0) HGOTO_DONE(FAIL); /* Set number of attributes */ diff --git a/fortran/src/H5Gf.c b/fortran/src/H5Gf.c index def67e1..770752d 100644 --- a/fortran/src/H5Gf.c +++ b/fortran/src/H5Gf.c @@ -170,7 +170,7 @@ h5gget_obj_info_idx_c(hid_t_f *loc_id, _fcd name, int_f *namelen, int_f *idx, _fcd obj_name, int_f *obj_namelen, int_f *obj_type) /******/ { - H5O_info_t oinfo; + H5O_info2_t oinfo; hid_t c_loc_id = (hid_t)*loc_id; char *c_name = NULL; size_t c_obj_namelen; @@ -200,7 +200,7 @@ h5gget_obj_info_idx_c(hid_t_f *loc_id, _fcd name, int_f *namelen, int_f *idx, /* Query the object's information */ if(H5Lget_name_by_idx(gid, ".", H5_INDEX_NAME, H5_ITER_INC, c_idx, c_obj_name, c_obj_namelen, H5P_DEFAULT) < 0) goto DONE; - if(H5Oget_info_by_idx2(gid, ".", H5_INDEX_NAME, H5_ITER_INC, c_idx, &oinfo, H5O_INFO_BASIC, H5P_DEFAULT) < 0) + if(H5Oget_info_by_idx3(gid, ".", H5_INDEX_NAME, H5_ITER_INC, c_idx, &oinfo, H5O_INFO_BASIC, H5P_DEFAULT) < 0) goto DONE; /* XXX: Switch from using H5Gget_objtype_by_idx() means that this routine won't diff --git a/fortran/src/H5Lf.c b/fortran/src/H5Lf.c index 31fedfd..b5ff7f2 100644 --- a/fortran/src/H5Lf.c +++ b/fortran/src/H5Lf.c @@ -441,7 +441,7 @@ done: * H5L_LINK_SOFT_F - Soft link * H5L_LINK_EXTERNAL_F - External link * H5L_LINK_ERROR_F - Error - * address - If the link is a hard link, address specifies the file address that the link points to + * token - If the link is a hard link, token specifies the token for the object that the link points to * val_size - If the link is a symbolic link, val_size will be the length of the link value * * RETURNS @@ -456,13 +456,12 @@ done: int_f h5lget_info_c(hid_t_f *link_loc_id, _fcd link_name, size_t_f *link_namelen, int_f *cset, int_f *corder, int_f *corder_valid, int_f *link_type, - haddr_t_f *address, size_t_f *val_size, - hid_t_f *lapl_id) + H5O_token_t *token, size_t_f *val_size, hid_t_f *lapl_id) /******/ { char *c_link_name = NULL; /* Buffer to hold C string */ int_f ret_value = 0; /* Return value */ - H5L_info_t link_buff; + H5L_info2_t link_buff; /* * Convert FORTRAN name to C name @@ -473,7 +472,7 @@ h5lget_info_c(hid_t_f *link_loc_id, _fcd link_name, size_t_f *link_namelen, /* * Call H5Linfo function. */ - if(H5Lget_info((hid_t)*link_loc_id, c_link_name, &link_buff, (hid_t)*lapl_id) < 0) + if(H5Lget_info2((hid_t)*link_loc_id, c_link_name, &link_buff, (hid_t)*lapl_id) < 0) HGOTO_DONE(FAIL); /* Unpack the structure */ @@ -482,7 +481,7 @@ h5lget_info_c(hid_t_f *link_loc_id, _fcd link_name, size_t_f *link_namelen, *corder_valid = 0; if(link_buff.corder_valid > 0) *corder_valid = 1; *link_type = (int_f)link_buff.type; - *address = (haddr_t_f)link_buff.u.address; + *token = link_buff.u.token; *val_size = (size_t_f)link_buff.u.val_size; done: @@ -525,14 +524,15 @@ done: int_f h5lget_info_by_idx_c(hid_t_f *loc_id, _fcd group_name, size_t_f *group_namelen, int_f *index_field, int_f *order, hsize_t_f *n, - int_f *link_type, int_f *corder_valid, int_f *corder, int_f *cset, haddr_t_f *address, size_t_f *val_size, hid_t_f *lapl_id) + int_f *link_type, int_f *corder_valid, int_f *corder, + int_f *cset, H5O_token_t *token, size_t_f *val_size, hid_t_f *lapl_id) /******/ { char *c_group_name = NULL; /* Buffer to hold C string */ H5_index_t c_index_field; H5_iter_order_t c_order; int_f ret_value = 0; /* Return value */ - H5L_info_t link_buff; + H5L_info2_t link_buff; /* * Convert FORTRAN name to C name @@ -545,7 +545,7 @@ h5lget_info_by_idx_c(hid_t_f *loc_id, _fcd group_name, size_t_f *group_namelen, /* * Call H5Linfo_by_idx function. */ - if(H5Lget_info_by_idx((hid_t)*loc_id, c_group_name, c_index_field, c_order, (hsize_t)*n, + if(H5Lget_info_by_idx2((hid_t)*loc_id, c_group_name, c_index_field, c_order, (hsize_t)*n, &link_buff, (hid_t)*lapl_id) < 0) HGOTO_DONE(FAIL); @@ -557,7 +557,7 @@ h5lget_info_by_idx_c(hid_t_f *loc_id, _fcd group_name, size_t_f *group_namelen, *corder = (int_f)link_buff.corder; *cset = (int_f)link_buff.cset; *link_type = (int_f)link_buff.type; - *address = (haddr_t_f)link_buff.u.address; + *token = link_buff.u.token; *val_size = (size_t_f)link_buff.u.val_size; done: @@ -988,7 +988,7 @@ done: * SOURCE */ int_f -h5literate_c(hid_t_f *group_id, int_f *index_type, int_f *order, hsize_t_f *idx, H5L_iterate_t op, void *op_data ) +h5literate_c(hid_t_f *group_id, int_f *index_type, int_f *order, hsize_t_f *idx, H5L_iterate2_t op, void *op_data ) /******/ { int_f ret_value = -1; /* Return value */ @@ -1001,7 +1001,7 @@ h5literate_c(hid_t_f *group_id, int_f *index_type, int_f *order, hsize_t_f *idx, * Call H5Linterate */ - func_ret_value = H5Literate( (hid_t)*group_id, (H5_index_t)*index_type, (H5_iter_order_t)*order, &idx_c, op, op_data); + func_ret_value = H5Literate2( (hid_t)*group_id, (H5_index_t)*index_type, (H5_iter_order_t)*order, &idx_c, op, op_data); ret_value = (int_f)func_ret_value; *idx = (hsize_t_f)idx_c; @@ -1038,7 +1038,7 @@ h5literate_c(hid_t_f *group_id, int_f *index_type, int_f *order, hsize_t_f *idx, * SOURCE */ int_f -h5literate_by_name_c(hid_t_f *loc_id, _fcd name, size_t_f *namelen, int_f *index_type, int_f *order, hsize_t_f *idx, H5L_iterate_t op, void *op_data, hid_t_f *lapl_id) +h5literate_by_name_c(hid_t_f *loc_id, _fcd name, size_t_f *namelen, int_f *index_type, int_f *order, hsize_t_f *idx, H5L_iterate2_t op, void *op_data, hid_t_f *lapl_id) /******/ { int_f ret_value = -1; /* Return value */ @@ -1058,7 +1058,7 @@ h5literate_by_name_c(hid_t_f *loc_id, _fcd name, size_t_f *namelen, int_f *index * Call H5Linterate */ - func_ret_value = H5Literate_by_name((hid_t)*loc_id, c_name,(H5_index_t)*index_type,(H5_iter_order_t)*order,&idx_c,op,op_data,(hid_t)*lapl_id); + func_ret_value = H5Literate_by_name2((hid_t)*loc_id, c_name,(H5_index_t)*index_type,(H5_iter_order_t)*order,&idx_c,op,op_data,(hid_t)*lapl_id); ret_value = (int_f)func_ret_value; *idx = (hsize_t_f)idx_c; diff --git a/fortran/src/H5Lff.F90 b/fortran/src/H5Lff.F90 index d5bb1d1..f672547 100644 --- a/fortran/src/H5Lff.F90 +++ b/fortran/src/H5Lff.F90 @@ -46,7 +46,7 @@ MODULE H5L ! Fortran2003 Derived Type: ! TYPE, bind(c) :: union_t - INTEGER(haddr_t) :: address + TYPE(H5O_TOKEN_T_F) :: token INTEGER(size_t) :: val_size END TYPE union_t @@ -604,7 +604,7 @@ CONTAINS ! H5L_TYPE_SOFT_F - Soft link ! H5L_TYPE_EXTERNAL_F - External link ! H5L_TYPE_ERROR_ F - Error -! address - If the link is a hard link, address specifies the file address that the link points to +! token - If the link is a hard link, token specifies the object token that the link points to ! val_size - If the link is a symbolic link, val_size will be the length of the link value, e.g., ! the length of the name of the pointed-to object with a null terminator. ! hdferr - Returns 0 if successful and -1 if fails @@ -625,7 +625,7 @@ CONTAINS ! ! SOURCE SUBROUTINE h5lget_info_f(link_loc_id, link_name, & - cset, corder, f_corder_valid, link_type, address, val_size, & + cset, corder, f_corder_valid, link_type, token, val_size, & hdferr, lapl_id) IMPLICIT NONE @@ -641,7 +641,7 @@ CONTAINS ! H5L_TYPE_SOFT_F - Soft link ! H5L_TYPE_EXTERNAL_F - External link ! H5L_TYPE_ERROR _F - Error - INTEGER(HADDR_T), INTENT(OUT) :: address ! If the link is a hard link, address specifies the file address that the link points to + TYPE(H5O_TOKEN_T_F), INTENT(OUT), TARGET :: token ! If the link is a hard link, token specifies the object token that the link points to INTEGER(SIZE_T), INTENT(OUT) :: val_size ! If the link is a symbolic link, val_size will be the length of the link value, e.g., ! the length of the name of the pointed-to object with a null terminator. INTEGER, INTENT(OUT) :: hdferr ! Error code: @@ -654,17 +654,17 @@ CONTAINS INTERFACE INTEGER FUNCTION h5lget_info_c(link_loc_id, link_name, link_namelen, & - cset, corder, corder_valid, link_type, address, val_size, & + cset, corder, corder_valid, link_type, token, val_size, & lapl_id_default) BIND(C,NAME='h5lget_info_c') IMPORT :: c_char - IMPORT :: HID_T, SIZE_T, HADDR_T + IMPORT :: HID_T, SIZE_T, H5O_TOKEN_T_F IMPLICIT NONE INTEGER(HID_T), INTENT(IN) :: link_loc_id CHARACTER(KIND=C_CHAR), DIMENSION(*), INTENT(IN) :: link_name INTEGER, INTENT(OUT) :: cset INTEGER, INTENT(OUT) :: corder INTEGER, INTENT(OUT) :: link_type - INTEGER(HADDR_T), INTENT(OUT) :: address + TYPE(H5O_TOKEN_T_F), INTENT(OUT) :: token INTEGER(SIZE_T), INTENT(OUT) :: val_size INTEGER(HID_T) :: lapl_id_default INTEGER(SIZE_T) :: link_namelen @@ -677,10 +677,8 @@ CONTAINS lapl_id_default = H5P_DEFAULT_F IF(PRESENT(lapl_id)) lapl_id_default = lapl_id - hdferr = h5lget_info_c(link_loc_id, link_name, link_namelen, & - cset, corder, corder_valid, link_type, & - address, val_size, & - lapl_id_default) + hdferr = h5lget_info_c(link_loc_id, link_name, link_namelen, cset, & + corder, corder_valid, link_type, token, val_size, lapl_id_default) f_corder_valid =.FALSE. IF(corder_valid .EQ. 1) f_corder_valid =.TRUE. @@ -708,8 +706,8 @@ CONTAINS ! corder_valid - Indicates whether the creation order data is valid for this attribute ! corder - Is a positive integer containing the creation order of the attribute ! cset - Indicates the character set used for the attribute’s name -! address - If the link is a hard link, address specifies the file address that the link points to -! val_size - If the link is a symbolic link, val_size will be the length of the link value, e.g., +! token - If the link is a hard link, token specifies the object token that the link points to +! val_size - If the link is a symbolic link, val_size will be the length of the link value, e.g., ! the length of the name of the pointed-to object with a null terminator. ! hdferr - Returns 0 if successful and -1 if fails ! @@ -729,7 +727,7 @@ CONTAINS ! ! SOURCE SUBROUTINE h5lget_info_by_idx_f(loc_id, group_name, index_field, order, n, & - link_type, f_corder_valid, corder, cset, address, val_size, hdferr, lapl_id) + link_type, f_corder_valid, corder, cset, token, val_size, hdferr, lapl_id) IMPLICIT NONE INTEGER(HID_T), INTENT(IN) :: loc_id ! File or group identifier specifying location of subject group CHARACTER(LEN=*), INTENT(IN) :: group_name ! Name of subject group @@ -752,7 +750,7 @@ CONTAINS LOGICAL, INTENT(OUT) :: f_corder_valid ! Indicates whether the creation order data is valid for this attribute INTEGER, INTENT(OUT) :: corder ! Is a positive integer containing the creation order of the attribute INTEGER, INTENT(OUT) :: cset ! Indicates the character set used for the attribute’s name - INTEGER(HADDR_T), INTENT(OUT) :: address ! If the link is a hard link, address specifies the file address that the link points to + TYPE(H5O_TOKEN_T_F), INTENT(OUT), TARGET :: token ! If the link is a hard link, token specifies the object token that the link points to INTEGER(SIZE_T), INTENT(OUT) :: val_size ! If the link is a symbolic link, val_size will be the length of the link value, e.g., ! the length of the name of the pointed-to object with a null terminator. INTEGER, INTENT(OUT) :: hdferr ! Error code: @@ -767,10 +765,10 @@ CONTAINS ! INTERFACE INTEGER FUNCTION h5lget_info_by_idx_c(loc_id, group_name, group_namelen, index_field, order, n, & - link_type, corder_valid, corder, cset, address, val_size, lapl_id_default) & + link_type, corder_valid, corder, cset, token, val_size, lapl_id_default) & BIND(C,NAME='h5lget_info_by_idx_c') IMPORT :: c_char - IMPORT :: HID_T, SIZE_T, HSIZE_T, HADDR_T + IMPORT :: HID_T, SIZE_T, HSIZE_T, H5O_TOKEN_T_F IMPLICIT NONE INTEGER(HID_T), INTENT(IN) :: loc_id CHARACTER(KIND=C_CHAR), DIMENSION(*), INTENT(IN) :: group_name @@ -779,10 +777,10 @@ CONTAINS INTEGER, INTENT(IN) :: order INTEGER(HSIZE_T), INTENT(IN) :: n INTEGER, INTENT(OUT) :: link_type - INTEGER :: corder_valid + INTEGER :: corder_valid INTEGER, INTENT(OUT) :: corder INTEGER, INTENT(OUT) :: cset - INTEGER(HADDR_T), INTENT(OUT) :: address + TYPE(H5O_TOKEN_T_F), INTENT(OUT) :: token INTEGER(SIZE_T), INTENT(OUT) :: val_size INTEGER(HID_T) :: lapl_id_default END FUNCTION h5lget_info_by_idx_c @@ -794,7 +792,7 @@ CONTAINS IF(PRESENT(lapl_id)) lapl_id_default = lapl_id hdferr = h5lget_info_by_idx_c(loc_id, group_name, group_namelen, index_field, order, n, & - link_type, corder_valid, corder, cset, address, val_size, lapl_id_default) + link_type, corder_valid, corder, cset, token, val_size, lapl_id_default) f_corder_valid =.FALSE. IF (corder_valid .EQ. 1) f_corder_valid =.TRUE. diff --git a/fortran/src/H5Of.c b/fortran/src/H5Of.c index 08305ea..9780814 100644 --- a/fortran/src/H5Of.c +++ b/fortran/src/H5Of.c @@ -22,10 +22,10 @@ #include "H5f90.h" #include "H5Eprivate.h" int_f -fill_h5o_info_t_f(H5O_info_t Oinfo, H5O_info_t_f *object_info); +fill_h5o_info_t_f(H5O_info2_t Oinfo, H5O_info_t_f *object_info); int_f -fill_h5o_info_t_f(H5O_info_t Oinfo, H5O_info_t_f *object_info) { +fill_h5o_info_t_f(H5O_info2_t Oinfo, H5O_info_t_f *object_info) { /* This function does not used the field parameter because we want * this function to fill the unfilled fields with C's default values. @@ -34,7 +34,7 @@ fill_h5o_info_t_f(H5O_info_t Oinfo, H5O_info_t_f *object_info) { struct tm *ts; object_info->fileno = Oinfo.fileno; - object_info->addr = (haddr_t_f)Oinfo.addr; + object_info->token = Oinfo.token; object_info->type = (int_f)Oinfo.type; object_info->rc = (int_f)Oinfo.rc; @@ -85,24 +85,6 @@ fill_h5o_info_t_f(H5O_info_t Oinfo, H5O_info_t_f *object_info) { object_info->num_attrs = (hsize_t_f)Oinfo.num_attrs; - object_info->hdr.version = (int_f)Oinfo.hdr.version; - object_info->hdr.nmesgs = (int_f)Oinfo.hdr.nmesgs; - object_info->hdr.nchunks = (int_f)Oinfo.hdr.nchunks; - object_info->hdr.flags = (int_f)Oinfo.hdr.flags; - - object_info->hdr.space.total = (hsize_t_f)Oinfo.hdr.space.total; - object_info->hdr.space.meta = (hsize_t_f)Oinfo.hdr.space.meta; - object_info->hdr.space.mesg = (hsize_t_f)Oinfo.hdr.space.mesg; - object_info->hdr.space.free = (hsize_t_f)Oinfo.hdr.space.free; - - object_info->hdr.mesg.present = Oinfo.hdr.mesg.present; - object_info->hdr.mesg.shared = Oinfo.hdr.mesg.shared; - - object_info->meta_size.obj.index_size = (hsize_t_f)Oinfo.meta_size.obj.index_size; - object_info->meta_size.obj.heap_size = (hsize_t_f)Oinfo.meta_size.obj.heap_size; - object_info->meta_size.attr.index_size = (hsize_t_f)Oinfo.meta_size.attr.index_size; - object_info->meta_size.attr.heap_size = (hsize_t_f)Oinfo.meta_size.attr.heap_size; - return 0; } @@ -248,34 +230,35 @@ h5oclose_c ( hid_t_f *object_id ) * SOURCE */ int_f -h5ovisit_c(hid_t_f *group_id, int_f *index_type, int_f *order, H5O_iterate_t op, void *op_data, int_f *fields ) +h5ovisit_c(hid_t_f *group_id, int_f *index_type, int_f *order, H5O_iterate2_t op, + void *op_data, int_f *fields ) /******/ { int_f ret_value = -1; /* Return value */ herr_t func_ret_value; /* H5Linterate return value */ /* - * Call H5Ovisit2 + * Call H5Ovisit */ - func_ret_value = H5Ovisit2( (hid_t)*group_id, (H5_index_t)*index_type, (H5_iter_order_t)*order, op, op_data, (unsigned)*fields); + func_ret_value = H5Ovisit3( (hid_t)*group_id, (H5_index_t)*index_type, (H5_iter_order_t)*order, op, op_data, (unsigned)*fields); ret_value = (int_f)func_ret_value; return ret_value; } -/****if* H5Of/h5oopen_by_addr_c +/****if* H5Of/h5oopen_by_token_c * NAME - * h5oopen_by_addr_c + * h5oopen_by_token_c * PURPOSE - * Calls H5open_by_addr + * Calls H5open_by_token * INPUTS - * loc_id - File or group identifier - * addr - Object’s address in the file + * loc_id - File or group identifier + * token - Object’s token in the file * * OUTPUTS - * obj_id - Dataset identifier + * obj_id - Object identifier * * RETURNS * 0 on success, -1 on failure @@ -285,15 +268,15 @@ h5ovisit_c(hid_t_f *group_id, int_f *index_type, int_f *order, H5O_iterate_t op, * SOURCE */ int_f -h5oopen_by_addr_c (hid_t_f *loc_id, haddr_t_f *addr, hid_t_f *obj_id) +h5oopen_by_token_c(hid_t_f *loc_id, H5O_token_t *token, hid_t_f *obj_id) /******/ { int_f ret_value = 0; /* Return value */ /* - * Call H5Oopen_by_address function. + * Call H5Oopen_by_token function. */ - if((*obj_id = (hid_t_f)H5Oopen_by_addr((hid_t)*loc_id, (haddr_t)*addr)) < 0) + if((*obj_id = (hid_t_f)H5Oopen_by_token((hid_t)*loc_id, *token)) < 0) HGOTO_DONE(FAIL); done: @@ -328,7 +311,7 @@ h5oget_info_by_name_c (hid_t_f *loc_id, _fcd name, size_t_f *namelen, hid_t_f *l { char *c_name = NULL; /* Buffer to hold C string */ int_f ret_value = 0; /* Return value */ - H5O_info_t Oinfo; + H5O_info2_t Oinfo; /* * Convert FORTRAN name to C name @@ -339,7 +322,7 @@ h5oget_info_by_name_c (hid_t_f *loc_id, _fcd name, size_t_f *namelen, hid_t_f *l /* * Call H5Oinfo_by_name function. */ - if(H5Oget_info_by_name2((hid_t)*loc_id, c_name, + if(H5Oget_info_by_name3((hid_t)*loc_id, c_name, &Oinfo, (unsigned)*fields, (hid_t)*lapl_id) < 0) HGOTO_DONE(FAIL); @@ -379,10 +362,10 @@ h5oget_info_by_idx_c (hid_t_f *loc_id, _fcd group_name, size_t_f *namelen, { char *c_group_name = NULL; /* Buffer to hold C string */ int_f ret_value = 0; /* Return value */ - H5O_info_t Oinfo; + H5O_info2_t Oinfo; H5_index_t c_index_field; H5_iter_order_t c_order; - + /* * Convert FORTRAN name to C name */ @@ -395,7 +378,7 @@ h5oget_info_by_idx_c (hid_t_f *loc_id, _fcd group_name, size_t_f *namelen, /* * Call H5Oinfo_by_idx function. */ - if(H5Oget_info_by_idx2((hid_t)*loc_id, c_group_name, c_index_field, c_order, (hsize_t)*n, + if(H5Oget_info_by_idx3((hid_t)*loc_id, c_group_name, c_index_field, c_order, (hsize_t)*n, &Oinfo, (unsigned)*fields, (hid_t)*lapl_id) < 0) HGOTO_DONE(FAIL); @@ -430,12 +413,12 @@ h5oget_info_c (hid_t_f *object_id, H5O_info_t_f *object_info, int_f *fields) /******/ { int_f ret_value = 0; /* Return value */ - H5O_info_t Oinfo; - + H5O_info2_t Oinfo; + /* * Call H5Oinfo_by_name function. */ - if(H5Oget_info2((hid_t)*object_id, &Oinfo, (unsigned)*fields) < 0) + if(H5Oget_info3((hid_t)*object_id, &Oinfo, (unsigned)*fields) < 0) HGOTO_DONE(FAIL); ret_value = fill_h5o_info_t_f(Oinfo,object_info); @@ -528,7 +511,7 @@ h5ocopy_c (hid_t_f *src_loc_id, _fcd src_name, size_t_f *src_name_len, */ int_f h5ovisit_by_name_c(hid_t_f *loc_id, _fcd object_name, size_t_f *namelen, int_f *index_type, int_f *order, - H5O_iterate_t op, void *op_data, hid_t_f *lapl_id, int_f *fields ) + H5O_iterate2_t op, void *op_data, hid_t_f *lapl_id, int_f *fields ) /******/ { int_f ret_value = -1; /* Return value */ @@ -542,9 +525,9 @@ h5ovisit_by_name_c(hid_t_f *loc_id, _fcd object_name, size_t_f *namelen, int_f HGOTO_DONE(FAIL); /* - * Call H5Ovisit + * Call H5Ovisit_by_name */ - func_ret_value = H5Ovisit_by_name2( (hid_t)*loc_id, c_object_name, (H5_index_t)*index_type, (H5_iter_order_t)*order, + func_ret_value = H5Ovisit_by_name3( (hid_t)*loc_id, c_object_name, (H5_index_t)*index_type, (H5_iter_order_t)*order, op, op_data, (unsigned)*fields, (hid_t)*lapl_id); ret_value = (int_f)func_ret_value; @@ -934,3 +917,41 @@ h5oget_comment_by_name_c (hid_t_f *loc_id, _fcd name, size_t_f *name_size, return ret_value; } + +/****if* H5Of/h5otoken_cmp_c + * NAME + * h5otoken_cmp_c + * PURPOSE + * Calls H5Otoken_cmp + * INPUTS + * loc_id - Identifier of an object in the file / container. + * token1 - The first token to compare. + * token2 - The second token to compare. + * cmp_value - Whether the tokens are equal. + * RETURNS + * 0 on success, -1 on failure + * AUTHOR + * Quincey Koziol + * January 10, 2019 + * SOURCE +*/ +int_f +h5otoken_cmp_c(hid_t_f *loc_id, H5O_token_t *token1, H5O_token_t *token2, + int_f *cmp_value_f) +/******/ +{ + int cmp_value; /* Token comparison result */ + int_f ret_value = 0; /* Return value */ + + /* Call H5Otoken_cmp function */ + cmp_value = 0; + if(H5Otoken_cmp((hid_t)*loc_id, token1, token2, &cmp_value) < 0) + HGOTO_DONE(FAIL); + + /* Set the comparison value to return */ + *cmp_value_f = cmp_value; + +done: + return ret_value; +} + diff --git a/fortran/src/H5Off.F90 b/fortran/src/H5Off.F90 index 8c77230..2b025a7 100644 --- a/fortran/src/H5Off.F90 +++ b/fortran/src/H5Off.F90 @@ -44,7 +44,43 @@ MODULE H5O USE H5GLOBAL IMPLICIT NONE -!****t* H5T (F03)/h5o_info_t +!****t* H5O (F03)/h5o_info_t +! +! Fortran2003 Derived Type: +! + TYPE, BIND(C) :: h5o_info_t + INTEGER(C_LONG) :: fileno ! File number that object is located in + TYPE(H5O_TOKEN_T_F) :: token ! Token for object in file + INTEGER(C_INT) :: type ! Basic object type (group, dataset, etc.) + INTEGER :: rc ! Reference count of object + + INTEGER, DIMENSION(8) :: atime ! Access time ! -- NOTE -- + INTEGER, DIMENSION(8) :: mtime ! Modification time ! Returns an integer array + INTEGER, DIMENSION(8) :: ctime ! Change time ! as specified in the Fortran + INTEGER, DIMENSION(8) :: btime ! Birth time ! intrinsic DATE_AND_TIME(VALUES) + + INTEGER(hsize_t) :: num_attrs ! # of attributes attached to object + END TYPE h5o_info_t + +! C interoperable structure for h5o_info_t. The Fortran derived type returns the time +! values as an integer array as specified in the Fortran intrinsic DATE_AND_TIME(VALUES). +! Whereas, this derived type does not. + + TYPE, BIND(C) :: c_h5o_info_t + INTEGER(C_LONG) :: fileno ! File number that object is located in + TYPE(H5O_TOKEN_T_F) :: token ! Token for object in file + INTEGER(C_INT) :: type ! Basic object type (group, dataset, etc.) + INTEGER(C_INT) :: rc ! Reference count of object + + INTEGER(KIND=TIME_T) :: atime ! Access time + INTEGER(KIND=TIME_T) :: mtime ! Modify time + INTEGER(KIND=TIME_T) :: ctime ! Create time + INTEGER(KIND=TIME_T) :: btime ! Birth time + + INTEGER(hsize_t) :: num_attrs ! # of attributes attached to object + END TYPE c_h5o_info_t + +!****t* H5O (F03)/h5o_native_info_t ! ! Fortran2003 Derived Type: ! @@ -59,13 +95,13 @@ MODULE H5O INTEGER(c_int64_t) :: present ! Flags to indicate presence of message type in header INTEGER(c_int64_t) :: shared ! Flags to indicate message type is shared in header END TYPE mesg_t - + TYPE, BIND(C) :: hdr_t INTEGER :: version ! Version number of header format in file INTEGER :: nmesgs ! Number of object header messages INTEGER :: nchunks ! Number of object header chunks INTEGER :: flags ! Object header status flags - TYPE(space_t) :: space + TYPE(space_t) :: space TYPE(mesg_t) :: mesg END TYPE hdr_t @@ -74,7 +110,7 @@ MODULE H5O INTEGER(C_INT) :: nmesgs ! Number of object header messages INTEGER(C_INT) :: nchunks ! Number of object header chunks INTEGER(C_INT) :: flags ! Object header status flags - TYPE(space_t) :: space + TYPE(space_t) :: space TYPE(mesg_t) :: mesg END TYPE c_hdr_t @@ -88,46 +124,17 @@ MODULE H5O TYPE(H5_ih_info_t) :: obj ! v1/v2 B-tree & local/fractal heap for groups, B-tree for chunked datasets TYPE(H5_ih_info_t) :: attr ! v2 B-tree & heap for attributes ENDTYPE meta_size_t - - TYPE, BIND(C) :: h5o_info_t - INTEGER(C_LONG) :: fileno ! File number that object is located in - INTEGER(haddr_t) :: addr ! Object address in file - INTEGER(C_INT) :: type ! Basic object type (group, dataset, etc.) - INTEGER :: rc ! Reference count of object - - INTEGER, DIMENSION(8) :: atime ! Access time ! -- NOTE -- - INTEGER, DIMENSION(8) :: mtime ! Modification time ! Returns an integer array - INTEGER, DIMENSION(8) :: ctime ! Change time ! as specified in the Fortran - INTEGER, DIMENSION(8) :: btime ! Birth time ! intrinsic DATE_AND_TIME(VALUES) - - INTEGER(hsize_t) :: num_attrs ! # of attributes attached to object + TYPE, BIND(C) :: h5o_native_info_t TYPE(hdr_t) :: hdr - TYPE(meta_size_t) :: meta_size - END TYPE h5o_info_t - -! C interoperable structure for h5o_info_t. The Fortran derived type returns the time -! values as an integer array as specified in the Fortran intrinsic DATE_AND_TIME(VALUES). -! Whereas, this derived type does not. - - TYPE, BIND(C) :: c_h5o_info_t - INTEGER(C_LONG) :: fileno ! File number that object is located in - INTEGER(haddr_t) :: addr ! Object address in file - INTEGER(C_INT) :: type ! Basic object type (group, dataset, etc.) - INTEGER(C_INT) :: rc ! Reference count of object - - INTEGER(KIND=TIME_T) :: atime ! Access time - INTEGER(KIND=TIME_T) :: mtime ! modify time - INTEGER(KIND=TIME_T) :: ctime ! create time - INTEGER(KIND=TIME_T) :: btime ! Access time - - INTEGER(hsize_t) :: num_attrs ! # of attributes attached to object + END TYPE h5o_native_info_t +! C interoperable structure for h5o_native_info_t. + TYPE, BIND(C) :: c_h5o_native_info_t TYPE(c_hdr_t) :: hdr - TYPE(meta_size_t) :: meta_size - END TYPE c_h5o_info_t + END TYPE c_h5o_native_info_t !***** @@ -292,46 +299,46 @@ CONTAINS END SUBROUTINE h5oclose_f ! -!****s* H5O/h5open_by_addr_f -! NAME -! h5oopen_by_addr_f +!****s* H5O/h5oopen_by_token_f +! NAME +! h5oopen_by_token_f ! ! PURPOSE -! Opens an object using its address within an HDF5 file. +! Opens an object using its token within an HDF5 file. ! -! Inputs: +! Inputs: ! loc_id - File or group identifier. -! addr - Object’s address in the file. +! token - Object’s token in the file. ! ! Outputs: ! obj_id - Object identifier for the opened object. ! hdferr - Returns 0 if successful and -1 if fails. ! -! AUTHOR +! AUTHOR ! M. Scot Breitenfeld ! September 14, 2009 -! +! ! Fortran90 Interface: - SUBROUTINE h5oopen_by_addr_f(loc_id, addr, obj_id, hdferr) + SUBROUTINE h5oopen_by_token_f(loc_id, token, obj_id, hdferr) IMPLICIT NONE - INTEGER(HID_T) , INTENT(IN) :: loc_id - INTEGER(HADDR_T), INTENT(IN) :: addr - INTEGER(HID_T) , INTENT(OUT) :: obj_id - INTEGER , INTENT(OUT) :: hdferr + INTEGER(HID_T) , INTENT(IN) :: loc_id + TYPE(H5O_TOKEN_T_F), INTENT(IN) :: token + INTEGER(HID_T) , INTENT(OUT) :: obj_id + INTEGER , INTENT(OUT) :: hdferr !***** INTERFACE - INTEGER FUNCTION h5oopen_by_addr_c(loc_id, addr, obj_id) BIND(C,NAME='h5oopen_by_addr_c') - IMPORT :: HID_T, HADDR_T + INTEGER FUNCTION h5oopen_by_token_c(loc_id, token, obj_id) BIND(C,NAME='h5oopen_by_token_c') + IMPORT :: HID_T, H5O_TOKEN_T_F IMPLICIT NONE INTEGER(HID_T), INTENT(IN) :: loc_id - INTEGER(HADDR_T), INTENT(IN) :: addr + TYPE(H5O_TOKEN_T_F), INTENT(IN) :: token INTEGER(HID_T), INTENT(OUT) :: obj_id - END FUNCTION h5oopen_by_addr_c + END FUNCTION h5oopen_by_token_c END INTERFACE - hdferr = h5oopen_by_addr_c(loc_id, addr, obj_id) + hdferr = h5oopen_by_token_c(loc_id, token, obj_id) - END SUBROUTINE h5oopen_by_addr_f + END SUBROUTINE h5oopen_by_token_f ! !****s* H5O/h5ocopy_f ! NAME @@ -966,7 +973,7 @@ CONTAINS CHARACTER(KIND=C_CHAR), DIMENSION(*), INTENT(IN) :: name INTEGER(SIZE_T) , INTENT(IN) :: namelen INTEGER(HID_T) , INTENT(IN) :: lapl_id_default - TYPE(C_PTR),VALUE :: object_info + TYPE(C_PTR), VALUE :: object_info INTEGER , INTENT(IN) :: fields END FUNCTION h5oget_info_by_name_c END INTERFACE @@ -1212,5 +1219,50 @@ CONTAINS END SUBROUTINE h5ovisit_by_name_f +!****s* H5O/h5otoken_cmp_f +! NAME +! h5otoken_cmp_f +! +! PURPOSE +! Compare two tokens, which must be from the same file / containers. +! +! Inputs: +! loc_id - Identifier of an object in the file / container. +! token1 - The first token to compare. +! token2 - The second token to compare. +! +! Outputs: +! cmp_value - Returns 0 if tokens are equal, non-zero for unequal tokens. +! hdferr - Returns 0 if successful and -1 if fails. +! +! AUTHOR +! Quincey Koziol +! January 10, 2019 +! +! Fortran90 Interface: + SUBROUTINE h5otoken_cmp_f(loc_id, token1, token2, cmp_value, hdferr) + IMPLICIT NONE + INTEGER(HID_T) , INTENT(IN) :: loc_id + TYPE(H5O_TOKEN_T_F), INTENT(IN) :: token1 ! First token + TYPE(H5O_TOKEN_T_F), INTENT(IN) :: token2 ! First token + INTEGER , INTENT(OUT) :: cmp_value + INTEGER , INTENT(OUT) :: hdferr +!***** + INTERFACE + INTEGER FUNCTION h5otoken_cmp_c(loc_id, token1, token2, cmp_value) BIND(C,NAME='h5otoken_cmp_c') + IMPORT :: HID_T, C_PTR, H5O_TOKEN_T_F + IMPLICIT NONE + INTEGER(HID_T), INTENT(IN) :: loc_id + TYPE(H5O_TOKEN_T_F), INTENT(IN) :: token1 ! First token + TYPE(H5O_TOKEN_T_F), INTENT(IN) :: token2 ! First token + INTEGER, INTENT(OUT) :: cmp_value + + END FUNCTION h5otoken_cmp_c + END INTERFACE + + hdferr = h5otoken_cmp_c(loc_id, token1, token2, cmp_value) + + END SUBROUTINE h5otoken_cmp_f + END MODULE H5O diff --git a/fortran/src/H5VLff.F90 b/fortran/src/H5VLff.F90 index e21f38f..eea9dfe 100644 --- a/fortran/src/H5VLff.F90 +++ b/fortran/src/H5VLff.F90 @@ -167,10 +167,49 @@ CONTAINS END SUBROUTINE H5VLis_connector_registered_f ! -!****s* H5VL/H5VLis_connector_registered_f +!****s* H5VL/H5VLget_connector_id_f ! ! NAME -! H5VLis_connector_registered_f +! H5VLget_connector_id_f +! +! PURPOSE +! Retrieves the ID for a registered VOL connector. +! +! INPUTS +! obj_id - Object id +! OUTPUTS +! vol_id - Connector id +! hdferr - Returns 0 if successful and -1 if fails +! SOURCE + + SUBROUTINE H5VLget_connector_id_f(obj_id, vol_id, hdferr) + IMPLICIT NONE + INTEGER(HID_T), INTENT(IN) :: obj_id + INTEGER(HID_T), INTENT(OUT) :: vol_id + INTEGER, INTENT(OUT) :: hdferr +!***** + + INTERFACE + INTEGER(HID_T) FUNCTION H5VLget_connector_id(obj_id) BIND(C,NAME='H5VLget_connector_id') + IMPORT :: HID_T + INTEGER(HID_T), INTENT(IN) :: obj_id + END FUNCTION H5VLget_connector_id + END INTERFACE + + vol_id = H5VLget_connector_id(obj_id) + + IF(vol_id.LT.0)THEN + hdferr = -1 + vol_id = H5I_INVALID_HID_F + ENDIF + + END SUBROUTINE H5VLget_connector_id_f + +! +!****s* H5VL/H5VLget_connector_id_by_name_f +! +! NAME +! H5VLget_connector_id_by_name_f ! ! PURPOSE ! Retrieves the ID for a registered VOL connector. @@ -182,7 +221,7 @@ CONTAINS ! hdferr - Returns 0 if successful and -1 if fails ! SOURCE - SUBROUTINE H5VLget_connector_id_f(name, vol_id, hdferr) + SUBROUTINE H5VLget_connector_id_by_name_f(name, vol_id, hdferr) IMPLICIT NONE CHARACTER(LEN=*), INTENT(IN) :: name INTEGER(HID_T), INTENT(OUT) :: vol_id @@ -191,22 +230,23 @@ CONTAINS CHARACTER(LEN=LEN_TRIM(name)+1,KIND=C_CHAR) :: c_name INTERFACE - INTEGER(HID_T) FUNCTION H5VLget_connector_id(name) BIND(C,NAME='H5VLget_connector_id') + INTEGER(HID_T) FUNCTION H5VLget_connector_id_by_name(name) BIND(C,NAME='H5VLget_connector_id_by_name') IMPORT :: C_CHAR IMPORT :: HID_T CHARACTER(KIND=C_CHAR), DIMENSION(*), INTENT(IN) :: name - END FUNCTION H5VLget_connector_id + END FUNCTION H5VLget_connector_id_by_name END INTERFACE c_name = TRIM(name)//C_NULL_CHAR - vol_id = H5VLget_connector_id(c_name) - + vol_id = H5VLget_connector_id_by_name(c_name) + + hdferr = 0 IF(vol_id.LT.0)THEN hdferr = -1 vol_id = H5I_INVALID_HID_F ENDIF - END SUBROUTINE H5VLget_connector_id_f + END SUBROUTINE H5VLget_connector_id_by_name_f SUBROUTINE H5VLget_connector_name_f(obj_id, name, hdferr, name_len) IMPLICIT NONE diff --git a/fortran/src/H5_f.c b/fortran/src/H5_f.c index 2d1c6e7..132da7b 100644 --- a/fortran/src/H5_f.c +++ b/fortran/src/H5_f.c @@ -56,7 +56,6 @@ h5init_types_c( hid_t_f * types, hid_t_f * floatingtypes, hid_t_f * integertypes { int ret_value = -1; hid_t c_type_id; - size_t tmp_val; int i; /* Fortran INTEGER may not be the same as C; do all checking to find @@ -133,8 +132,7 @@ h5init_types_c( hid_t_f * types, hid_t_f * floatingtypes, hid_t_f * integertypes #endif if ((c_type_id = H5Tcopy(H5T_FORTRAN_S1)) < 0) return ret_value; - tmp_val = 1; - if(H5Tset_size(c_type_id, tmp_val) < 0) return ret_value; + if(H5Tset_size(c_type_id, 1) < 0) return ret_value; if(H5Tset_strpad(c_type_id, H5T_STR_SPACEPAD) < 0) return ret_value; types[8] = (hid_t_f)c_type_id; @@ -313,6 +311,7 @@ h5close_types_c( hid_t_f * types, int_f *lentypes, ret_value = 0; return ret_value; } + /****if* H5_f/h5init_flags_c * NAME * h5init_flags_c @@ -370,7 +369,6 @@ h5init_flags_c( int_f *h5d_flags, size_t_f *h5d_size_flags, haddr_t_f *h5_haddr_generic_flags) /******/ { - int ret_value = -1; /* * H5D flags */ @@ -538,196 +536,201 @@ h5init_flags_c( int_f *h5d_flags, size_t_f *h5d_size_flags, * but we need to assign each kind of message to a different bit so that * one index can hold multiple types.) */ - h5o_flags[7] = (int_f)H5O_SHMESG_NONE_FLAG; /* No shared messages */ - h5o_flags[8] = (int_f)H5O_SHMESG_SDSPACE_FLAG; /* Simple Dataspace Message. */ - h5o_flags[9] = (int_f)H5O_SHMESG_DTYPE_FLAG; /* Datatype Message. */ - h5o_flags[10] = (int_f)H5O_SHMESG_FILL_FLAG; /* Fill Value Message. */ - h5o_flags[11] = (int_f)H5O_SHMESG_PLINE_FLAG; /* Filter pipeline message. */ - h5o_flags[12] = (int_f)H5O_SHMESG_ATTR_FLAG; /* Attribute Message. */ - h5o_flags[13] = (int_f)H5O_SHMESG_ALL_FLAG; + h5o_flags[7] = (int_f)H5O_SHMESG_NONE_FLAG; /* No shared messages */ + h5o_flags[8] = (int_f)H5O_SHMESG_SDSPACE_FLAG; /* Simple Dataspace Message. */ + h5o_flags[9] = (int_f)H5O_SHMESG_DTYPE_FLAG; /* Datatype Message. */ + h5o_flags[10] = (int_f)H5O_SHMESG_FILL_FLAG; /* Fill Value Message. */ + h5o_flags[11] = (int_f)H5O_SHMESG_PLINE_FLAG; /* Filter pipeline message. */ + h5o_flags[12] = (int_f)H5O_SHMESG_ATTR_FLAG; /* Attribute Message. */ + h5o_flags[13] = (int_f)H5O_SHMESG_ALL_FLAG; /* Object header status flag definitions */ - h5o_flags[14] = (int_f)H5O_HDR_CHUNK0_SIZE; /* 2-bit field indicating # of bytes to store the size of chunk 0's data */ - h5o_flags[15] = (int_f)H5O_HDR_ATTR_CRT_ORDER_TRACKED; /* Attribute creation order is tracked */ - h5o_flags[16] = (int_f)H5O_HDR_ATTR_CRT_ORDER_INDEXED; /* Attribute creation order has index */ - h5o_flags[17] = (int_f)H5O_HDR_ATTR_STORE_PHASE_CHANGE; /* Non-default attribute storage phase change values stored */ - h5o_flags[18] = (int_f)H5O_HDR_STORE_TIMES; /* Store access, modification, change & birth times for object */ - h5o_flags[19] = (int_f)H5O_HDR_ALL_FLAGS; + h5o_flags[14] = (int_f)H5O_HDR_CHUNK0_SIZE; /* 2-bit field indicating # of bytes to store the size of chunk 0's data */ + h5o_flags[15] = (int_f)H5O_HDR_ATTR_CRT_ORDER_TRACKED; /* Attribute creation order is tracked */ + h5o_flags[16] = (int_f)H5O_HDR_ATTR_CRT_ORDER_INDEXED; /* Attribute creation order has index */ + h5o_flags[17] = (int_f)H5O_HDR_ATTR_STORE_PHASE_CHANGE; /* Non-default attribute storage phase change values stored */ + h5o_flags[18] = (int_f)H5O_HDR_STORE_TIMES; /* Store access, modification, change & birth times for object */ + h5o_flags[19] = (int_f)H5O_HDR_ALL_FLAGS; /* Maximum shared message values. Number of indexes is 8 to allow room to add * new types of messages. */ - h5o_flags[20] = (int_f)H5O_SHMESG_MAX_NINDEXES; - h5o_flags[21] = (int_f)H5O_SHMESG_MAX_LIST_SIZE; + h5o_flags[20] = (int_f)H5O_SHMESG_MAX_NINDEXES; + h5o_flags[21] = (int_f)H5O_SHMESG_MAX_LIST_SIZE; /* Types of objects in file */ - h5o_flags[22] = (int_f)H5O_TYPE_UNKNOWN; /* Unknown object type */ - h5o_flags[23] = (int_f)H5O_TYPE_GROUP; /* Object is a group */ - h5o_flags[24] = (int_f)H5O_TYPE_DATASET; /* Object is a dataset */ - h5o_flags[25] = (int_f)H5O_TYPE_NAMED_DATATYPE; /* Object is a named data type */ - h5o_flags[26] = (int_f)H5O_TYPE_NTYPES; /* Number of different object types */ + h5o_flags[22] = (int_f)H5O_TYPE_UNKNOWN; /* Unknown object type */ + h5o_flags[23] = (int_f)H5O_TYPE_GROUP; /* Object is a group */ + h5o_flags[24] = (int_f)H5O_TYPE_DATASET; /* Object is a dataset */ + h5o_flags[25] = (int_f)H5O_TYPE_NAMED_DATATYPE; /* Object is a named data type */ + h5o_flags[26] = (int_f)H5O_TYPE_NTYPES; /* Number of different object types */ /* Flags for H5Oget_info. * These flags determine which fields will be filled in in the H5O_info_t - * struct. + * struct. */ - h5o_flags[27] = (int_f)H5O_INFO_ALL; /* (H5O_INFO_BASIC|H5O_INFO_TIME|H5O_INFO_NUM_ATTRS|H5O_INFO_HDR|H5O_INFO_META_SIZE) */ - h5o_flags[28] = (int_f)H5O_INFO_BASIC; /* Fill in the fileno, addr, type, and rc fields */ - h5o_flags[29] = (int_f)H5O_INFO_TIME; /* Fill in the atime, mtime, ctime, and btime fields */ - h5o_flags[30] = (int_f)H5O_INFO_NUM_ATTRS; /* Fill in the num_attrs field */ - h5o_flags[31] = (int_f)H5O_INFO_HDR; /* Fill in the hdr field */ - h5o_flags[32] = (int_f)H5O_INFO_META_SIZE; /* Fill in the meta_size field */ + h5o_flags[27] = (int_f)H5O_INFO_ALL; /* (H5O_INFO_BASIC|H5O_INFO_TIME|H5O_INFO_NUM_ATTRS) */ + h5o_flags[28] = (int_f)H5O_INFO_BASIC; /* Fill in the fileno, addr, type, and rc fields */ + h5o_flags[29] = (int_f)H5O_INFO_TIME; /* Fill in the atime, mtime, ctime, and btime fields */ + h5o_flags[30] = (int_f)H5O_INFO_NUM_ATTRS; /* Fill in the num_attrs field */ + +/* Flags for H5Oget_native_info. + * These flags determine which fields will be filled in in the H5O_native_info_t + * struct. + */ + h5o_flags[31] = (int_f)H5O_NATIVE_INFO_ALL; /* (H5O_NATIVE_INFO_HDR|H5O_NATIVE_INFO_META_SIZE) */ + h5o_flags[32] = (int_f)H5O_NATIVE_INFO_HDR; /* Fill in the hdr field */ + h5o_flags[33] = (int_f)H5O_NATIVE_INFO_META_SIZE; /* Fill in the meta_size field */ /* * H5P flags */ - h5p_flags[0] = (hid_t_f)H5P_FILE_CREATE; - h5p_flags[1] = (hid_t_f)H5P_FILE_ACCESS; - h5p_flags[2] = (hid_t_f)H5P_DATASET_CREATE; - h5p_flags[3] = (hid_t_f)H5P_DATASET_XFER; - h5p_flags[4] = (hid_t_f)H5P_FILE_MOUNT; - h5p_flags[5] = (hid_t_f)H5P_DEFAULT; - h5p_flags[6] = (hid_t_f)H5P_ROOT; - h5p_flags[7] = (hid_t_f)H5P_OBJECT_CREATE; - h5p_flags[8] = (hid_t_f)H5P_DATASET_ACCESS; - h5p_flags[9] = (hid_t_f)H5P_GROUP_CREATE; - h5p_flags[10] = (hid_t_f)H5P_GROUP_ACCESS; - h5p_flags[11] = (hid_t_f)H5P_DATATYPE_CREATE; - h5p_flags[12] = (hid_t_f)H5P_DATATYPE_ACCESS; - h5p_flags[13] = (hid_t_f)H5P_STRING_CREATE; - h5p_flags[14] = (hid_t_f)H5P_ATTRIBUTE_CREATE; - h5p_flags[15] = (hid_t_f)H5P_OBJECT_COPY; - h5p_flags[16] = (hid_t_f)H5P_LINK_CREATE; - h5p_flags[17] = (hid_t_f)H5P_LINK_ACCESS; + h5p_flags[0] = (hid_t_f)H5P_FILE_CREATE; + h5p_flags[1] = (hid_t_f)H5P_FILE_ACCESS; + h5p_flags[2] = (hid_t_f)H5P_DATASET_CREATE; + h5p_flags[3] = (hid_t_f)H5P_DATASET_XFER; + h5p_flags[4] = (hid_t_f)H5P_FILE_MOUNT; + h5p_flags[5] = (hid_t_f)H5P_DEFAULT; + h5p_flags[6] = (hid_t_f)H5P_ROOT; + h5p_flags[7] = (hid_t_f)H5P_OBJECT_CREATE; + h5p_flags[8] = (hid_t_f)H5P_DATASET_ACCESS; + h5p_flags[9] = (hid_t_f)H5P_GROUP_CREATE; + h5p_flags[10] = (hid_t_f)H5P_GROUP_ACCESS; + h5p_flags[11] = (hid_t_f)H5P_DATATYPE_CREATE; + h5p_flags[12] = (hid_t_f)H5P_DATATYPE_ACCESS; + h5p_flags[13] = (hid_t_f)H5P_STRING_CREATE; + h5p_flags[14] = (hid_t_f)H5P_ATTRIBUTE_CREATE; + h5p_flags[15] = (hid_t_f)H5P_OBJECT_COPY; + h5p_flags[16] = (hid_t_f)H5P_LINK_CREATE; + h5p_flags[17] = (hid_t_f)H5P_LINK_ACCESS; /* * H5P integer flags */ - h5p_flags_int[0] = (int_f)H5P_CRT_ORDER_INDEXED; - h5p_flags_int[1] = (int_f)H5P_CRT_ORDER_TRACKED; + h5p_flags_int[0] = (int_f)H5P_CRT_ORDER_INDEXED; + h5p_flags_int[1] = (int_f)H5P_CRT_ORDER_TRACKED; /* * H5R flags */ - - h5r_flags[0] = (int_f)H5R_OBJECT; - h5r_flags[1] = (int_f)H5R_DATASET_REGION; + h5r_flags[0] = (int_f)H5R_OBJECT; + h5r_flags[1] = (int_f)H5R_DATASET_REGION; /* * H5S flags */ - - h5s_hid_flags[0] = (hid_t_f)H5S_ALL; - - h5s_hsize_flags[0] = (hsize_t_f)H5S_UNLIMITED; - - h5s_flags[0] = (int_f)H5S_SCALAR; - h5s_flags[1] = (int_f)H5S_SIMPLE; - h5s_flags[2] = (int_f)H5S_NULL; - h5s_flags[3] = (int_f)H5S_SELECT_SET; - h5s_flags[4] = (int_f)H5S_SELECT_OR; - - h5s_flags[5] = (int_f)H5S_SELECT_NOOP; - h5s_flags[6] = (int_f)H5S_SELECT_AND; - h5s_flags[7] = (int_f)H5S_SELECT_XOR; - h5s_flags[8] = (int_f)H5S_SELECT_NOTB; - h5s_flags[9] = (int_f)H5S_SELECT_NOTA; - - h5s_flags[10] = (int_f)H5S_SELECT_APPEND; - h5s_flags[11] = (int_f)H5S_SELECT_PREPEND; - h5s_flags[12] = (int_f)H5S_SELECT_INVALID; - h5s_flags[13] = (int_f)H5S_SEL_ERROR; - h5s_flags[14] = (int_f)H5S_SEL_NONE; - - h5s_flags[15] = (int_f)H5S_SEL_POINTS; - h5s_flags[16] = (int_f)H5S_SEL_HYPERSLABS; - h5s_flags[17] = (int_f)H5S_SEL_ALL; + h5s_hid_flags[0] = (hid_t_f)H5S_ALL; + + h5s_hsize_flags[0] = (hsize_t_f)H5S_UNLIMITED; + + h5s_flags[0] = (int_f)H5S_SCALAR; + h5s_flags[1] = (int_f)H5S_SIMPLE; + h5s_flags[2] = (int_f)H5S_NULL; + h5s_flags[3] = (int_f)H5S_SELECT_SET; + h5s_flags[4] = (int_f)H5S_SELECT_OR; + + h5s_flags[5] = (int_f)H5S_SELECT_NOOP; + h5s_flags[6] = (int_f)H5S_SELECT_AND; + h5s_flags[7] = (int_f)H5S_SELECT_XOR; + h5s_flags[8] = (int_f)H5S_SELECT_NOTB; + h5s_flags[9] = (int_f)H5S_SELECT_NOTA; + + h5s_flags[10] = (int_f)H5S_SELECT_APPEND; + h5s_flags[11] = (int_f)H5S_SELECT_PREPEND; + h5s_flags[12] = (int_f)H5S_SELECT_INVALID; + h5s_flags[13] = (int_f)H5S_SEL_ERROR; + h5s_flags[14] = (int_f)H5S_SEL_NONE; + + h5s_flags[15] = (int_f)H5S_SEL_POINTS; + h5s_flags[16] = (int_f)H5S_SEL_HYPERSLABS; + h5s_flags[17] = (int_f)H5S_SEL_ALL; + /* * H5T flags */ - h5t_flags[0] = (int_f)H5T_NO_CLASS; - h5t_flags[1] = (int_f)H5T_INTEGER; - h5t_flags[2] = (int_f)H5T_FLOAT; - h5t_flags[3] = (int_f)H5T_TIME; - h5t_flags[4] = (int_f)H5T_STRING; - h5t_flags[5] = (int_f)H5T_BITFIELD; - h5t_flags[6] = (int_f)H5T_OPAQUE; - h5t_flags[7] = (int_f)H5T_COMPOUND; - h5t_flags[8] = (int_f)H5T_REFERENCE; - h5t_flags[9] = (int_f)H5T_ENUM; - h5t_flags[10] = (int_f)H5T_ORDER_LE; - h5t_flags[11] = (int_f)H5T_ORDER_BE; - h5t_flags[12] = (int_f)H5T_ORDER_MIXED; - h5t_flags[13] = (int_f)H5T_ORDER_VAX; - h5t_flags[14] = (int_f)H5T_ORDER_NONE; - h5t_flags[15] = (int_f)H5T_PAD_ZERO; - h5t_flags[16] = (int_f)H5T_PAD_ONE; - h5t_flags[17] = (int_f)H5T_PAD_BACKGROUND; - h5t_flags[18] = (int_f)H5T_PAD_ERROR; - h5t_flags[19] = (int_f)H5T_SGN_NONE; - h5t_flags[20] = (int_f)H5T_SGN_2; - h5t_flags[21] = (int_f)H5T_SGN_ERROR; - h5t_flags[22] = (int_f)H5T_NORM_IMPLIED; - h5t_flags[23] = (int_f)H5T_NORM_MSBSET; - h5t_flags[24] = (int_f)H5T_NORM_NONE; - h5t_flags[25] = (int_f)H5T_CSET_ASCII; - h5t_flags[26] = (int_f)H5T_CSET_UTF8; - h5t_flags[27] = (int_f)H5T_STR_NULLTERM; - h5t_flags[28] = (int_f)H5T_STR_NULLPAD; - h5t_flags[29] = (int_f)H5T_STR_SPACEPAD; - h5t_flags[30] = (int_f)H5T_STR_ERROR; - h5t_flags[31] = (int_f)H5T_VLEN; - h5t_flags[32] = (int_f)H5T_ARRAY; - h5t_flags[33] = (int_f)H5T_DIR_ASCEND; - h5t_flags[34] = (int_f)H5T_DIR_DESCEND; + h5t_flags[0] = (int_f)H5T_NO_CLASS; + h5t_flags[1] = (int_f)H5T_INTEGER; + h5t_flags[2] = (int_f)H5T_FLOAT; + h5t_flags[3] = (int_f)H5T_TIME; + h5t_flags[4] = (int_f)H5T_STRING; + h5t_flags[5] = (int_f)H5T_BITFIELD; + h5t_flags[6] = (int_f)H5T_OPAQUE; + h5t_flags[7] = (int_f)H5T_COMPOUND; + h5t_flags[8] = (int_f)H5T_REFERENCE; + h5t_flags[9] = (int_f)H5T_ENUM; + h5t_flags[10] = (int_f)H5T_ORDER_LE; + h5t_flags[11] = (int_f)H5T_ORDER_BE; + h5t_flags[12] = (int_f)H5T_ORDER_MIXED; + h5t_flags[13] = (int_f)H5T_ORDER_VAX; + h5t_flags[14] = (int_f)H5T_ORDER_NONE; + h5t_flags[15] = (int_f)H5T_PAD_ZERO; + h5t_flags[16] = (int_f)H5T_PAD_ONE; + h5t_flags[17] = (int_f)H5T_PAD_BACKGROUND; + h5t_flags[18] = (int_f)H5T_PAD_ERROR; + h5t_flags[19] = (int_f)H5T_SGN_NONE; + h5t_flags[20] = (int_f)H5T_SGN_2; + h5t_flags[21] = (int_f)H5T_SGN_ERROR; + h5t_flags[22] = (int_f)H5T_NORM_IMPLIED; + h5t_flags[23] = (int_f)H5T_NORM_MSBSET; + h5t_flags[24] = (int_f)H5T_NORM_NONE; + h5t_flags[25] = (int_f)H5T_CSET_ASCII; + h5t_flags[26] = (int_f)H5T_CSET_UTF8; + h5t_flags[27] = (int_f)H5T_STR_NULLTERM; + h5t_flags[28] = (int_f)H5T_STR_NULLPAD; + h5t_flags[29] = (int_f)H5T_STR_SPACEPAD; + h5t_flags[30] = (int_f)H5T_STR_ERROR; + h5t_flags[31] = (int_f)H5T_VLEN; + h5t_flags[32] = (int_f)H5T_ARRAY; + h5t_flags[33] = (int_f)H5T_DIR_ASCEND; + h5t_flags[34] = (int_f)H5T_DIR_DESCEND; + /* * H5Z flags */ - h5z_flags[0] = (int_f)H5Z_FILTER_ERROR; - h5z_flags[1] = (int_f)H5Z_FILTER_NONE; - h5z_flags[2] = (int_f)H5Z_FILTER_DEFLATE; - h5z_flags[3] = (int_f)H5Z_FILTER_SHUFFLE; - h5z_flags[4] = (int_f)H5Z_FILTER_FLETCHER32; - h5z_flags[5] = (int_f)H5Z_ERROR_EDC; - h5z_flags[6] = (int_f)H5Z_DISABLE_EDC; - h5z_flags[7] = (int_f)H5Z_ENABLE_EDC; - h5z_flags[8] = (int_f)H5Z_NO_EDC; - h5z_flags[9] = (int_f)H5Z_FILTER_SZIP; - h5z_flags[10] = (int_f)H5Z_FLAG_OPTIONAL; - h5z_flags[11] = (int_f)H5Z_FILTER_CONFIG_ENCODE_ENABLED; - h5z_flags[12] = (int_f)H5Z_FILTER_CONFIG_DECODE_ENABLED; - h5z_flags[13] = (int_f)H5Z_FILTER_ALL; - h5z_flags[14] = (int_f)H5Z_FILTER_NBIT; - h5z_flags[15] = (int_f)H5Z_FILTER_SCALEOFFSET; - h5z_flags[16] = (int_f)H5Z_SO_FLOAT_DSCALE; - h5z_flags[17] = (int_f)H5Z_SO_FLOAT_ESCALE; - h5z_flags[18] = (int_f)H5Z_SO_INT; - h5z_flags[19] = (int_f)H5Z_SO_INT_MINBITS_DEFAULT; + h5z_flags[0] = (int_f)H5Z_FILTER_ERROR; + h5z_flags[1] = (int_f)H5Z_FILTER_NONE; + h5z_flags[2] = (int_f)H5Z_FILTER_DEFLATE; + h5z_flags[3] = (int_f)H5Z_FILTER_SHUFFLE; + h5z_flags[4] = (int_f)H5Z_FILTER_FLETCHER32; + h5z_flags[5] = (int_f)H5Z_ERROR_EDC; + h5z_flags[6] = (int_f)H5Z_DISABLE_EDC; + h5z_flags[7] = (int_f)H5Z_ENABLE_EDC; + h5z_flags[8] = (int_f)H5Z_NO_EDC; + h5z_flags[9] = (int_f)H5Z_FILTER_SZIP; + h5z_flags[10] = (int_f)H5Z_FLAG_OPTIONAL; + h5z_flags[11] = (int_f)H5Z_FILTER_CONFIG_ENCODE_ENABLED; + h5z_flags[12] = (int_f)H5Z_FILTER_CONFIG_DECODE_ENABLED; + h5z_flags[13] = (int_f)H5Z_FILTER_ALL; + h5z_flags[14] = (int_f)H5Z_FILTER_NBIT; + h5z_flags[15] = (int_f)H5Z_FILTER_SCALEOFFSET; + h5z_flags[16] = (int_f)H5Z_SO_FLOAT_DSCALE; + h5z_flags[17] = (int_f)H5Z_SO_FLOAT_ESCALE; + h5z_flags[18] = (int_f)H5Z_SO_INT; + h5z_flags[19] = (int_f)H5Z_SO_INT_MINBITS_DEFAULT; /* * H5 Generic flags introduced in version 1.8 */ - /* H5_index_t enum struct */ + /* H5_index_t enum struct */ - h5_generic_flags[0] = (int_f)H5_INDEX_UNKNOWN; /* Unknown index type */ - h5_generic_flags[1] = (int_f)H5_INDEX_NAME; /* Index on names */ - h5_generic_flags[2] = (int_f)H5_INDEX_CRT_ORDER; /* Index on creation order */ - h5_generic_flags[3] = (int_f)H5_INDEX_N; /* Index on creation order */ + h5_generic_flags[0] = (int_f)H5_INDEX_UNKNOWN; /* Unknown index type */ + h5_generic_flags[1] = (int_f)H5_INDEX_NAME; /* Index on names */ + h5_generic_flags[2] = (int_f)H5_INDEX_CRT_ORDER; /* Index on creation order */ + h5_generic_flags[3] = (int_f)H5_INDEX_N; /* Index on creation order */ - /* H5_iter_order_t enum struct */ + /* H5_iter_order_t enum struct */ - h5_generic_flags[4] = (int_f)H5_ITER_UNKNOWN; /* Unknown order */ - h5_generic_flags[5] = (int_f)H5_ITER_INC; /* Increasing order */ - h5_generic_flags[6] = (int_f)H5_ITER_DEC; /* Decreasing order */ - h5_generic_flags[7] = (int_f)H5_ITER_NATIVE; /* No particular order, whatever is fastest */ - h5_generic_flags[8] = (int_f)H5_ITER_N; /* Number of iteration orders */ + h5_generic_flags[4] = (int_f)H5_ITER_UNKNOWN; /* Unknown order */ + h5_generic_flags[5] = (int_f)H5_ITER_INC; /* Increasing order */ + h5_generic_flags[6] = (int_f)H5_ITER_DEC; /* Decreasing order */ + h5_generic_flags[7] = (int_f)H5_ITER_NATIVE; /* No particular order, whatever is fastest */ + h5_generic_flags[8] = (int_f)H5_ITER_N; /* Number of iteration orders */ - h5_haddr_generic_flags[0] = (haddr_t_f)HADDR_UNDEF; /* undefined address */ + h5_haddr_generic_flags[0] = (haddr_t_f)HADDR_UNDEF; /* undefined address */ - ret_value = 0; - return ret_value; + return 0; } int_f diff --git a/fortran/src/H5f90.h b/fortran/src/H5f90.h index eabe3d0..655cb9b 100644 --- a/fortran/src/H5f90.h +++ b/fortran/src/H5f90.h @@ -25,5 +25,8 @@ /* Constants used in H5Gf.c files */ #define OBJECT_NAMELEN_DEFAULT_F -1 + #define H5_MAX(a,b) (((a)>(b)) ? (a) : (b)) + #endif /* _H5f90_H */ + diff --git a/fortran/src/H5f90global.F90 b/fortran/src/H5f90global.F90 index 02e3bc3..dabc0bb 100644 --- a/fortran/src/H5f90global.F90 +++ b/fortran/src/H5f90global.F90 @@ -54,6 +54,7 @@ MODULE H5GLOBAL ! If you change the value of these parameters, do not forget to change corresponding ! values in the H5f90.h file. INTEGER, PARAMETER :: REF_REG_BUF_LEN = 3 + INTEGER, PARAMETER :: H5O_TOKEN_BUF_LEN = 16 ! Matches C defined value in H5public.h ! Parameters used in the function 'h5kind_to_type' located in H5_ff.F90. ! The flag is used to tell the function whether the kind input variable @@ -70,13 +71,17 @@ MODULE H5GLOBAL INTEGER, DIMENSION(1:REF_REG_BUF_LEN) :: ref END TYPE hdset_reg_ref_t_f + TYPE, BIND(C) :: h5o_token_t_f + INTEGER(C_INT8_T), DIMENSION(1:H5O_TOKEN_BUF_LEN) :: token + END TYPE h5o_token_t_f + ! Do not forget to change these values when new predefined ! datatypes are added INTEGER, PARAMETER :: PREDEF_TYPES_LEN = 19 INTEGER, PARAMETER :: FLOATING_TYPES_LEN = 4 INTEGER, PARAMETER :: INTEGER_TYPES_LEN = 27 - ! These arrays need to be global because they are used in + ! These arrays need to be global because they are used in ! both h5open_f and in h5close_f; initialize to fix linking issues ! on OSX and Intel compilers. INTEGER(HID_T), DIMENSION(1:PREDEF_TYPES_LEN) :: predef_types = -1 diff --git a/fortran/src/H5f90i.h b/fortran/src/H5f90i.h index 7d066cd..057edc5 100644 --- a/fortran/src/H5f90i.h +++ b/fortran/src/H5f90i.h @@ -21,8 +21,7 @@ */ #include "H5f90i_gen.h" -/* Define _fcd. These are the same on every system - * but UNICOS. +/* Define _fcd. These are the same on every system but UNICOS. */ #define _fcdtocp(desc) (desc) diff --git a/fortran/src/H5f90proto.h b/fortran/src/H5f90proto.h index 5faf4b4..e6f5dd4 100644 --- a/fortran/src/H5f90proto.h +++ b/fortran/src/H5f90proto.h @@ -23,7 +23,7 @@ H5_FCDLL void HD5packFstring(char *src, char *dest, size_t len); /* - * Storage info struct used by H5O_info_t and H5F_info_t + * Storage info struct used by H5O_info_t and H5F_info_t * interoperable with Fortran. */ typedef struct H5_ih_info_t_f { @@ -31,7 +31,7 @@ typedef struct H5_ih_info_t_f { hsize_t heap_size; } H5_ih_info_t_f; -/* Information struct for object header metadata (for H5Oget_info/H5Oget_info_by_name/H5Oget_info_by_idx) +/* Information struct for object header metadata (for H5Oget_info/H5Oget_info_by_name/H5Oget_info_by_idx) * interoperable with Fortran. */ typedef struct H5O_hdr_info_t_f { @@ -51,12 +51,11 @@ typedef struct H5O_hdr_info_t_f { } mesg; } H5O_hdr_info_t_f; -/* Information struct for object (for H5Oget_info/H5Oget_info_by_name/H5Oget_info_by_idx) - * interoperable with Fortran. +/* Information struct for object (for H5Oget_info/H5Oget_info_by_name/H5Oget_info_by_idx) */ typedef struct H5O_info_t_f { unsigned long fileno; /* File number that object is located in */ - haddr_t_f addr; /* Object address in file */ + H5O_token_t token; /* Token of object in file */ int type; /* Basic object type (group, dataset, etc.) */ int_f rc; /* Reference count of object */ int_f atime[8]; /* Access time */ @@ -64,13 +63,18 @@ typedef struct H5O_info_t_f { int_f ctime[8]; /* Change time */ int_f btime[8]; /* Birth time */ hsize_t num_attrs; /* # of attributes attached to object */ +} H5O_info_t_f; + +/* Information struct for native object (for H5Oget_native_info/H5Oget_native_info_by_name/H5Oget_native_info_by_idx) + */ +typedef struct H5O_native_info_t_f { H5O_hdr_info_t_f hdr; /* Object header information */ /* Extra metadata storage for obj & attributes */ struct { H5_ih_info_t_f obj; /* v1/v2 B-tree & local/fractal heap for groups, B-tree for chunked datasets */ H5_ih_info_t_f attr; /* v2 B-tree & heap for attributes */ } meta_size; -} H5O_info_t_f; +} H5O_native_info_t_f; /* @@ -312,12 +316,12 @@ H5_FCDLL int_f h5tconvert_c(hid_t_f *src_id, hid_t_f *dst_id, size_t_f *nelmts, H5_FCDLL int_f h5oopen_c(hid_t_f *loc_id, _fcd name, size_t_f *namelen, hid_t_f *lapl_id, hid_t_f *obj_id); H5_FCDLL int_f h5oclose_c(hid_t_f *object_id ); -H5_FCDLL int_f h5oopen_by_addr_c(hid_t_f *loc_id, haddr_t_f *addr, hid_t_f *obj_id); +H5_FCDLL int_f h5oopen_by_token_c(hid_t_f *loc_id, H5O_token_t *token, hid_t_f *obj_id); H5_FCDLL int_f h5olink_c(hid_t_f *object_id, hid_t_f *new_loc_id, _fcd name, size_t_f *namelen, hid_t_f *lcpl_id, hid_t_f *lapl_id); -H5_FCDLL int_f h5ovisit_c(hid_t_f *group_id, int_f *index_type, int_f *order, H5O_iterate_t op, void *op_data, int_f *fields); +H5_FCDLL int_f h5ovisit_c(hid_t_f *group_id, int_f *index_type, int_f *order, H5O_iterate2_t op, void *op_data, int_f *fields); H5_FCDLL int_f h5ovisit_by_name_c(hid_t_f *loc_id, _fcd object_name, size_t_f *namelen, int_f *index_type, int_f *order, - H5O_iterate_t op, void *op_data, hid_t_f *lapl_id, int_f *fields ); + H5O_iterate2_t op, void *op_data, hid_t_f *lapl_id, int_f *fields ); H5_FCDLL int_f h5oget_info_c(hid_t_f *object_id, H5O_info_t_f *object_info, int_f *fields); H5_FCDLL int_f h5oget_info_by_idx_c(hid_t_f *loc_id, _fcd group_name, size_t_f *namelen, int_f *index_field, int_f *order, hsize_t_f *n, hid_t_f *lapl_id, H5O_info_t_f *object_info, int_f *fields); @@ -336,6 +340,8 @@ H5_FCDLL int_f h5oopen_by_idx_c(hid_t_f *loc_id, _fcd group_name, size_t_f *gro H5_FCDLL int_f h5oget_comment_c(hid_t_f *object_id, _fcd comment, size_t_f *commentsize, hssize_t_f *bufsize); H5_FCDLL int_f h5oget_comment_by_name_c(hid_t_f *loc_id, _fcd name, size_t_f *name_size, _fcd comment, size_t_f *commentsize, size_t_f *bufsize, hid_t_f *lapl_id); +H5_FCDLL int_f h5otoken_cmp_c(hid_t_f *loc_id, H5O_token_t *token1, + H5O_token_t *token2, int_f *cmp_value); /* * Functions from H5Pf.c */ @@ -568,11 +574,11 @@ H5_FCDLL int_f h5ldelete_by_idx_c(hid_t_f *loc_id, _fcd group_name, size_t_f *gr H5_FCDLL int_f h5lexists_c(hid_t_f *loc_id, _fcd name, size_t_f *namelen, hid_t_f *lapl_id, int_f *link_exists); H5_FCDLL int_f h5lget_info_c(hid_t_f *link_loc_id, _fcd link_name, size_t_f *link_namelen, int_f *cset, int_f *corder, int_f *corder_valid, int_f *link_type, - haddr_t_f *address, size_t_f *val_size, - hid_t_f *lapl_id); + H5O_token_t *token, size_t_f *val_size, hid_t_f *lapl_id); H5_FCDLL int_f h5lget_info_by_idx_c(hid_t_f *loc_id, _fcd group_name, size_t_f *group_namelen, int_f *index_field, int_f *order, hsize_t_f *n, - int_f *link_type, int_f *corder_valid, int_f *corder, int_f *cset, haddr_t_f *address, size_t_f *val_size, hid_t_f *lapl_id); + int_f *link_type, int_f *corder_valid, int_f *corder, + int_f *cset, H5O_token_t *token, size_t_f *val_size, hid_t_f *lapl_id); H5_FCDLL int_f h5lis_registered_c(int_f *link_cls_id); H5_FCDLL int_f h5lmove_c(hid_t_f *src_loc_id, _fcd src_name, size_t_f *src_namelen, hid_t_f *dest_loc_id, _fcd dest_name, size_t_f *dest_namelen, hid_t_f *lcpl_id, hid_t_f *lapl_id); @@ -582,8 +588,8 @@ H5_FCDLL int_f h5lget_name_by_idx_c(hid_t_f *loc_id, _fcd group_name, size_t_f * H5_FCDLL int_f h5lget_val_c(hid_t_f *link_loc_id, _fcd link_name, size_t_f *link_namelen, size_t_f *size, void *linkval_buff, hid_t_f *lapl_id) ; -H5_FCDLL int_f h5literate_c(hid_t_f *group_id, int_f *index_type, int_f *order, hsize_t_f *idx, H5L_iterate_t op, void *op_data ); -H5_FCDLL int_f h5literate_by_name_c(hid_t_f *loc_id, _fcd name, size_t_f *namelen, int_f *index_type, int_f *order, hsize_t_f *idx, H5L_iterate_t op, void *op_data, hid_t_f *lapl_id); +H5_FCDLL int_f h5literate_c(hid_t_f *group_id, int_f *index_type, int_f *order, hsize_t_f *idx, H5L_iterate2_t op, void *op_data ); +H5_FCDLL int_f h5literate_by_name_c(hid_t_f *loc_id, _fcd name, size_t_f *namelen, int_f *index_type, int_f *order, hsize_t_f *idx, H5L_iterate2_t op, void *op_data, hid_t_f *lapl_id); #endif /* _H5f90proto_H */ diff --git a/fortran/src/H5match_types.c b/fortran/src/H5match_types.c index e39e85a..2a6204d 100644 --- a/fortran/src/H5match_types.c +++ b/fortran/src/H5match_types.c @@ -414,13 +414,19 @@ int main(void) return -1; } - /* Need the buffer size for the fortran derive type 'hdset_reg_ref_t_f03' + /* Need the buffer size for the fortran derived type 'hdset_reg_ref_t_f03' * in order to be interoperable with C's structure, the C buffer size * H5R_DSET_REG_REF_BUF_SIZE is (sizeof(haddr_t)+4) */ - + fprintf(fort_header, " INTEGER, PARAMETER :: H5R_DSET_REG_REF_BUF_SIZE_F = %u\n", H5_SIZEOF_HADDR_T + 4 ); + /* Need the buffer size for the fortran derived type 'h5o_token_t' + * in order to be interoperable with C's structure. + */ + + fprintf(fort_header, " INTEGER, PARAMETER :: H5O_MAX_TOKEN_SIZE_F = %u\n", H5O_MAX_TOKEN_SIZE); + /* Close files */ endCfile(); endFfile(); diff --git a/fortran/src/README b/fortran/src/README index a258e07..f9316b5 100644 --- a/fortran/src/README +++ b/fortran/src/README @@ -87,7 +87,7 @@ Quick overview of the Fortran APIs to the file, a C program will read it as a 6x4 two-dimensional dataset into memory. The HDF5 C utilities h5dump and h5ls display transposed data, if data is written from a Fortran program. - + * Fortran indices are 1 based. ============================ @@ -105,29 +105,29 @@ Procedure to add a new function Procedure for passing C variables to Fortran --------------------------------------------- -(1) Find the C struct name you are interested in: +(1) Find the C struct name you are interested in: (a) src/H5public.h if it is a generic type, i.e. H5_* or - (b) src/H5*public.h if is a specific type, i.e. H5*_ - + (b) src/H5*public.h if is a specific type, i.e. H5*_ + (2) Put that structure into an array that will be passed to fortran in: (a) fortran/src/H5_f.c (add to nh5init_flags_c subroutine) (b) edit fortran/src/H5f90proto.h and edit nh5init_flags_c interface call - + (3) Edit the function call in fortran/src/H5_ff.F90 - (a) edit the call: FUNCTION h5init_flags_c + (a) edit the call: FUNCTION h5init_flags_c (b) edit h5init_flags_c call in h5open_f to match the number of arguments passing - -(4) add the size of the array and array to fortran/src/H5f90global.F90 + +(4) add the size of the array and array to fortran/src/H5f90global.F90 - must match the size found it H5_f.c -NOTE: To just add a default C value argument, do steps (2a) and (4) +NOTE: To just add a default C value argument, do steps (2a) and (4) Procedure for adding a new file to the repository -------------------------------------------------- -Add the name of the file to the: +Add the name of the file to the: (1) Makefile.am located in the same directory as the newfile (2) CMakeLists.txt located in the same directory as the newfile (3) MANIFEST located in the top level directory diff --git a/fortran/src/hdf5_fortrandll.def.in b/fortran/src/hdf5_fortrandll.def.in index e31a582..7e8b611 100644 --- a/fortran/src/hdf5_fortrandll.def.in +++ b/fortran/src/hdf5_fortrandll.def.in @@ -175,7 +175,7 @@ H5O_mp_H5OGET_COMMENT_F H5O_mp_H5OGET_COMMENT_BY_NAME_F H5O_mp_H5OINCR_REFCOUNT_F H5O_mp_H5OLINK_F -H5O_mp_H5OOPEN_BY_ADDR_F +H5O_mp_H5OOPEN_BY_TOKEN_F H5O_mp_H5OOPEN_BY_IDX_F H5O_mp_H5OOPEN_F H5O_mp_H5OSET_COMMENT_F @@ -185,6 +185,7 @@ H5O_mp_H5OGET_INFO_BY_NAME_F H5O_mp_H5OGET_INFO_F H5O_mp_H5OVISIT_BY_NAME_F H5O_mp_H5OVISIT_F +H5O_mp_H5OTOKEN_CMP_F ; H5P H5P_mp_H5PCREATE_F H5P_mp_H5PSET_PRESERVE_F @@ -459,6 +460,7 @@ H5VL_mp_H5VLREGISTER_CONNECTOR_BY_NAME_F H5VL_mp_H5VLREGISTER_CONNECTOR_BY_VALUE_F H5VL_mp_H5VLIS_CONNECTOR_REGISTERED_F H5VL_mp_H5VLGET_CONNECTOR_ID_F +H5VL_mp_H5VLGET_CONNECTOR_ID_BY_NAME_F H5VL_mp_H5VLGET_CONNECTOR_NAME_F H5VL_mp_H5VLCLOSE_F H5VL_mp_H5VLUNREGISTER_CONNECTOR_F diff --git a/fortran/test/tH5G_1_8.F90 b/fortran/test/tH5G_1_8.F90 index d3be525..58431a1 100644 --- a/fortran/test/tH5G_1_8.F90 +++ b/fortran/test/tH5G_1_8.F90 @@ -665,11 +665,11 @@ SUBROUTINE group_info(cleanup, fapl, total_error) ! H5L_TYPE_SOFT_F - Soft link ! H5L_TYPE_EXTERNAL_F - External link ! H5L_TYPE_ERROR _F - Error - INTEGER(HADDR_T) :: address ! If the link is a hard link, address specifies the file address that the link points to + TYPE(H5O_TOKEN_T_F) :: token ! If the link is a hard link, token specifies the object token that the link points to INTEGER(SIZE_T) :: val_size ! If the link is a symbolic link, val_size will be the length of the link value -! WRITE(*,*) "link creation (w/new group format)" + WRITE(*,*) "link creation (w/new group format)" ! Create a file CALL h5fcreate_f(FileName, H5F_ACC_TRUNC_F, file, error, H5P_DEFAULT_F, fapl) @@ -698,7 +698,7 @@ SUBROUTINE group_info(cleanup, fapl, total_error) CALL check("H5Lcreate_soft_f", error, total_error) CALL H5Lget_info_f(file, "grp1/soft", & - cset, corder, f_corder_valid, link_type, address, val_size, & + cset, corder, f_corder_valid, link_type, token, val_size, & error, H5P_DEFAULT_F) CALL check("H5Lget_info_f",error,total_error) @@ -770,7 +770,7 @@ SUBROUTINE group_info(cleanup, fapl, total_error) ! H5L_TYPE_SOFT_F - Soft link ! H5L_TYPE_EXTERNAL_F - External link ! H5L_TYPE_ERROR _F - Error - INTEGER(HADDR_T) :: address ! If the link is a hard link, address specifies the file address that the link points to + TYPE(H5O_TOKEN_T_F) :: token ! If the link is a hard link, token specifies the object token that the link points to INTEGER(SIZE_T) :: val_size ! If the link is a symbolic link, val_size will be the length of the link value INTEGER :: error @@ -816,7 +816,7 @@ SUBROUTINE group_info(cleanup, fapl, total_error) ! Get the group's link's information CALL H5Lget_info_f(file_id, "group", & - cset, corder, f_corder_valid, link_type, address, val_size, & + cset, corder, f_corder_valid, link_type, token, val_size, & error, H5P_DEFAULT_F) CALL check("H5Lget_info_f",error,total_error) @@ -1179,7 +1179,7 @@ SUBROUTINE delete_by_idx(cleanup, fapl, total_error) INTEGER :: cset ! Indicates the character set used for the attribute’s name INTEGER(SIZE_T) :: val_size INTEGER :: link_type - INTEGER(HADDR_T) :: address + TYPE(H5O_TOKEN_T_F) :: token INTEGER :: u ! Local index variable INTEGER :: Input1, i @@ -1309,10 +1309,10 @@ SUBROUTINE delete_by_idx(cleanup, fapl, total_error) ! HDmemset(&linfo, 0, sizeof(linfo)); CALL H5Lget_info_by_idx_f(group_id, ".", idx_type, iorder, INT(0,HSIZE_T), & - link_type, f_corder_valid, corder, cset, address, val_size, error) + link_type, f_corder_valid, corder, cset, token, val_size, error) - CALL H5Oopen_by_addr_f(group_id, address, grp, error) - CALL check("H5Oopen_by_addr_f", error, total_error) + CALL H5Oopen_by_token_f(group_id, token, grp, error) + CALL check("H5Oopen_by_token_f", error, total_error) CALL H5Iget_type_f(grp, id_type, error) CALL check("H5Iget_type_f", error, total_error) @@ -1357,11 +1357,11 @@ SUBROUTINE delete_by_idx(cleanup, fapl, total_error) ! Close the group creation property list CALL H5Pclose_f(gcpl_id, error) - CALL check("delete_by_idx.H5Gclose_f", error, total_error) + CALL check("delete_by_idx.H5Pclose_f", error, total_error) ! Close the file CALL H5Fclose_f(file_id, error) - CALL check("delete_by_idx.H5Gclose_f", error, total_error) + CALL check("delete_by_idx.H5Fclose_f", error, total_error) IF(cleanup) CALL h5_cleanup_f("file0", H5P_DEFAULT_F, error) CALL check("h5_cleanup_f", error, total_error) @@ -1407,7 +1407,7 @@ SUBROUTINE link_info_by_idx_check(group_id, linkname, n, & INTEGER :: corder ! Is a positive integer containing the creation order of the attribute INTEGER :: cset ! Indicates the character set used for the attribute’s name INTEGER :: link_type - INTEGER(HADDR_T) :: address + TYPE(H5O_TOKEN_T_F) :: token INTEGER(SIZE_T) :: val_size ! Indicates the size, in the number of characters, of the attribute CHARACTER(LEN=7) :: tmpname ! Temporary link name @@ -1427,14 +1427,14 @@ SUBROUTINE link_info_by_idx_check(group_id, linkname, n, & ! Verify the link information for first link, in increasing creation order ! HDmemset(&linfo, 0, sizeof(linfo)); CALL H5Lget_info_by_idx_f(group_id, ".", H5_INDEX_CRT_ORDER_F, H5_ITER_INC_F, INT(0,HSIZE_T), & - link_type, f_corder_valid, corder, cset, address, val_size, error) + link_type, f_corder_valid, corder, cset, token, val_size, error) CALL check("H5Lget_info_by_idx_f", error, total_error) CALL verify("H5Lget_info_by_idx_f", corder, 0, total_error) ! Verify the link information for new link, in increasing creation order ! HDmemset(&linfo, 0, sizeof(linfo)); CALL H5Lget_info_by_idx_f(group_id, ".", H5_INDEX_CRT_ORDER_F, H5_ITER_INC_F, INT(n,HSIZE_T), & - link_type, f_corder_valid, corder, cset, address, val_size, error) + link_type, f_corder_valid, corder, cset, token, val_size, error) CALL check("H5Lget_info_by_idx_f", error, total_error) CALL verify("H5Lget_info_by_idx_f", corder, n, total_error) @@ -1516,7 +1516,7 @@ SUBROUTINE link_info_by_idx_check(group_id, linkname, n, & ! H5L_TYPE_SOFT_F - Soft link ! H5L_TYPE_EXTERNAL_F - External link ! H5L_TYPE_ERROR _F - Error - INTEGER(HADDR_T) :: address ! If the link is a hard link, address specifies the file address that the link points to + TYPE(H5O_TOKEN_T_F) :: token ! If the link is a hard link, token specifies the object token that the link points to INTEGER(SIZE_T) :: val_size ! If the link is a symbolic link, val_size will be the length of the link value CHARACTER(LEN=1024) :: filename = 'tempfile.h5' @@ -1555,7 +1555,7 @@ SUBROUTINE link_info_by_idx_check(group_id, linkname, n, & ! Check that its character encoding is the default CALL H5Lget_info_f(file_id, "group", & - cset, corder, f_corder_valid, link_type, address, val_size, & + cset, corder, f_corder_valid, link_type, token, val_size, & error, H5P_DEFAULT_F) ! File-wide default character encoding can not yet be set via the file @@ -1575,7 +1575,7 @@ SUBROUTINE link_info_by_idx_check(group_id, linkname, n, & ! Check that its character encoding is the default CALL H5Lget_info_f(file_id, "type", & - cset, corder, f_corder_valid, link_type, address, val_size, & + cset, corder, f_corder_valid, link_type, token, val_size, & error) CALL check("h5tclose_f", error, total_error) @@ -1636,7 +1636,7 @@ SUBROUTINE link_info_by_idx_check(group_id, linkname, n, & ! Check that its character encoding is the default CALL H5Lget_info_f(file_id, "dataset", & - cset, corder, f_corder_valid, link_type, address, val_size, & + cset, corder, f_corder_valid, link_type, token, val_size, & error) CALL check("H5Lget_info_f", error, total_error) @@ -1661,7 +1661,7 @@ SUBROUTINE link_info_by_idx_check(group_id, linkname, n, & ! Check that its character encoding is UTF-8 CALL H5Lget_info_f(file_id, "group2", & - cset, corder, f_corder_valid, link_type, address, val_size, & + cset, corder, f_corder_valid, link_type, token, val_size, & error) CALL check("H5Lget_info_f", error, total_error) CALL verify("H5Lget_info_f",cset, H5T_CSET_UTF8_F,total_error) @@ -1679,7 +1679,7 @@ SUBROUTINE link_info_by_idx_check(group_id, linkname, n, & ! Check that its character encoding is UTF-8 CALL H5Lget_info_f(file_id, "type2", & - cset, corder, f_corder_valid, link_type, address, val_size, & + cset, corder, f_corder_valid, link_type, token, val_size, & error) CALL check("H5Lget_info_f", error, total_error) CALL verify("H5Lget_info_f",cset, H5T_CSET_UTF8_F,total_error) @@ -1697,7 +1697,7 @@ SUBROUTINE link_info_by_idx_check(group_id, linkname, n, & ! Check that its character encoding is UTF-8 CALL H5Lget_info_f(file_id, "dataset2", & - cset, corder, f_corder_valid, link_type, address, val_size, & + cset, corder, f_corder_valid, link_type, token, val_size, & error) CALL check("H5Lget_info_f", error, total_error) CALL verify("H5Lget_info_f2",cset, H5T_CSET_UTF8_F,total_error) @@ -1719,7 +1719,7 @@ SUBROUTINE link_info_by_idx_check(group_id, linkname, n, & ! Check that its character encoding is ASCII CALL H5Lget_info_f(file_id, "/dataset2_link", & - cset, corder, f_corder_valid, link_type, address, val_size, & + cset, corder, f_corder_valid, link_type, token, val_size, & error) CALL check("H5Lget_info_f", error, total_error) CALL verify("H5Lget_info_f",cset, H5T_CSET_ASCII_F,total_error) @@ -1727,7 +1727,7 @@ SUBROUTINE link_info_by_idx_check(group_id, linkname, n, & ! Check that the first link's encoding hasn't changed CALL H5Lget_info_f(file_id, "/dataset2", & - cset, corder, f_corder_valid, link_type, address, val_size, & + cset, corder, f_corder_valid, link_type, token, val_size, & error) CALL check("H5Lget_info_f", error, total_error) CALL verify("H5Lget_info_f3",cset, H5T_CSET_UTF8_F,total_error) @@ -1742,7 +1742,7 @@ SUBROUTINE link_info_by_idx_check(group_id, linkname, n, & CALL check("H5Lcreate_soft_f", error, total_error) CALL H5Lget_info_f(file_id, "slink_to_dset2", & - cset, corder, f_corder_valid, link_type, address, val_size, & + cset, corder, f_corder_valid, link_type, token, val_size, & error) CALL check("H5Lget_info_f", error, total_error) CALL verify("H5Lget_info_f",cset, H5T_CSET_UTF8_F,total_error) @@ -1756,7 +1756,7 @@ SUBROUTINE link_info_by_idx_check(group_id, linkname, n, & CALL check("H5Lmove_f",error, total_error) CALL H5Lget_info_f(file_id, "moved_slink", & - cset, corder, f_corder_valid, link_type, address, val_size, & + cset, corder, f_corder_valid, link_type, token, val_size, & error) CALL check("H5Lget_info_f", error, total_error) CALL verify("H5Lget_info_f",cset, H5T_CSET_ASCII_F,total_error) @@ -1770,7 +1770,7 @@ SUBROUTINE link_info_by_idx_check(group_id, linkname, n, & CALL H5Lcopy_f(file_id, "moved_slink", file_id, "copied_slink", error, lcpl_id) CALL H5Lget_info_f(file_id, "copied_slink", & - cset, corder, f_corder_valid, link_type, address, val_size, & + cset, corder, f_corder_valid, link_type, token, val_size, & error) CALL check("H5Lget_info_f", error, total_error) CALL verify("H5Lget_info_f",cset, H5T_CSET_UTF8_F,total_error) @@ -1782,7 +1782,7 @@ SUBROUTINE link_info_by_idx_check(group_id, linkname, n, & CALL check("H5Lcreate_external_f", error, total_error) CALL H5Lget_info_f(file_id, "extlink", & - cset, corder, f_corder_valid, link_type, address, val_size, & + cset, corder, f_corder_valid, link_type, token, val_size, & error) CALL check("H5Lget_info_f", error, total_error) CALL verify("H5Lget_info_f",cset, H5T_CSET_UTF8_F,total_error) diff --git a/fortran/test/tH5O_F03.F90 b/fortran/test/tH5O_F03.F90 index 5b446a4..c9ecccc 100644 --- a/fortran/test/tH5O_F03.F90 +++ b/fortran/test/tH5O_F03.F90 @@ -63,27 +63,33 @@ MODULE visit_cb CONTAINS -! Compares the field values of a C h5O_info_t and a Fortran H5O_info_t. +! Compares the field values of a C H5O_info_t and a Fortran H5O_info_t. + + INTEGER FUNCTION compare_h5o_info_t( loc_id, oinfo_f, oinfo_c, field, full_f_field ) RESULT(status) - INTEGER FUNCTION compare_h5o_info_t( oinfo_f, oinfo_c, field, full_f_field ) RESULT(status) - IMPLICIT NONE + INTEGER(HID_T) :: loc_id TYPE(h5o_info_t) :: oinfo_f TYPE(c_h5o_info_t) :: oinfo_c + TYPE(H5O_TOKEN_T_F) :: token_c INTEGER :: field - LOGICAL :: full_f_field ! All the fields of Fortran H5O_info_t where filled + LOGICAL :: full_f_field ! All the fields of Fortran H5O_info_t where filled ! local INTEGER(C_INT), DIMENSION(1:8) :: atime, btime, ctime, mtime + INTEGER :: cmp_value INTEGER :: i + INTEGER :: ierr status = 0 - + IF( (field .EQ. H5O_INFO_BASIC_F).OR.(field .EQ. H5O_INFO_ALL_F) )THEN IF( (oinfo_f%fileno.LE.0) .OR. (oinfo_c%fileno .NE. oinfo_f%fileno) )THEN status = -1 RETURN ENDIF - IF( (oinfo_f%addr.LE.0) .OR. (oinfo_c%addr .NE. oinfo_f%addr) )THEN + token_c%token = oinfo_c%token%token + CALL H5Otoken_cmp_f(loc_id, oinfo_f%token, token_c, cmp_value, ierr); + IF( (ierr .EQ. -1) .OR. (cmp_value .NE. 0) ) THEN status = -1 RETURN ENDIF @@ -131,26 +137,12 @@ CONTAINS ! check other field values are not filled (using only a small subset to check) status = 0 IF( oinfo_c%fileno .NE. oinfo_f%fileno) status = status + 1 - IF( oinfo_c%addr .NE. oinfo_f%addr) status = status + 1 - IF( oinfo_c%type .NE. oinfo_f%type) status = status + 1 - IF( oinfo_c%rc .NE. oinfo_f%rc) status = status + 1 - IF(status.EQ.0) THEN ! There was no difference found, which is only possible if the field was filled. - status = -1 - RETURN - ENDIF - status = 0 ! reset - ENDIF - - IF((field .EQ. H5O_INFO_NUM_ATTRS_F).OR.(field .EQ. H5O_INFO_ALL_F))THEN - IF( (oinfo_f%num_attrs.LT.0) .OR. (oinfo_c%num_attrs .NE. oinfo_f%num_attrs) )THEN + token_c%token = oinfo_c%token%token + CALL H5Otoken_cmp_f(loc_id, oinfo_f%token, token_c, cmp_value, ierr); + IF( (ierr .EQ. -1) .OR. (cmp_value .NE. 0) ) THEN status = -1 RETURN ENDIF - ELSE IF( field .EQ. H5O_INFO_ALL_F.AND.full_f_field)THEN - ! check other field values are not filled (using only a small subset to check) - status = 0 - IF( oinfo_c%fileno .NE. oinfo_f%fileno) status = status + 1 - IF( oinfo_c%addr .NE. oinfo_f%addr) status = status + 1 IF( oinfo_c%type .NE. oinfo_f%type) status = status + 1 IF( oinfo_c%rc .NE. oinfo_f%rc) status = status + 1 IF(status.EQ.0) THEN ! There was no difference found, which is only possible if the field was filled. @@ -158,85 +150,23 @@ CONTAINS RETURN ENDIF status = 0 ! reset - ENDIF - IF((field).EQ.H5O_INFO_HDR_F.OR.(field .EQ. H5O_INFO_ALL_F))THEN - IF( (oinfo_f%hdr%version.LT.0) .OR. (oinfo_c%hdr%version .NE. oinfo_f%hdr%version) )THEN - status = -1 - RETURN - ENDIF - IF( (oinfo_f%hdr%nmesgs.LT.0) .OR. (oinfo_c%hdr%nmesgs .NE. oinfo_f%hdr%nmesgs) )THEN - status = -1 - RETURN - ENDIF - IF( (oinfo_f%hdr%nchunks.LT.0) .OR. (oinfo_c%hdr%nchunks .NE. oinfo_f%hdr%nchunks) )THEN - status = -1 - RETURN - ENDIF - IF( (oinfo_f%hdr%flags.LT.0) .OR. (oinfo_c%hdr%flags .NE. oinfo_f%hdr%flags) )THEN - status = -1 - RETURN - ENDIF - IF( (oinfo_f%hdr%space%total.LT.0) .OR. (oinfo_c%hdr%space%total .NE. oinfo_f%hdr%space%total) )THEN - status = -1 - RETURN - ENDIF - IF( (oinfo_f%hdr%space%meta.LT.0) .OR. (oinfo_c%hdr%space%meta .NE. oinfo_f%hdr%space%meta) )THEN - status = -1 - RETURN - ENDIF - IF( (oinfo_f%hdr%space%mesg.LT.0) .OR. (oinfo_c%hdr%space%mesg .NE. oinfo_f%hdr%space%mesg) )THEN - status = -1 - RETURN - ENDIF - IF( (oinfo_f%hdr%space%free.LT.0) .OR. (oinfo_c%hdr%space%free .NE. oinfo_f%hdr%space%free) )THEN - status = -1 - RETURN - ENDIF - IF( (oinfo_f%hdr%mesg%present.LT.0) .OR. (oinfo_c%hdr%mesg%present .NE. oinfo_f%hdr%mesg%present) )THEN - status = -1 - RETURN - ENDIF - IF( (oinfo_f%hdr%mesg%shared.LT.0) .OR. (oinfo_c%hdr%mesg%shared .NE. oinfo_f%hdr%mesg%shared) )THEN + IF((field .EQ. H5O_INFO_NUM_ATTRS_F).OR.(field .EQ. H5O_INFO_ALL_F))THEN + IF( (oinfo_f%num_attrs.LT.0) .OR. (oinfo_c%num_attrs .NE. oinfo_f%num_attrs) )THEN status = -1 RETURN ENDIF - ELSE IF( field .EQ. H5O_INFO_HDR_F.AND.full_f_field)THEN + ELSE IF( field .EQ. H5O_INFO_ALL_F.AND.full_f_field)THEN ! check other field values are not filled (using only a small subset to check) status = 0 IF( oinfo_c%fileno .NE. oinfo_f%fileno) status = status + 1 - IF( oinfo_c%addr .NE. oinfo_f%addr) status = status + 1 - IF( oinfo_c%type .NE. oinfo_f%type) status = status + 1 - IF( oinfo_c%rc .NE. oinfo_f%rc) status = status + 1 - IF(status.EQ.0) THEN ! There was no difference found, which is only possible if the field was filled. - status = -1 - RETURN - ENDIF - status = 0 ! reset - ENDIF - IF((field).EQ.H5O_INFO_META_SIZE_F.OR.(field .EQ. H5O_INFO_ALL_F))THEN - IF((oinfo_f%meta_size%obj%index_size.LT.0).OR.(oinfo_c%meta_size%obj%index_size.NE.oinfo_f%meta_size%obj%index_size))THEN - status = -1 - RETURN - ENDIF - IF((oinfo_f%meta_size%obj%heap_size.LT.0).OR.(oinfo_c%meta_size%obj%heap_size.NE.oinfo_f%meta_size%obj%heap_size))THEN - status = -1 - RETURN - ENDIF - IF((oinfo_f%meta_size%attr%index_size.LT.0).OR.(oinfo_c%meta_size%attr%index_size.NE.oinfo_f%meta_size%attr%index_size))THEN - status = -1 - RETURN - ENDIF - IF((oinfo_f%meta_size%attr%heap_size.LT.0).OR.(oinfo_c%meta_size%attr%heap_size.NE.oinfo_f%meta_size%attr%heap_size))THEN + token_c%token = oinfo_c%token%token + CALL H5Otoken_cmp_f(loc_id, oinfo_f%token, token_c, cmp_value, ierr); + IF( (ierr .EQ. -1) .OR. (cmp_value .NE. 0) ) THEN status = -1 RETURN ENDIF - ELSE IF( field .EQ. H5O_INFO_META_SIZE_F.AND.full_f_field)THEN - ! check other field values are not filled (using only a small subset to check) - status = 0 - IF( oinfo_c%fileno .NE. oinfo_f%fileno) status = status + 1 - IF( oinfo_c%addr .NE. oinfo_f%addr) status = status + 1 IF( oinfo_c%type .NE. oinfo_f%type) status = status + 1 IF( oinfo_c%rc .NE. oinfo_f%rc) status = status + 1 IF(status.EQ.0) THEN ! There was no difference found, which is only possible if the field was filled. @@ -295,13 +225,13 @@ CONTAINS IF(op_data%field .EQ. H5O_INFO_ALL_F)THEN idx = op_data%idx - + DO i = 1, len IF(op_data%info(idx)%path(i)(1:1) .NE. name(i)(1:1))THEN visit_obj_cb = -1 RETURN ENDIF - + IF(op_data%info(idx)%type_obj .NE. oinfo_c%type)THEN visit_obj_cb = -1 RETURN @@ -310,14 +240,14 @@ CONTAINS ENDIF - ! Check H5Oget_info_by_name_f; if partial field values where filled correctly + ! Check H5Oget_info_by_name_f; if partial field values were filled correctly CALL H5Oget_info_by_name_f(group_id, name2, oinfo_f, ierr); - visit_obj_cb = compare_h5o_info_t( oinfo_f, oinfo_c, op_data%field, .TRUE. ) + visit_obj_cb = compare_h5o_info_t( group_id, oinfo_f, oinfo_c, op_data%field, .TRUE. ) IF(visit_obj_cb.EQ.-1) RETURN ! Check H5Oget_info_by_name_f, only check field values CALL H5Oget_info_by_name_f(group_id, name2, oinfo_f, ierr, fields = op_data%field); - visit_obj_cb = compare_h5o_info_t( oinfo_f, oinfo_c, op_data%field, .FALSE. ) + visit_obj_cb = compare_h5o_info_t(group_id, oinfo_f, oinfo_c, op_data%field, .FALSE. ) IF(visit_obj_cb.EQ.-1) RETURN @@ -325,12 +255,12 @@ CONTAINS ! Check H5Oget_info_f, only check field values CALL H5Oget_info_f(group_id, oinfo_f, ierr, fields = op_data%field); - visit_obj_cb = compare_h5o_info_t( oinfo_f, oinfo_c, op_data%field, .FALSE. ) + visit_obj_cb = compare_h5o_info_t(group_id, oinfo_f, oinfo_c, op_data%field, .FALSE. ) IF(visit_obj_cb.EQ.-1) RETURN ! Check H5Oget_info_f; if partial field values where filled correctly CALL H5Oget_info_f(group_id, oinfo_f, ierr); - visit_obj_cb = compare_h5o_info_t( oinfo_f, oinfo_c, op_data%field, .TRUE. ) + visit_obj_cb = compare_h5o_info_t(group_id, oinfo_f, oinfo_c, op_data%field, .TRUE. ) IF(visit_obj_cb.EQ.-1) RETURN ENDIF @@ -583,20 +513,6 @@ SUBROUTINE test_obj_visit(total_error) IF(ret_val.LT.0)THEN CALL check("h5ovisit_f", -1, total_error) ENDIF - udata%field = H5O_INFO_HDR_F - udata%idx = 1 - CALL h5ovisit_f(fid, H5_INDEX_NAME_F, H5_ITER_INC_F, fun_ptr, f_ptr, ret_val, error, fields=udata%field) - CALL check("h5ovisit_f", error, total_error) - IF(ret_val.LT.0)THEN - CALL check("h5ovisit_f", -1, total_error) - ENDIF - udata%field = H5O_INFO_META_SIZE_F - udata%idx = 1 - CALL h5ovisit_f(fid, H5_INDEX_NAME_F, H5_ITER_INC_F, fun_ptr, f_ptr, ret_val, error, fields=udata%field) - CALL check("h5ovisit_f", error, total_error) - IF(ret_val.LT.0)THEN - CALL check("h5ovisit_f", -1, total_error) - ENDIF ! Test h5ovisit_by_name_f object_name = "/" @@ -630,21 +546,7 @@ SUBROUTINE test_obj_visit(total_error) IF(ret_val.LT.0)THEN CALL check("h5ovisit_by_name_f", -1, total_error) ENDIF - udata%idx = 1 - udata%field = H5O_INFO_HDR_F - CALL h5ovisit_by_name_f(fid, object_name, H5_INDEX_NAME_F, H5_ITER_INC_F, fun_ptr, f_ptr, ret_val, error, fields=udata%field) - CALL check("h5ovisit_by_name_f", error, total_error) - IF(ret_val.LT.0)THEN - CALL check("h5ovisit_by_name_f", -1, total_error) - ENDIF - udata%idx = 1 - udata%field = H5O_INFO_META_SIZE_F - CALL h5ovisit_by_name_f(fid, object_name, H5_INDEX_NAME_F, H5_ITER_INC_F, fun_ptr, f_ptr, ret_val, error, fields=udata%field) - CALL check("h5ovisit_by_name_f", error, total_error) - IF(ret_val.LT.0)THEN - CALL check("h5ovisit_by_name_f", -1, total_error) - ENDIF - + CALL h5fclose_f(fid, error) CALL check("h5fclose_f",error, total_error) diff --git a/fortran/test/vol_connector.F90 b/fortran/test/vol_connector.F90 index aabb2b8..cd05cb1 100644 --- a/fortran/test/vol_connector.F90 +++ b/fortran/test/vol_connector.F90 @@ -74,8 +74,8 @@ CONTAINS CALL check("H5VLis_connector_registered_f",error,total_error) CALL VERIFY("H5VLis_connector_registered_f", is_registered, .TRUE., total_error) - CALL H5VLget_connector_id_f(NATIVE_VOL_CONNECTOR_NAME, vol_id_out, error) - CALL check("H5VLget_connector_id_f",error,total_error) + CALL H5VLget_connector_id_by_name_f(NATIVE_VOL_CONNECTOR_NAME, vol_id_out, error) + CALL check("H5VLget_connector_id_by_name_f",error,total_error) CALL H5Fcreate_f("voltest.h5",H5F_ACC_TRUNC_F, file_id, error) CALL check("H5F_create_f",error,total_error) @@ -201,9 +201,9 @@ CONTAINS CALL VERIFY("H5Pget_vol_id_f", vol_id_out, vol_id, total_error) ENDIF - CALL H5VLget_connector_id_f(NATIVE_VOL_CONNECTOR_NAME, vol_id_out, error) - CALL check("H5VLget_connector_id_f",error,total_error) - CALL VERIFY("H5VLget_connector_id_f", vol_id_out, vol_id, total_error) + CALL H5VLget_connector_id_by_name_f(NATIVE_VOL_CONNECTOR_NAME, vol_id_out, error) + CALL check("H5VLget_connector_id_by_name_f",error,total_error) + CALL VERIFY("H5VLget_connector_id_by_name_f", vol_id_out, vol_id, total_error) CALL H5Fcreate_f("voltest.h5",H5F_ACC_TRUNC_F, file_id, error, H5P_DEFAULT_F, fapl_id) CALL check("H5F_create_f",error,total_error) diff --git a/hl/src/H5DS.c b/hl/src/H5DS.c index c91ea1f..63fb461 100644 --- a/hl/src/H5DS.c +++ b/hl/src/H5DS.c @@ -140,10 +140,10 @@ herr_t H5DSattach_scale(hid_t did, hobj_ref_t ref_j; /* iterator reference */ hvl_t *buf = NULL; /* VL buffer to store in the attribute */ hid_t dsid_j; /* DS dataset ID in DIMENSION_LIST */ - H5O_info_t oi1, oi2; + H5O_info2_t oi1, oi2; H5I_type_t it1, it2; int i; - size_t len; + size_t len; int found_ds=0; htri_t is_scale; @@ -156,20 +156,26 @@ herr_t H5DSattach_scale(hid_t did, return FAIL; /* the dataset cannot be a DS dataset */ - if ( is_scale == 1) + if (is_scale == 1) return FAIL; /* get info for the dataset in the parameter list */ - if(H5Oget_info2(did, &oi1, H5O_INFO_BASIC) < 0) + if(H5Oget_info3(did, &oi1, H5O_INFO_BASIC) < 0) return FAIL; /* get info for the scale in the parameter list */ - if(H5Oget_info2(dsid, &oi2, H5O_INFO_BASIC) < 0) + if(H5Oget_info3(dsid, &oi2, H5O_INFO_BASIC) < 0) return FAIL; /* same object, not valid */ - if(oi1.fileno == oi2.fileno && oi1.addr == oi2.addr) - return FAIL; + if(oi1.fileno == oi2.fileno) { + int token_cmp; + + if(H5Otoken_cmp(did, &oi1.token, &oi2.token, &token_cmp) < 0) + return FAIL; + if(!token_cmp) + return FAIL; + } /* end if */ /* get ID type */ if ((it1 = H5Iget_type(did)) < 0) @@ -324,16 +330,22 @@ herr_t H5DSattach_scale(hid_t did, goto out; /* get info for DS in the parameter list */ - if(H5Oget_info2(dsid, &oi1, H5O_INFO_BASIC) < 0) + if(H5Oget_info3(dsid, &oi1, H5O_INFO_BASIC) < 0) goto out; /* get info for this DS */ - if(H5Oget_info2(dsid_j, &oi2, H5O_INFO_BASIC) < 0) + if(H5Oget_info3(dsid_j, &oi2, H5O_INFO_BASIC) < 0) goto out; /* same object, so this DS scale is already in this DIM IDX */ - if(oi1.fileno == oi2.fileno && oi1.addr == oi2.addr) - found_ds = 1; + if(oi1.fileno == oi2.fileno) { + int token_cmp; + + if(H5Otoken_cmp(did, &oi1.token, &oi2.token, &token_cmp) < 0) + goto out; + if(!token_cmp) + found_ds = 1; + } /* end if */ /* close the dereferenced dataset */ if(H5Dclose(dsid_j) < 0) @@ -586,7 +598,7 @@ herr_t H5DSdetach_scale(hid_t did, int i; size_t j; hssize_t ii; - H5O_info_t did_oi, dsid_oi, tmp_oi; + H5O_info2_t did_oi, dsid_oi, tmp_oi; int found_dset = 0, found_ds = 0; int have_ds = 0; htri_t is_scale; @@ -609,16 +621,22 @@ herr_t H5DSdetach_scale(hid_t did, return FAIL; /* get info for the dataset in the parameter list */ - if(H5Oget_info2(did, &did_oi, H5O_INFO_BASIC) < 0) + if(H5Oget_info3(did, &did_oi, H5O_INFO_BASIC) < 0) return FAIL; /* get info for the scale in the parameter list */ - if(H5Oget_info2(dsid, &dsid_oi, H5O_INFO_BASIC) < 0) + if(H5Oget_info3(dsid, &dsid_oi, H5O_INFO_BASIC) < 0) return FAIL; /* same object, not valid */ - if(did_oi.fileno == dsid_oi.fileno && did_oi.addr == dsid_oi.addr) - return FAIL; + if(did_oi.fileno == dsid_oi.fileno) { + int token_cmp; + + if(H5Otoken_cmp(did, &did_oi.token, &dsid_oi.token, &token_cmp) < 0) + return FAIL; + if(!token_cmp) + return FAIL; + } /* end if */ /*------------------------------------------------------------------------- @@ -696,7 +714,7 @@ herr_t H5DSdetach_scale(hid_t did, goto out; /* get info for this DS */ - if(H5Oget_info2(dsid_j, &tmp_oi, H5O_INFO_BASIC) < 0) + if(H5Oget_info3(dsid_j, &tmp_oi, H5O_INFO_BASIC) < 0) goto out; /* Close the dereferenced dataset */ @@ -704,30 +722,35 @@ herr_t H5DSdetach_scale(hid_t did, goto out; /* same object, reset */ - if(dsid_oi.fileno == tmp_oi.fileno && dsid_oi.addr == tmp_oi.addr) - { - /* If there are more than one reference in the VL element - and the reference we found is not the last one, - copy the last one to replace the found one since the order - of the references doesn't matter according to the spec; - reduce the size of the VL element by 1; - if the length of the element becomes 0, free the pointer - and reset to NULL */ - - size_t len = buf[idx].len; - - if(j < len - 1) - ((hobj_ref_t *)buf[idx].p)[j] = ((hobj_ref_t *)buf[idx].p)[len-1]; - len = --buf[idx].len; - if(len == 0) { - HDfree(buf[idx].p); - buf[idx].p = NULL; - } - /* Since a reference to a dim. scale can be inserted only once, - we do not need to continue the search if it is found */ - found_ds = 1; - break; - } + if(dsid_oi.fileno == tmp_oi.fileno) { + int token_cmp; + + if(H5Otoken_cmp(did, &dsid_oi.token, &tmp_oi.token, &token_cmp) < 0) + goto out; + if(!token_cmp) { + /* If there are more than one reference in the VL element + and the reference we found is not the last one, + copy the last one to replace the found one since the order + of the references doesn't matter according to the spec; + reduce the size of the VL element by 1; + if the length of the element becomes 0, free the pointer + and reset to NULL */ + + size_t len = buf[idx].len; + + if(j < len - 1) + ((hobj_ref_t *)buf[idx].p)[j] = ((hobj_ref_t *)buf[idx].p)[len-1]; + len = --buf[idx].len; + if(len == 0) { + HDfree(buf[idx].p); + buf[idx].p = NULL; + } + /* Since a reference to a dim. scale can be inserted only once, + we do not need to continue the search if it is found */ + found_ds = 1; + break; + } /* end if */ + } /* end if */ } /* j */ } /* if */ @@ -806,7 +829,7 @@ herr_t H5DSdetach_scale(hid_t did, goto out; /* get info for this dataset */ - if(H5Oget_info2(did_i, &tmp_oi, H5O_INFO_BASIC) < 0) + if(H5Oget_info3(did_i, &tmp_oi, H5O_INFO_BASIC) < 0) goto out; /* close the dereferenced dataset */ @@ -814,13 +837,19 @@ herr_t H5DSdetach_scale(hid_t did, goto out; /* same object, reset. we want to detach only for this DIM */ - if(did_oi.fileno == tmp_oi.fileno && did_oi.addr == tmp_oi.addr) { - /* copy the last one to replace the one which is found */ - dsbuf[ii] = dsbuf[nelmts-1]; - nelmts--; - found_dset=1; - break; - } /* if */ + if(did_oi.fileno == tmp_oi.fileno) { + int token_cmp; + + if(H5Otoken_cmp(did, &did_oi.token, &tmp_oi.token, &token_cmp) < 0) + goto out; + if(!token_cmp) { + /* copy the last one to replace the one which is found */ + dsbuf[ii] = dsbuf[nelmts-1]; + nelmts--; + found_dset=1; + break; + } /* end if */ + } /* end if */ } /* if we have the same dimension index */ } /* ii */ @@ -954,7 +983,7 @@ htri_t H5DSis_attached(hid_t did, hvl_t *buf = NULL; /* VL buffer to store in the attribute */ hid_t dsid_j; /* DS dataset ID in DIMENSION_LIST */ hid_t did_i; /* dataset ID in REFERENCE_LIST */ - H5O_info_t oi1, oi2, oi3, oi4; + H5O_info2_t oi1, oi2, oi3, oi4; H5I_type_t it1, it2; int i; int found_dset=0, found_ds=0; @@ -973,16 +1002,22 @@ htri_t H5DSis_attached(hid_t did, return FAIL; /* get info for the dataset in the parameter list */ - if(H5Oget_info2(did, &oi1, H5O_INFO_BASIC) < 0) + if(H5Oget_info3(did, &oi1, H5O_INFO_BASIC) < 0) return FAIL; /* get info for the scale in the parameter list */ - if(H5Oget_info2(dsid, &oi2, H5O_INFO_BASIC) < 0) + if(H5Oget_info3(dsid, &oi2, H5O_INFO_BASIC) < 0) return FAIL; /* same object, not valid */ - if(oi1.fileno == oi2.fileno && oi1.addr == oi2.addr) - return FAIL; + if(oi1.fileno == oi2.fileno) { + int token_cmp; + + if(H5Otoken_cmp(did, &oi1.token, &oi2.token, &token_cmp) < 0) + return FAIL; + if(!token_cmp) + return FAIL; + } /* end if */ /* get ID type */ if ((it1 = H5Iget_type(did)) < 0) @@ -1054,16 +1089,22 @@ htri_t H5DSis_attached(hid_t did, goto out; /* get info for DS in the parameter list */ - if(H5Oget_info2(dsid, &oi1, H5O_INFO_BASIC) < 0) + if(H5Oget_info3(dsid, &oi1, H5O_INFO_BASIC) < 0) goto out; /* get info for this DS */ - if(H5Oget_info2(dsid_j, &oi2, H5O_INFO_BASIC) < 0) + if(H5Oget_info3(dsid_j, &oi2, H5O_INFO_BASIC) < 0) goto out; /* same object */ - if(oi1.fileno == oi2.fileno && oi1.addr == oi2.addr) - found_ds = 1; + if(oi1.fileno == oi2.fileno) { + int token_cmp; + + if(H5Otoken_cmp(did, &oi1.token, &oi2.token, &token_cmp) < 0) + goto out; + if(!token_cmp) + found_ds = 1; + } /* end if */ /* close the dereferenced dataset */ if (H5Dclose(dsid_j) < 0) @@ -1144,16 +1185,22 @@ htri_t H5DSis_attached(hid_t did, goto out; /* get info for dataset in the parameter list */ - if(H5Oget_info2(did, &oi3, H5O_INFO_BASIC) < 0) + if(H5Oget_info3(did, &oi3, H5O_INFO_BASIC) < 0) goto out; /* get info for this dataset */ - if(H5Oget_info2(did_i, &oi4, H5O_INFO_BASIC) < 0) + if(H5Oget_info3(did_i, &oi4, H5O_INFO_BASIC) < 0) goto out; /* same object */ - if(oi3.fileno == oi4.fileno && oi3.addr == oi4.addr && idx==dsbuf[i].dim_idx) - found_dset=1; + if(oi3.fileno == oi4.fileno) { + int token_cmp; + + if(H5Otoken_cmp(did, &oi3.token, &oi4.token, &token_cmp) < 0) + goto out; + if(!token_cmp && (idx == dsbuf[i].dim_idx)) + found_dset=1; + } /* end if */ /* close the dereferenced dataset */ if (H5Dclose(did_i) < 0) diff --git a/hl/src/H5LT.c b/hl/src/H5LT.c index bb72ce6..3f6c538 100644 --- a/hl/src/H5LT.c +++ b/hl/src/H5LT.c @@ -1360,7 +1360,7 @@ out: */ static herr_t -find_dataset(hid_t loc_id, const char *name, const H5L_info_t *linfo, void *op_data) +find_dataset(hid_t loc_id, const char *name, const H5L_info2_t *linfo, void *op_data) { /* Define a default zero value for return. This will cause the iterator to continue if * the dataset is not found yet. @@ -1411,7 +1411,7 @@ find_dataset(hid_t loc_id, const char *name, const H5L_info_t *linfo, void *op_d herr_t H5LTfind_dataset( hid_t loc_id, const char *dset_name ) { - return H5Literate(loc_id, H5_INDEX_NAME, H5_ITER_INC, 0, find_dataset, (void *)dset_name); + return H5Literate2(loc_id, H5_INDEX_NAME, H5_ITER_INC, 0, find_dataset, (void *)dset_name); } diff --git a/java/examples/groups/H5Ex_G_Intermediate.java b/java/examples/groups/H5Ex_G_Intermediate.java index f7d5a50..e97e5f8 100644 --- a/java/examples/groups/H5Ex_G_Intermediate.java +++ b/java/examples/groups/H5Ex_G_Intermediate.java @@ -19,8 +19,8 @@ package examples.groups; import hdf.hdf5lib.H5; import hdf.hdf5lib.HDF5Constants; -import hdf.hdf5lib.callbacks.H5O_iterate_cb; import hdf.hdf5lib.callbacks.H5O_iterate_t; +import hdf.hdf5lib.callbacks.H5O_iterate_opdata_t; import hdf.hdf5lib.structs.H5O_info_t; import java.util.ArrayList; @@ -53,9 +53,9 @@ public class H5Ex_G_Intermediate { // Print all the objects in the file_ids to show that intermediate group_ids have been created. System.out.println("Objects in the file_id:"); - // H5O_iterate_t iter_data = null; - H5O_iterate_t iter_data = new H5O_iter_data(); - H5O_iterate_cb iter_cb = new H5O_iter_callback(); + // H5O_iterate_opdata_t iter_data = null; + H5O_iterate_opdata_t iter_data = new H5O_iter_data(); + H5O_iterate_t iter_cb = new H5O_iter_callback(); H5.H5Ovisit(file_id, HDF5Constants.H5_INDEX_NAME, HDF5Constants.H5_ITER_NATIVE, iter_cb, iter_data); } @@ -92,12 +92,12 @@ public class H5Ex_G_Intermediate { } } - private class H5O_iter_data implements H5O_iterate_t { + private class H5O_iter_data implements H5O_iterate_opdata_t { public ArrayList iterdata = new ArrayList(); } - private class H5O_iter_callback implements H5O_iterate_cb { - public int callback(long group, String name, H5O_info_t info, H5O_iterate_t op_data) { + private class H5O_iter_callback implements H5O_iterate_t { + public int callback(long group, String name, H5O_info_t info, H5O_iterate_opdata_t op_data) { idata id = new idata(name, info.type); ((H5O_iter_data) op_data).iterdata.add(id); diff --git a/java/examples/groups/H5Ex_G_Iterate.java b/java/examples/groups/H5Ex_G_Iterate.java index 3c9ca82..5acbf65 100644 --- a/java/examples/groups/H5Ex_G_Iterate.java +++ b/java/examples/groups/H5Ex_G_Iterate.java @@ -19,6 +19,7 @@ package examples.groups; import hdf.hdf5lib.H5; import hdf.hdf5lib.HDF5Constants; +import hdf.hdf5lib.structs.H5O_token_t; import java.util.EnumSet; import java.util.HashMap; @@ -75,8 +76,8 @@ public class H5Ex_G_Iterate { String[] oname = new String[count]; int[] otype = new int[count]; int[] ltype = new int[count]; - long[] orefs = new long[count]; - H5.H5Gget_obj_info_all(file_id, DATASETNAME, oname, otype, ltype, orefs, HDF5Constants.H5_INDEX_NAME); + H5O_token_t[] otokens = new H5O_token_t[count]; + H5.H5Gget_obj_info_all(file_id, DATASETNAME, oname, otype, ltype, otokens, HDF5Constants.H5_INDEX_NAME); // Get type of the object and display its name and type. for (int indx = 0; indx < otype.length; indx++) { diff --git a/java/examples/groups/H5Ex_G_Traverse.java b/java/examples/groups/H5Ex_G_Traverse.java index 2a2cba3..6225a9e 100644 --- a/java/examples/groups/H5Ex_G_Traverse.java +++ b/java/examples/groups/H5Ex_G_Traverse.java @@ -25,22 +25,22 @@ package examples.groups; import hdf.hdf5lib.H5; import hdf.hdf5lib.HDF5Constants; -import hdf.hdf5lib.callbacks.H5L_iterate_cb; import hdf.hdf5lib.callbacks.H5L_iterate_t; +import hdf.hdf5lib.callbacks.H5L_iterate_opdata_t; import hdf.hdf5lib.structs.H5L_info_t; import hdf.hdf5lib.structs.H5O_info_t; import examples.groups.H5Ex_G_Iterate.H5O_type; -class opdata implements H5L_iterate_t { +class opdata implements H5L_iterate_opdata_t { int recurs; opdata prev; - long addr; + H5O_token_t obj_token; } public class H5Ex_G_Traverse { private static String FILE = "h5ex_g_traverse.h5"; - public static H5L_iterate_cb iter_cb = new H5L_iter_callbackT(); + public static H5L_iterate_t iter_cb = new H5L_iter_callbackT(); private static void OpenGroup() { long file_id = -1; @@ -54,7 +54,7 @@ public class H5Ex_G_Traverse { infobuf = H5.H5Oget_info(file_id); od.recurs = 0; od.prev = null; - od.addr = infobuf.addr; + od.obj_token = infobuf.token; } } catch (Exception e) { @@ -64,7 +64,7 @@ public class H5Ex_G_Traverse { // Print the root group and formatting, begin iteration. try { System.out.println("/ {"); - // H5L_iterate_cb iter_cb = new H5L_iter_callbackT(); + // H5L_iterate_t iter_cb = new H5L_iter_callbackT(); H5.H5Literate(file_id, HDF5Constants.H5_INDEX_NAME, HDF5Constants.H5_ITER_NATIVE, 0L, iter_cb, od); System.out.println("}"); } @@ -87,8 +87,8 @@ public class H5Ex_G_Traverse { } } -class H5L_iter_callbackT implements H5L_iterate_cb { - public int callback(long group, String name, H5L_info_t info, H5L_iterate_t op_data) { +class H5L_iter_callbackT implements H5L_iterate_t { + public int callback(long group, String name, H5L_info_t info, H5L_iterate_opdata_t op_data) { H5O_info_t infobuf; int return_val = 0; @@ -105,7 +105,7 @@ class H5L_iter_callbackT implements H5L_iterate_cb { switch (H5O_type.get(infobuf.type)) { case H5O_TYPE_GROUP: System.out.println("Group: " + name + " { "); - // Check group address against linked list of operator + // Check group object token against linked list of operator // data structures. We will always run the check, as the // reference count cannot be relied upon if there are // symbolic links, and H5Oget_info_by_name always follows @@ -114,7 +114,7 @@ class H5L_iter_callbackT implements H5L_iterate_cb { // links, however it could still fail if an object's // reference count was manually manipulated with // H5Odecr_refcount. - if (group_check(od, infobuf.addr)) { + if (group_check(od, infobuf.token)) { for (int i = 0; i < spaces; i++) System.out.print(" "); System.out.println(" Warning: Loop detected!"); @@ -127,8 +127,8 @@ class H5L_iter_callbackT implements H5L_iterate_cb { opdata nextod = new opdata(); nextod.recurs = od.recurs + 1; nextod.prev = od; - nextod.addr = infobuf.addr; - H5L_iterate_cb iter_cb2 = new H5L_iter_callbackT(); + nextod.obj_token = infobuf.token; + H5L_iterate_t iter_cb2 = new H5L_iter_callbackT(); return_val = H5.H5Literate_by_name(group, name, HDF5Constants.H5_INDEX_NAME, HDF5Constants.H5_ITER_NATIVE, 0L, iter_cb2, nextod, HDF5Constants.H5P_DEFAULT); } @@ -153,13 +153,13 @@ class H5L_iter_callbackT implements H5L_iterate_cb { return return_val; } - public boolean group_check(opdata od, long target_addr) { - if (od.addr == target_addr) - return true; // Addresses match + public boolean group_check(opdata od, H5O_token_t target_token) { + if (od.obj_token.equals(target_token)) + return true; // Object tokens match else if (od.recurs == 0) return false; // Root group reached with no matches else - return group_check(od.prev, target_addr); // Recursively examine the next node + return group_check(od.prev, target_token); // Recursively examine the next node } } diff --git a/java/examples/groups/H5Ex_G_Visit.java b/java/examples/groups/H5Ex_G_Visit.java index f91c707..4255316 100644 --- a/java/examples/groups/H5Ex_G_Visit.java +++ b/java/examples/groups/H5Ex_G_Visit.java @@ -23,10 +23,10 @@ package examples.groups; import hdf.hdf5lib.H5; import hdf.hdf5lib.HDF5Constants; -import hdf.hdf5lib.callbacks.H5L_iterate_cb; import hdf.hdf5lib.callbacks.H5L_iterate_t; -import hdf.hdf5lib.callbacks.H5O_iterate_cb; +import hdf.hdf5lib.callbacks.H5L_iterate_opdata_t; import hdf.hdf5lib.callbacks.H5O_iterate_t; +import hdf.hdf5lib.callbacks.H5O_iterate_opdata_t; import hdf.hdf5lib.structs.H5L_info_t; import hdf.hdf5lib.structs.H5O_info_t; @@ -55,13 +55,13 @@ public class H5Ex_G_Visit { // Begin iteration using H5Ovisit System.out.println("Objects in the file:"); - H5O_iterate_t iter_data = new H5O_iter_data(); - H5O_iterate_cb iter_cb = new H5O_iter_callback(); + H5O_iterate_opdata_t iter_data = new H5O_iter_data(); + H5O_iterate_t iter_cb = new H5O_iter_callback(); H5.H5Ovisit(file_id, HDF5Constants.H5_INDEX_NAME, HDF5Constants.H5_ITER_NATIVE, iter_cb, iter_data); System.out.println(); // Repeat the same process using H5Lvisit - H5L_iterate_t iter_data2 = new H5L_iter_data(); - H5L_iterate_cb iter_cb2 = new H5L_iter_callback(); + H5L_iterate_opdata_t iter_data2 = new H5L_iter_data(); + H5L_iterate_t iter_cb2 = new H5L_iter_callback(); System.out.println("Links in the file:"); H5.H5Lvisit(file_id, HDF5Constants.H5_INDEX_NAME, HDF5Constants.H5_ITER_NATIVE, iter_cb2, iter_data2); @@ -91,12 +91,12 @@ public class H5Ex_G_Visit { } } - private class H5L_iter_data implements H5L_iterate_t { + private class H5L_iter_data implements H5L_iterate_opdata_t { public ArrayList iterdata = new ArrayList(); } - private class H5L_iter_callback implements H5L_iterate_cb { - public int callback(long group, String name, H5L_info_t info, H5L_iterate_t op_data) { + private class H5L_iter_callback implements H5L_iterate_t { + public int callback(long group, String name, H5L_info_t info, H5L_iterate_opdata_t op_data) { idata id = new idata(name, info.type); ((H5L_iter_data) op_data).iterdata.add(id); @@ -107,8 +107,8 @@ public class H5Ex_G_Visit { // Get type of the object and display its name and type. The name of the object is passed to this // function by the Library. infobuf = H5.H5Oget_info_by_name(group, name, HDF5Constants.H5P_DEFAULT); - H5O_iterate_cb iter_cbO = new H5O_iter_callback(); - H5O_iterate_t iter_dataO = new H5O_iter_data(); + H5O_iterate_t iter_cbO = new H5O_iter_callback(); + H5O_iterate_opdata_t iter_dataO = new H5O_iter_data(); ret = iter_cbO.callback(group, name, infobuf, iter_dataO); } catch (Exception e) { @@ -119,12 +119,12 @@ public class H5Ex_G_Visit { } } - private class H5O_iter_data implements H5O_iterate_t { + private class H5O_iter_data implements H5O_iterate_opdata_t { public ArrayList iterdata = new ArrayList(); } - private class H5O_iter_callback implements H5O_iterate_cb { - public int callback(long group, String name, H5O_info_t info, H5O_iterate_t op_data) { + private class H5O_iter_callback implements H5O_iterate_t { + public int callback(long group, String name, H5O_info_t info, H5O_iterate_opdata_t op_data) { idata id = new idata(name, info.type); ((H5O_iter_data) op_data).iterdata.add(id); diff --git a/java/src/Makefile.am b/java/src/Makefile.am index fcdeae9..b7ad4bd 100644 --- a/java/src/Makefile.am +++ b/java/src/Makefile.am @@ -51,10 +51,10 @@ hdf5_java_JAVA = \ ${pkgpath}/callbacks/H5D_iterate_t.java \ ${pkgpath}/callbacks/H5E_walk_cb.java \ ${pkgpath}/callbacks/H5E_walk_t.java \ - ${pkgpath}/callbacks/H5L_iterate_cb.java \ ${pkgpath}/callbacks/H5L_iterate_t.java \ - ${pkgpath}/callbacks/H5O_iterate_cb.java \ + ${pkgpath}/callbacks/H5L_iterate_opdata_t.java \ ${pkgpath}/callbacks/H5O_iterate_t.java \ + ${pkgpath}/callbacks/H5O_iterate_opdata_t.java \ ${pkgpath}/callbacks/H5P_cls_close_func_cb.java \ ${pkgpath}/callbacks/H5P_cls_close_func_t.java \ ${pkgpath}/callbacks/H5P_cls_copy_func_cb.java \ @@ -103,6 +103,8 @@ hdf5_java_JAVA = \ ${pkgpath}/structs/H5G_info_t.java \ ${pkgpath}/structs/H5L_info_t.java \ ${pkgpath}/structs/H5O_info_t.java \ + ${pkgpath}/structs/H5O_native_info_t.java \ + ${pkgpath}/structs/H5O_token_t.java \ ${pkgpath}/structs/H5O_hdr_info_t.java \ ${pkgpath}/structs/H5AC_cache_config_t.java \ ${pkgpath}/H5.java \ diff --git a/java/src/hdf/hdf5lib/CMakeLists.txt b/java/src/hdf/hdf5lib/CMakeLists.txt index be8f60a..b0293fb 100644 --- a/java/src/hdf/hdf5lib/CMakeLists.txt +++ b/java/src/hdf/hdf5lib/CMakeLists.txt @@ -18,10 +18,10 @@ set (HDF5_JAVA_HDF_HDF5_CALLBACKS_SOURCES callbacks/H5D_iterate_t.java callbacks/H5E_walk_cb.java callbacks/H5E_walk_t.java - callbacks/H5L_iterate_cb.java callbacks/H5L_iterate_t.java - callbacks/H5O_iterate_cb.java + callbacks/H5L_iterate_opdata_t.java callbacks/H5O_iterate_t.java + callbacks/H5O_iterate_opdata_t.java callbacks/H5P_cls_close_func_cb.java callbacks/H5P_cls_close_func_t.java callbacks/H5P_cls_copy_func_cb.java @@ -79,6 +79,8 @@ set (HDF5_JAVA_HDF_HDF5_STRUCTS_SOURCES structs/H5L_info_t.java structs/H5O_hdr_info_t.java structs/H5O_info_t.java + structs/H5O_native_info_t.java + structs/H5O_token_t.java ) set (HDF5_JAVA_HDF_HDF5_SOURCES diff --git a/java/src/hdf/hdf5lib/H5.java b/java/src/hdf/hdf5lib/H5.java index ba10f5e..5b704dd 100644 --- a/java/src/hdf/hdf5lib/H5.java +++ b/java/src/hdf/hdf5lib/H5.java @@ -24,10 +24,10 @@ import hdf.hdf5lib.callbacks.H5D_iterate_cb; import hdf.hdf5lib.callbacks.H5D_iterate_t; import hdf.hdf5lib.callbacks.H5E_walk_cb; import hdf.hdf5lib.callbacks.H5E_walk_t; -import hdf.hdf5lib.callbacks.H5L_iterate_cb; import hdf.hdf5lib.callbacks.H5L_iterate_t; -import hdf.hdf5lib.callbacks.H5O_iterate_cb; +import hdf.hdf5lib.callbacks.H5L_iterate_opdata_t; import hdf.hdf5lib.callbacks.H5O_iterate_t; +import hdf.hdf5lib.callbacks.H5O_iterate_opdata_t; import hdf.hdf5lib.callbacks.H5P_cls_close_func_cb; import hdf.hdf5lib.callbacks.H5P_cls_close_func_t; import hdf.hdf5lib.callbacks.H5P_cls_copy_func_cb; @@ -55,6 +55,8 @@ import hdf.hdf5lib.structs.H5FD_ros3_fapl_t; import hdf.hdf5lib.structs.H5G_info_t; import hdf.hdf5lib.structs.H5L_info_t; import hdf.hdf5lib.structs.H5O_info_t; +import hdf.hdf5lib.structs.H5O_native_info_t; +import hdf.hdf5lib.structs.H5O_token_t; /** * This class is the Java interface for the HDF5 library. @@ -3577,8 +3579,8 @@ public class H5 implements java.io.Serializable { * OUT: Names of all objects under the group, name. * @param objTypes * OUT: Types of all objects under the group, name. - * @param objRef - * OUT: Reference number of all objects under the group, name. + * @param tokens + * OUT: Object token of all objects under the group, name. * * @return the number of items found * @@ -3588,26 +3590,26 @@ public class H5 implements java.io.Serializable { * - name is null. */ public synchronized static int H5Gget_obj_info_all(long loc_id, String name, String[] objNames, int[] objTypes, - long[] objRef) throws HDF5LibraryException, NullPointerException { + H5O_token_t[] tokens) throws HDF5LibraryException, NullPointerException { if (objNames == null) { throw new NullPointerException("H5Gget_obj_info_all(): name array is null"); } - return H5Gget_obj_info_all(loc_id, name, objNames, objTypes, null, null, objRef, HDF5Constants.H5_INDEX_NAME); + return H5Gget_obj_info_all(loc_id, name, objNames, objTypes, null, null, tokens, HDF5Constants.H5_INDEX_NAME); } public synchronized static int H5Gget_obj_info_all(long loc_id, String name, String[] oname, int[] otype, - int[] ltype, long[] ref, int indx_type) throws HDF5LibraryException, NullPointerException { - return H5Gget_obj_info_full(loc_id, name, oname, otype, ltype, null, ref, indx_type, -1); + int[] ltype, H5O_token_t[] tokens, int indx_type) throws HDF5LibraryException, NullPointerException { + return H5Gget_obj_info_full(loc_id, name, oname, otype, ltype, null, tokens, indx_type, -1); } public synchronized static int H5Gget_obj_info_all(long loc_id, String name, String[] oname, int[] otype, - int[] ltype, long[] fno, long[] ref, int indx_type) throws HDF5LibraryException, NullPointerException { - return H5Gget_obj_info_full(loc_id, name, oname, otype, ltype, fno, ref, oname.length, indx_type, -1); + int[] ltype, long[] fno, H5O_token_t[] tokens, int indx_type) throws HDF5LibraryException, NullPointerException { + return H5Gget_obj_info_full(loc_id, name, oname, otype, ltype, fno, tokens, oname.length, indx_type, -1); } public synchronized static int H5Gget_obj_info_full(long loc_id, String name, String[] oname, int[] otype, - int[] ltype, long[] fno, long[] ref, int indx_type, int indx_order) throws HDF5LibraryException, + int[] ltype, long[] fno, H5O_token_t[] tokens, int indx_type, int indx_order) throws HDF5LibraryException, NullPointerException { if (oname == null) { throw new NullPointerException("H5Gget_obj_info_full(): name array is null"); @@ -3629,7 +3631,7 @@ public class H5 implements java.io.Serializable { ltype = new int[otype.length]; if (fno == null) - fno = new long[ref.length]; + fno = new long[tokens.length]; if (indx_type < 0) indx_type = HDF5Constants.H5_INDEX_NAME; @@ -3638,7 +3640,7 @@ public class H5 implements java.io.Serializable { indx_order = HDF5Constants.H5_ITER_INC; log.trace("H5Gget_obj_info_full: oname_len={}", oname.length); - int status = H5Gget_obj_info_full(loc_id, name, oname, otype, ltype, fno, ref, oname.length, indx_type, + int status = H5Gget_obj_info_full(loc_id, name, oname, otype, ltype, fno, tokens, oname.length, indx_type, indx_order); for (int indx = 0; indx < oname.length; indx++) log.trace("H5Gget_obj_info_full: oname={}", oname[indx]); @@ -3646,7 +3648,7 @@ public class H5 implements java.io.Serializable { } private synchronized static native int H5Gget_obj_info_full(long loc_id, String name, String[] oname, int[] otype, - int[] ltype, long[] fno, long[] ref, int n, int indx_type, int indx_order) throws HDF5LibraryException, + int[] ltype, long[] fno, H5O_token_t[] tokens, int n, int indx_type, int indx_order) throws HDF5LibraryException, NullPointerException; /** @@ -3701,8 +3703,8 @@ public class H5 implements java.io.Serializable { * OUT: Types of all objects under the group, name. * @param lnkTypes * OUT: Types of all links under the group, name. - * @param objRef - * OUT: Reference number of all objects under the group, name. + * @param objToken + * OUT: Object token of all objects under the group, name. * @param objMax * IN: Maximum number of all objects under the group, name. * @@ -3714,7 +3716,7 @@ public class H5 implements java.io.Serializable { * - name is null. */ public synchronized static int H5Gget_obj_info_max(long loc_id, String[] objNames, int[] objTypes, int[] lnkTypes, - long[] objRef, long objMax) throws HDF5LibraryException, NullPointerException { + H5O_token_t[] objToken, long objMax) throws HDF5LibraryException, NullPointerException { if (objNames == null) { throw new NullPointerException("H5Gget_obj_info_max(): name array is null"); } @@ -3739,11 +3741,11 @@ public class H5 implements java.io.Serializable { throw new HDF5LibraryException("H5Gget_obj_info_max(): name and type array sizes are different"); } - return H5Gget_obj_info_max(loc_id, objNames, objTypes, lnkTypes, objRef, objMax, objNames.length); + return H5Gget_obj_info_max(loc_id, objNames, objTypes, lnkTypes, objToken, objMax, objNames.length); } private synchronized static native int H5Gget_obj_info_max(long loc_id, String[] oname, int[] otype, int[] ltype, - long[] ref, long amax, int n) throws HDF5LibraryException, NullPointerException; + H5O_token_t[] tokens, long amax, int n) throws HDF5LibraryException, NullPointerException; /** * H5Gn_members report the number of objects in a Group. The 'objects' include everything that will be visited by @@ -4340,8 +4342,8 @@ public class H5 implements java.io.Serializable { * @exception HDF5LibraryException * - Error from the HDF-5 Library. **/ - public synchronized static native int H5Literate(long grp_id, int idx_type, int order, long idx, H5L_iterate_cb op, - H5L_iterate_t op_data) throws HDF5LibraryException; + public synchronized static native int H5Literate(long grp_id, int idx_type, int order, long idx, H5L_iterate_t op, + H5L_iterate_opdata_t op_data) throws HDF5LibraryException; /** * H5Literate_by_name iterates through links in a group. @@ -4372,7 +4374,7 @@ public class H5 implements java.io.Serializable { * - group_name is null. **/ public synchronized static native int H5Literate_by_name(long grp_id, String group_name, int idx_type, int order, - long idx, H5L_iterate_cb op, H5L_iterate_t op_data, long lapl_id) throws HDF5LibraryException, + long idx, H5L_iterate_t op, H5L_iterate_opdata_t op_data, long lapl_id) throws HDF5LibraryException, NullPointerException; /** @@ -4419,8 +4421,8 @@ public class H5 implements java.io.Serializable { * @exception HDF5LibraryException * - Error from the HDF-5 Library. **/ - public synchronized static native int H5Lvisit(long grp_id, int idx_type, int order, H5L_iterate_cb op, - H5L_iterate_t op_data) throws HDF5LibraryException; + public synchronized static native int H5Lvisit(long grp_id, int idx_type, int order, H5L_iterate_t op, + H5L_iterate_opdata_t op_data) throws HDF5LibraryException; /** * H5Lvisit_by_name recursively visits all links starting from a specified group. @@ -4449,7 +4451,7 @@ public class H5 implements java.io.Serializable { * - group_name is null. **/ public synchronized static native int H5Lvisit_by_name(long loc_id, String group_name, int idx_type, int order, - H5L_iterate_cb op, H5L_iterate_t op_data, long lapl_id) throws HDF5LibraryException, NullPointerException; + H5L_iterate_t op, H5L_iterate_opdata_t op_data, long lapl_id) throws HDF5LibraryException, NullPointerException; /** @@ -4666,6 +4668,52 @@ public class H5 implements java.io.Serializable { NullPointerException; /** + * H5Oget_info_by_name retrieves the metadata for an object, identifying the object by location and relative name. + * + * @param loc_id + * IN: File or group identifier specifying location of group in which object is located + * @param name + * IN: Relative name of group + * @param lapl_id + * IN: Access property list identifier for the link pointing to the object (Not currently used; pass as + * H5P_DEFAULT.) + * + * @return object information + * + * @exception HDF5LibraryException + * - Error from the HDF-5 Library. + * @exception NullPointerException + * - name is null. + **/ + public static H5O_info_t H5Oget_info_by_name(long loc_id, String name, long lapl_id) + throws HDF5LibraryException, NullPointerException { + return H5Oget_info_by_name(loc_id, name, HDF5Constants.H5O_INFO_ALL, lapl_id); + } + + /** + * H5Oget_info_by_name retrieves the metadata for an object, identifying the object by location and relative name. + * + * @param loc_id + * IN: File or group identifier specifying location of group in which object is located + * @param name + * IN: Relative name of group + * @param fields + * IN: Object fields to select + * @param lapl_id + * IN: Access property list identifier for the link pointing to the object (Not currently used; pass as + * H5P_DEFAULT.) + * + * @return object information + * + * @exception HDF5LibraryException + * - Error from the HDF-5 Library. + * @exception NullPointerException + * - name is null. + **/ + public synchronized static native H5O_info_t H5Oget_info_by_name(long loc_id, String name, int fields, long lapl_id) + throws HDF5LibraryException, NullPointerException; + + /** * H5Oget_info_by_idx retrieves the metadata for an object, identifying the object by an index position. * * @param loc_id @@ -4724,7 +4772,47 @@ public class H5 implements java.io.Serializable { int order, long n, int fields, long lapl_id) throws HDF5LibraryException, NullPointerException; /** - * H5Oget_info_by_name retrieves the metadata for an object, identifying the object by location and relative name. + * H5Oget_native_info retrieves the native HDF5-specific metadata for an HDF5 object specified by an identifier. + * Native HDF5-specific metadata includes things like object header information and object storage layout information. + * + * @param loc_id + * IN: Identifier for target object + * + * @return object information + * + * @exception HDF5LibraryException + * - Error from the HDF-5 Library. + * @exception NullPointerException + * - name is null. + **/ + public static H5O_native_info_t H5Oget_native_info(long loc_id) throws HDF5LibraryException, + NullPointerException { + return H5Oget_native_info(loc_id, HDF5Constants.H5O_NATIVE_INFO_ALL); + } + + /** + * H5Oget_native_info retrieves the native HDF5-specific metadata for an HDF5 object specified by an identifier. + * Native HDF5-specific metadata includes things like object header information and object storage layout information. + * + * @param loc_id + * IN: Identifier for target object + * @param fields + * IN: Object fields to select + * + * @return object information + * + * @exception HDF5LibraryException + * - Error from the HDF-5 Library. + * @exception NullPointerException + * - name is null. + **/ + public synchronized static native H5O_native_info_t H5Oget_native_info(long loc_id, int fields) throws HDF5LibraryException, + NullPointerException; + + /** + * H5Oget_native_info_by_name retrieves the native HDF5-specific metadata for an HDF5 object, identifying the object + * by location and relative name. Native HDF5-specific metadata includes things like object header information and + * object storage layout information. * * @param loc_id * IN: File or group identifier specifying location of group in which object is located @@ -4741,13 +4829,15 @@ public class H5 implements java.io.Serializable { * @exception NullPointerException * - name is null. **/ - public static H5O_info_t H5Oget_info_by_name(long loc_id, String name, long lapl_id) + public static H5O_native_info_t H5Oget_native_info_by_name(long loc_id, String name, long lapl_id) throws HDF5LibraryException, NullPointerException { - return H5Oget_info_by_name(loc_id, name, HDF5Constants.H5O_INFO_ALL, lapl_id); + return H5Oget_native_info_by_name(loc_id, name, HDF5Constants.H5O_NATIVE_INFO_ALL, lapl_id); } /** - * H5Oget_info_by_name retrieves the metadata for an object, identifying the object by location and relative name. + * H5Oget_native_info_by_name retrieves the native HDF5-specific metadata for an HDF5 object, identifying the object + * by location and relative name. Native HDF5-specific metadata includes things like object header information and + * object storage layout information. * * @param loc_id * IN: File or group identifier specifying location of group in which object is located @@ -4766,10 +4856,72 @@ public class H5 implements java.io.Serializable { * @exception NullPointerException * - name is null. **/ - public synchronized static native H5O_info_t H5Oget_info_by_name(long loc_id, String name, int fields, long lapl_id) + public synchronized static native H5O_native_info_t H5Oget_native_info_by_name(long loc_id, String name, int fields, long lapl_id) throws HDF5LibraryException, NullPointerException; /** + * H5Oget_native_info_by_idx retrieves the native HDF5-specific metadata for an HDF5 object, identifying the object + * by an index position. Native HDF5-specific metadata includes things like object header information and + * object storage layout information. + * + * @param loc_id + * IN: File or group identifier + * @param group_name + * IN: Name of group, relative to loc_id, in which object is located + * @param idx_type + * IN: Type of index by which objects are ordered + * @param order + * IN: Order of iteration within index + * @param n + * IN: Object to open + * @param lapl_id + * IN: Access property list identifier for the link pointing to the object (Not currently used; pass as + * H5P_DEFAULT.) + * + * @return object information + * + * @exception HDF5LibraryException + * - Error from the HDF-5 Library. + * @exception NullPointerException + * - name is null. + **/ + public static H5O_native_info_t H5Oget_native_info_by_idx(long loc_id, String group_name, int idx_type, + int order, long n, long lapl_id) throws HDF5LibraryException, NullPointerException { + return H5Oget_native_info_by_idx(loc_id, group_name, idx_type, order, n, HDF5Constants.H5O_NATIVE_INFO_ALL, lapl_id); + } + + /** + * H5Oget_native_info_by_idx retrieves the native HDF5-specific metadata for an HDF5 object, identifying the object + * by an index position. Native HDF5-specific metadata includes things like object header information and + * object storage layout information. + * + * @param loc_id + * IN: File or group identifier + * @param group_name + * IN: Name of group, relative to loc_id, in which object is located + * @param idx_type + * IN: Type of index by which objects are ordered + * @param order + * IN: Order of iteration within index + * @param n + * IN: Object to open + * @param fields + * IN: Object fields to select + * @param lapl_id + * IN: Access property list identifier for the link pointing to the object (Not currently used; pass as + * H5P_DEFAULT.) + * + * @return object information + * + * @exception HDF5LibraryException + * - Error from the HDF-5 Library. + * @exception NullPointerException + * - name is null. + **/ + public synchronized static native H5O_native_info_t H5Oget_native_info_by_idx(long loc_id, String group_name, int idx_type, + int order, long n, int fields, long lapl_id) throws HDF5LibraryException, NullPointerException; + + /** * H5Olink creates a new hard link to an object in an HDF5 file. * * @param obj_id @@ -4843,7 +4995,7 @@ public class H5 implements java.io.Serializable { * @exception NullPointerException * - name is null. **/ - public static int H5Ovisit(long obj_id, int idx_type, int order, H5O_iterate_cb op, H5O_iterate_t op_data) + public static int H5Ovisit(long obj_id, int idx_type, int order, H5O_iterate_t op, H5O_iterate_opdata_t op_data) throws HDF5LibraryException, NullPointerException { return H5Ovisit(obj_id, idx_type, order, op, op_data, HDF5Constants.H5O_INFO_ALL); } @@ -4872,8 +5024,8 @@ public class H5 implements java.io.Serializable { * @exception NullPointerException * - name is null. **/ - public synchronized static native int H5Ovisit(long obj_id, int idx_type, int order, H5O_iterate_cb op, - H5O_iterate_t op_data, int fields) throws HDF5LibraryException, NullPointerException; + public synchronized static native int H5Ovisit(long obj_id, int idx_type, int order, H5O_iterate_t op, + H5O_iterate_opdata_t op_data, int fields) throws HDF5LibraryException, NullPointerException; /** * H5Ovisit_by_name recursively visits all objects starting from a specified object. @@ -4902,7 +5054,7 @@ public class H5 implements java.io.Serializable { * - name is null. **/ public static int H5Ovisit_by_name(long loc_id, String obj_name, int idx_type, int order, - H5O_iterate_cb op, H5O_iterate_t op_data, long lapl_id) throws HDF5LibraryException, NullPointerException { + H5O_iterate_t op, H5O_iterate_opdata_t op_data, long lapl_id) throws HDF5LibraryException, NullPointerException { return H5Ovisit_by_name(loc_id, obj_name, idx_type, order, op, op_data, HDF5Constants.H5O_INFO_ALL, lapl_id); } @@ -4935,7 +5087,7 @@ public class H5 implements java.io.Serializable { * - name is null. **/ public synchronized static native int H5Ovisit_by_name(long loc_id, String obj_name, int idx_type, int order, - H5O_iterate_cb op, H5O_iterate_t op_data, int fields, long lapl_id) throws HDF5LibraryException, NullPointerException; + H5O_iterate_t op, H5O_iterate_opdata_t op_data, int fields, long lapl_id) throws HDF5LibraryException, NullPointerException; /** @@ -4977,26 +5129,28 @@ public class H5 implements java.io.Serializable { public synchronized static native void H5Oincr_refcount(long object_id) throws HDF5LibraryException; /** - * H5Oopen_by_addr opens a group, dataset, or named datatype using its address within an HDF5 file. + * H5Oopen_by_token opens a group, dataset, or named datatype using its object token within an HDF5 file. * * @param loc_id IN: File or group identifier - * @param addr IN: Object's address in the file + * @param token IN: Object's token in the file * * @return an object identifier for the opened object * * @exception HDF5LibraryException - Error from the HDF-5 Library. **/ - public static long H5Oopen_by_addr(long loc_id, long addr) throws HDF5LibraryException { - long id = _H5Oopen_by_addr(loc_id, addr); + public static long H5Oopen_by_token(long loc_id, H5O_token_t token) throws HDF5LibraryException { + long id = _H5Oopen_by_token(loc_id, token); + if (id > 0) { - log.trace("OPEN_IDS: H5Oopen_by_addr add {}", id); + log.trace("OPEN_IDS: H5Oopen_by_token add {}", id); OPEN_IDS.add(id); log.trace("OPEN_IDS: {}", OPEN_IDS.size()); } + return id; } - private synchronized static native long _H5Oopen_by_addr(long loc_id, long addr) + private synchronized static native long _H5Oopen_by_token(long loc_id, H5O_token_t token) throws HDF5LibraryException, NullPointerException; /** @@ -5060,6 +5214,12 @@ public class H5 implements java.io.Serializable { public synchronized static native void H5Oenable_mdc_flushes(long object_id); public synchronized static native boolean H5Oare_mdc_flushes_disabled(long object_id); + // /////// unimplemented //////// + // herr_t H5Otoken_cmp(hid_t loc_id, const H5O_token_t *token1, const H5O_token_t *token2, + // int *cmp_value); + // herr_t H5Otoken_to_str(hid_t loc_id, const H5O_token_t *token, char **token_str); + // herr_t H5Otoken_from_str(hid_t loc_id, const char *token_str, H5O_token_t *token); + // //////////////////////////////////////////////////////////// // // // H5P: Property List Interface Functions // @@ -10736,7 +10896,8 @@ public class H5 implements java.io.Serializable { public synchronized static native long H5VLregister_connector_by_name(String connector_name, long vipl_id); public synchronized static native long H5VLregister_connector_by_value(int connector_value, long vipl_id); public synchronized static native boolean H5VLis_connector_registered(String name); - public synchronized static native long H5VLget_connector_id(String name); + public synchronized static native long H5VLget_connector_id(long object_id); + public synchronized static native long H5VLget_connector_id_by_name(String name); public synchronized static native String H5VLget_connector_name(long object_id); public synchronized static native void H5VLclose(long connector_id); public synchronized static native void H5VLunregister_connector(long connector_id); diff --git a/java/src/hdf/hdf5lib/HDF5Constants.java b/java/src/hdf/hdf5lib/HDF5Constants.java index 4aeeb98..beba1d1 100644 --- a/java/src/hdf/hdf5lib/HDF5Constants.java +++ b/java/src/hdf/hdf5lib/HDF5Constants.java @@ -14,6 +14,8 @@ package hdf.hdf5lib; +import hdf.hdf5lib.structs.H5O_token_t; + /** * /** This class contains C constants and enumerated types of HDF5 library. The * values of these constants are obtained from the library by calling J2C(int @@ -344,9 +346,10 @@ public class HDF5Constants { public static final int H5O_INFO_BASIC = H5O_INFO_BASIC(); public static final int H5O_INFO_TIME = H5O_INFO_TIME(); public static final int H5O_INFO_NUM_ATTRS = H5O_INFO_NUM_ATTRS(); - public static final int H5O_INFO_HDR = H5O_INFO_HDR(); - public static final int H5O_INFO_META_SIZE = H5O_INFO_META_SIZE(); public static final int H5O_INFO_ALL = H5O_INFO_ALL(); + public static final int H5O_NATIVE_INFO_HDR = H5O_NATIVE_INFO_HDR(); + public static final int H5O_NATIVE_INFO_META_SIZE = H5O_NATIVE_INFO_META_SIZE(); + public static final int H5O_NATIVE_INFO_ALL = H5O_NATIVE_INFO_ALL(); public static final int H5O_SHMESG_NONE_FLAG = H5O_SHMESG_NONE_FLAG(); public static final int H5O_SHMESG_SDSPACE_FLAG = H5O_SHMESG_SDSPACE_FLAG(); public static final int H5O_SHMESG_DTYPE_FLAG = H5O_SHMESG_DTYPE_FLAG(); @@ -359,6 +362,8 @@ public class HDF5Constants { public static final int H5O_TYPE_DATASET = H5O_TYPE_DATASET(); public static final int H5O_TYPE_NAMED_DATATYPE = H5O_TYPE_NAMED_DATATYPE(); public static final int H5O_TYPE_NTYPES = H5O_TYPE_NTYPES(); + public static final int H5O_MAX_TOKEN_SIZE = H5O_MAX_TOKEN_SIZE(); + public static final H5O_token_t H5O_TOKEN_UNDEF = H5O_TOKEN_UNDEF(); public static final long H5P_ROOT = H5P_ROOT(); public static final long H5P_OBJECT_CREATE = H5P_OBJECT_CREATE(); @@ -1308,11 +1313,13 @@ public class HDF5Constants { private static native final int H5O_INFO_NUM_ATTRS(); - private static native final int H5O_INFO_HDR(); + private static native final int H5O_INFO_ALL(); - private static native final int H5O_INFO_META_SIZE(); + private static native final int H5O_NATIVE_INFO_HDR(); - private static native final int H5O_INFO_ALL(); + private static native final int H5O_NATIVE_INFO_META_SIZE(); + + private static native final int H5O_NATIVE_INFO_ALL(); private static native final int H5O_SHMESG_NONE_FLAG(); @@ -1338,6 +1345,10 @@ public class HDF5Constants { private static native final int H5O_TYPE_NTYPES(); + private static native final int H5O_MAX_TOKEN_SIZE(); + + private static native final H5O_token_t H5O_TOKEN_UNDEF(); + private static native final long H5P_ROOT(); private static native final long H5P_OBJECT_CREATE(); diff --git a/java/src/hdf/hdf5lib/callbacks/H5L_iterate_cb.java b/java/src/hdf/hdf5lib/callbacks/H5L_iterate_cb.java deleted file mode 100644 index ec71911..0000000 --- a/java/src/hdf/hdf5lib/callbacks/H5L_iterate_cb.java +++ /dev/null @@ -1,21 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * 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 COPYING file, which can be found at the root of the source code * - * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. * - * If you do not have access to either file, you may request a copy from * - * help@hdfgroup.org. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -package hdf.hdf5lib.callbacks; - -import hdf.hdf5lib.structs.H5L_info_t; - -//Information class for link callback(for H5Lvisit/H5Lvisit_by_name) -public interface H5L_iterate_cb extends Callbacks { - int callback(long group, String name, H5L_info_t info, H5L_iterate_t op_data); -} diff --git a/java/src/hdf/hdf5lib/callbacks/H5L_iterate_opdata_t.java b/java/src/hdf/hdf5lib/callbacks/H5L_iterate_opdata_t.java new file mode 100644 index 0000000..ad9ad8c --- /dev/null +++ b/java/src/hdf/hdf5lib/callbacks/H5L_iterate_opdata_t.java @@ -0,0 +1,18 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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 COPYING file, which can be found at the root of the source code * + * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. * + * If you do not have access to either file, you may request a copy from * + * help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +package hdf.hdf5lib.callbacks; + +public interface H5L_iterate_opdata_t { + +} diff --git a/java/src/hdf/hdf5lib/callbacks/H5L_iterate_t.java b/java/src/hdf/hdf5lib/callbacks/H5L_iterate_t.java index 28ffb8a..f92fbc4 100644 --- a/java/src/hdf/hdf5lib/callbacks/H5L_iterate_t.java +++ b/java/src/hdf/hdf5lib/callbacks/H5L_iterate_t.java @@ -13,8 +13,9 @@ package hdf.hdf5lib.callbacks; -public interface H5L_iterate_t { -/** public ArrayList iterdata = new ArrayList(); - * Any derived interfaces must define the single public variable as above. - */ +import hdf.hdf5lib.structs.H5L_info_t; + +// Information class for link callback (for H5Lvisit/H5Lvisit_by_name). +public interface H5L_iterate_t extends Callbacks { + int callback(long group, String name, H5L_info_t info, H5L_iterate_opdata_t op_data); } diff --git a/java/src/hdf/hdf5lib/callbacks/H5O_iterate_cb.java b/java/src/hdf/hdf5lib/callbacks/H5O_iterate_cb.java deleted file mode 100644 index 89cf206..0000000 --- a/java/src/hdf/hdf5lib/callbacks/H5O_iterate_cb.java +++ /dev/null @@ -1,21 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * 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 COPYING file, which can be found at the root of the source code * - * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. * - * If you do not have access to either file, you may request a copy from * - * help@hdfgroup.org. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -package hdf.hdf5lib.callbacks; - -import hdf.hdf5lib.structs.H5O_info_t; - -//Information class for link callback(for H5Ovisit/H5Ovisit_by_name) -public interface H5O_iterate_cb extends Callbacks { - int callback(long group, String name, H5O_info_t info, H5O_iterate_t op_data); -} diff --git a/java/src/hdf/hdf5lib/callbacks/H5O_iterate_opdata_t.java b/java/src/hdf/hdf5lib/callbacks/H5O_iterate_opdata_t.java new file mode 100644 index 0000000..e1c47b5 --- /dev/null +++ b/java/src/hdf/hdf5lib/callbacks/H5O_iterate_opdata_t.java @@ -0,0 +1,18 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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 COPYING file, which can be found at the root of the source code * + * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. * + * If you do not have access to either file, you may request a copy from * + * help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +package hdf.hdf5lib.callbacks; + +public interface H5O_iterate_opdata_t { + +} diff --git a/java/src/hdf/hdf5lib/callbacks/H5O_iterate_t.java b/java/src/hdf/hdf5lib/callbacks/H5O_iterate_t.java index 1491b09..9a55106 100644 --- a/java/src/hdf/hdf5lib/callbacks/H5O_iterate_t.java +++ b/java/src/hdf/hdf5lib/callbacks/H5O_iterate_t.java @@ -13,8 +13,9 @@ package hdf.hdf5lib.callbacks; -public interface H5O_iterate_t { -/** public ArrayList iterdata = new ArrayList(); - * Any derived interfaces must define the single public variable as above. - */ +import hdf.hdf5lib.structs.H5O_info_t; + +// Information class for link callback(for H5Ovisit/H5Ovisit_by_name) +public interface H5O_iterate_t extends Callbacks { + int callback(long group, String name, H5O_info_t info, H5O_iterate_opdata_t op_data); } diff --git a/java/src/hdf/hdf5lib/structs/H5L_info_t.java b/java/src/hdf/hdf5lib/structs/H5L_info_t.java index 3bbb189..377e617 100644 --- a/java/src/hdf/hdf5lib/structs/H5L_info_t.java +++ b/java/src/hdf/hdf5lib/structs/H5L_info_t.java @@ -15,22 +15,39 @@ package hdf.hdf5lib.structs; import java.io.Serializable; -//Information struct for link (for H5Lget_info/H5Lget_info_by_idx) -public class H5L_info_t implements Serializable{ +import hdf.hdf5lib.HDF5Constants; + +// Information struct for link (for H5Lget_info/H5Lget_info_by_idx) +public class H5L_info_t implements Serializable { private static final long serialVersionUID = -4754320605310155033L; - public int type; - public boolean corder_valid; - public long corder; - public int cset; - public long address_val_size; + public int type; + public boolean corder_valid; + public long corder; + public int cset; + public H5O_token_t token; + public long val_size; + + // Constructor for using object token portion of C union + H5L_info_t (int type, boolean corder_valid, long corder, + int cset, H5O_token_t token) + { + this.type = type; + this.corder_valid = corder_valid; + this.corder = corder; + this.cset = cset; + this.token = token; + this.val_size = -1; + } + // Constructor for using val_size portion of C union H5L_info_t (int type, boolean corder_valid, long corder, - int cset, long address_val_size) + int cset, long val_size) { this.type = type; this.corder_valid = corder_valid; this.corder = corder; this.cset = cset; - this.address_val_size = address_val_size; + this.token = HDF5Constants.H5O_TOKEN_UNDEF; + this.val_size = val_size; } } diff --git a/java/src/hdf/hdf5lib/structs/H5O_hdr_info_t.java b/java/src/hdf/hdf5lib/structs/H5O_hdr_info_t.java index a39c1ed..8d0cc24 100644 --- a/java/src/hdf/hdf5lib/structs/H5O_hdr_info_t.java +++ b/java/src/hdf/hdf5lib/structs/H5O_hdr_info_t.java @@ -16,7 +16,7 @@ package hdf.hdf5lib.structs; import java.io.Serializable; // Information struct for object header metadata (for H5Oget_info/H5Oget_info_by_name/H5Oget_info_by_idx) -public class H5O_hdr_info_t implements Serializable{ +public class H5O_hdr_info_t implements Serializable { private static final long serialVersionUID = 7883826382952577189L; public int version; /* Version number of header format in file */ public int nmesgs; /* Number of object header messages */ @@ -44,4 +44,38 @@ public class H5O_hdr_info_t implements Serializable{ this.mesg_present = mesg_present; this.mesg_shared = mesg_shared; } + + @Override + public boolean equals(Object o) { + if (this == o) + return true; + + if (!(o instanceof H5O_hdr_info_t)) + return false; + + H5O_hdr_info_t info = (H5O_hdr_info_t) o; + + if (this.version != info.version) + return false; + if (this.nmesgs != info.nmesgs) + return false; + if (this.nchunks != info.nchunks) + return false; + if (this.flags != info.flags) + return false; + if (this.space_total != info.space_total) + return false; + if (this.space_meta != info.space_meta) + return false; + if (this.space_mesg != info.space_mesg) + return false; + if (this.space_free != info.space_free) + return false; + if (this.mesg_present != info.mesg_present) + return false; + if (this.mesg_shared != info.mesg_shared) + return false; + + return true; + } } diff --git a/java/src/hdf/hdf5lib/structs/H5O_info_t.java b/java/src/hdf/hdf5lib/structs/H5O_info_t.java index ac32f6a..6a26a10 100644 --- a/java/src/hdf/hdf5lib/structs/H5O_info_t.java +++ b/java/src/hdf/hdf5lib/structs/H5O_info_t.java @@ -15,38 +15,30 @@ package hdf.hdf5lib.structs; import java.io.Serializable; -//Information struct for object (for H5Oget_info/H5Oget_info_by_name/H5Oget_info_by_idx) -public class H5O_info_t implements Serializable{ +// Information struct for object (for H5Oget_info/H5Oget_info_by_name/H5Oget_info_by_idx) +public class H5O_info_t implements Serializable { private static final long serialVersionUID = 4691681163544054518L; - public long fileno; /* File number that object is located in */ - public long addr; /* Object address in file */ - public int type; /* Basic object type (group, dataset, etc.) */ - public int rc; /* Reference count of object */ - public long atime; /* Access time */ - public long mtime; /* Modification time */ - public long ctime; /* Change time */ - public long btime; /* Birth time */ - public long num_attrs; /* # of attributes attached to object */ - public H5O_hdr_info_t hdr; /* Object header information */ - /* Extra metadata storage for obj & attributes */ - public H5_ih_info_t meta_size_obj; /* v1/v2 B-tree & local/fractal heap for groups, B-tree for chunked datasets */ - public H5_ih_info_t meta_size_attr; /* v2 B-tree & heap for attributes */ + public long fileno; /* File number that object is located in */ + public H5O_token_t token; /* Object token in file */ + public int type; /* Basic object type (group, dataset, etc.) */ + public int rc; /* Reference count of object */ + public long atime; /* Access time */ + public long mtime; /* Modification time */ + public long ctime; /* Change time */ + public long btime; /* Birth time */ + public long num_attrs; /* # of attributes attached to object */ - public H5O_info_t (long fileno, long addr, int type, - int rc, long num_attrs, long atime, long mtime, long ctime, long btime, - H5O_hdr_info_t hdr, H5_ih_info_t meta_size_obj, H5_ih_info_t meta_size_attr) + public H5O_info_t (long fileno, H5O_token_t token, int type, + int rc, long atime, long mtime, long ctime, long btime, long num_attrs) { this.fileno = fileno; - this.addr = addr; + this.token = token; this.type = type; this.rc = rc; - this.num_attrs = num_attrs; this.atime = atime; this.mtime = mtime; this.ctime = ctime; this.btime = btime; - this.hdr = hdr; - this.meta_size_obj = meta_size_obj; - this.meta_size_attr = meta_size_attr; + this.num_attrs = num_attrs; } } diff --git a/java/src/hdf/hdf5lib/structs/H5O_native_info_t.java b/java/src/hdf/hdf5lib/structs/H5O_native_info_t.java new file mode 100644 index 0000000..4e80849 --- /dev/null +++ b/java/src/hdf/hdf5lib/structs/H5O_native_info_t.java @@ -0,0 +1,52 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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 COPYING file, which can be found at the root of the source code * + * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. * + * If you do not have access to either file, you may request a copy from * + * help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +package hdf.hdf5lib.structs; + +import java.io.Serializable; + +// Information struct for native HDF5 object info, such as object header metadata (for H5Oget_info/H5Oget_info_by_name/H5Oget_info_by_idx). +public class H5O_native_info_t implements Serializable { + private static final long serialVersionUID = 7883826382952577189L; + + public H5O_hdr_info_t hdr_info; /* Object header information */ + + /* Extra metadata storage for obj & attributes */ + public H5_ih_info_t obj_info; /* v1/v2 B-tree & local/fractal heap for groups, B-tree for chunked datasets */ + public H5_ih_info_t attr_info; /* v2 B-tree & heap for attributes */ + + H5O_native_info_t (H5O_hdr_info_t oheader_info, H5_ih_info_t obj_info, H5_ih_info_t attr_info) + { + this.hdr_info = oheader_info; + this.obj_info = obj_info; + this.attr_info = attr_info; + } + + @Override + public boolean equals(Object o) { + if (this == o) + return true; + + if (!(o instanceof H5O_native_info_t)) + return false; + + H5O_native_info_t info = (H5O_native_info_t) o; + + if (!this.hdr_info.equals(info.hdr_info) + || !this.obj_info.equals(info.obj_info) + || !this.attr_info.equals(info.attr_info)) + return false; + + return true; + } +} \ No newline at end of file diff --git a/java/src/hdf/hdf5lib/structs/H5O_token_t.java b/java/src/hdf/hdf5lib/structs/H5O_token_t.java new file mode 100644 index 0000000..8ec0b7f --- /dev/null +++ b/java/src/hdf/hdf5lib/structs/H5O_token_t.java @@ -0,0 +1,45 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * 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 COPYING file, which can be found at the root of the source code * + * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. * + * If you do not have access to either file, you may request a copy from * + * help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +package hdf.hdf5lib.structs; + +import java.io.Serializable; +import java.util.Arrays; + +import hdf.hdf5lib.HDF5Constants; + +// Object token, which is a unique and permanent identifier, for an HDF5 object within a container. +public class H5O_token_t implements Serializable { + private static final long serialVersionUID = -4754320605310155032L; + public byte[] data; + + H5O_token_t (byte[] data) { + this.data = data; + } + + public boolean isUndefined() { + return this.equals(HDF5Constants.H5O_TOKEN_UNDEF); + } + + @Override + public boolean equals(Object o) { + if (this == o) + return true; + + if (!(o instanceof H5O_token_t)) + return false; + + H5O_token_t token = (H5O_token_t) o; + + return Arrays.equals(this.data, token.data); + } +} \ No newline at end of file diff --git a/java/src/hdf/hdf5lib/structs/H5_ih_info_t.java b/java/src/hdf/hdf5lib/structs/H5_ih_info_t.java index ea36d85..7159f02 100644 --- a/java/src/hdf/hdf5lib/structs/H5_ih_info_t.java +++ b/java/src/hdf/hdf5lib/structs/H5_ih_info_t.java @@ -26,4 +26,22 @@ public class H5_ih_info_t implements Serializable { this.index_size = index_size; this.heap_size = heap_size; } + + @Override + public boolean equals(Object o) { + if (this == o) + return true; + + if (!(o instanceof H5_ih_info_t)) + return false; + + H5_ih_info_t info = (H5_ih_info_t) o; + + if (this.index_size != info.index_size) + return false; + if (this.heap_size != info.heap_size) + return false; + + return true; + } } diff --git a/java/src/jni/exceptionImp.c b/java/src/jni/exceptionImp.c index 0faa0cc..c08b67b 100644 --- a/java/src/jni/exceptionImp.c +++ b/java/src/jni/exceptionImp.c @@ -409,7 +409,7 @@ h5libraryError if (msg_size > 0) { if (NULL == (msg_str = (char *) HDcalloc((size_t)msg_size + 1, sizeof(char)))) - H5_JNI_FATAL_ERROR(ENVONLY, "h5libraryerror: failed to allocate buffer for error message"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "h5libraryerror: failed to allocate buffer for error message"); if ((msg_size = H5Eget_msg(min_num, &error_msg_type, msg_str, (size_t)msg_size + 1)) < 0) goto done; diff --git a/java/src/jni/h5Constants.c b/java/src/jni/h5Constants.c index 05dc2ea..77a5d18 100644 --- a/java/src/jni/h5Constants.c +++ b/java/src/jni/h5Constants.c @@ -684,11 +684,13 @@ Java_hdf_hdf5lib_HDF5Constants_H5O_1INFO_1TIME(JNIEnv *env, jclass cls) { return JNIEXPORT jint JNICALL Java_hdf_hdf5lib_HDF5Constants_H5O_1INFO_1NUM_1ATTRS(JNIEnv *env, jclass cls) { return H5O_INFO_NUM_ATTRS; } JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_HDF5Constants_H5O_1INFO_1HDR(JNIEnv *env, jclass cls) { return H5O_INFO_HDR; } +Java_hdf_hdf5lib_HDF5Constants_H5O_1INFO_1ALL(JNIEnv *env, jclass cls) { return H5O_INFO_ALL; } JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_HDF5Constants_H5O_1INFO_1META_1SIZE(JNIEnv *env, jclass cls) { return H5O_INFO_META_SIZE; } +Java_hdf_hdf5lib_HDF5Constants_H5O_1NATIVE_1INFO_1HDR(JNIEnv *env, jclass cls) { return H5O_NATIVE_INFO_HDR; } JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_HDF5Constants_H5O_1INFO_1ALL(JNIEnv *env, jclass cls) { return H5O_INFO_ALL; } +Java_hdf_hdf5lib_HDF5Constants_H5O_1NATIVE_1INFO_1META_1SIZE(JNIEnv *env, jclass cls) { return H5O_NATIVE_INFO_META_SIZE; } +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_HDF5Constants_H5O_1NATIVE_1INFO_1ALL(JNIEnv *env, jclass cls) { return H5O_NATIVE_INFO_ALL; } JNIEXPORT jint JNICALL Java_hdf_hdf5lib_HDF5Constants_H5O_1SHMESG_1NONE_1FLAG(JNIEnv *env, jclass cls){return H5O_SHMESG_NONE_FLAG; } JNIEXPORT jint JNICALL @@ -713,6 +715,16 @@ JNIEXPORT jint JNICALL Java_hdf_hdf5lib_HDF5Constants_H5O_1TYPE_1NAMED_1DATATYPE(JNIEnv *env, jclass cls) { return H5O_TYPE_NAMED_DATATYPE; } JNIEXPORT jint JNICALL Java_hdf_hdf5lib_HDF5Constants_H5O_1TYPE_1NTYPES(JNIEnv *env, jclass cls) { return H5O_TYPE_NTYPES; } +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_HDF5Constants_H5O_1MAX_1TOKEN_1SIZE(JNIEnv *env, jclass cls) { return H5O_MAX_TOKEN_SIZE; } +JNIEXPORT jobject JNICALL +Java_hdf_hdf5lib_HDF5Constants_H5O_1TOKEN_1UNDEF(JNIEnv *env, jclass cls) +{ + H5O_token_t undef_token = H5O_TOKEN_UNDEF; + + /* TODO: Can be optimized by keeping a global reference to the undefined token class */ + return create_H5O_token_t(env, &undef_token, FALSE); +} JNIEXPORT jlong JNICALL Java_hdf_hdf5lib_HDF5Constants_H5P_1ROOT(JNIEnv *env, jclass cls){return H5P_ROOT;} diff --git a/java/src/jni/h5aImp.c b/java/src/jni/h5aImp.c index 85872b2..fb933ad 100644 --- a/java/src/jni/h5aImp.c +++ b/java/src/jni/h5aImp.c @@ -841,10 +841,10 @@ Java_hdf_hdf5lib_H5_H5Aread_1string H5_LIBRARY_ERROR(ENVONLY); if (NULL == (cstr = (char *) HDmalloc(str_len + 1))) - H5_JNI_FATAL_ERROR(ENVONLY, "H5Aread_string: memory allocation failed"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Aread_string: memory allocation failed"); if (NULL == (c_buf = (char *) HDmalloc((size_t)n * str_len))) - H5_JNI_FATAL_ERROR(ENVONLY, "H5Aread_string: memory allocation failed"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Aread_string: memory allocation failed"); if ((status = H5Aread((hid_t)attr_id, (hid_t)mem_type_id, c_buf)) < 0) H5_LIBRARY_ERROR(ENVONLY); @@ -855,7 +855,7 @@ Java_hdf_hdf5lib_H5_H5Aread_1string if (NULL == (jstr = ENVPTR->NewStringUTF(ENVONLY, cstr))) { CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); - H5_JNI_FATAL_ERROR(ENVONLY, "H5Aread_string: out of memory - unable to construct string from UTF characters"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Aread_string: out of memory - unable to construct string from UTF characters"); } ENVPTR->SetObjectArrayElement(ENVONLY, j_buf, i, jstr); @@ -905,7 +905,7 @@ Java_hdf_hdf5lib_H5_H5Awrite_1string H5_LIBRARY_ERROR(ENVONLY); if (NULL == (c_buf = (char *) HDmalloc((size_t)n * str_len))) - H5_JNI_FATAL_ERROR(ENVONLY, "H5Awrite_string: memory allocation failed"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Awrite_string: memory allocation failed"); for (i = 0; i < (size_t) n; i++) { if (NULL == (obj = (jstring) ENVPTR->GetObjectArrayElement(ENVONLY, (jobjectArray)j_buf, (jsize) i))) { @@ -1037,7 +1037,7 @@ H5AreadVL_str } if (NULL == (strs = (char **) HDcalloc((size_t)n, sizeof(char *)))) - H5_JNI_FATAL_ERROR(ENVONLY, "H5AreadVL_str: failed to allocate variable length string read buffer"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5AreadVL_str: failed to allocate variable length string read buffer"); if ((status = H5Aread(aid, tid, strs)) < 0) H5_LIBRARY_ERROR(ENVONLY); @@ -1110,7 +1110,7 @@ H5AreadVL_asstr H5_LIBRARY_ERROR(ENVONLY); if (NULL == (readBuf = HDcalloc((size_t)n, typeSize))) - H5_JNI_FATAL_ERROR(ENVONLY, "H5AreadVL_asstr: failed to allocate read buffer"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5AreadVL_asstr: failed to allocate read buffer"); if ((status = H5Aread(aid, tid, readBuf)) < 0) H5_LIBRARY_ERROR(ENVONLY); @@ -1119,7 +1119,7 @@ H5AreadVL_asstr h5str_new(&h5str, 4 * typeSize); if (!h5str.s) - H5_JNI_FATAL_ERROR(ENVONLY, "H5AreadVL_asstr: failed to allocate buffer"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5AreadVL_asstr: failed to allocate buffer"); /* Convert each element to a char string */ for (i = 0; i < (size_t) n; i++) { @@ -1243,7 +1243,7 @@ H5AwriteVL_str } if (NULL == (writeBuf = (char **) HDcalloc((size_t)size + 1, sizeof(char *)))) - H5_JNI_FATAL_ERROR(ENVONLY, "H5AwriteVL_str: failed to allocate variable length string write buffer") + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5AwriteVL_str: failed to allocate variable length string write buffer"); for (i = 0; i < size; ++i) { jsize length; @@ -1264,7 +1264,7 @@ H5AwriteVL_str PIN_JAVA_STRING(ENVONLY, obj, utf8, NULL, "H5AwriteVL_str: string not pinned"); if (NULL == (writeBuf[i] = (char *) HDmalloc((size_t)length + 1))) - H5_JNI_FATAL_ERROR(ENVONLY, "H5AwriteVL_str: failed to allocate string buffer"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5AwriteVL_str: failed to allocate string buffer"); HDstrncpy(writeBuf[i], utf8, (size_t)length); writeBuf[i][length] = '\0'; @@ -1325,7 +1325,7 @@ H5AwriteVL_asstr H5_LIBRARY_ERROR(ENVONLY); if (NULL == (writeBuf = HDcalloc((size_t)n, typeSize))) - H5_JNI_FATAL_ERROR(ENVONLY, "H5AwriteVL_asstr: failed to allocate write buffer"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5AwriteVL_asstr: failed to allocate write buffer"); /* * When repeatedly writing a dataset with a large number of strs (e.g., 1,000,000 strings), @@ -1406,7 +1406,7 @@ Java_hdf_hdf5lib_H5_H5Aread_1reg_1ref } if (NULL == (ref_data = (H5R_ref_t *) HDcalloc(1, (size_t)n * sizeof(H5R_ref_t)))) - H5_JNI_FATAL_ERROR(ENVONLY, "H5Aread_reg_ref: failed to allocate read buffer"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Aread_reg_ref: failed to allocate read buffer"); if ((status = H5Aread((hid_t)attr_id, (hid_t)mem_type_id, ref_data)) < 0) H5_LIBRARY_ERROR(ENVONLY); @@ -1414,7 +1414,7 @@ Java_hdf_hdf5lib_H5_H5Aread_1reg_1ref h5str_new(&h5str, 1024); if (!h5str.s) - H5_JNI_FATAL_ERROR(ENVONLY, "H5Aread_reg_ref: failed to allocate buffer"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Aread_reg_ref: failed to allocate buffer"); for (i = 0; i < n; i++) { h5str.s[0] = '\0'; @@ -1499,7 +1499,7 @@ Java_hdf_hdf5lib_H5_H5Aget_1name H5_LIBRARY_ERROR(ENVONLY); if (NULL == (attrName = (char *) HDmalloc(sizeof(char) * (size_t)buf_size + 1))) - H5_JNI_FATAL_ERROR(ENVONLY, "H5Aget_name: failed to allocate attribute name buffer"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Aget_name: failed to allocate attribute name buffer"); if (H5Aget_name((hid_t)attr_id, (size_t)buf_size + 1, attrName) < 0) H5_LIBRARY_ERROR(ENVONLY); @@ -1856,7 +1856,7 @@ Java_hdf_hdf5lib_H5_H5Aget_1name_1by_1idx H5_LIBRARY_ERROR(ENVONLY); if (NULL == (attrName = (char *) HDmalloc(sizeof(char) * (size_t) status_size + 1))) - H5_JNI_FATAL_ERROR(ENVONLY, "H5Aget_name_by_idx: failed to allocate buffer for attribute name"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Aget_name_by_idx: failed to allocate buffer for attribute name"); if ((H5Aget_name_by_idx((hid_t)loc_id, objName, (H5_index_t)idx_type, (H5_iter_order_t) order, (hsize_t) n, (char *)attrName, (size_t)status_size + 1, (hid_t)lapl_id)) < 0) @@ -2162,7 +2162,7 @@ static herr_t H5A_iterate_cb (hid_t g_id, const char *name, const H5A_info_t *info, void *cb_data) { cb_wrapper *wrapper = (cb_wrapper *)cb_data; - jmethodID constructor, mid; + jmethodID mid; jobject cb_info_t = NULL; jobject visit_callback = wrapper->visit_callback; jstring str; @@ -2191,18 +2191,7 @@ H5A_iterate_cb args[2].i = info->cset; args[3].j = (jlong)info->data_size; - /* Get a reference to your class if you don't have it already */ - if (NULL == (cls = CBENVPTR->FindClass(CBENVONLY, "hdf/hdf5lib/structs/H5A_info_t"))) - CHECK_JNI_EXCEPTION(CBENVONLY, JNI_FALSE); - - /* Get a reference to the constructor; the name is */ - if (NULL == (constructor = CBENVPTR->GetMethodID(CBENVONLY, cls, "", "(ZJIJ)V"))) - CHECK_JNI_EXCEPTION(CBENVONLY, JNI_FALSE); - - if (NULL == (cb_info_t = CBENVPTR->NewObjectA(CBENVONLY, cls, constructor, args))) { - HDprintf("FATAL ERROR: hdf/hdf5lib/structs/H5A_info_t: Creation failed\n"); - CHECK_JNI_EXCEPTION(CBENVONLY, JNI_FALSE); - } + CALL_CONSTRUCTOR(CBENVONLY, "hdf/hdf5lib/structs/H5A_info_t", "(ZJIJ)V", args, cb_info_t); status = CBENVPTR->CallIntMethod(CBENVONLY, visit_callback, mid, g_id, str, cb_info_t, op_data); CHECK_JNI_EXCEPTION(CBENVONLY, JNI_FALSE); diff --git a/java/src/jni/h5dImp.c b/java/src/jni/h5dImp.c index 352c047..bcefe12 100644 --- a/java/src/jni/h5dImp.c +++ b/java/src/jni/h5dImp.c @@ -975,10 +975,10 @@ Java_hdf_hdf5lib_H5_H5Dread_1string H5_LIBRARY_ERROR(ENVONLY); if (NULL == (cstr = (char *) HDmalloc(str_len + 1))) - H5_JNI_FATAL_ERROR(ENVONLY, "H5Dread_string: memory allocation failed"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Dread_string: memory allocation failed"); if (NULL == (c_buf = (char *) HDmalloc((size_t)n * str_len))) - H5_JNI_FATAL_ERROR(ENVONLY, "H5Dread_string: memory allocation failed"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Dread_string: memory allocation failed"); if ((status = H5Dread((hid_t)dataset_id, (hid_t)mem_type_id, (hid_t)mem_space_id, (hid_t)file_space_id, (hid_t)xfer_plist_id, c_buf)) < 0) @@ -990,7 +990,7 @@ Java_hdf_hdf5lib_H5_H5Dread_1string if (NULL == (jstr = ENVPTR->NewStringUTF(ENVONLY, cstr))) { CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); - H5_JNI_FATAL_ERROR(ENVONLY, "H5Dread_string: out of memory - unable to construct string from UTF characters"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Dread_string: out of memory - unable to construct string from UTF characters"); } ENVPTR->SetObjectArrayElement(ENVONLY, j_buf, i, jstr); @@ -1041,7 +1041,7 @@ Java_hdf_hdf5lib_H5_H5Dwrite_1string H5_LIBRARY_ERROR(ENVONLY); if (NULL == (c_buf = (char *) HDmalloc((size_t)n * str_len))) - H5_JNI_FATAL_ERROR(ENVONLY, "H5Dwrite_string: memory allocation failed"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Dwrite_string: memory allocation failed"); for (i = 0; i < (size_t) n; i++) { if (NULL == (obj = (jstring) ENVPTR->GetObjectArrayElement(ENVONLY, (jobjectArray)j_buf, (jsize) i))) { @@ -1177,7 +1177,7 @@ H5DreadVL_str } if (NULL == (strs = (char **) HDcalloc((size_t)n, sizeof(char *)))) - H5_JNI_FATAL_ERROR(ENVONLY, "H5DreadVL_str: failed to allocate variable length string read buffer"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5DreadVL_str: failed to allocate variable length string read buffer"); if ((status = H5Dread(did, tid, mem_sid, file_sid, xfer_plist_id, strs)) < 0) H5_LIBRARY_ERROR(ENVONLY); @@ -1263,7 +1263,7 @@ H5DreadVL_asstr H5_LIBRARY_ERROR(ENVONLY); if (NULL == (readBuf = HDcalloc((size_t)n, typeSize))) - H5_JNI_FATAL_ERROR(ENVONLY, "H5DreadVL_asstr: failed to allocate read buffer"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5DreadVL_asstr: failed to allocate read buffer"); if ((status = H5Dread(did, tid, mem_sid, file_sid, xfer_plist_id, readBuf)) < 0) H5_LIBRARY_ERROR(ENVONLY); @@ -1272,7 +1272,7 @@ H5DreadVL_asstr h5str_new(&h5str, 4 * typeSize); if (!h5str.s) - H5_JNI_FATAL_ERROR(ENVONLY, "H5DreadVL_asstr: failed to allocate buffer"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5DreadVL_asstr: failed to allocate buffer"); if ((tclass = H5Tget_class(tid)) < 0) H5_LIBRARY_ERROR(ENVONLY); @@ -1442,7 +1442,7 @@ H5DwriteVL_str } if (NULL == (writeBuf = (char **) HDcalloc((size_t)size + 1, sizeof(char *)))) - H5_JNI_FATAL_ERROR(ENVONLY, "H5DwriteVL_str: failed to allocate variable length string write buffer"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5DwriteVL_str: failed to allocate variable length string write buffer"); for (i = 0; i < size; ++i) { jsize length; @@ -1463,7 +1463,7 @@ H5DwriteVL_str PIN_JAVA_STRING(ENVONLY, obj, utf8, NULL, "H5DwriteVL_str: string not pinned"); if (NULL == (writeBuf[i] = (char *) HDmalloc((size_t)length + 1))) - H5_JNI_FATAL_ERROR(ENVONLY, "H5DwriteVL_str: failed to allocate string buffer"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5DwriteVL_str: failed to allocate string buffer"); HDstrncpy(writeBuf[i], utf8, (size_t)length + 1); writeBuf[i][length] = '\0'; @@ -1536,7 +1536,7 @@ H5DwriteVL_asstr H5_LIBRARY_ERROR(ENVONLY); if (NULL == (writeBuf = HDcalloc((size_t)n, typeSize))) - H5_JNI_FATAL_ERROR(ENVONLY, "H5AwriteVL_asstr: failed to allocate write buffer"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5AwriteVL_asstr: failed to allocate write buffer"); for (i = 0; i < (size_t) n; ++i) { if (NULL == (obj = (jstring) ENVPTR->GetObjectArrayElement(ENVONLY, (jobjectArray)buf, (jsize) i))) { @@ -1646,7 +1646,7 @@ Java_hdf_hdf5lib_H5_H5Dread_1reg_1ref } if (NULL == (ref_data = (H5R_ref_t *) HDcalloc(1, (size_t)n * sizeof(H5R_ref_t)))) - H5_JNI_FATAL_ERROR(ENVONLY, "H5Dread_reg_ref: failed to allocate read buffer"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Dread_reg_ref: failed to allocate read buffer"); if ((status = H5Dread((hid_t)dataset_id, (hid_t)mem_type_id, (hid_t)mem_space_id, (hid_t)file_space_id, xfer_plist_id, ref_data)) < 0) H5_LIBRARY_ERROR(ENVONLY); @@ -1654,7 +1654,7 @@ Java_hdf_hdf5lib_H5_H5Dread_1reg_1ref h5str_new(&h5str, 1024); if (!h5str.s) - H5_JNI_FATAL_ERROR(ENVONLY, "H5Dread_reg_ref: failed to allocate buffer"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Dread_reg_ref: failed to allocate buffer"); for (i = 0; i < n; i++) { h5str.s[0] = '\0'; @@ -1909,7 +1909,7 @@ Java_hdf_hdf5lib_H5_H5Dset_1extent PIN_LONG_ARRAY(ENVONLY, buf, dimsBuf, &isCopy, "H5Dset_extent: buffer not pinned"); if (NULL == (dims = (hsize_t *) HDmalloc((size_t)rank * sizeof(hsize_t)))) - H5_JNI_FATAL_ERROR(ENVONLY, "H5Dset_extent: failed to allocate dataset dimension buffer"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Dset_extent: failed to allocate dataset dimension buffer"); for (i = 0; i < rank; i++) dims[i] = (hsize_t)dimsBuf[i]; diff --git a/java/src/jni/h5eImp.c b/java/src/jni/h5eImp.c index 937323e..7ea4223 100644 --- a/java/src/jni/h5eImp.c +++ b/java/src/jni/h5eImp.c @@ -309,7 +309,7 @@ Java_hdf_hdf5lib_H5_H5Eget_1class_1name H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Eget_class_name: no class name"); if (NULL == (namePtr = (char *) HDmalloc(sizeof(char) * (size_t)buf_size + 1))) - H5_JNI_FATAL_ERROR(ENVONLY, "H5Eget_class_name: malloc failed"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Eget_class_name: malloc failed"); if ((H5Eget_class_name((hid_t)cls_id, (char *)namePtr, (size_t)buf_size + 1)) < 0) H5_LIBRARY_ERROR(ENVONLY); @@ -464,10 +464,10 @@ Java_hdf_hdf5lib_H5_H5Eget_1msg H5_LIBRARY_ERROR(ENVONLY); if (!buf_size) - H5_JNI_FATAL_ERROR(ENVONLY, "H5Eget_msg: invalid message"); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Eget_msg: invalid message"); if (NULL == (namePtr = (char *) HDmalloc(sizeof(char) * (size_t)buf_size + 1))) - H5_JNI_FATAL_ERROR(ENVONLY, "H5Eget_msg: malloc failed"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Eget_msg: malloc failed"); PIN_INT_ARRAY(ENVONLY, error_msg_type_list, theArray, NULL, "H5Eget_msg: error_msg_type_list not pinned"); @@ -517,7 +517,6 @@ H5E_walk_cb (int nindx, const H5E_error2_t *info, void *cb_data) { cb_wrapper *wrapper = (cb_wrapper *)cb_data; - jmethodID constructor; jmethodID mid; jobject visit_callback = wrapper->visit_callback; jstring str1, str2, str3; @@ -559,16 +558,7 @@ H5E_walk_cb args[6].l = str3; - /* Get a reference to your class if you don't have it already */ - if (NULL == (cls = CBENVPTR->FindClass(CBENVONLY, "hdf/hdf5lib/structs/H5E_error2_t"))) - CHECK_JNI_EXCEPTION(CBENVONLY, JNI_FALSE); - - /* get a reference to the constructor; the name is */ - if (NULL == (constructor = CBENVPTR->GetMethodID(CBENVONLY, cls, "", "(JJJILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)V"))) - CHECK_JNI_EXCEPTION(CBENVONLY, JNI_FALSE); - - if (NULL == (cb_info_t = CBENVPTR->NewObjectA(CBENVONLY, cls, constructor, args))) - CHECK_JNI_EXCEPTION(CBENVONLY, JNI_FALSE); + CALL_CONSTRUCTOR(CBENVONLY, "hdf/hdf5lib/structs/H5E_error2_t", "(JJJILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)V", args, cb_info_t); status = CBENVPTR->CallIntMethod(CBENVONLY, visit_callback, mid, nindx, cb_info_t, op_data); CHECK_JNI_EXCEPTION(CBENVONLY, JNI_FALSE); diff --git a/java/src/jni/h5fImp.c b/java/src/jni/h5fImp.c index 2eb3ad5..3b7b96c 100644 --- a/java/src/jni/h5fImp.c +++ b/java/src/jni/h5fImp.c @@ -131,7 +131,7 @@ Java_hdf_hdf5lib_H5_H5Fget_1name H5_LIBRARY_ERROR(ENVONLY); if (NULL == (namePtr = (char *) HDmalloc(sizeof(char) * (size_t)buf_size + 1))) - H5_JNI_FATAL_ERROR(ENVONLY, "H5Fget_name: malloc failed"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Fget_name: malloc failed"); if ((H5Fget_name((hid_t)file_id, namePtr, (size_t)buf_size + 1)) < 0) H5_LIBRARY_ERROR(ENVONLY); @@ -446,7 +446,7 @@ Java_hdf_hdf5lib_H5_H5Fget_1obj_1ids } if (NULL == (id_list = (hid_t *) HDmalloc((size_t)rank * sizeof(hid_t)))) - H5_JNI_FATAL_ERROR(ENVONLY, "H5Fget_obj_ids: malloc failed"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Fget_obj_ids: malloc failed"); if ((ret_val = H5Fget_obj_ids((hid_t)file_id, (unsigned int)types, (size_t)maxObjs, id_list)) < 0) H5_LIBRARY_ERROR(ENVONLY); diff --git a/java/src/jni/h5iImp.c b/java/src/jni/h5iImp.c index a367802..e8030aee 100644 --- a/java/src/jni/h5iImp.c +++ b/java/src/jni/h5iImp.c @@ -71,7 +71,7 @@ Java_hdf_hdf5lib_H5_H5Iget_1name_1long H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Iget_name_long: buf_size < 0"); if (NULL == (aName = (char *) HDmalloc(sizeof(char) * (size_t)buf_size + 1))) - H5_JNI_FATAL_ERROR(ENVONLY, "H5Iget_name_long: malloc failed"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Iget_name_long: malloc failed"); if ((size = H5Iget_name((hid_t)obj_id, aName, (size_t)buf_size + 1)) < 0) H5_LIBRARY_ERROR(ENVONLY); @@ -111,7 +111,7 @@ Java_hdf_hdf5lib_H5_H5Iget_1name H5_LIBRARY_ERROR(ENVONLY); if (NULL == (aName = (char *) HDmalloc(sizeof(char) * (size_t)buf_size + 1))) - H5_JNI_FATAL_ERROR(ENVONLY, "H5Iget_name: malloc failed"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Iget_name: malloc failed"); if (H5Iget_name((hid_t)obj_id, aName, (size_t)buf_size + 1) < 0) H5_LIBRARY_ERROR(ENVONLY); diff --git a/java/src/jni/h5jni.h b/java/src/jni/h5jni.h index 4a94180..f583630 100644 --- a/java/src/jni/h5jni.h +++ b/java/src/jni/h5jni.h @@ -47,195 +47,6 @@ */ #define UNUSED(o) (void) o -/* Macros for class access */ -/* Calling code must define ret_obj as jobject */ -#define CALL_CONSTRUCTOR(env, classname, classsig, args, ret_obj) \ -{ \ - jmethodID constructor; \ - jclass cls; \ - \ - if (NULL == (cls = ENVPTR->FindClass(env, (classname)))) { \ - CHECK_JNI_EXCEPTION(env, JNI_TRUE); \ - H5_JNI_FATAL_ERROR(env, "JNI error: GetObjectClass"); \ - } \ - if (NULL == (constructor = ENVPTR->GetMethodID(ENVONLY, cls, "", (classsig)))) { \ - CHECK_JNI_EXCEPTION(env, JNI_TRUE); \ - H5_JNI_FATAL_ERROR(env, "JNI error: GetMethodID failed"); \ - } \ - if (NULL == (ret_obj = ENVPTR->NewObjectA(ENVONLY, cls, constructor, (args)))) { \ - CHECK_JNI_EXCEPTION(env, JNI_FALSE); \ - } \ -} - -/* - * Macros for pinning/unpinning objects. - */ -#define PIN_BYTE_ARRAY(env, arrayToPin, outBuf, isCopy, failErrMsg) \ -{ \ - if (NULL == (outBuf = ENVPTR->GetByteArrayElements(env, arrayToPin, isCopy))) { \ - CHECK_JNI_EXCEPTION(env, JNI_TRUE); \ - H5_JNI_FATAL_ERROR(env, failErrMsg); \ - } \ -} - -#define PIN_BYTE_ARRAY_CRITICAL(env, arrayToPin, outBuf, isCopy, failErrMsg) \ -{ \ - if (NULL == (outBuf = (jbyte *) ENVPTR->GetPrimitiveArrayCritical(env, arrayToPin, isCopy))) { \ - CHECK_JNI_EXCEPTION(env, JNI_TRUE); \ - H5_JNI_FATAL_ERROR(env, failErrMsg); \ - } \ -} - -#define UNPIN_BYTE_ARRAY(env, pinnedArray, bufToRelease, freeMode) \ -{ \ - ENVPTR->ReleaseByteArrayElements(env, pinnedArray, (jbyte *) bufToRelease, freeMode); \ -} - -#define PIN_SHORT_ARRAY(env, arrayToPin, outBuf, isCopy, failErrMsg) \ -{ \ - if (NULL == (outBuf = ENVPTR->GetShortArrayElements(env, arrayToPin, isCopy))) { \ - CHECK_JNI_EXCEPTION(env, JNI_TRUE); \ - H5_JNI_FATAL_ERROR(env, failErrMsg); \ - } \ -} - -#define PIN_SHORT_ARRAY_CRITICAL(env, arrayToPin, outBuf, isCopy, failErrMsg) \ -{ \ - if (NULL == (outBuf = (jshort *) ENVPTR->GetPrimitiveArrayCritical(env, arrayToPin, isCopy))) { \ - CHECK_JNI_EXCEPTION(env, JNI_TRUE); \ - H5_JNI_FATAL_ERROR(env, failErrMsg); \ - } \ -} - -#define UNPIN_SHORT_ARRAY(env, pinnedArray, bufToRelease, freeMode) \ -{ \ - ENVPTR->ReleaseShortArrayElements(env, pinnedArray, (jshort *) bufToRelease, freeMode); \ -} - -#define PIN_INT_ARRAY(env, arrayToPin, outBuf, isCopy, failErrMsg) \ -{ \ - if (NULL == (outBuf = ENVPTR->GetIntArrayElements(env, arrayToPin, isCopy))) { \ - CHECK_JNI_EXCEPTION(env, JNI_TRUE); \ - H5_JNI_FATAL_ERROR(env, failErrMsg); \ - } \ -} - -#define PIN_INT_ARRAY_CRITICAL(env, arrayToPin, outBuf, isCopy, failErrMsg) \ -{ \ - if (NULL == (outBuf = (jint *) ENVPTR->GetPrimitiveArrayCritical(env, arrayToPin, isCopy))) { \ - CHECK_JNI_EXCEPTION(env, JNI_TRUE); \ - H5_JNI_FATAL_ERROR(env, failErrMsg); \ - } \ -} - -#define UNPIN_INT_ARRAY(env, pinnedArray, bufToRelease, freeMode) \ -{ \ - ENVPTR->ReleaseIntArrayElements(env, pinnedArray, (jint *) bufToRelease, freeMode); \ -} - -#define PIN_LONG_ARRAY(env, arrayToPin, outBuf, isCopy, failErrMsg) \ -{ \ - if (NULL == (outBuf = ENVPTR->GetLongArrayElements(env, arrayToPin, isCopy))) { \ - CHECK_JNI_EXCEPTION(env, JNI_TRUE); \ - H5_JNI_FATAL_ERROR(env, failErrMsg); \ - } \ -} - -#define PIN_LONG_ARRAY_CRITICAL(env, arrayToPin, outBuf, isCopy, failErrMsg) \ -{ \ - if (NULL == (outBuf = (jlong *) ENVPTR->GetPrimitiveArrayCritical(env, arrayToPin, isCopy))) { \ - CHECK_JNI_EXCEPTION(env, JNI_TRUE); \ - H5_JNI_FATAL_ERROR(env, failErrMsg); \ - } \ -} - -#define UNPIN_LONG_ARRAY(env, pinnedArray, bufToRelease, freeMode) \ -{ \ - ENVPTR->ReleaseLongArrayElements(env, pinnedArray, (jlong *) bufToRelease, freeMode); \ -} - -#define PIN_FLOAT_ARRAY(env, arrayToPin, outBuf, isCopy, failErrMsg) \ -{ \ - if (NULL == (outBuf = ENVPTR->GetFloatArrayElements(env, arrayToPin, isCopy))) { \ - CHECK_JNI_EXCEPTION(env, JNI_TRUE); \ - H5_JNI_FATAL_ERROR(env, failErrMsg); \ - } \ -} - -#define PIN_FLOAT_ARRAY_CRITICAL(env, arrayToPin, outBuf, isCopy, failErrMsg) \ -{ \ - if (NULL == (outBuf = (jfloat *) ENVPTR->GetPrimitiveArrayCritical(env, arrayToPin, isCopy))) { \ - CHECK_JNI_EXCEPTION(env, JNI_TRUE); \ - H5_JNI_FATAL_ERROR(env, failErrMsg); \ - } \ -} - -#define UNPIN_FLOAT_ARRAY(env, pinnedArray, bufToRelease, freeMode) \ -{ \ - ENVPTR->ReleaseFloatArrayElements(env, pinnedArray, (jfloat *) bufToRelease, freeMode); \ -} - -#define PIN_DOUBLE_ARRAY(env, arrayToPin, outBuf, isCopy, failErrMsg) \ -{ \ - if (NULL == (outBuf = ENVPTR->GetDoubleArrayElements(env, arrayToPin, isCopy))) { \ - CHECK_JNI_EXCEPTION(env, JNI_TRUE); \ - H5_JNI_FATAL_ERROR(env, failErrMsg); \ - } \ -} - -#define PIN_DOUBLE_ARRAY_CRITICAL(env, arrayToPin, outBuf, isCopy, failErrMsg) \ -{ \ - if (NULL == (outBuf = (jdouble *) ENVPTR->GetPrimitiveArrayCritical(env, arrayToPin, isCopy))) { \ - CHECK_JNI_EXCEPTION(env, JNI_TRUE); \ - H5_JNI_FATAL_ERROR(env, failErrMsg); \ - } \ -} - -#define UNPIN_DOUBLE_ARRAY(env, pinnedArray, bufToRelease, freeMode) \ -{ \ - ENVPTR->ReleaseDoubleArrayElements(env, pinnedArray, (jdouble *) bufToRelease, freeMode); \ -} - -#define PIN_BOOL_ARRAY(env, arrayToPin, outBuf, isCopy, failErrMsg) \ -{ \ - if (NULL == (outBuf = ENVPTR->GetBooleanArrayElements(env, arrayToPin, isCopy))) { \ - CHECK_JNI_EXCEPTION(env, JNI_TRUE); \ - H5_JNI_FATAL_ERROR(env, failErrMsg); \ - } \ -} - -#define PIN_BOOL_ARRAY_CRITICAL(env, arrayToPin, outBuf, isCopy, failErrMsg) \ -{ \ - if (NULL == (outBuf = (jboolean *) ENVPTR->GetPrimitiveArrayCritical(env, arrayToPin, isCopy))) { \ - CHECK_JNI_EXCEPTION(env, JNI_TRUE); \ - H5_JNI_FATAL_ERROR(env, failErrMsg); \ - } \ -} - -#define UNPIN_BOOL_ARRAY(env, pinnedArray, bufToRelease, freeMode) \ -{ \ - ENVPTR->ReleaseBooleanArrayElements(env, pinnedArray, (jboolean *) bufToRelease, freeMode); \ -} - -#define UNPIN_ARRAY_CRITICAL(env, pinnedArray, bufToRelease, freeMode) \ -{ \ - ENVPTR->ReleasePrimitiveArrayCritical(env, pinnedArray, bufToRelease, freeMode); \ -} - -/* Macros for string access */ -#define PIN_JAVA_STRING(env, stringToPin, outString, isCopy, failErrMsg) \ -{ \ - if (NULL == (outString = ENVPTR->GetStringUTFChars(env, stringToPin, isCopy))) { \ - CHECK_JNI_EXCEPTION(env, JNI_TRUE); \ - H5_JNI_FATAL_ERROR(env, failErrMsg); \ - } \ -} - -#define UNPIN_JAVA_STRING(env, pinnedString, stringToRelease) \ -{ \ - ENVPTR->ReleaseStringUTFChars(env, pinnedString, stringToRelease); \ -} - /* * Macro to check for a JNI exception after a JNI method is called. * If an exception occurred, the value of 'clearException' will determine @@ -246,15 +57,205 @@ * cleanup+return section of the native method, since at that point * cleaning up and returning is the only safe thing that can be done. */ -#define CHECK_JNI_EXCEPTION(env, clearException) \ -{ \ - if (JNI_TRUE == (*env)->ExceptionCheck(env)) { \ - if (JNI_TRUE == clearException) \ - (*env)->ExceptionClear(env); \ - else \ - goto done; \ - } \ -} +#define CHECK_JNI_EXCEPTION(envptr, clearException) \ +do { \ + if (JNI_TRUE == (*envptr)->ExceptionCheck(envptr)) { \ + if (JNI_TRUE == clearException) \ + (*envptr)->ExceptionClear(envptr); \ + else \ + goto done; \ + } \ +} while(0) + +/* Macros for class access */ +/* Calling code must define ret_obj as jobject */ +#define CALL_CONSTRUCTOR(envptr, classname, classsig, args, ret_obj) \ +do { \ + jmethodID constructor; \ + jclass cls; \ + \ + if (NULL == (cls = (*envptr)->FindClass(envptr, (classname)))) { \ + CHECK_JNI_EXCEPTION(envptr, JNI_TRUE); \ + H5_JNI_FATAL_ERROR(envptr, "JNI error: GetObjectClass"); \ + } \ + if (NULL == (constructor = (*envptr)->GetMethodID(envptr, cls, "", (classsig)))) { \ + CHECK_JNI_EXCEPTION(envptr, JNI_TRUE); \ + H5_JNI_FATAL_ERROR(envptr, "JNI error: GetMethodID failed"); \ + } \ + if (NULL == (ret_obj = (*envptr)->NewObjectA(envptr, cls, constructor, (args)))) { \ + HDprintf("FATAL ERROR: %s: Creation failed\n", classname); \ + CHECK_JNI_EXCEPTION(envptr, JNI_FALSE); \ + } \ +} while(0) + +/* + * Macros for pinning/unpinning objects. + */ +#define PIN_BYTE_ARRAY(envptr, arrayToPin, outBuf, isCopy, failErrMsg) \ +do { \ + if (NULL == (outBuf = (*envptr)->GetByteArrayElements(envptr, arrayToPin, isCopy))) { \ + CHECK_JNI_EXCEPTION(envptr, JNI_TRUE); \ + H5_JNI_FATAL_ERROR(envptr, failErrMsg); \ + } \ +} while(0) + +#define PIN_BYTE_ARRAY_CRITICAL(envptr, arrayToPin, outBuf, isCopy, failErrMsg) \ +do { \ + if (NULL == (outBuf = (jbyte *) (*envptr)->GetPrimitiveArrayCritical(envptr, arrayToPin, isCopy))) { \ + CHECK_JNI_EXCEPTION(envptr, JNI_TRUE); \ + H5_JNI_FATAL_ERROR(envptr, failErrMsg); \ + } \ +} while(0) + +#define UNPIN_BYTE_ARRAY(envptr, pinnedArray, bufToRelease, freeMode) \ +do { \ + (*envptr)->ReleaseByteArrayElements(envptr, pinnedArray, (jbyte *) bufToRelease, freeMode); \ +} while(0) + +#define PIN_SHORT_ARRAY(envptr, arrayToPin, outBuf, isCopy, failErrMsg) \ +do { \ + if (NULL == (outBuf = (*envptr)->GetShortArrayElements(envptr, arrayToPin, isCopy))) { \ + CHECK_JNI_EXCEPTION(envptr, JNI_TRUE); \ + H5_JNI_FATAL_ERROR(envptr, failErrMsg); \ + } \ +} while(0) + +#define PIN_SHORT_ARRAY_CRITICAL(envptr, arrayToPin, outBuf, isCopy, failErrMsg) \ +do { \ + if (NULL == (outBuf = (jshort *) (*envptr)->GetPrimitiveArrayCritical(envptr, arrayToPin, isCopy))) { \ + CHECK_JNI_EXCEPTION(envptr, JNI_TRUE); \ + H5_JNI_FATAL_ERROR(envptr, failErrMsg); \ + } \ +} while(0) + +#define UNPIN_SHORT_ARRAY(envptr, pinnedArray, bufToRelease, freeMode) \ +do { \ + (*envptr)->ReleaseShortArrayElements(envptr, pinnedArray, (jshort *) bufToRelease, freeMode); \ +} while(0) + +#define PIN_INT_ARRAY(envptr, arrayToPin, outBuf, isCopy, failErrMsg) \ +do { \ + if (NULL == (outBuf = (*envptr)->GetIntArrayElements(envptr, arrayToPin, isCopy))) { \ + CHECK_JNI_EXCEPTION(envptr, JNI_TRUE); \ + H5_JNI_FATAL_ERROR(envptr, failErrMsg); \ + } \ +} while(0) + +#define PIN_INT_ARRAY_CRITICAL(envptr, arrayToPin, outBuf, isCopy, failErrMsg) \ +do { \ + if (NULL == (outBuf = (jint *) (*envptr)->GetPrimitiveArrayCritical(envptr, arrayToPin, isCopy))) { \ + CHECK_JNI_EXCEPTION(envptr, JNI_TRUE); \ + H5_JNI_FATAL_ERROR(envptr, failErrMsg); \ + } \ +} while(0) + +#define UNPIN_INT_ARRAY(envptr, pinnedArray, bufToRelease, freeMode) \ +do { \ + (*envptr)->ReleaseIntArrayElements(envptr, pinnedArray, (jint *) bufToRelease, freeMode); \ +} while(0) + +#define PIN_LONG_ARRAY(envptr, arrayToPin, outBuf, isCopy, failErrMsg) \ +do { \ + if (NULL == (outBuf = (*envptr)->GetLongArrayElements(envptr, arrayToPin, isCopy))) { \ + CHECK_JNI_EXCEPTION(envptr, JNI_TRUE); \ + H5_JNI_FATAL_ERROR(envptr, failErrMsg); \ + } \ +} while(0) + +#define PIN_LONG_ARRAY_CRITICAL(envptr, arrayToPin, outBuf, isCopy, failErrMsg) \ +do { \ + if (NULL == (outBuf = (jlong *) (*envptr)->GetPrimitiveArrayCritical(envptr, arrayToPin, isCopy))) { \ + CHECK_JNI_EXCEPTION(envptr, JNI_TRUE); \ + H5_JNI_FATAL_ERROR(envptr, failErrMsg); \ + } \ +} while(0) + +#define UNPIN_LONG_ARRAY(envptr, pinnedArray, bufToRelease, freeMode) \ +do { \ + (*envptr)->ReleaseLongArrayElements(envptr, pinnedArray, (jlong *) bufToRelease, freeMode); \ +} while(0) + +#define PIN_FLOAT_ARRAY(envptr, arrayToPin, outBuf, isCopy, failErrMsg) \ +do { \ + if (NULL == (outBuf = (*envptr)->GetFloatArrayElements(envptr, arrayToPin, isCopy))) { \ + CHECK_JNI_EXCEPTION(envptr, JNI_TRUE); \ + H5_JNI_FATAL_ERROR(envptr, failErrMsg); \ + } \ +} while(0) + +#define PIN_FLOAT_ARRAY_CRITICAL(envptr, arrayToPin, outBuf, isCopy, failErrMsg) \ +do { \ + if (NULL == (outBuf = (jfloat *) (*envptr)->GetPrimitiveArrayCritical(envptr, arrayToPin, isCopy))) { \ + CHECK_JNI_EXCEPTION(envptr, JNI_TRUE); \ + H5_JNI_FATAL_ERROR(envptr, failErrMsg); \ + } \ +} while(0) + +#define UNPIN_FLOAT_ARRAY(envptr, pinnedArray, bufToRelease, freeMode) \ +do { \ + (*envptr)->ReleaseFloatArrayElements(envptr, pinnedArray, (jfloat *) bufToRelease, freeMode); \ +} while(0) + +#define PIN_DOUBLE_ARRAY(envptr, arrayToPin, outBuf, isCopy, failErrMsg) \ +do { \ + if (NULL == (outBuf = (*envptr)->GetDoubleArrayElements(envptr, arrayToPin, isCopy))) { \ + CHECK_JNI_EXCEPTION(envptr, JNI_TRUE); \ + H5_JNI_FATAL_ERROR(envptr, failErrMsg); \ + } \ +} while(0) + +#define PIN_DOUBLE_ARRAY_CRITICAL(envptr, arrayToPin, outBuf, isCopy, failErrMsg) \ +do { \ + if (NULL == (outBuf = (jdouble *) (*envptr)->GetPrimitiveArrayCritical(envptr, arrayToPin, isCopy))) { \ + CHECK_JNI_EXCEPTION(envptr, JNI_TRUE); \ + H5_JNI_FATAL_ERROR(envptr, failErrMsg); \ + } \ +} while(0) + +#define UNPIN_DOUBLE_ARRAY(envptr, pinnedArray, bufToRelease, freeMode) \ +do { \ + (*envptr)->ReleaseDoubleArrayElements(envptr, pinnedArray, (jdouble *) bufToRelease, freeMode); \ +} while(0) + +#define PIN_BOOL_ARRAY(envptr, arrayToPin, outBuf, isCopy, failErrMsg) \ +do { \ + if (NULL == (outBuf = (*envptr)->GetBooleanArrayElements(envptr, arrayToPin, isCopy))) { \ + CHECK_JNI_EXCEPTION(envptr, JNI_TRUE); \ + H5_JNI_FATAL_ERROR(envptr, failErrMsg); \ + } \ +} while(0) + +#define PIN_BOOL_ARRAY_CRITICAL(envptr, arrayToPin, outBuf, isCopy, failErrMsg) \ +do { \ + if (NULL == (outBuf = (jboolean *) (*envptr)->GetPrimitiveArrayCritical(envptr, arrayToPin, isCopy))) { \ + CHECK_JNI_EXCEPTION(envptr, JNI_TRUE); \ + H5_JNI_FATAL_ERROR(envptr, failErrMsg); \ + } \ +} while(0) + +#define UNPIN_BOOL_ARRAY(envptr, pinnedArray, bufToRelease, freeMode) \ +do { \ + (*envptr)->ReleaseBooleanArrayElements(envptr, pinnedArray, (jboolean *) bufToRelease, freeMode); \ +} while(0) + +#define UNPIN_ARRAY_CRITICAL(envptr, pinnedArray, bufToRelease, freeMode) \ +do { \ + (*envptr)->ReleasePrimitiveArrayCritical(envptr, pinnedArray, bufToRelease, freeMode); \ +} while(0) + +/* Macros for string access */ +#define PIN_JAVA_STRING(envptr, stringToPin, outString, isCopy, failErrMsg) \ +do { \ + if (NULL == (outString = (*envptr)->GetStringUTFChars(envptr, stringToPin, isCopy))) { \ + CHECK_JNI_EXCEPTION(envptr, JNI_TRUE); \ + H5_JNI_FATAL_ERROR(envptr, failErrMsg); \ + } \ +} while(0) + +#define UNPIN_JAVA_STRING(envptr, pinnedString, stringToRelease) \ +do { \ + (*envptr)->ReleaseStringUTFChars(envptr, pinnedString, stringToRelease); \ +} while(0) #ifdef __cplusplus extern "C" { @@ -279,46 +280,46 @@ extern jboolean h5unimplemented( JNIEnv *env, const char *functName); * then do its own error handling, but we instead opt to immediately return. */ #define H5_JNI_FATAL_ERROR(env, message) \ -{ \ +do { \ h5JNIFatalError(env, message); \ goto done; \ -} +} while(0) #define H5_NULL_ARGUMENT_ERROR(env, message) \ -{ \ +do { \ h5nullArgument(env, message); \ goto done; \ -} +} while(0) #define H5_BAD_ARGUMENT_ERROR(env, message) \ -{ \ +do { \ h5badArgument(env, message); \ goto done; \ -} +} while(0) #define H5_OUT_OF_MEMORY_ERROR(env, message) \ -{ \ +do { \ h5outOfMemory(env, message); \ goto done; \ -} +} while(0) #define H5_LIBRARY_ERROR(env) \ -{ \ +do { \ h5libraryError(env); \ goto done; \ -} +} while(0) #define H5_RAISE_EXCEPTION(env, message, exception) \ -{ \ +do { \ h5raiseException(env, message, exception); \ goto done; \ -} +} while(0) #define H5_UNIMPLEMENTED(env, message) \ -{ \ +do { \ h5unimplemented(env, message); \ goto done; \ -} +} while(0) /* implemented at H5.c */ extern jint get_enum_value(JNIEnv *env, jobject enum_obj); @@ -328,6 +329,9 @@ extern jobject get_enum_object(JNIEnv *env, const char* enum_class_name, /* implemented at H5G.c */ extern jobject create_H5G_info_t(JNIEnv *env, H5G_info_t group_info); +/* implemented at h5oimp.c */ +extern jobject create_H5O_token_t(JNIEnv *env, const H5O_token_t *token, hbool_t is_critical_pinning); + #ifdef __cplusplus } /* end extern "C" */ #endif /* __cplusplus */ diff --git a/java/src/jni/h5lImp.c b/java/src/jni/h5lImp.c index 7eee3d4..e60e1ab 100644 --- a/java/src/jni/h5lImp.c +++ b/java/src/jni/h5lImp.c @@ -41,7 +41,7 @@ typedef struct _cb_wrapper { /* Local Prototypes */ /********************/ -static herr_t H5L_iterate_cb(hid_t g_id, const char *name, const H5L_info_t *info, void *cb_data); +static herr_t H5L_iterate_cb(hid_t g_id, const char *name, const H5L_info2_t *info, void *cb_data); /* * Class: hdf_hdf5lib_H5 @@ -281,11 +281,11 @@ JNIEXPORT jobject JNICALL Java_hdf_hdf5lib_H5_H5Lget_1info (JNIEnv *env, jclass clss, jlong loc_id, jstring name, jlong access_id) { - H5L_info_t infobuf; - const char *linkName = NULL; - jvalue args[5]; - herr_t status = FAIL; - jobject ret_obj = NULL; + H5L_info2_t infobuf; + const char *linkName = NULL; + jvalue args[5]; + herr_t status = FAIL; + jobject ret_obj = NULL; UNUSED(clss); @@ -294,16 +294,38 @@ Java_hdf_hdf5lib_H5_H5Lget_1info PIN_JAVA_STRING(ENVONLY, name, linkName, NULL, "H5Lget_info: link name not pinned"); - if ((status = H5Lget_info((hid_t)loc_id, linkName, &infobuf, (hid_t)access_id)) < 0) + if ((status = H5Lget_info2((hid_t)loc_id, linkName, &infobuf, (hid_t)access_id)) < 0) H5_LIBRARY_ERROR(ENVONLY); - args[0].i = infobuf.type; - args[1].z = infobuf.corder_valid; - args[2].j = infobuf.corder; - args[3].i = infobuf.cset; - args[4].j = (infobuf.type == H5L_TYPE_HARD) ? (jlong) infobuf.u.address : (jlong) infobuf.u.val_size; + /* + * Set the last argument based upon whether this is a hard link (which returns object tokens) + * or a soft/user-defined link (which returns the link's value size). Then, call the appropriate + * constructor to instantiate an H5L_info_t object. + */ + if (infobuf.type == H5L_TYPE_HARD) { + jobject token; + + /* Create an H5O_token_t object */ + if (NULL == (token = create_H5O_token_t(ENVONLY, &infobuf.u.token, FALSE))) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + args[0].i = infobuf.type; + args[1].z = infobuf.corder_valid; + args[2].j = infobuf.corder; + args[3].i = infobuf.cset; + args[4].l = token; - CALL_CONSTRUCTOR(ENVONLY, "hdf/hdf5lib/structs/H5L_info_t", "(IZJIJ)V", args, ret_obj); + CALL_CONSTRUCTOR(ENVONLY, "hdf/hdf5lib/structs/H5L_info_t", "(IZJILhdf/hdf5lib/structs/H5O_token_t;)V", args, ret_obj); + } + else { + args[0].i = infobuf.type; + args[1].z = infobuf.corder_valid; + args[2].j = infobuf.corder; + args[3].i = infobuf.cset; + args[4].j = (jlong)infobuf.u.val_size; + + CALL_CONSTRUCTOR(ENVONLY, "hdf/hdf5lib/structs/H5L_info_t", "(IZJIJ)V", args, ret_obj); + } done: if (linkName) @@ -322,11 +344,11 @@ Java_hdf_hdf5lib_H5_H5Lget_1info_1by_1idx (JNIEnv *env, jclass clss, jlong loc_id, jstring name, jint index_field, jint order, jlong link_n, jlong access_id) { - H5L_info_t infobuf; - const char *groupName = NULL; - jvalue args[5]; - herr_t status = FAIL; - jobject ret_obj = NULL; + H5L_info2_t infobuf; + const char *groupName = NULL; + jvalue args[5]; + herr_t status = FAIL; + jobject ret_obj = NULL; UNUSED(clss); @@ -335,16 +357,38 @@ Java_hdf_hdf5lib_H5_H5Lget_1info_1by_1idx PIN_JAVA_STRING(ENVONLY, name, groupName, NULL, "H5Lget_info_by_idx: group name not pinned"); - if ((status = H5Lget_info_by_idx((hid_t)loc_id, groupName, (H5_index_t)index_field, (H5_iter_order_t)order, (hsize_t)link_n, &infobuf, (hid_t)access_id)) < 0) + if ((status = H5Lget_info_by_idx2((hid_t)loc_id, groupName, (H5_index_t)index_field, (H5_iter_order_t)order, (hsize_t)link_n, &infobuf, (hid_t)access_id)) < 0) H5_LIBRARY_ERROR(ENVONLY); - args[0].i = infobuf.type; - args[1].z = infobuf.corder_valid; - args[2].j = infobuf.corder; - args[3].i = infobuf.cset; - args[4].j = (infobuf.type == H5L_TYPE_HARD) ? (jlong) infobuf.u.address : (jlong) infobuf.u.val_size; + /* + * Set the last argument based upon whether this is a hard link (which returns object tokens) + * or a soft/user-defined link (which returns the link's value size). Then, call the appropriate + * constructor to instantiate an H5L_info_t object. + */ + if (infobuf.type == H5L_TYPE_HARD) { + jobject token; - CALL_CONSTRUCTOR(ENVONLY, "hdf/hdf5lib/structs/H5L_info_t", "(IZJIJ)V", args, ret_obj); + /* Create an H5O_token_t object */ + if (NULL == (token = create_H5O_token_t(ENVONLY, &infobuf.u.token, FALSE))) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + args[0].i = infobuf.type; + args[1].z = infobuf.corder_valid; + args[2].j = infobuf.corder; + args[3].i = infobuf.cset; + args[4].l = token; + + CALL_CONSTRUCTOR(ENVONLY, "hdf/hdf5lib/structs/H5L_info_t", "(IZJILhdf/hdf5lib/structs/H5O_token_t;)V", args, ret_obj); + } + else { + args[0].i = infobuf.type; + args[1].z = infobuf.corder_valid; + args[2].j = infobuf.corder; + args[3].i = infobuf.cset; + args[4].j = (jlong)infobuf.u.val_size; + + CALL_CONSTRUCTOR(ENVONLY, "hdf/hdf5lib/structs/H5L_info_t", "(IZJIJ)V", args, ret_obj); + } done: if (groupName) @@ -381,7 +425,7 @@ Java_hdf_hdf5lib_H5_H5Lget_1name_1by_1idx /* add extra space for the null terminator */ if (NULL == (linkName = (char *) HDmalloc(sizeof(char) * (size_t)status_size + 1))) - H5_JNI_FATAL_ERROR(ENVONLY, "H5Lget_name_by_idx: failed to allocate buffer for link name"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Lget_name_by_idx: failed to allocate buffer for link name"); if ((H5Lget_name_by_idx((hid_t)loc_id, groupName, (H5_index_t)index_field, (H5_iter_order_t)order, (hsize_t)link_n, (char *)linkName, (size_t)status_size + 1, (hid_t)access_id)) < 0) H5_LIBRARY_ERROR(ENVONLY); @@ -408,13 +452,13 @@ JNIEXPORT jint JNICALL Java_hdf_hdf5lib_H5_H5Lget_1value (JNIEnv *env, jclass clss, jlong loc_id, jstring name, jobjectArray link_value, jlong access_id) { - H5L_info_t infobuf; - const char *file_name = NULL; - const char *obj_name = NULL; - const char *linkName = NULL; - jstring str; - herr_t status; - char *linkValue = NULL; + H5L_info2_t infobuf; + const char *file_name = NULL; + const char *obj_name = NULL; + const char *linkName = NULL; + jstring str; + herr_t status; + char *linkValue = NULL; UNUSED(clss); @@ -426,14 +470,14 @@ Java_hdf_hdf5lib_H5_H5Lget_1value PIN_JAVA_STRING(ENVONLY, name, linkName, NULL, "H5Lget_value: link name not pinned"); /* Get the length of the link value */ - if ((status = H5Lget_info((hid_t)loc_id, linkName, &infobuf, H5P_DEFAULT)) < 0) + if ((status = H5Lget_info2((hid_t)loc_id, linkName, &infobuf, H5P_DEFAULT)) < 0) H5_LIBRARY_ERROR(ENVONLY); if (H5L_TYPE_HARD == infobuf.type) - H5_JNI_FATAL_ERROR(ENVONLY, "H5Lget_val: hard links are unsupported"); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Lget_val: hard links are unsupported"); if (NULL == (linkValue = (char *) HDmalloc(sizeof(char) * infobuf.u.val_size + 1))) - H5_JNI_FATAL_ERROR(ENVONLY, "H5Lget_val: failed to allocate buffer for link value"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Lget_val: failed to allocate buffer for link value"); if ((status = H5Lget_val((hid_t)loc_id, linkName, (void *)linkValue, infobuf.u.val_size + 1, (hid_t)access_id)) < 0) H5_LIBRARY_ERROR(ENVONLY); @@ -475,7 +519,7 @@ Java_hdf_hdf5lib_H5_H5Lget_1value case H5L_TYPE_MAX: case H5L_TYPE_HARD: default: - H5_JNI_FATAL_ERROR(ENVONLY, "H5Lget_val: invalid link type"); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Lget_val: invalid link type"); break; } @@ -498,13 +542,13 @@ Java_hdf_hdf5lib_H5_H5Lget_1value_1by_1idx (JNIEnv *env, jclass clss, jlong loc_id, jstring name, jint index_field, jint order, jlong link_n, jobjectArray link_value, jlong access_id) { - H5L_info_t infobuf; - const char *file_name = NULL; - const char *obj_name = NULL; - const char *grpName = NULL; - jstring str; - herr_t status; - void *linkValue = NULL; + H5L_info2_t infobuf; + const char *file_name = NULL; + const char *obj_name = NULL; + const char *grpName = NULL; + jstring str; + herr_t status; + void *linkValue = NULL; UNUSED(clss); @@ -516,17 +560,17 @@ Java_hdf_hdf5lib_H5_H5Lget_1value_1by_1idx PIN_JAVA_STRING(ENVONLY, name, grpName, NULL, "H5Lget_val_by_idx: group name not pinned"); /* Get the length of the link value */ - if ((status = H5Lget_info_by_idx((hid_t)loc_id, grpName, (H5_index_t)index_field, (H5_iter_order_t)order, (hsize_t)link_n, &infobuf, (hid_t)access_id)) < 0) + if ((status = H5Lget_info_by_idx2((hid_t)loc_id, grpName, (H5_index_t)index_field, (H5_iter_order_t)order, (hsize_t)link_n, &infobuf, (hid_t)access_id)) < 0) H5_LIBRARY_ERROR(ENVONLY); if (H5L_TYPE_HARD == infobuf.type) - H5_JNI_FATAL_ERROR(ENVONLY, "H5Lget_val_by_idx: hard links are unsupported") + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Lget_val_by_idx: hard links are unsupported"); if (!infobuf.u.val_size) H5_LIBRARY_ERROR(ENVONLY); if (NULL == (linkValue = (void *) HDmalloc(infobuf.u.val_size + 1))) - H5_JNI_FATAL_ERROR(ENVONLY, "H5Lget_val_by_idx: failed to allocate buffer for link value"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Lget_val_by_idx: failed to allocate buffer for link value"); if ((status = H5Lget_val_by_idx((hid_t)loc_id, grpName, (H5_index_t)index_field, (H5_iter_order_t)order, (hsize_t)link_n, (void *)linkValue, infobuf.u.val_size + 1, (hid_t)access_id)) < 0) H5_LIBRARY_ERROR(ENVONLY); @@ -568,7 +612,7 @@ Java_hdf_hdf5lib_H5_H5Lget_1value_1by_1idx case H5L_TYPE_MAX: case H5L_TYPE_HARD: default: - H5_JNI_FATAL_ERROR(ENVONLY, "H5Lget_val_by_idx: invalid link type"); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Lget_val_by_idx: invalid link type"); break; } @@ -615,12 +659,15 @@ done: UNPIN_JAVA_STRING(ENVONLY, cur_name, lCurName); } /* end Java_hdf_hdf5lib_H5_H5Lmove */ +/* + * Shim function for link iteration and link visiting which + */ static herr_t H5L_iterate_cb - (hid_t g_id, const char *name, const H5L_info_t *info, void *cb_data) + (hid_t g_id, const char *name, const H5L_info2_t *info, void *cb_data) { cb_wrapper *wrapper = (cb_wrapper *)cb_data; - jmethodID constructor, mid; + jmethodID mid; jobject cb_info_t = NULL; jobject visit_callback = wrapper->visit_callback; jstring str; @@ -635,32 +682,44 @@ H5L_iterate_cb H5_JNI_FATAL_ERROR(CBENVONLY, "H5L_iterate_cb: failed to attach current thread to JVM"); } + /* Get the Method ID for the "callback" function of the H5L_iterate_t class */ if (NULL == (cls = CBENVPTR->GetObjectClass(CBENVONLY, visit_callback))) CHECK_JNI_EXCEPTION(CBENVONLY, JNI_FALSE); - if (NULL == (mid = CBENVPTR->GetMethodID(CBENVONLY, cls, "callback", "(JLjava/lang/String;Lhdf/hdf5lib/structs/H5L_info_t;Lhdf/hdf5lib/callbacks/H5L_iterate_t;)I"))) + if (NULL == (mid = CBENVPTR->GetMethodID(CBENVONLY, cls, "callback", "(JLjava/lang/String;Lhdf/hdf5lib/structs/H5L_info_t;Lhdf/hdf5lib/callbacks/H5L_iterate_opdata_t;)I"))) CHECK_JNI_EXCEPTION(CBENVONLY, JNI_FALSE); if (NULL == (str = CBENVPTR->NewStringUTF(CBENVONLY, name))) CHECK_JNI_EXCEPTION(CBENVONLY, JNI_FALSE); - args[0].i = info->type; - args[1].z = info->corder_valid; - args[2].j = info->corder; - args[3].i = info->cset; - args[4].j = (info->type == H5L_TYPE_HARD) ? (jlong)info->u.address : (jlong)info->u.val_size; - - /* Get a reference to your class if you don't have it already */ - if (NULL == (cls = CBENVPTR->FindClass(CBENVONLY, "hdf/hdf5lib/structs/H5L_info_t"))) - CHECK_JNI_EXCEPTION(CBENVONLY, JNI_FALSE); - - /* Get a reference to the constructor; the name is */ - if (NULL == (constructor = CBENVPTR->GetMethodID(CBENVONLY, cls, "", "(IZJIJ)V"))) - CHECK_JNI_EXCEPTION(CBENVONLY, JNI_FALSE); - - if (NULL == (cb_info_t = CBENVPTR->NewObjectA(CBENVONLY, cls, constructor, args))) { - HDprintf("FATAL ERROR: hdf/hdf5lib/structs/H5L_info_t: Creation failed\n"); - CHECK_JNI_EXCEPTION(CBENVONLY, JNI_FALSE); + /* + * Set the last argument based upon whether this is a hard link (which returns object tokens) + * or a soft/user-defined link (which returns the link's value size). Then, call the appropriate + * constructor to instantiate an H5L_info_t object. + */ + if (info->type == H5L_TYPE_HARD) { + jobject token; + + /* Create an H5O_token_t object */ + if (NULL == (token = create_H5O_token_t(CBENVONLY, &info->u.token, FALSE))) + CHECK_JNI_EXCEPTION(CBENVONLY, JNI_FALSE); + + args[0].i = info->type; + args[1].z = info->corder_valid; + args[2].j = info->corder; + args[3].i = info->cset; + args[4].l = token; + + CALL_CONSTRUCTOR(CBENVONLY, "hdf/hdf5lib/structs/H5L_info_t", "(IZJILhdf/hdf5lib/structs/H5O_token_t;)V", args, cb_info_t); + } + else { + args[0].i = info->type; + args[1].z = info->corder_valid; + args[2].j = info->corder; + args[3].i = info->cset; + args[4].j = (jlong)info->u.val_size; + + CALL_CONSTRUCTOR(CBENVONLY, "hdf/hdf5lib/structs/H5L_info_t", "(IZJIJ)V", args, cb_info_t); } status = CBENVPTR->CallIntMethod(CBENVONLY, visit_callback, mid, g_id, str, cb_info_t, op_data); @@ -696,7 +755,8 @@ Java_hdf_hdf5lib_H5_H5Lvisit if (NULL == callback_op) H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Lvisit: callback_op is NULL"); - if ((status = H5Lvisit((hid_t)grp_id, (H5_index_t)idx_type, (H5_iter_order_t)order, (H5L_iterate_t)H5L_iterate_cb, (void *)&wrapper)) < 0) + if ((status = H5Lvisit2((hid_t)grp_id, (H5_index_t)idx_type, (H5_iter_order_t)order, + H5L_iterate_cb, (void *)&wrapper)) < 0) H5_LIBRARY_ERROR(ENVONLY); done: @@ -731,7 +791,8 @@ Java_hdf_hdf5lib_H5_H5Lvisit_1by_1name PIN_JAVA_STRING(ENVONLY, name, grpName, NULL, "H5Lvisit_by_name: group name not pinned"); - if ((status = H5Lvisit_by_name((hid_t)grp_id, grpName, (H5_index_t)idx_type, (H5_iter_order_t)order, (H5L_iterate_t)H5L_iterate_cb, (void *)&wrapper, (hid_t)access_id)) < 0) + if ((status = H5Lvisit_by_name2((hid_t)grp_id, grpName, (H5_index_t)idx_type, (H5_iter_order_t)order, + H5L_iterate_cb, (void *)&wrapper, (hid_t)access_id)) < 0) H5_LIBRARY_ERROR(ENVONLY); done: @@ -765,7 +826,8 @@ Java_hdf_hdf5lib_H5_H5Literate if (NULL == callback_op) H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Literate: callback_op is NULL"); - if ((status = H5Literate((hid_t)grp_id, (H5_index_t)idx_type, (H5_iter_order_t)order, (hsize_t *)&start_idx, (H5L_iterate_t)H5L_iterate_cb, (void *)&wrapper)) < 0) + if ((status = H5Literate2((hid_t)grp_id, (H5_index_t)idx_type, (H5_iter_order_t)order, + &start_idx, H5L_iterate_cb, (void *)&wrapper)) < 0) H5_LIBRARY_ERROR(ENVONLY); done: @@ -801,7 +863,8 @@ Java_hdf_hdf5lib_H5_H5Literate_1by_1name PIN_JAVA_STRING(ENVONLY, name, groupName, NULL, "H5Literate_by_name: group name not pinned"); - if ((status = H5Literate_by_name((hid_t)grp_id, groupName, (H5_index_t)idx_type, (H5_iter_order_t)order, (hsize_t*)&start_idx, (H5L_iterate_t)H5L_iterate_cb, (void*)&wrapper, (hid_t)access_id)) < 0) + if ((status = H5Literate_by_name2((hid_t)grp_id, groupName, (H5_index_t)idx_type, (H5_iter_order_t)order, + &start_idx, H5L_iterate_cb, (void*)&wrapper, (hid_t)access_id)) < 0) H5_LIBRARY_ERROR(ENVONLY); done: diff --git a/java/src/jni/h5oImp.c b/java/src/jni/h5oImp.c index b49a3e9..1d828a1 100644 --- a/java/src/jni/h5oImp.c +++ b/java/src/jni/h5oImp.c @@ -40,7 +40,58 @@ typedef struct _cb_wrapper { /* Local Prototypes */ /********************/ -static herr_t H5O_iterate_cb(hid_t g_id, const char *name, const H5O_info_t *info, void *cb_data); +static herr_t H5O_iterate_cb(hid_t g_id, const char *name, const H5O_info2_t *info, void *cb_data); + +/* + * Create a java object of hdf.hdf5lib.structs.H5O_token_t. + */ +jobject +create_H5O_token_t + (JNIEnv *envptr, const H5O_token_t *token, hbool_t is_critical_pinning) +{ + jbyteArray tokenByteBuf; + jboolean token_buf_is_copy; + jvalue constructor_args[1]; + jbyte *token_buf = NULL; + jobject ret_token_obj = NULL; + + if (NULL == (tokenByteBuf = (*envptr)->NewByteArray(envptr, H5O_MAX_TOKEN_SIZE))) + CHECK_JNI_EXCEPTION(envptr, JNI_FALSE); + + if (is_critical_pinning) + PIN_BYTE_ARRAY_CRITICAL(envptr, tokenByteBuf, token_buf, &token_buf_is_copy, "create_H5O_token_t: object token buffer not pinned"); + else + PIN_BYTE_ARRAY(envptr, tokenByteBuf, token_buf, &token_buf_is_copy, "create_H5O_token_t: object token buffer not pinned"); + + HDmemcpy(token_buf, token, sizeof(H5O_token_t)); + + if (is_critical_pinning) + UNPIN_ARRAY_CRITICAL(envptr, tokenByteBuf, token_buf, 0); + else + UNPIN_BYTE_ARRAY(envptr, tokenByteBuf, token_buf, 0); + + token_buf = NULL; + + constructor_args[0].l = tokenByteBuf; + CALL_CONSTRUCTOR(envptr, "hdf/hdf5lib/structs/H5O_token_t", "([B)V", constructor_args, ret_token_obj); + + /* + * If critical pinning is being used, this routine is probably being + * called within a loop, so we'll clean up local references. + */ + if (is_critical_pinning) + (*envptr)->DeleteLocalRef(envptr, tokenByteBuf); + +done: + if (token_buf) { + if (is_critical_pinning) + UNPIN_ARRAY_CRITICAL(envptr, tokenByteBuf, token_buf, JNI_ABORT); + else + UNPIN_BYTE_ARRAY(envptr, tokenByteBuf, token_buf, JNI_ABORT); + } /* end if */ + + return ret_token_obj; +} /* end create_H5O_token_t */ /* * Class: hdf_hdf5lib_H5 @@ -134,17 +185,156 @@ JNIEXPORT jobject JNICALL Java_hdf_hdf5lib_H5_H5Oget_1info (JNIEnv *env, jclass clss, jlong loc_id, jint fields) { - H5O_info_t infobuf; - jobject hdrinfobuf; - jobject ihinfobuf1; - jobject ihinfobuf2; - jvalue args[12]; - herr_t status = FAIL; - jobject ret_obj = NULL; + H5O_info2_t infobuf; + jobject token; + jvalue args[9]; + herr_t status = FAIL; + jobject ret_obj = NULL; + + UNUSED(clss); + + if ((status = H5Oget_info3((hid_t)loc_id, &infobuf, (unsigned)fields)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + if (NULL == (token = create_H5O_token_t(ENVONLY, &infobuf.token, FALSE))) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + args[0].j = (jlong)infobuf.fileno; + args[1].l = token; + args[2].i = infobuf.type; + args[3].i = (jint)infobuf.rc; + args[4].j = infobuf.atime; + args[5].j = infobuf.mtime; + args[6].j = infobuf.ctime; + args[7].j = infobuf.btime; + args[8].j = (jlong)infobuf.num_attrs; + + CALL_CONSTRUCTOR(ENVONLY, "hdf/hdf5lib/structs/H5O_info_t", "(JLhdf/hdf5lib/structs/H5O_token_t;IIJJJJJ)V", args, ret_obj); + +done: + return ret_obj; +} /* end Java_hdf_hdf5lib_H5_H5Oget_1info */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Oget_info_by_name + * Signature: (JLjava/lang/String;IJ)Lhdf/hdf5lib/structs/H5O_info_t; + */ +JNIEXPORT jobject JNICALL +Java_hdf_hdf5lib_H5_H5Oget_1info_1by_1name + (JNIEnv *env, jclass clss, jlong loc_id, jstring name, jint fields, jlong access_id) +{ + H5O_info2_t infobuf; + const char *objName = NULL; + jobject token; + jvalue args[9]; + herr_t status = FAIL; + jobject ret_obj = NULL; UNUSED(clss); - if ((status = H5Oget_info2((hid_t)loc_id, &infobuf, (unsigned)fields)) < 0) + if (NULL == name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Oget_info_by_name: object name is NULL"); + + PIN_JAVA_STRING(ENVONLY, name, objName, NULL, "H5Oget_info_by_name: object name not pinned"); + + if ((status = H5Oget_info_by_name3((hid_t)loc_id, objName, &infobuf, (unsigned)fields, (hid_t)access_id)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + /* Create an H5O_token_t object */ + if (NULL == (token = create_H5O_token_t(ENVONLY, &infobuf.token, FALSE))) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + args[0].j = (jlong)infobuf.fileno; + args[1].l = token; + args[2].i = infobuf.type; + args[3].i = (jint)infobuf.rc; + args[4].j = infobuf.atime; + args[5].j = infobuf.mtime; + args[6].j = infobuf.ctime; + args[7].j = infobuf.btime; + args[8].j = (jlong)infobuf.num_attrs; + + CALL_CONSTRUCTOR(ENVONLY, "hdf/hdf5lib/structs/H5O_info_t", "(JLhdf/hdf5lib/structs/H5O_token_t;IIJJJJJ)V", args, ret_obj); + +done: + if (objName) + UNPIN_JAVA_STRING(ENVONLY, name, objName); + + return ret_obj; +} /* end Java_hdf_hdf5lib_H5_H5Oget_1info_1by_1name */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Oget_info_by_idx + * Signature: (JLjava/lang/String;IIJIJ)Lhdf/hdf5lib/structs/H5O_info_t; + */ +JNIEXPORT jobject JNICALL +Java_hdf_hdf5lib_H5_H5Oget_1info_1by_1idx + (JNIEnv *env, jclass clss, jlong loc_id, + jstring name, jint index_field, jint order, jlong link_n, jint fields, jlong access_id) +{ + H5O_info2_t infobuf; + const char *grpName = NULL; + jobject token; + jvalue args[9]; + herr_t status = FAIL; + jobject ret_obj = NULL; + + UNUSED(clss); + + if (NULL == name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Oget_info_by_idx: group name is NULL"); + + PIN_JAVA_STRING(ENVONLY, name, grpName, NULL, "H5Oget_info_by_idx: group name not pinned"); + + if ((status = H5Oget_info_by_idx3((hid_t)loc_id, grpName, (H5_index_t)index_field, (H5_iter_order_t)order, (hsize_t)link_n, + &infobuf, (unsigned)fields, (hid_t)access_id)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + /* Create an H5O_token_t object */ + if (NULL == (token = create_H5O_token_t(ENVONLY, &infobuf.token, FALSE))) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + args[0].j = (jlong)infobuf.fileno; + args[1].l = token; + args[2].i = infobuf.type; + args[3].i = (jint)infobuf.rc; + args[4].j = infobuf.atime; + args[5].j = infobuf.mtime; + args[6].j = infobuf.ctime; + args[7].j = infobuf.btime; + args[8].j = (jlong)infobuf.num_attrs; + + CALL_CONSTRUCTOR(ENVONLY, "hdf/hdf5lib/structs/H5O_info_t", "(JLhdf/hdf5lib/structs/H5O_token_t;IIJJJJJ)V", args, ret_obj); + +done: + if (grpName) + UNPIN_JAVA_STRING(ENVONLY, name, grpName); + + return ret_obj; +} /* end Java_hdf_hdf5lib_H5_H5Oget_1info_1by_1idx */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Oget_native_info + * Signature: (JI)Lhdf/hdf5lib/structs/H5O_native_info_t; + */ +JNIEXPORT jobject JNICALL +Java_hdf_hdf5lib_H5_H5Oget_1native_1info + (JNIEnv *env, jclass clss, jlong loc_id, jint fields) +{ + H5O_native_info_t infobuf; + jobject hdrinfobuf; + jobject obj_ihinfobuf; + jobject attr_ihinfobuf; + jvalue args[10]; + herr_t status = FAIL; + jobject ret_obj = NULL; + + UNUSED(clss); + + if ((status = H5Oget_native_info((hid_t)loc_id, &infobuf, (unsigned)fields)) < 0) H5_LIBRARY_ERROR(ENVONLY); args[0].i = (jint)infobuf.hdr.version; @@ -165,59 +355,50 @@ Java_hdf_hdf5lib_H5_H5Oget_1info args[1].j = (jlong)infobuf.meta_size.obj.heap_size; CALL_CONSTRUCTOR(ENVONLY, "hdf/hdf5lib/structs/H5_ih_info_t", "(JJ)V", args, ret_obj); - ihinfobuf1 = ret_obj; + obj_ihinfobuf = ret_obj; args[0].j = (jlong)infobuf.meta_size.attr.index_size; args[1].j = (jlong)infobuf.meta_size.attr.heap_size; CALL_CONSTRUCTOR(ENVONLY, "hdf/hdf5lib/structs/H5_ih_info_t", "(JJ)V", args, ret_obj); - ihinfobuf2 = ret_obj; + attr_ihinfobuf = ret_obj; - args[0].j = (jlong)infobuf.fileno; - args[1].j = (jlong)infobuf.addr; - args[2].i = infobuf.type; - args[3].i = (jint)infobuf.rc; - args[4].j = (jlong)infobuf.num_attrs; - args[5].j = infobuf.atime; - args[6].j = infobuf.mtime; - args[7].j = infobuf.ctime; - args[8].j = infobuf.btime; - args[9].l = hdrinfobuf; - args[10].l = ihinfobuf1; - args[11].l = ihinfobuf2; + args[0].l = hdrinfobuf; + args[1].l = obj_ihinfobuf; + args[2].l = attr_ihinfobuf; - CALL_CONSTRUCTOR(ENVONLY, "hdf/hdf5lib/structs/H5O_info_t", "(JJIIJJJJJLhdf/hdf5lib/structs/H5O_hdr_info_t;Lhdf/hdf5lib/structs/H5_ih_info_t;Lhdf/hdf5lib/structs/H5_ih_info_t;)V", args, ret_obj); + CALL_CONSTRUCTOR(ENVONLY, "hdf/hdf5lib/structs/H5O_native_info_t", "(Lhdf/hdf5lib/structs/H5O_hdr_info_t;Lhdf/hdf5lib/structs/H5_ih_info_t;Lhdf/hdf5lib/structs/H5_ih_info_t;)V", args, ret_obj); done: return ret_obj; -} /* end Java_hdf_hdf5lib_H5_H5Oget_1info */ +} /* end Java_hdf_hdf5lib_H5_H5Oget_1native_1info */ /* * Class: hdf_hdf5lib_H5 - * Method: H5Oget_info_by_name - * Signature: (JLjava/lang/String;IJ)Lhdf/hdf5lib/structs/H5O_info_t; + * Method: H5Oget_native_info_by_name + * Signature: (JLjava/lang/String;IJ)Lhdf/hdf5lib/structs/H5O_native_info_t; */ JNIEXPORT jobject JNICALL -Java_hdf_hdf5lib_H5_H5Oget_1info_1by_1name +Java_hdf_hdf5lib_H5_H5Oget_1native_1info_1by_1name (JNIEnv *env, jclass clss, jlong loc_id, jstring name, jint fields, jlong access_id) { - H5O_info_t infobuf; - const char *objName = NULL; - jobject hdrinfobuf; - jobject ihinfobuf1; - jobject ihinfobuf2; - jvalue args[12]; - herr_t status = FAIL; - jobject ret_obj = NULL; + H5O_native_info_t infobuf; + const char *objName = NULL; + jobject hdrinfobuf; + jobject obj_ihinfobuf; + jobject attr_ihinfobuf; + jvalue args[10]; + herr_t status = FAIL; + jobject ret_obj = NULL; UNUSED(clss); if (NULL == name) - H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Oget_info_by_name: object name is NULL"); + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Oget_native_info_by_name: object name is NULL"); - PIN_JAVA_STRING(ENVONLY, name, objName, NULL, "H5Oget_info_by_name: object name not pinned"); + PIN_JAVA_STRING(ENVONLY, name, objName, NULL, "H5Oget_native_info_by_name: object name not pinned"); - if ((status = H5Oget_info_by_name2((hid_t)loc_id, objName, &infobuf, (unsigned)fields, (hid_t)access_id)) < 0) + if ((status = H5Oget_native_info_by_name((hid_t)loc_id, objName, &infobuf, (unsigned)fields, (hid_t)access_id)) < 0) H5_LIBRARY_ERROR(ENVONLY); args[0].i = (jint)infobuf.hdr.version; @@ -238,63 +419,55 @@ Java_hdf_hdf5lib_H5_H5Oget_1info_1by_1name args[1].j = (jlong)infobuf.meta_size.obj.heap_size; CALL_CONSTRUCTOR(ENVONLY, "hdf/hdf5lib/structs/H5_ih_info_t", "(JJ)V", args, ret_obj); - ihinfobuf1 = ret_obj; + obj_ihinfobuf = ret_obj; args[0].j = (jlong)infobuf.meta_size.attr.index_size; args[1].j = (jlong)infobuf.meta_size.attr.heap_size; CALL_CONSTRUCTOR(ENVONLY, "hdf/hdf5lib/structs/H5_ih_info_t", "(JJ)V", args, ret_obj); - ihinfobuf2 = ret_obj; + attr_ihinfobuf = ret_obj; - args[0].j = (jlong)infobuf.fileno; - args[1].j = (jlong)infobuf.addr; - args[2].i = infobuf.type; - args[3].i = (jint)infobuf.rc; - args[4].j = (jlong)infobuf.num_attrs; - args[5].j = infobuf.atime; - args[6].j = infobuf.mtime; - args[7].j = infobuf.ctime; - args[8].j = infobuf.btime; - args[9].l = hdrinfobuf; - args[10].l = ihinfobuf1; - args[11].l = ihinfobuf2; + args[0].l = hdrinfobuf; + args[1].l = obj_ihinfobuf; + args[2].l = attr_ihinfobuf; - CALL_CONSTRUCTOR(ENVONLY, "hdf/hdf5lib/structs/H5O_info_t", "(JJIIJJJJJLhdf/hdf5lib/structs/H5O_hdr_info_t;Lhdf/hdf5lib/structs/H5_ih_info_t;Lhdf/hdf5lib/structs/H5_ih_info_t;)V", args, ret_obj); + CALL_CONSTRUCTOR(ENVONLY, "hdf/hdf5lib/structs/H5O_native_info_t", "(Lhdf/hdf5lib/structs/H5O_hdr_info_t;Lhdf/hdf5lib/structs/H5_ih_info_t;Lhdf/hdf5lib/structs/H5_ih_info_t;)V", args, ret_obj); done: if (objName) UNPIN_JAVA_STRING(ENVONLY, name, objName); return ret_obj; -} /* end Java_hdf_hdf5lib_H5_H5Oget_1info_1by_1name */ +} /* end Java_hdf_hdf5lib_H5_H5Oget_1native_1info_1by_1name */ /* * Class: hdf_hdf5lib_H5 - * Method: H5Oget_info_by_idx - * Signature: (JLjava/lang/String;IIJIJ)Lhdf/hdf5lib/structs/H5O_info_t; + * Method: H5Oget_native_info_by_idx + * Signature: (JLjava/lang/String;IIJIJ)Lhdf/hdf5lib/structs/H5O_native_info_t; */ JNIEXPORT jobject JNICALL -Java_hdf_hdf5lib_H5_H5Oget_1info_1by_1idx +Java_hdf_hdf5lib_H5_H5Oget_1native_1info_1by_1idx (JNIEnv *env, jclass clss, jlong loc_id, jstring name, jint index_field, jint order, jlong link_n, jint fields, jlong access_id) { - H5O_info_t infobuf; - const char *grpName = NULL; - jobject hdrinfobuf; - jobject ihinfobuf1; - jobject ihinfobuf2; - jvalue args[12]; - herr_t status = FAIL; - jobject ret_obj = NULL; + H5O_native_info_t infobuf; + const char *grpName = NULL; + jobject hdrinfobuf; + jobject obj_ihinfobuf; + jobject attr_ihinfobuf; + jvalue args[10]; + herr_t status = FAIL; + jobject ret_obj = NULL; UNUSED(clss); if (NULL == name) - H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Oget_info_by_idx: group name is NULL"); + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Oget_native_info_by_idx: group name is NULL"); - PIN_JAVA_STRING(ENVONLY, name, grpName, NULL, "H5Oget_info_by_idx: group name not pinned"); + PIN_JAVA_STRING(ENVONLY, name, grpName, NULL, "H5Oget_native_info_by_idx: group name not pinned"); - if ((status = H5Oget_info_by_idx2((hid_t)loc_id, grpName, (H5_index_t)index_field, (H5_iter_order_t)order, (hsize_t)link_n, &infobuf, (unsigned)fields, (hid_t)access_id)) < 0) + if ((status = H5Oget_native_info_by_idx((hid_t)loc_id, grpName, (H5_index_t)index_field, (H5_iter_order_t)order, (hsize_t)link_n, + &infobuf, (unsigned)fields, (hid_t)access_id)) < 0) H5_LIBRARY_ERROR(ENVONLY); args[0].i = (jint)infobuf.hdr.version; @@ -315,35 +488,26 @@ Java_hdf_hdf5lib_H5_H5Oget_1info_1by_1idx args[1].j = (jlong)infobuf.meta_size.obj.heap_size; CALL_CONSTRUCTOR(ENVONLY, "hdf/hdf5lib/structs/H5_ih_info_t", "(JJ)V", args, ret_obj); - ihinfobuf1 = ret_obj; + obj_ihinfobuf = ret_obj; args[0].j = (jlong)infobuf.meta_size.attr.index_size; args[1].j = (jlong)infobuf.meta_size.attr.heap_size; CALL_CONSTRUCTOR(ENVONLY, "hdf/hdf5lib/structs/H5_ih_info_t", "(JJ)V", args, ret_obj); - ihinfobuf2 = ret_obj; + attr_ihinfobuf = ret_obj; - args[0].j = (jlong)infobuf.fileno; - args[1].j = (jlong)infobuf.addr; - args[2].i = infobuf.type; - args[3].i = (jint)infobuf.rc; - args[4].j = (jlong)infobuf.num_attrs; - args[5].j = infobuf.atime; - args[6].j = infobuf.mtime; - args[7].j = infobuf.ctime; - args[8].j = infobuf.btime; - args[9].l = hdrinfobuf; - args[10].l = ihinfobuf1; - args[11].l = ihinfobuf2; + args[0].l = hdrinfobuf; + args[1].l = obj_ihinfobuf; + args[2].l = attr_ihinfobuf; - CALL_CONSTRUCTOR(ENVONLY, "hdf/hdf5lib/structs/H5O_info_t", "(JJIIJJJJJLhdf/hdf5lib/structs/H5O_hdr_info_t;Lhdf/hdf5lib/structs/H5_ih_info_t;Lhdf/hdf5lib/structs/H5_ih_info_t;)V", args, ret_obj); + CALL_CONSTRUCTOR(ENVONLY, "hdf/hdf5lib/structs/H5O_native_info_t", "(Lhdf/hdf5lib/structs/H5O_hdr_info_t;Lhdf/hdf5lib/structs/H5_ih_info_t;Lhdf/hdf5lib/structs/H5_ih_info_t;)V", args, ret_obj); done: if (grpName) UNPIN_JAVA_STRING(ENVONLY, name, grpName); return ret_obj; -} /* end Java_hdf_hdf5lib_H5_H5Oget_1info_1by_1idx */ +} /* end Java_hdf_hdf5lib_H5_H5Oget_1native_1info_1by_1idx */ /* * Class: hdf_hdf5lib_H5 @@ -375,15 +539,13 @@ done: static herr_t H5O_iterate_cb - (hid_t g_id, const char *name, const H5O_info_t *info, void *cb_data) + (hid_t g_id, const char *name, const H5O_info2_t *info, void *cb_data) { cb_wrapper *wrapper = (cb_wrapper *)cb_data; - jmethodID constructor, mid; + jmethodID mid; jobject cb_info_t = NULL; jobject visit_callback = wrapper->visit_callback; - jobject hdrinfobuf; - jobject ihinfobuf1; - jobject ihinfobuf2; + jobject token; jstring str; JNIEnv *cbenv = NULL; jclass cls; @@ -399,85 +561,28 @@ H5O_iterate_cb if (NULL == (cls = CBENVPTR->GetObjectClass(CBENVONLY, visit_callback))) CHECK_JNI_EXCEPTION(CBENVONLY, JNI_FALSE); - if (NULL == (mid = CBENVPTR->GetMethodID(CBENVONLY, cls, "callback", "(JLjava/lang/String;Lhdf/hdf5lib/structs/H5O_info_t;Lhdf/hdf5lib/callbacks/H5O_iterate_t;)I"))) + if (NULL == (mid = CBENVPTR->GetMethodID(CBENVONLY, cls, "callback", "(JLjava/lang/String;Lhdf/hdf5lib/structs/H5O_info_t;Lhdf/hdf5lib/callbacks/H5O_iterate_opdata_t;)I"))) CHECK_JNI_EXCEPTION(CBENVONLY, JNI_FALSE); if (NULL == (str = CBENVPTR->NewStringUTF(CBENVONLY, name))) CHECK_JNI_EXCEPTION(CBENVONLY, JNI_FALSE); - args[0].i = (jint)info->hdr.version; - args[1].i = (jint)info->hdr.nmesgs; - args[2].i = (jint)info->hdr.nchunks; - args[3].i = (jint)info->hdr.flags; - args[4].j = (jlong)info->hdr.space.total; - args[5].j = (jlong)info->hdr.space.meta; - args[6].j = (jlong)info->hdr.space.mesg; - args[7].j = (jlong)info->hdr.space.free; - args[8].j = (jlong)info->hdr.mesg.present; - args[9].j = (jlong)info->hdr.mesg.shared; - - /* Get a reference to the H5_hdr_info_t class */ - if (NULL == (cls = CBENVPTR->FindClass(CBENVONLY, "hdf/hdf5lib/structs/H5O_hdr_info_t"))) - CHECK_JNI_EXCEPTION(CBENVONLY, JNI_FALSE); - - /* Get a reference to the constructor; the name is */ - if (NULL == (constructor = CBENVPTR->GetMethodID(CBENVONLY, cls, "", "(IIIIJJJJJJ)V"))) - CHECK_JNI_EXCEPTION(CBENVONLY, JNI_FALSE); - - if (NULL == (hdrinfobuf = CBENVPTR->NewObjectA(CBENVONLY, cls, constructor, args))) { - HDprintf("H5O_iterate_cb ERROR: hdf/hdf5lib/structs/H5O_hdr_info_t: Creation failed\n"); - CHECK_JNI_EXCEPTION(CBENVONLY, JNI_FALSE); - } - - args[0].j = (jlong)info->meta_size.obj.index_size; - args[1].j = (jlong)info->meta_size.obj.heap_size; - - /* Get a reference to the H5_ih_info_t class */ - if (NULL == (cls = CBENVPTR->FindClass(CBENVONLY, "hdf/hdf5lib/structs/H5_ih_info_t"))) - CHECK_JNI_EXCEPTION(CBENVONLY, JNI_FALSE); - - /* Get a reference to the constructor; the name is */ - if (NULL == (constructor = CBENVPTR->GetMethodID(CBENVONLY, cls, "", "(JJ)V"))) + /* Create an H5O_token_t object */ + if (NULL == (token = create_H5O_token_t(CBENVONLY, &info->token, FALSE))) CHECK_JNI_EXCEPTION(CBENVONLY, JNI_FALSE); - if (NULL == (ihinfobuf1 = CBENVPTR->NewObjectA(CBENVONLY, cls, constructor, args))) { - HDprintf("H5O_iterate_cb ERROR: hdf/hdf5lib/structs/H5_ih_info_t: Creation failed\n"); - CHECK_JNI_EXCEPTION(CBENVONLY, JNI_FALSE); - } - - args[0].j = (jlong)info->meta_size.attr.index_size; - args[1].j = (jlong)info->meta_size.attr.heap_size; - - if (NULL == (ihinfobuf2 = CBENVPTR->NewObjectA(CBENVONLY, cls, constructor, args))) { - HDprintf("H5O_iterate_cb ERROR: hdf/hdf5lib/structs/H5_ih_info_t: Creation failed\n"); - CHECK_JNI_EXCEPTION(CBENVONLY, JNI_FALSE); - } - args[0].j = (jlong)info->fileno; - args[1].j = (jlong)info->addr; + args[1].l = token; args[2].i = info->type; args[3].i = (jint)info->rc; - args[4].j = (jlong)info->num_attrs; - args[5].j = info->atime; - args[6].j = info->mtime; - args[7].j = info->ctime; - args[8].j = info->btime; - args[9].l = hdrinfobuf; - args[10].l = ihinfobuf1; - args[11].l = ihinfobuf2; + args[4].j = info->atime; + args[5].j = info->mtime; + args[6].j = info->ctime; + args[7].j = info->btime; + args[8].j = (jlong)info->num_attrs; /* Get a reference to the H5O_info_t class */ - if (NULL == (cls = CBENVPTR->FindClass(CBENVONLY, "hdf/hdf5lib/structs/H5O_info_t"))) - CHECK_JNI_EXCEPTION(CBENVONLY, JNI_FALSE); - - /* Get a reference to the constructor; the name is */ - if (NULL == (constructor = CBENVPTR->GetMethodID(CBENVONLY, cls, "", "(JJIIJJJJJLhdf/hdf5lib/structs/H5O_hdr_info_t;Lhdf/hdf5lib/structs/H5_ih_info_t;Lhdf/hdf5lib/structs/H5_ih_info_t;)V"))) - CHECK_JNI_EXCEPTION(CBENVONLY, JNI_FALSE); - - if (NULL == (cb_info_t = CBENVPTR->NewObjectA(CBENVONLY, cls, constructor, args))) { - HDprintf("H5O_iterate_cb ERROR: hdf/hdf5lib/structs/H5O_info_t: Creation failed\n"); - CHECK_JNI_EXCEPTION(CBENVONLY, JNI_FALSE); - } + CALL_CONSTRUCTOR(CBENVONLY, "hdf/hdf5lib/structs/H5O_info_t", "(JLhdf/hdf5lib/structs/H5O_token_t;IIJJJJJ)V", args, cb_info_t); status = CBENVPTR->CallIntMethod(CBENVONLY, visit_callback, mid, g_id, str, cb_info_t, op_data); CHECK_JNI_EXCEPTION(CBENVONLY, JNI_FALSE); @@ -512,7 +617,8 @@ Java_hdf_hdf5lib_H5_H5Ovisit if (NULL == callback_op) H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Ovisit: callback_op is NULL"); - if ((status = H5Ovisit2((hid_t)grp_id, (H5_index_t)idx_type, (H5_iter_order_t)order, (H5O_iterate_t)H5O_iterate_cb, (void *)&wrapper, (unsigned)fields)) < 0) + if ((status = H5Ovisit3((hid_t)grp_id, (H5_index_t)idx_type, (H5_iter_order_t)order, + H5O_iterate_cb, (void *)&wrapper, (unsigned)fields)) < 0) H5_LIBRARY_ERROR(ENVONLY); done: @@ -547,7 +653,8 @@ Java_hdf_hdf5lib_H5_H5Ovisit_1by_1name PIN_JAVA_STRING(ENVONLY, name, objName, NULL, "H5Ovisit_by_name: object name not pinned"); - if ((status = H5Ovisit_by_name2((hid_t)grp_id, objName, (H5_index_t)idx_type, (H5_iter_order_t)order, (H5O_iterate_t)H5O_iterate_cb, (void *)&wrapper, (unsigned)fields, (hid_t)access_id)) < 0) + if ((status = H5Ovisit_by_name3((hid_t)grp_id, objName, (H5_index_t)idx_type, (H5_iter_order_t)order, + H5O_iterate_cb, (void *)&wrapper, (unsigned)fields, (hid_t)access_id)) < 0) H5_LIBRARY_ERROR(ENVONLY); done: @@ -639,7 +746,7 @@ Java_hdf_hdf5lib_H5_H5Oget_1comment if (buf_size) { if (NULL == (oComment = (char *) HDmalloc(sizeof(char) * (size_t)buf_size + 1))) - H5_JNI_FATAL_ERROR(ENVONLY, "H5Oget_comment: failed to allocate object comment buffer"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Oget_comment: failed to allocate object comment buffer"); if ((status = H5Oget_comment((hid_t)loc_id, oComment, (size_t)buf_size + 1)) < 0) H5_LIBRARY_ERROR(ENVONLY); @@ -684,7 +791,7 @@ Java_hdf_hdf5lib_H5_H5Oget_1comment_1by_1name if (buf_size) { if (NULL == (objComment = (char *) HDmalloc(sizeof(char) * (size_t)buf_size + 1))) - H5_JNI_FATAL_ERROR(ENVONLY, "H5Oget_comment_by_name: failed to allocate buffer for object comment"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Oget_comment_by_name: failed to allocate buffer for object comment"); if ((status = H5Oget_comment_by_name((hid_t)loc_id, objName, objComment, (size_t)buf_size + 1, (hid_t)access_id)) < 0) H5_LIBRARY_ERROR(ENVONLY); @@ -772,23 +879,46 @@ done: /* * Class: hdf_hdf5lib_H5 - * Method: _H5Oopen_by_addr - * Signature: (JJ)J; + * Method: _H5Oopen_by_token + * Signature: (JLhdf/hdf5lib/structs/H5O_token_t;)J; */ JNIEXPORT jlong JNICALL -Java_hdf_hdf5lib_H5__1H5Oopen_1by_1addr - (JNIEnv *env, jclass clss, jlong loc_id, jlong addr) +Java_hdf_hdf5lib_H5__1H5Oopen_1by_1token + (JNIEnv *env, jclass clss, jlong loc_id, jobject token) { - hid_t retVal = H5I_INVALID_HID; + H5O_token_t obj_token; + jboolean token_buf_is_copy; + jfieldID token_data_field_id; + jclass token_cls; + jbyte *token_buf = NULL; + jobject token_data; + hid_t retVal = H5I_INVALID_HID; UNUSED(clss); - if ((retVal = H5Oopen_by_addr((hid_t)loc_id, (haddr_t)addr)) < 0) + token_cls = ENVPTR->GetObjectClass(ENVONLY, token); + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + if (NULL == (token_data_field_id = ENVPTR->GetFieldID(ENVONLY, token_cls, "data", "[B"))) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + token_data = ENVPTR->GetObjectField(ENVONLY, token, token_data_field_id); + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + PIN_BYTE_ARRAY(ENVONLY, (jbyteArray)token_data, token_buf, &token_buf_is_copy, "H5Oopen_by_token: token buffer not pinned"); + HDmemcpy(&obj_token, token_buf, sizeof(H5O_token_t)); + UNPIN_BYTE_ARRAY(ENVONLY, (jbyteArray)token_data, token_buf, JNI_ABORT); + token_buf = NULL; + + if ((retVal = H5Oopen_by_token((hid_t)loc_id, obj_token)) < 0) H5_LIBRARY_ERROR(ENVONLY); done: + if (token_buf) + UNPIN_BYTE_ARRAY(ENVONLY, (jbyteArray)token_data, token_buf, (retVal < 0) ? JNI_ABORT : 0); + return (jlong)retVal; -} /* end Java_hdf_hdf5lib_H5__1H5Oopen_1by_1addr */ +} /* end Java_hdf_hdf5lib_H5__1H5Oopen_1by_1token */ /* * Class: hdf_hdf5lib_H5 diff --git a/java/src/jni/h5oImp.h b/java/src/jni/h5oImp.h index 5241aba..2b53fd3 100644 --- a/java/src/jni/h5oImp.h +++ b/java/src/jni/h5oImp.h @@ -78,6 +78,33 @@ Java_hdf_hdf5lib_H5_H5Oget_1info_1by_1idx /* * Class: hdf_hdf5lib_H5 + * Method: H5Oget_native_info + * Signature: (JI)Lhdf/hdf5lib/structs/H5O_native_info_t; + */ +JNIEXPORT jobject JNICALL +Java_hdf_hdf5lib_H5_H5Oget_1native_1info +(JNIEnv*, jclass, jlong, jint fields); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Oget_native_info_by_name + * Signature: (JLjava/lang/String;IJ)Lhdf/hdf5lib/structs/H5O_native_info_t; + */ +JNIEXPORT jobject JNICALL +Java_hdf_hdf5lib_H5_H5Oget_1native_1info_1by_1name +(JNIEnv*, jclass, jlong, jstring, jint fields, jlong); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Oget_native_info_by_idx + * Signature: (JLjava/lang/String;IIJIJ)Lhdf/hdf5lib/structs/H5O_native_info_t; + */ +JNIEXPORT jobject JNICALL +Java_hdf_hdf5lib_H5_H5Oget_1native_1info_1by_1idx +(JNIEnv*, jclass, jlong, jstring, jint, jint, jlong, jint fields, jlong); + +/* + * Class: hdf_hdf5lib_H5 * Method: H5Olink * Signature: (JJLjava/lang/String;JJ)V */ @@ -168,12 +195,12 @@ Java_hdf_hdf5lib_H5_H5Oincr_1refcount /* * Class: hdf_hdf5lib_H5 - * Method: _H5Oopen_by_addr - * Signature: (JJ)J; + * Method: _H5Oopen_by_token + * Signature: (JLhdf/hdf5lib/structs/H5O_token_t;)J; */ JNIEXPORT jlong JNICALL -Java_hdf_hdf5lib_H5__1H5Oopen_1by_1addr - (JNIEnv*, jclass, jlong, jlong); +Java_hdf_hdf5lib_H5__1H5Oopen_1by_1token + (JNIEnv*, jclass, jlong, jobject); /* * Class: hdf_hdf5lib_H5 diff --git a/java/src/jni/h5pDAPLImp.c b/java/src/jni/h5pDAPLImp.c index fb39b84..2386df1 100644 --- a/java/src/jni/h5pDAPLImp.c +++ b/java/src/jni/h5pDAPLImp.c @@ -151,7 +151,7 @@ Java_hdf_hdf5lib_H5_H5Pget_1efile_1prefix H5_LIBRARY_ERROR(ENVONLY); if (NULL == (pre = (char *) HDmalloc(sizeof(char) * (size_t)prefix_size + 1))) - H5_JNI_FATAL_ERROR(ENVONLY, "H5Pget_efile_prefix: memory allocation failed"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Pget_efile_prefix: memory allocation failed"); if (H5Pget_efile_prefix((hid_t)dapl_id, (char *)pre, (size_t)prefix_size + 1) < 0) H5_LIBRARY_ERROR(ENVONLY); @@ -159,7 +159,7 @@ Java_hdf_hdf5lib_H5_H5Pget_1efile_1prefix if (NULL == (str = ENVPTR->NewStringUTF(ENVONLY, pre))) { CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); - H5_JNI_FATAL_ERROR(ENVONLY, "H5Pget_efile_prefix: out of memory - unable to construct string from UTF characters"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Pget_efile_prefix: out of memory - unable to construct string from UTF characters"); } done: diff --git a/java/src/jni/h5pDCPLImp.c b/java/src/jni/h5pDCPLImp.c index 7559c3b..c43079f 100644 --- a/java/src/jni/h5pDCPLImp.c +++ b/java/src/jni/h5pDCPLImp.c @@ -109,7 +109,7 @@ Java_hdf_hdf5lib_H5_H5Pset_1chunk PIN_BYTE_ARRAY(ENVONLY, dim, theArray, &isCopy, "H5Pset_chunk: dim array not pinned"); if (NULL == (da = lp = (hsize_t *) HDmalloc(rank * sizeof(hsize_t)))) - H5_JNI_FATAL_ERROR(ENVONLY, "H5Pset_chunk: memory allocation failed"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Pset_chunk: memory allocation failed"); jlp = (jlong *)theArray; for (i = 0; i < rank; i++) { @@ -161,7 +161,7 @@ Java_hdf_hdf5lib_H5_H5Pget_1chunk PIN_LONG_ARRAY(ENVONLY, dims, theArray, &isCopy, "H5Pget_chunk: input dims not pinned"); if (NULL == (da = (hsize_t *) HDmalloc((size_t)max_ndims * sizeof(hsize_t)))) - H5_JNI_FATAL_ERROR(ENVONLY, "H5Pget_chunk: memory allocation failed"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Pget_chunk: memory allocation failed"); if ((status = H5Pget_chunk((hid_t)plist, (int)max_ndims, da)) < 0) H5_LIBRARY_ERROR(ENVONLY); @@ -595,7 +595,7 @@ Java_hdf_hdf5lib_H5_H5Pget_1filter H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Pget_filter: cd_values is NULL"); if (NULL == (filter = (char *) HDmalloc(sizeof(char) * (size_t)namelen))) - H5_JNI_FATAL_ERROR(ENVONLY, "H5Pget_filter: memory allocation failed"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Pget_filter: memory allocation failed"); PIN_INT_ARRAY(ENVONLY, flags, flagsArray, &isCopy, "H5Pget_filter: flags array not pinned"); PIN_LONG_ARRAY(ENVONLY, cd_nelmts, cd_nelmtsArray, &isCopy, "H5Pget_filter: nelmts array not pinned"); @@ -620,7 +620,7 @@ Java_hdf_hdf5lib_H5_H5Pget_1filter if (NULL == (str = ENVPTR->NewStringUTF(ENVONLY, filter))) { CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); - H5_JNI_FATAL_ERROR(ENVONLY, "H5Pget_filter: out of memory - unable to construct string from UTF characters"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Pget_filter: out of memory - unable to construct string from UTF characters"); } ENVPTR->SetObjectArrayElement(ENVONLY, name, 0, (jobject)str); @@ -632,7 +632,7 @@ done: if (cd_nelmtsArray) UNPIN_LONG_ARRAY(ENVONLY, cd_nelmts, cd_nelmtsArray, (status < 0) ? JNI_ABORT : 0); if (flagsArray) - UNPIN_INT_ARRAY(ENVONLY, flags, flagsArray, (status < 0) ? JNI_ABORT : 0) + UNPIN_INT_ARRAY(ENVONLY, flags, flagsArray, (status < 0) ? JNI_ABORT : 0); if (filter) HDfree(filter); @@ -671,7 +671,7 @@ Java_hdf_hdf5lib_H5_H5Pget_1filter2 H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Pget_filter2: filter_config is NULL"); if (NULL == (filter = (char *) HDmalloc(sizeof(char) * (size_t)namelen))) - H5_JNI_FATAL_ERROR(ENVONLY, "H5Pget_filter2: memory allocation failed"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Pget_filter2: memory allocation failed"); PIN_INT_ARRAY(ENVONLY, flags, flagsArray, &isCopy, "H5Pget_filter2: flags array not pinned"); PIN_LONG_ARRAY(ENVONLY, cd_nelmts, cd_nelmtsArray, &isCopy, "H5Pget_filter2: nelmts array not pinned"); @@ -715,7 +715,7 @@ Java_hdf_hdf5lib_H5_H5Pget_1filter2 if (NULL == (str = ENVPTR->NewStringUTF(ENVONLY, filter))) { CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); - H5_JNI_FATAL_ERROR(ENVONLY, "H5Pget_filter2: out of memory - unable to construct string from UTF characters"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Pget_filter2: out of memory - unable to construct string from UTF characters"); } ENVPTR->SetObjectArrayElement(ENVONLY, name, 0, (jobject)str); @@ -772,7 +772,7 @@ Java_hdf_hdf5lib_H5_H5Pget_1filter_1by_1id H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Pget_filter_by_id: name is NULL"); if (NULL == (aName = (char *) HDmalloc(sizeof(char) * (size_t)bs))) - H5_JNI_FATAL_ERROR(ENVONLY, "H5Pget_filter_by_id: memory allocation failed"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Pget_filter_by_id: memory allocation failed"); PIN_INT_ARRAY(ENVONLY, flags, flagsArray, &isCopy, "H5Pget_filter_by_id: flags not pinned"); PIN_LONG_ARRAY(ENVONLY, cd_nelmts, cd_nelmtsArray, &isCopy, "H5Pget_filter_by_id: cd_nelms not pinned"); @@ -801,7 +801,7 @@ Java_hdf_hdf5lib_H5_H5Pget_1filter_1by_1id if (NULL == (str = ENVPTR->NewStringUTF(ENVONLY, aName))) { CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); - H5_JNI_FATAL_ERROR(ENVONLY, "H5Pget_filter_by_id: out of memory - unable to construct string from UTF characters"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Pget_filter_by_id: out of memory - unable to construct string from UTF characters"); } ENVPTR->SetObjectArrayElement(ENVONLY, name, 0, (jobject)str); @@ -858,7 +858,7 @@ Java_hdf_hdf5lib_H5_H5Pget_1filter_1by_1id2 H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Pget_filter_by_id2: filter_config is NULL"); if (NULL == (aName = (char *) HDmalloc(sizeof(char) * (size_t)bs))) - H5_JNI_FATAL_ERROR(ENVONLY, "H5Pget_filter_by_id2: memory allocation failed"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Pget_filter_by_id2: memory allocation failed"); PIN_INT_ARRAY(ENVONLY, flags, flagsArray, &isCopy, "H5Pget_filter_by_id2: flags not pinned"); PIN_LONG_ARRAY(ENVONLY, cd_nelmts, cd_nelmtsArray, &isCopy, "H5Pget_filter_by_id2: cd_nelms not pinned"); @@ -882,7 +882,7 @@ Java_hdf_hdf5lib_H5_H5Pget_1filter_1by_1id2 if (NULL == (str = ENVPTR->NewStringUTF(ENVONLY, aName))) { CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); - H5_JNI_FATAL_ERROR(ENVONLY, "H5Pget_filter_by_id2: out of memory - unable to construct string from UTF characters"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Pget_filter_by_id2: out of memory - unable to construct string from UTF characters"); } ENVPTR->SetObjectArrayElement(ENVONLY, name, 0, (jobject)str); @@ -1122,7 +1122,7 @@ Java_hdf_hdf5lib_H5_H5Pget_1external if (name_size > 0) if (NULL == (file = (char *) HDmalloc(sizeof(char) * (size_t)name_size))) - H5_JNI_FATAL_ERROR(ENVONLY, "H5Pget_external: memory allocation failed"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Pget_external: memory allocation failed"); if ((status = H5Pget_external((hid_t) plist, (unsigned)idx, (size_t)name_size, file, (off_t *)&o, (hsize_t *)&s)) < 0) @@ -1140,7 +1140,7 @@ Java_hdf_hdf5lib_H5_H5Pget_1external if (NULL == (str = ENVPTR->NewStringUTF(ENVONLY, file))) { CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); - H5_JNI_FATAL_ERROR(ENVONLY, "H5Pget_external: out of memory - unable to construct string from UTF characters"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Pget_external: out of memory - unable to construct string from UTF characters"); } ENVPTR->SetObjectArrayElement(ENVONLY, name, 0, (jobject)str); @@ -1250,7 +1250,7 @@ Java_hdf_hdf5lib_H5_H5Pget_1virtual_1dsetname H5_LIBRARY_ERROR(ENVONLY); if (NULL == (dname = (char *) HDmalloc(sizeof(char) * (size_t)buf_size + 1))) - H5_JNI_FATAL_ERROR(ENVONLY, "H5Pget_virtual_dsetname: memory allocation failed"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Pget_virtual_dsetname: memory allocation failed"); if (H5Pget_virtual_dsetname((hid_t)dcpl_id, (size_t)index, dname, (size_t)buf_size + 1) < 0) H5_LIBRARY_ERROR(ENVONLY); @@ -1258,7 +1258,7 @@ Java_hdf_hdf5lib_H5_H5Pget_1virtual_1dsetname if (NULL == (str = ENVPTR->NewStringUTF(ENVONLY, dname))) { CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); - H5_JNI_FATAL_ERROR(ENVONLY, "H5Pget_virtual_dsetname: out of memory - unable to construct string from UTF characters"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Pget_virtual_dsetname: out of memory - unable to construct string from UTF characters"); } done: @@ -1288,7 +1288,7 @@ Java_hdf_hdf5lib_H5_H5Pget_1virtual_1filename H5_LIBRARY_ERROR(ENVONLY); if (NULL == (fname = (char *) HDmalloc(sizeof(char) * (size_t)buf_size + 1))) - H5_JNI_FATAL_ERROR(ENVONLY, "H5Pget_virtual_filename: memory allocation failed"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Pget_virtual_filename: memory allocation failed"); if (H5Pget_virtual_filename((hid_t)dcpl_id, (size_t)index, fname, (size_t)buf_size + 1) < 0) H5_LIBRARY_ERROR(ENVONLY); @@ -1296,7 +1296,7 @@ Java_hdf_hdf5lib_H5_H5Pget_1virtual_1filename if (NULL == (str = ENVPTR->NewStringUTF(ENVONLY, fname))) { CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); - H5_JNI_FATAL_ERROR(ENVONLY, "H5Pget_virtual_filename: out of memory - unable to construct string from UTF characters"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Pget_virtual_filename: out of memory - unable to construct string from UTF characters"); } done: @@ -1392,7 +1392,7 @@ Java_hdf_hdf5lib_H5_H5Pget_1virtual_1prefix H5_LIBRARY_ERROR(ENVONLY); if (NULL == (pre = (char *) HDmalloc(sizeof(char) * (size_t) prefix_size + 1))) - H5_JNI_FATAL_ERROR(ENVONLY, "H5Pget_virtual_prefix: memory allocation failed"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Pget_virtual_prefix: memory allocation failed"); if (H5Pget_virtual_prefix((hid_t)dapl_id, (char *)pre, (size_t) prefix_size + 1) < 0) H5_LIBRARY_ERROR(ENVONLY); @@ -1400,7 +1400,7 @@ Java_hdf_hdf5lib_H5_H5Pget_1virtual_1prefix if (NULL == (str = ENVPTR->NewStringUTF(ENVONLY, pre))) { CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); - H5_JNI_FATAL_ERROR(ENVONLY, "H5Pget_virtual_prefix: out of memory - unable to construct string from UTF characters"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Pget_virtual_prefix: out of memory - unable to construct string from UTF characters"); } done: diff --git a/java/src/jni/h5pDXPLImp.c b/java/src/jni/h5pDXPLImp.c index 323fa8c..12e3367 100644 --- a/java/src/jni/h5pDXPLImp.c +++ b/java/src/jni/h5pDXPLImp.c @@ -310,7 +310,7 @@ Java_hdf_hdf5lib_H5_H5Pget_1data_1transform H5_LIBRARY_ERROR(ENVONLY); if (NULL == (express = (char *) HDmalloc(sizeof(char) * (size_t)express_size + 1))) - H5_JNI_FATAL_ERROR(ENVONLY, "H5Pget_data_transform: memory allocation failed"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Pget_data_transform: memory allocation failed"); if (H5Pget_data_transform((hid_t)plist_id, express, (size_t)express_size + 1) < 0) H5_LIBRARY_ERROR(ENVONLY); @@ -318,7 +318,7 @@ Java_hdf_hdf5lib_H5_H5Pget_1data_1transform if (NULL == (str = ENVPTR->NewStringUTF(ENVONLY, express))) { CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); - H5_JNI_FATAL_ERROR(ENVONLY, "H5Pget_data_transform: out of memory - unable to construct string from UTF characters"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Pget_data_transform: out of memory - unable to construct string from UTF characters"); } ENVPTR->SetObjectArrayElement(ENVONLY, expression, 0, str); diff --git a/java/src/jni/h5pFAPLImp.c b/java/src/jni/h5pFAPLImp.c index a627e65..c9844b7 100644 --- a/java/src/jni/h5pFAPLImp.c +++ b/java/src/jni/h5pFAPLImp.c @@ -308,7 +308,7 @@ Java_hdf_hdf5lib_H5_H5Pget_1fapl_1family } if (NULL == (sa = (hsize_t *) HDmalloc((size_t) rank * sizeof(hsize_t)))) - H5_JNI_FATAL_ERROR(ENVONLY, "H5Pget_family: memory allocation failed"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Pget_family: memory allocation failed"); PIN_LONG_ARRAY(ENVONLY, memb_plist, plistArray, &isCopy, "H5Pget_family: plistArray not pinned"); @@ -398,7 +398,7 @@ Java_hdf_hdf5lib_H5_H5Pget_1fapl_1hdfs if (NULL != fa.namenode_name) { if (NULL == (j_namenode_name = ENVPTR->NewStringUTF(ENVONLY, fa.namenode_name))) { CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); - H5_JNI_FATAL_ERROR(ENVONLY, "H5Pget_fapl_hdfs: out of memory - can't create namenode_name string"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Pget_fapl_hdfs: out of memory - can't create namenode_name string"); } } args[0].l = j_namenode_name; @@ -408,7 +408,7 @@ Java_hdf_hdf5lib_H5_H5Pget_1fapl_1hdfs if (NULL != fa.user_name) { if (NULL == (j_user_name = ENVPTR->NewStringUTF(ENVONLY, fa.user_name))) { CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); - H5_JNI_FATAL_ERROR(ENVONLY, "H5Pget_fapl_hdfs: out of memory - can't create user_name string"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Pget_fapl_hdfs: out of memory - can't create user_name string"); } } args[2].l = j_user_name; @@ -416,7 +416,7 @@ Java_hdf_hdf5lib_H5_H5Pget_1fapl_1hdfs if (NULL != fa.kerberos_ticket_cache) { if (NULL == (j_kerb_cache_path = ENVPTR->NewStringUTF(ENVONLY, fa.kerberos_ticket_cache))) { CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); - H5_JNI_FATAL_ERROR(ENVONLY, "H5Pget_fapl_hdfs: out of memory - can't create kerberos_ticket_cache string"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Pget_fapl_hdfs: out of memory - can't create kerberos_ticket_cache string"); } } args[3].l = j_kerb_cache_path; @@ -651,7 +651,7 @@ Java_hdf_hdf5lib_H5_H5Pset_1fapl_1multi str_len = HDstrlen(utf8); if (NULL == (member_name[i] = (char *) HDmalloc(str_len + 1))) - H5_JNI_FATAL_ERROR(ENVONLY, "H5Pset_fapl_multi: memory allocation failed"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Pset_fapl_multi: memory allocation failed"); HDstrncpy(member_name[i], utf8, str_len + 1); (member_name[i])[str_len] = '\0'; @@ -678,7 +678,7 @@ Java_hdf_hdf5lib_H5_H5Pset_1fapl_1multi if (NULL == (rstring = ENVPTR->NewStringUTF(ENVONLY, member_name[i]))) { CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); - H5_JNI_FATAL_ERROR(ENVONLY, "H5Pset_fapl_multi: out of memory - unable to construct string from UTF characters"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Pset_fapl_multi: out of memory - unable to construct string from UTF characters"); } if (NULL == (o = ENVPTR->GetObjectArrayElement(ENVONLY, memb_name, (jsize) i))) { @@ -750,7 +750,7 @@ Java_hdf_hdf5lib_H5_H5Pget_1fapl_1multi PIN_LONG_ARRAY(ENVONLY, memb_addr, theaddrArray, &isCopy, "H5Pget_fapl_multi: memb_addr not pinned"); if (memb_name) if (NULL == (mName = (char **) HDcalloc(H5FD_MEM_NTYPES, sizeof(*mName)))) - H5_JNI_FATAL_ERROR(ENVONLY, "H5Pget_fapl_multi: memory allocation failed"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Pget_fapl_multi: memory allocation failed"); if ((status = H5Pget_fapl_multi((hid_t)tid, (H5FD_mem_t *)themapArray, (hid_t *)thefaplArray, mName, (haddr_t *)theaddrArray, (hbool_t *)&relax)) < 0) @@ -761,7 +761,7 @@ Java_hdf_hdf5lib_H5_H5Pget_1fapl_1multi if (mName[i]) { if (NULL == (str = ENVPTR->NewStringUTF(ENVONLY, mName[i]))) { CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); - H5_JNI_FATAL_ERROR(ENVONLY, "H5Pget_fapl_multi: out of memory - unable to construct string from UTF characters"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Pget_fapl_multi: out of memory - unable to construct string from UTF characters"); } ENVPTR->SetObjectArrayElement(ENVONLY, memb_name, (jsize) i, (jobject)str); @@ -823,7 +823,7 @@ Java_hdf_hdf5lib_H5_H5Pget_1fapl_1ros3 if (NULL != fa.aws_region) { if (NULL == (j_aws = ENVPTR->NewStringUTF(ENVONLY, fa.aws_region))) { CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); - H5_JNI_FATAL_ERROR(ENVONLY, "H5Pget_fapl_ros3: out of memory - can't create aws_region string"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Pget_fapl_ros3: out of memory - can't create aws_region string"); } } args[0].l = j_aws; @@ -831,7 +831,7 @@ Java_hdf_hdf5lib_H5_H5Pget_1fapl_1ros3 if (NULL != fa.secret_id) { if (NULL == (j_id = ENVPTR->NewStringUTF(ENVONLY, fa.secret_id))) { CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); - H5_JNI_FATAL_ERROR(ENVONLY, "H5Pget_fapl_ros3: out of memory - can't create secret_id string"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Pget_fapl_ros3: out of memory - can't create secret_id string"); } } args[1].l = j_id; @@ -839,7 +839,7 @@ Java_hdf_hdf5lib_H5_H5Pget_1fapl_1ros3 if (NULL != fa.secret_key) { if (NULL == (j_key = ENVPTR->NewStringUTF(ENVONLY, fa.secret_key))) { CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); - H5_JNI_FATAL_ERROR(ENVONLY, "H5Pget_fapl_ros3: out of memory - can't create secret_key string"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Pget_fapl_ros3: out of memory - can't create secret_key string"); } } args[2].l = j_key; @@ -1688,7 +1688,7 @@ Java_hdf_hdf5lib_H5_H5Pget_1mdc_1config if (NULL != cacheinfo.trace_file_name) { if (NULL == (j_str = ENVPTR->NewStringUTF(ENVONLY, cacheinfo.trace_file_name))) { CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); - H5_JNI_FATAL_ERROR(ENVONLY, "H5Pget_mdc_config: out of memory - unable to construct string from UTF characters"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Pget_mdc_config: out of memory - unable to construct string from UTF characters"); } } @@ -1802,7 +1802,7 @@ Java_hdf_hdf5lib_H5_H5Pget_1mdc_1log_1options location_size++; /* add extra space for the null terminator */ if (NULL == (lname = (char *) HDmalloc(sizeof(char) * location_size))) - H5_JNI_FATAL_ERROR(ENVONLY, "H5Pget_mdc_log_options: memory allocation failed"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Pget_mdc_log_options: memory allocation failed"); if ((status = H5Pget_mdc_log_options((hid_t)fapl_id, &is_enabled, lname, &location_size, &start_on_access)) < 0) H5_LIBRARY_ERROR(ENVONLY); @@ -1810,7 +1810,7 @@ Java_hdf_hdf5lib_H5_H5Pget_1mdc_1log_1options if (NULL == (str = ENVPTR->NewStringUTF(ENVONLY, lname))) { CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); - H5_JNI_FATAL_ERROR(ENVONLY, "H5Pget_mdc_log_options: out of memory - unable to construct string from UTF characters"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Pget_mdc_log_options: out of memory - unable to construct string from UTF characters"); } mdc_log_options_ptr[0] = (jboolean)is_enabled; diff --git a/java/src/jni/h5pImp.c b/java/src/jni/h5pImp.c index 726e08c..9e5b004 100644 --- a/java/src/jni/h5pImp.c +++ b/java/src/jni/h5pImp.c @@ -503,7 +503,7 @@ Java_hdf_hdf5lib_H5_H5Pget_1class_1name if (NULL == (j_str = ENVPTR->NewStringUTF(ENVONLY, c_str))) { CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); - H5_JNI_FATAL_ERROR(ENVONLY, "H5Pget_class_name: out of memory - unable to construct string from UTF characters"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Pget_class_name: out of memory - unable to construct string from UTF characters"); } done: diff --git a/java/src/jni/h5pLAPLImp.c b/java/src/jni/h5pLAPLImp.c index f2cb80a..754bece 100644 --- a/java/src/jni/h5pLAPLImp.c +++ b/java/src/jni/h5pLAPLImp.c @@ -134,7 +134,7 @@ Java_hdf_hdf5lib_H5_H5Pget_1elink_1prefix H5_LIBRARY_ERROR(ENVONLY); if (NULL == (pre = (char *) HDmalloc(sizeof(char) * (size_t) prefix_size + 1))) - H5_JNI_FATAL_ERROR(ENVONLY, "H5Pget_elink_prefix: memory allocation failed"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Pget_elink_prefix: memory allocation failed"); if (H5Pget_elink_prefix((hid_t)lapl_id, (char *)pre, (size_t) prefix_size + 1) < 0) H5_LIBRARY_ERROR(ENVONLY); @@ -142,7 +142,7 @@ Java_hdf_hdf5lib_H5_H5Pget_1elink_1prefix if (NULL == (str = ENVPTR->NewStringUTF(ENVONLY, pre))) { CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); - H5_JNI_FATAL_ERROR(ENVONLY, "H5Pget_elink_prefix: out of memory - unable to construct string from UTF characters"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Pget_elink_prefix: out of memory - unable to construct string from UTF characters"); } ENVPTR->SetObjectArrayElement(ENVONLY, prefix, 0, str); diff --git a/java/src/jni/h5plImp.c b/java/src/jni/h5plImp.c index 90d78fe..b43b532 100644 --- a/java/src/jni/h5plImp.c +++ b/java/src/jni/h5plImp.c @@ -226,7 +226,7 @@ Java_hdf_hdf5lib_H5_H5PLget H5_LIBRARY_ERROR(ENVONLY); if (NULL == (aName = (char *) HDmalloc(sizeof(char) * (size_t)buf_size + 1))) - H5_JNI_FATAL_ERROR(ENVONLY, "H5PLget: failed to allocate plugin name buffer"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5PLget: failed to allocate plugin name buffer"); if ((H5PLget((unsigned) index, aName, (size_t)buf_size + 1)) < 0) H5_LIBRARY_ERROR(ENVONLY); diff --git a/java/src/jni/h5rImp.c b/java/src/jni/h5rImp.c index 21ee658..def27f4 100644 --- a/java/src/jni/h5rImp.c +++ b/java/src/jni/h5rImp.c @@ -51,7 +51,7 @@ Java_hdf_hdf5lib_H5_H5Rcreate_1object PIN_JAVA_STRING(ENVONLY, name, refName, NULL, "H5Rcreate_object: reference name not pinned"); if (NULL == (refBuf = (unsigned char *) HDcalloc((size_t) 1, H5R_REF_BUF_SIZE))) - H5_JNI_FATAL_ERROR(ENVONLY, "H5Rcreate_object: failed to allocate reference buffer"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Rcreate_object: failed to allocate reference buffer"); if ((status = H5Rcreate_object((hid_t)loc_id, refName, (hid_t)aid, (const H5R_ref_t *)refBuf)) < 0) H5_LIBRARY_ERROR(ENVONLY); @@ -94,7 +94,7 @@ Java_hdf_hdf5lib_H5_H5Rcreate_1region PIN_JAVA_STRING(ENVONLY, name, refName, NULL, "H5Rcreate_region: reference name not pinned"); if (NULL == (refBuf = (unsigned char *) HDcalloc((size_t) 1, H5R_REF_BUF_SIZE))) - H5_JNI_FATAL_ERROR(ENVONLY, "H5Rcreate_region: failed to allocate reference buffer"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Rcreate_region: failed to allocate reference buffer"); if ((status = H5Rcreate_region((hid_t)loc_id, refName, space_id, (hid_t)aid, (const H5R_ref_t *)refBuf)) < 0) H5_LIBRARY_ERROR(ENVONLY); @@ -141,7 +141,7 @@ Java_hdf_hdf5lib_H5_H5Rcreate_1attr PIN_JAVA_STRING(ENVONLY, name, refName, NULL, "H5Rcreate_attr: reference name not pinned"); if (NULL == (refBuf = (unsigned char *) HDcalloc((size_t) 1, H5R_REF_BUF_SIZE))) - H5_JNI_FATAL_ERROR(ENVONLY, "H5Rcreate_attr: failed to allocate reference buffer"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Rcreate_attr: failed to allocate reference buffer"); if ((status = H5Rcreate_attr((hid_t)loc_id, refName, attrName, (hid_t)aid, (const H5R_ref_t *)refBuf)) < 0) H5_LIBRARY_ERROR(ENVONLY); @@ -315,7 +315,7 @@ Java_hdf_hdf5lib_H5_H5Rcopy PIN_BYTE_ARRAY(ENVONLY, src_ref, src_refBuf, &isCopy, "H5Rcopy: src reference buffer not pinned"); if (NULL == (dst_refBuf = (unsigned char *) HDcalloc((size_t) 1, H5R_REF_BUF_SIZE))) - H5_JNI_FATAL_ERROR(ENVONLY, "H5Rcreate_attr: failed to allocate dst reference buffer"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Rcreate_attr: failed to allocate dst reference buffer"); if ((status = H5Rcopy((const H5R_ref_t *)src_refBuf, (const H5R_ref_t *)dst_refBuf)) < 0) H5_LIBRARY_ERROR(ENVONLY); @@ -505,7 +505,7 @@ Java_hdf_hdf5lib_H5_H5Rget_1file_1name H5_LIBRARY_ERROR(ENVONLY); if (NULL == (namePtr = (char *) HDmalloc(sizeof(char) * (size_t)buf_size + 1))) - H5_JNI_FATAL_ERROR(ENVONLY, "H5Rget_file_name: malloc failed"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Rget_file_name: malloc failed"); if ((check_size = H5Rget_file_name((const H5R_ref_t *)refBuf, namePtr, (size_t)buf_size + 1)) < 0) H5_LIBRARY_ERROR(ENVONLY); @@ -551,7 +551,7 @@ Java_hdf_hdf5lib_H5_H5Rget_1obj_1name H5_LIBRARY_ERROR(ENVONLY); if (NULL == (namePtr = (char *) HDmalloc(sizeof(char) * (size_t)buf_size + 1))) - H5_JNI_FATAL_ERROR(ENVONLY, "H5Rget_obj_name: malloc failed"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Rget_obj_name: malloc failed"); if ((check_size = H5Rget_obj_name((const H5R_ref_t *)refBuf, (hid_t)rapl_id, namePtr, (size_t)buf_size + 1)) < 0) H5_LIBRARY_ERROR(ENVONLY); @@ -597,7 +597,7 @@ Java_hdf_hdf5lib_H5_H5Rget_1attr_1name H5_LIBRARY_ERROR(ENVONLY); if (NULL == (namePtr = (char *) HDmalloc(sizeof(char) * (size_t)buf_size + 1))) - H5_JNI_FATAL_ERROR(ENVONLY, "H5Rget_attr_name: malloc failed"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Rget_attr_name: malloc failed"); if ((check_size = H5Rget_attr_name((const H5R_ref_t *)refBuf, namePtr, (size_t)buf_size + 1)) < 0) H5_LIBRARY_ERROR(ENVONLY); @@ -645,9 +645,9 @@ Java_hdf_hdf5lib_H5_H5Rcreate } if ((H5R_OBJECT == ref_type) && (refBufLen != H5R_OBJ_REF_BUF_SIZE)) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Rcreate: reference input array length != H5R_OBJ_REF_BUF_SIZE") + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Rcreate: reference input array length != H5R_OBJ_REF_BUF_SIZE"); else if ((H5R_DATASET_REGION == ref_type) && (refBufLen != H5R_DSET_REG_REF_BUF_SIZE)) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Rcreate: region reference input array length != H5R_DSET_REG_REF_BUF_SIZE") + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Rcreate: region reference input array length != H5R_DSET_REG_REF_BUF_SIZE"); else if ((H5R_OBJECT != ref_type) && (H5R_DATASET_REGION != ref_type)) H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Rcreate: unknown reference type"); @@ -692,9 +692,9 @@ Java_hdf_hdf5lib_H5__1H5Rdereference } if ((H5R_OBJECT == ref_type) && (refBufLen != H5R_OBJ_REF_BUF_SIZE)) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Rdereference: reference input array length != H5R_OBJ_REF_BUF_SIZE") + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Rdereference: reference input array length != H5R_OBJ_REF_BUF_SIZE"); else if ((H5R_DATASET_REGION == ref_type) && (refBufLen != H5R_DSET_REG_REF_BUF_SIZE)) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Rdereference: region reference input array length != H5R_DSET_REG_REF_BUF_SIZE") + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Rdereference: region reference input array length != H5R_DSET_REG_REF_BUF_SIZE"); else if ((H5R_OBJECT != ref_type) && (H5R_DATASET_REGION != ref_type)) H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Rdereference: unknown reference type"); @@ -854,16 +854,16 @@ Java_hdf_hdf5lib_H5_H5Rget_1name } if ((H5R_OBJECT == ref_type) && (refBufLen != H5R_OBJ_REF_BUF_SIZE)) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Rget_name: reference input array length != H5R_OBJ_REF_BUF_SIZE") + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Rget_name: reference input array length != H5R_OBJ_REF_BUF_SIZE"); else if ((H5R_DATASET_REGION == ref_type) && (refBufLen != H5R_DSET_REG_REF_BUF_SIZE)) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Rget_name: region reference input array length != H5R_DSET_REG_REF_BUF_SIZE") + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Rget_name: region reference input array length != H5R_DSET_REG_REF_BUF_SIZE"); else if ((H5R_OBJECT != ref_type) && (H5R_DATASET_REGION != ref_type)) H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Rget_name: unknown reference type"); PIN_BYTE_ARRAY(ENVONLY, ref, refBuf, &isCopy, "H5Rget_name: reference buffer not pinned"); if (NULL == (aName = (char *) HDmalloc(sizeof(char) * (size_t)size + 1))) - H5_JNI_FATAL_ERROR(ENVONLY, "H5Rget_name: failed to allocate referenced object name buffer"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Rget_name: failed to allocate referenced object name buffer"); if ((ret_val = (jlong)H5Rget_name((hid_t)loc_id, (H5R_type_t)ref_type, refBuf, aName, (size_t)size + 1)) < 0) H5_LIBRARY_ERROR(ENVONLY); diff --git a/java/src/jni/h5sImp.c b/java/src/jni/h5sImp.c index c703e90..74866ed 100644 --- a/java/src/jni/h5sImp.c +++ b/java/src/jni/h5sImp.c @@ -98,7 +98,7 @@ Java_hdf_hdf5lib_H5__1H5Screate_1simple PIN_LONG_ARRAY(ENVONLY, dims, dimsP, &isCopy, "H5Screate_simple: dims not pinned"); if (NULL == (sa = lp = (hsize_t *) HDmalloc((size_t)rank * sizeof(hsize_t)))) - H5_JNI_FATAL_ERROR(ENVONLY, "H5Screate_simple: failed to allocate dims buffer") + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Screate_simple: failed to allocate dims buffer"); jlp = (jlong *) dimsP; for (i = 0; i < rank; i++) { @@ -115,7 +115,7 @@ Java_hdf_hdf5lib_H5__1H5Screate_1simple PIN_LONG_ARRAY(ENVONLY, maxdims, maxdimsP, &isCopy, "H5Screate_simple: maxdims not pinned"); if (NULL == (msa = lp = (hsize_t *) HDmalloc((size_t)rank * sizeof(hsize_t)))) - H5_JNI_FATAL_ERROR(ENVONLY, "H5Screate_simple: failed to allocate maxdims buffer") + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Screate_simple: failed to allocate maxdims buffer"); jlp = (jlong *) maxdimsP; for (i = 0; i < mrank; i++) { @@ -194,7 +194,7 @@ Java_hdf_hdf5lib_H5_H5Sselect_1elements PIN_LONG_ARRAY(ENVONLY, coords, P, &isCopy, "H5Sselect_elements: coords not pinned"); if (NULL == (sa = (hssize_t *) HDmalloc( (size_t)num_elemn * 2 * sizeof(hssize_t)))) - H5_JNI_FATAL_ERROR(ENVONLY, "H5Sselect_elements: failed to allocate coordinate buffer"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Sselect_elements: failed to allocate coordinate buffer"); for (i = 0; i < (num_elemn * 2); i++) { sa[i] = P[i]; @@ -247,7 +247,7 @@ Java_hdf_hdf5lib_H5_H5Sselect_1elements nlongs = (int)((size_t)size / sizeof(jlong)); if (NULL == (lp = (hsize_t *) HDmalloc((size_t)nlongs * sizeof(hsize_t)))) - H5_JNI_FATAL_ERROR(ENVONLY, "H5Sselect_elements: failed to allocate coordinate buffer"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Sselect_elements: failed to allocate coordinate buffer"); jlp = (jlong *) P; llp = lp; @@ -444,7 +444,7 @@ Java_hdf_hdf5lib_H5_H5Sget_1simple_1extent_1dims } if (NULL == (sa = (hsize_t *) HDmalloc((size_t)rank * sizeof(hsize_t)))) - H5_JNI_FATAL_ERROR(ENVONLY, "H5Sget_simple_extent_dims: failed to allocate dimension buffer"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Sget_simple_extent_dims: failed to allocate dimension buffer"); } if (NULL == maxdims) { @@ -462,10 +462,10 @@ Java_hdf_hdf5lib_H5_H5Sget_1simple_1extent_1dims if (rank < 0) rank = mrank; else if (mrank != rank) - H5_JNI_FATAL_ERROR(ENVONLY, "H5Sget_simple_extent_dims: maxdims rank not same as dims"); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Sget_simple_extent_dims: maxdims rank not same as dims"); if (NULL == (msa = (hsize_t *) HDmalloc((size_t)rank * sizeof(hsize_t)))) - H5_JNI_FATAL_ERROR(ENVONLY, "H5Sget_simple_extent_dims: failed to allocate maximum dimension buffer"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Sget_simple_extent_dims: failed to allocate maximum dimension buffer"); } if ((status = H5Sget_simple_extent_dims(space_id, (hsize_t *)sa, (hsize_t *)msa)) < 0) @@ -564,7 +564,7 @@ Java_hdf_hdf5lib_H5_H5Sset_1extent_1simple PIN_LONG_ARRAY(ENVONLY, dims, dimsP, &isCopy, "H5Sset_extent_simple: dims not pinned"); if (NULL == (sa = lp = (hsize_t *) HDmalloc((size_t)rank * sizeof(hsize_t)))) - H5_JNI_FATAL_ERROR(ENVONLY, "H5Sset_extent_simple: failed to allocate dimension buffer"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Sset_extent_simple: failed to allocate dimension buffer"); jlp = (jlong *) dimsP; for (i = 0; i < rank; i++) { @@ -581,7 +581,7 @@ Java_hdf_hdf5lib_H5_H5Sset_1extent_1simple PIN_LONG_ARRAY(ENVONLY, maxdims, maxdimsP, &isCopy, "H5Sset_extent_simple: maxdims not pinned"); if (NULL == (msa = lp = (hsize_t *) HDmalloc((size_t)rank * sizeof(hsize_t)))) - H5_JNI_FATAL_ERROR(ENVONLY, "H5Sset_extent_simple: failed to allocate maximum dimension buffer"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Sset_extent_simple: failed to allocate maximum dimension buffer"); jlp = (jlong *) maxdimsP; for (i = 0; i < rank; i++) { @@ -660,7 +660,7 @@ Java_hdf_hdf5lib_H5_H5Soffset_1simple rank = (size_t) i / sizeof(jlong); if (NULL == (sa = lp = (hssize_t *) HDmalloc((size_t)rank * sizeof(hssize_t)))) - H5_JNI_FATAL_ERROR(ENVONLY, "H5Soffset_simple: failed to allocate offset buffer"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Soffset_simple: failed to allocate offset buffer"); jlp = (jlong *) P; for (i = 0; (size_t) i < rank; i++) { @@ -788,7 +788,7 @@ Java_hdf_hdf5lib_H5_H5Sselect_1hyperslab PIN_LONG_ARRAY(ENVONLY, start, startP, &isCopy, "H5Sselect_hyperslab: start not pinned"); if (NULL == (strt = lp = (hsize_t *) HDmalloc((size_t)start_rank * sizeof(hsize_t)))) - H5_JNI_FATAL_ERROR(ENVONLY, "H5Sselect_hyperslab: failed to allocate start buffer"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Sselect_hyperslab: failed to allocate start buffer"); jlp = (jlong *) startP; for (i = 0; i < start_rank; i++) { @@ -800,7 +800,7 @@ Java_hdf_hdf5lib_H5_H5Sselect_1hyperslab PIN_LONG_ARRAY(ENVONLY, count, countP, &isCopy, "H5Sselect_hyperslab: count not pinned"); if (NULL == (cnt = lp = (hsize_t *) HDmalloc((size_t)count_rank * sizeof(hsize_t)))) - H5_JNI_FATAL_ERROR(ENVONLY, "H5Sselect_hyperslab: failed to allocate count buffer"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Sselect_hyperslab: failed to allocate count buffer"); jlp = (jlong *) countP; for (i = 0; i < count_rank; i++) { @@ -825,7 +825,7 @@ Java_hdf_hdf5lib_H5_H5Sselect_1hyperslab PIN_LONG_ARRAY(ENVONLY, stride, strideP, &isCopy, "H5Sselect_hyperslab: stride not pinned"); if (NULL == (strd = lp = (hsize_t *) HDmalloc((size_t)stride_rank * sizeof(hsize_t)))) - H5_JNI_FATAL_ERROR(ENVONLY, "H5Sselect_hyperslab: failed to allocate stride buffer"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Sselect_hyperslab: failed to allocate stride buffer"); jlp = (jlong *) strideP; for (i = 0; i < stride_rank; i++) { @@ -851,7 +851,7 @@ Java_hdf_hdf5lib_H5_H5Sselect_1hyperslab PIN_LONG_ARRAY(ENVONLY, block, blockP, &isCopy, "H5Sselect_hyperslab: block not pinned"); if (NULL == (blk = lp = (hsize_t *) HDmalloc((size_t)block_rank * sizeof(hsize_t)))) - H5_JNI_FATAL_ERROR(ENVONLY, "H5Sselect_hyperslab: failed to allocate block buffer"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Sselect_hyperslab: failed to allocate block buffer"); jlp = (jlong *) blockP; for (i = 0; i < block_rank; i++) { @@ -988,7 +988,7 @@ Java_hdf_hdf5lib_H5_H5Sget_1select_1hyper_1blocklist buf_size = (size_t) numblocks * (size_t) 2 * (size_t) rank * sizeof(hsize_t); if (NULL == (ba = (hsize_t *) HDmalloc(buf_size))) - H5_JNI_FATAL_ERROR(ENVONLY, "H5Sget_select_hyper_blocklist: failed to allocate block list buffer"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Sget_select_hyper_blocklist: failed to allocate block list buffer"); if ((status = H5Sget_select_hyper_blocklist((hid_t)spaceid, (hsize_t) startblock, (hsize_t) numblocks, (hsize_t *)ba)) < 0) H5_LIBRARY_ERROR(ENVONLY); @@ -1044,7 +1044,7 @@ Java_hdf_hdf5lib_H5_H5Sget_1select_1elem_1pointlist PIN_LONG_ARRAY(ENVONLY, buf, bufP, &isCopy, "H5Sget_select_elem_pointlist: buffer not pinned"); if (NULL == (ba = (hsize_t *) HDmalloc(((size_t)numpoints * (size_t)rank) * sizeof(hsize_t)))) - H5_JNI_FATAL_ERROR(ENVONLY, "H5Sget_select_elem_pointlist: failed to allocate point list buffer"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Sget_select_elem_pointlist: failed to allocate point list buffer"); if ((status = H5Sget_select_elem_pointlist((hid_t)spaceid, (hsize_t)startpoint, (hsize_t)numpoints, (hsize_t *)ba)) < 0) H5_LIBRARY_ERROR(ENVONLY); @@ -1094,12 +1094,12 @@ Java_hdf_hdf5lib_H5_H5Sget_1select_1bounds } if (NULL == (strt = (hsize_t *) HDmalloc((size_t)rank * sizeof(hsize_t)))) - H5_JNI_FATAL_ERROR(ENVONLY, "H5Sget_select_bounds: failed to allocate start buffer"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Sget_select_bounds: failed to allocate start buffer"); PIN_LONG_ARRAY(ENVONLY, end, endP, &isCopy, "H5Sget_select_bounds: end not pinned"); if (NULL == (en = (hsize_t *) HDmalloc((size_t)rank * sizeof(hsize_t)))) - H5_JNI_FATAL_ERROR(ENVONLY, "H5Sget_select_bounds: failed to allocate end buffer"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Sget_select_bounds: failed to allocate end buffer"); if ((status = H5Sget_select_bounds((hid_t) spaceid, (hsize_t *) strt, (hsize_t *) en)) < 0) H5_LIBRARY_ERROR(ENVONLY); @@ -1148,7 +1148,7 @@ Java_hdf_hdf5lib_H5_H5Sencode H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Sencode: buf_size = 0"); if (NULL == (bufPtr = (unsigned char *) HDcalloc((size_t) 1, buf_size))) - H5_JNI_FATAL_ERROR(ENVONLY, "H5Sencode: failed to allocate encoding buffer"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Sencode: failed to allocate encoding buffer"); if ((status = H5Sencode2((hid_t) obj_id, bufPtr, &buf_size, H5P_DEFAULT)) < 0) H5_LIBRARY_ERROR(ENVONLY); @@ -1258,7 +1258,7 @@ Java_hdf_hdf5lib_H5_H5Sget_1regular_1hyperslab PIN_LONG_ARRAY(ENVONLY, start, startP, &isCopy, "H5Sget_regular_hyperslab: start not pinned"); if (NULL == (strt = (hsize_t *) HDmalloc((size_t)start_rank * sizeof(hsize_t)))) - H5_JNI_FATAL_ERROR(ENVONLY, "H5Sget_regular_hyperslab: failed to allocate start buffer"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Sget_regular_hyperslab: failed to allocate start buffer"); } if (NULL == stride) { @@ -1277,7 +1277,7 @@ Java_hdf_hdf5lib_H5_H5Sget_1regular_1hyperslab PIN_LONG_ARRAY(ENVONLY, stride, strideP, &isCopy, "H5Sget_regular_hyperslab: stride not pinned"); if (NULL == (strd = (hsize_t *) HDmalloc((size_t)stride_rank * sizeof(hsize_t)))) - H5_JNI_FATAL_ERROR(ENVONLY, "H5Sget_regular_hyperslab: failed to allocate stride buffer"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Sget_regular_hyperslab: failed to allocate stride buffer"); } if (NULL == count) { @@ -1296,7 +1296,7 @@ Java_hdf_hdf5lib_H5_H5Sget_1regular_1hyperslab PIN_LONG_ARRAY(ENVONLY, count, countP, &isCopy, "H5Sget_regular_hyperslab: count not pinned"); if (NULL == (cnt = (hsize_t *) HDmalloc((size_t)count_rank * sizeof(hsize_t)))) - H5_JNI_FATAL_ERROR(ENVONLY, "H5Sget_regular_hyperslab: failed to allocate count buffer"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Sget_regular_hyperslab: failed to allocate count buffer"); } if (NULL == block) { @@ -1315,7 +1315,7 @@ Java_hdf_hdf5lib_H5_H5Sget_1regular_1hyperslab PIN_LONG_ARRAY(ENVONLY, block, blockP, &isCopy, "H5Sget_regular_hyperslab: block not pinned"); if (NULL == (blk = (hsize_t *) HDmalloc((size_t)block_rank * sizeof(hsize_t)))) - H5_JNI_FATAL_ERROR(ENVONLY, "H5Sget_regular_hyperslab: failed to allocate block buffer"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Sget_regular_hyperslab: failed to allocate block buffer"); } if ((status = H5Sget_regular_hyperslab(space_id, (hsize_t *) strt, (hsize_t *) strd, (hsize_t *) cnt, (hsize_t *) blk)) < 0) diff --git a/java/src/jni/h5tImp.c b/java/src/jni/h5tImp.c index 1adff3c..1cbf1a5 100644 --- a/java/src/jni/h5tImp.c +++ b/java/src/jni/h5tImp.c @@ -1239,7 +1239,7 @@ Java_hdf_hdf5lib_H5_H5Tenum_1nameof_1int H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Tenum_nameof_int: name size < 0"); if (NULL == (nameP = (char *) HDmalloc(sizeof(char) * (size_t)size))) - H5_JNI_FATAL_ERROR(ENVONLY, "H5Tenum_nameof_int: failed to allocate name buffer"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Tenum_nameof_int: failed to allocate name buffer"); PIN_INT_ARRAY(ENVONLY, value, intP, &isCopy, "H5Tenum_nameof_int: value not pinned"); @@ -1285,7 +1285,7 @@ Java_hdf_hdf5lib_H5_H5Tenum_1nameof H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Tenum_nameof: value is NULL"); if (NULL == (nameP = (char *) HDmalloc(sizeof(char) * (size_t)size))) - H5_JNI_FATAL_ERROR(ENVONLY, "H5Tenum_nameof: failed to allocate name buffer"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Tenum_nameof: failed to allocate name buffer"); PIN_BYTE_ARRAY(ENVONLY, value, byteP, &isCopy, "H5Tenum_nameof: value not pinned"); @@ -1485,7 +1485,7 @@ Java_hdf_hdf5lib_H5_H5Tget_1array_1dims } if (NULL == (cdims = (hsize_t *) HDmalloc((size_t)dlen * sizeof(hsize_t)))) - H5_JNI_FATAL_ERROR(ENVONLY, "H5Tget_array_dims: failed to allocate dimension buffer"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Tget_array_dims: failed to allocate dimension buffer"); if ((ndims = H5Tget_array_dims2((hid_t)type_id, cdims)) < 0) H5_LIBRARY_ERROR(ENVONLY); @@ -1626,10 +1626,10 @@ Java_hdf_hdf5lib_H5__1H5Tarray_1create2 } if (dlen != rank) - H5_JNI_FATAL_ERROR(ENVONLY, "H5Tarray_create: dimension array length != array rank"); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Tarray_create: dimension array length != array rank"); if (NULL == (cdims = (hsize_t *) HDmalloc((size_t)dlen * sizeof(hsize_t)))) - H5_JNI_FATAL_ERROR(ENVONLY, "H5Tarray_create: failed to allocate dimension buffer"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Tarray_create: failed to allocate dimension buffer"); for (i = 0; i < (size_t) dlen; i++) { cdims[i] = (hsize_t)dimsP[i]; @@ -1676,7 +1676,7 @@ Java_hdf_hdf5lib_H5_H5Tget_1array_1dims2 } if (NULL == (cdims = (hsize_t *) HDmalloc((size_t)dlen * sizeof(hsize_t)))) - H5_JNI_FATAL_ERROR(ENVONLY, "H5Tarray_get_dims2: failed to allocate dimension buffer"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Tarray_get_dims2: failed to allocate dimension buffer"); if ((ndims = H5Tget_array_dims2((hid_t)type_id, (hsize_t*)cdims)) < 0) H5_LIBRARY_ERROR(ENVONLY); diff --git a/java/src/jni/h5util.c b/java/src/jni/h5util.c index 5c82edc..55f7571 100644 --- a/java/src/jni/h5util.c +++ b/java/src/jni/h5util.c @@ -515,7 +515,7 @@ h5str_convert total_elmts *= dims[i]; if (NULL == (cptr = (char *) HDcalloc((size_t)total_elmts, baseTypeSize))) - H5_JNI_FATAL_ERROR(ENVONLY, "h5str_convert: failed to allocate array buffer"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "h5str_convert: failed to allocate array buffer"); for (i = 0; i < total_elmts; i++) { if (!(h5str_convert(ENVONLY, &this_str, container, mtid, out_buf, i * baseTypeSize))) { @@ -556,7 +556,7 @@ h5str_convert H5_LIBRARY_ERROR(ENVONLY); if (NULL == (vl_buf->p = HDmalloc(baseTypeSize))) - H5_JNI_FATAL_ERROR(ENVONLY, "h5str_convert: failed to allocate vlen buffer"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "h5str_convert: failed to allocate vlen buffer"); vl_buf->len = 1; /* Skip whitespace and vlen indicators */ @@ -570,7 +570,7 @@ h5str_convert char *tmp_realloc; if (NULL == (tmp_realloc = (char *) HDrealloc(vl_buf->p, vl_buf->len * 2 * baseTypeSize))) - H5_JNI_FATAL_ERROR(ENVONLY, "h5str_convert: failed to reallocate vlen buffer"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "h5str_convert: failed to reallocate vlen buffer"); vl_buf->len *= 2; vl_buf->p = tmp_realloc; } @@ -733,9 +733,9 @@ h5str_sprintf /* Build default formats for long long types */ if (!fmt_llong[0]) { if (HDsnprintf(fmt_llong, sizeof(fmt_llong), "%%%sd", H5_PRINTF_LL_WIDTH) < 0) - H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: sprintf failure"); + H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: HDsnprintf failure"); if (HDsnprintf(fmt_ullong, sizeof(fmt_ullong), "%%%su", H5_PRINTF_LL_WIDTH) < 0) - H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: sprintf failure"); + H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: HDsnprintf failure"); } /* end if */ switch (tclass) { @@ -749,7 +749,7 @@ h5str_sprintf HDmemcpy(&tmp_float, cptr, sizeof(float)); if (NULL == (this_str = (char *) HDmalloc(25))) - H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: failed to allocate string buffer"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "h5str_sprintf: failed to allocate string buffer"); if (HDsprintf(this_str, "%g", tmp_float) < 0) H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: HDsprintf failure"); @@ -764,7 +764,7 @@ h5str_sprintf HDmemcpy(&tmp_double, cptr, sizeof(double)); if (NULL == (this_str = (char *) HDmalloc(25))) - H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: failed to allocate string buffer"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "h5str_sprintf: failed to allocate string buffer"); if (HDsprintf(this_str, "%g", tmp_double) < 0) H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: HDsprintf failure"); @@ -779,7 +779,7 @@ h5str_sprintf HDmemcpy(&tmp_ldouble, cptr, sizeof(long double)); if (NULL == (this_str = (char *) HDmalloc(27))) - H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: failed to allocate string buffer"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "h5str_sprintf: failed to allocate string buffer"); if (HDsprintf(this_str, "%Lf", tmp_ldouble) < 0) H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: HDsprintf failure"); @@ -819,13 +819,13 @@ h5str_sprintf /* Check for NULL pointer for string */ if (!tmp_str) { if (NULL == (this_str = (char *) HDmalloc(5))) - H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: failed to allocate string buffer"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "h5str_sprintf: failed to allocate string buffer"); HDstrncpy(this_str, "NULL", 5); } else { if (typeSize > 0) { if (NULL == (this_str = (char *) HDmalloc(typeSize + 1))) - H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: failed to allocate string buffer"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "h5str_sprintf: failed to allocate string buffer"); HDstrncpy(this_str, tmp_str, typeSize); this_str[typeSize] = '\0'; @@ -851,7 +851,7 @@ h5str_sprintf HDmemcpy(&tmp_uchar, cptr, sizeof(unsigned char)); if (NULL == (this_str = (char *) HDmalloc(7))) - H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: failed to allocate string buffer"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "h5str_sprintf: failed to allocate string buffer"); if (HDsprintf(this_str, "%hhu", tmp_uchar) < 0) H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: HDsprintf failure"); @@ -860,7 +860,7 @@ h5str_sprintf HDmemcpy(&tmp_char, cptr, sizeof(char)); if (NULL == (this_str = (char *) HDmalloc(7))) - H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: failed to allocate string buffer"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "h5str_sprintf: failed to allocate string buffer"); if (HDsprintf(this_str, "%hhd", tmp_char) < 0) H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: HDsprintf failure"); @@ -878,7 +878,7 @@ h5str_sprintf HDmemcpy(&tmp_ushort, cptr, sizeof(unsigned short)); if (NULL == (this_str = (char *) HDmalloc(9))) - H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: failed to allocate string buffer"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "h5str_sprintf: failed to allocate string buffer"); if (HDsprintf(this_str, "%hu", tmp_ushort) < 0) H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: HDsprintf failure"); @@ -887,7 +887,7 @@ h5str_sprintf HDmemcpy(&tmp_short, cptr, sizeof(short)); if (NULL == (this_str = (char *) HDmalloc(9))) - H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: failed to allocate string buffer"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "h5str_sprintf: failed to allocate string buffer"); if (HDsprintf(this_str, "%hd", tmp_short) < 0) H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: HDsprintf failure"); @@ -905,7 +905,7 @@ h5str_sprintf HDmemcpy(&tmp_uint, cptr, sizeof(unsigned int)); if (NULL == (this_str = (char *) HDmalloc(14))) - H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: failed to allocate string buffer"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "h5str_sprintf: failed to allocate string buffer"); if (HDsprintf(this_str, "%u", tmp_uint) < 0) H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: HDsprintf failure"); @@ -914,7 +914,7 @@ h5str_sprintf HDmemcpy(&tmp_int, cptr, sizeof(int)); if (NULL == (this_str = (char *) HDmalloc(14))) - H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: failed to allocate string buffer"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "h5str_sprintf: failed to allocate string buffer"); if (HDsprintf(this_str, "%d", tmp_int) < 0) H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: HDsprintf failure"); @@ -932,7 +932,7 @@ h5str_sprintf HDmemcpy(&tmp_ulong, cptr, sizeof(unsigned long)); if (NULL == (this_str = (char *) HDmalloc(23))) - H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: failed to allocate string buffer"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "h5str_sprintf: failed to allocate string buffer"); if (HDsprintf(this_str, "%lu", tmp_ulong) < 0) H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: HDsprintf failure"); @@ -941,7 +941,7 @@ h5str_sprintf HDmemcpy(&tmp_long, cptr, sizeof(long)); if (NULL == (this_str = (char *) HDmalloc(23))) - H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: failed to allocate string buffer"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "h5str_sprintf: failed to allocate string buffer"); if (HDsprintf(this_str, "%ld", tmp_long) < 0) H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: HDsprintf failure"); @@ -960,7 +960,7 @@ h5str_sprintf HDmemcpy(&tmp_ullong, cptr, sizeof(unsigned long long)); if (NULL == (this_str = (char *) HDmalloc(25))) - H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: failed to allocate string buffer"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "h5str_sprintf: failed to allocate string buffer"); if (HDsprintf(this_str, fmt_ullong, tmp_ullong) < 0) H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: HDsprintf failure"); @@ -969,7 +969,7 @@ h5str_sprintf HDmemcpy(&tmp_llong, cptr, sizeof(long long)); if (NULL == (this_str = (char *) HDmalloc(25))) - H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: failed to allocate string buffer"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "h5str_sprintf: failed to allocate string buffer"); if (HDsprintf(this_str, fmt_llong, tmp_llong) < 0) H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: HDsprintf failure"); @@ -1034,7 +1034,7 @@ h5str_sprintf size_t i; if (NULL == (this_str = (char *) HDmalloc(4 * (typeSize + 1)))) - H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: failed to allocate string buffer"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "h5str_sprintf: failed to allocate string buffer"); if (1 == typeSize) { if (HDsprintf(this_str, "%#02x", ucptr[0]) < 0) @@ -1069,10 +1069,10 @@ h5str_sprintf case H5R_OBJECT1: { /* Object references -- show the type and OID of the referenced object. */ - H5O_info_t oi; + H5O_info2_t oi; if((obj = H5Ropen_object(ref_vp, H5P_DEFAULT, H5P_DEFAULT)) >= 0) { - H5Oget_info2(obj, &oi, H5O_INFO_BASIC); + H5Oget_info3(obj, &oi, H5O_INFO_BASIC); if(H5Oclose(obj) < 0) CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); } @@ -1080,7 +1080,7 @@ h5str_sprintf CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); if (NULL == (this_str = (char *) HDmalloc(14))) - H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: failed to allocate string buffer"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "h5str_sprintf: failed to allocate string buffer"); if (HDsprintf(this_str, "%u-", (unsigned) oi.type) < 0) H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: HDsprintf failure"); if (!h5str_append(out_str, this_str)) @@ -1114,10 +1114,19 @@ h5str_sprintf h5str_sprint_reference(ENVONLY, out_str, container, ref_vp); /* Print OID */ - if (NULL == (this_str = (char *) HDmalloc(64))) - H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: failed to allocate string buffer"); - if (HDsprintf(this_str, "%lu:"H5_PRINTF_HADDR_FMT" ", oi.fileno, oi.addr) < 0) - H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: HDsprintf failure"); + { + char *token_str; + + H5Otoken_to_str(tid, &oi.token, &token_str); + + if (NULL == (this_str = (char *) HDmalloc(64 + strlen(token_str) + 1))) + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "h5str_sprintf: failed to allocate string buffer"); + if (HDsprintf(this_str, "%lu:%s", oi.fileno, token_str) < 0) + H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: HDsprintf failure"); + + H5free_memory(token_str); + } + } break; @@ -1273,7 +1282,7 @@ h5str_sprintf /* All other types get printed as hexadecimal */ if (NULL == (this_str = (char *) HDmalloc(4 * (typeSize + 1)))) - H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: failed to allocate string buffer"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "h5str_sprintf: failed to allocate string buffer"); if (1 == typeSize) { if (HDsprintf(this_str, "%#02x", ucptr[0]) < 0) @@ -1346,7 +1355,7 @@ h5str_print_region_data_blocks /* Allocate space for the dimension array */ if (NULL == (dims1 = (hsize_t *) HDmalloc(sizeof(hsize_t) * (size_t)ndims))) - H5_JNI_FATAL_ERROR(ENVONLY, "h5str_print_region_data_blocks: failed to allocate dimension array buffer"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "h5str_print_region_data_blocks: failed to allocate dimension array buffer"); /* Find the dimensions of each data space from the block coordinates */ for (jndx = 0, numelem = 1; jndx < (size_t) ndims; jndx++) { @@ -1362,15 +1371,15 @@ h5str_print_region_data_blocks H5_LIBRARY_ERROR(ENVONLY); if (NULL == (region_buf = HDmalloc(type_size * (size_t)numelem))) - H5_JNI_FATAL_ERROR(ENVONLY, "h5str_print_region_data_blocks: failed to allocate region buffer"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "h5str_print_region_data_blocks: failed to allocate region buffer"); /* Select (x , x , ..., x ) x (y , y , ..., y ) hyperslab for reading memory dataset */ /* 1 2 n 1 2 n */ if (NULL == (start = (hsize_t *) HDmalloc(sizeof(hsize_t) * (size_t)ndims))) - H5_JNI_FATAL_ERROR(ENVONLY, "h5str_print_region_data_blocks: failed to allocate hyperslab start buffer"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "h5str_print_region_data_blocks: failed to allocate hyperslab start buffer"); if (NULL == (count = (hsize_t *) HDmalloc(sizeof(hsize_t) * (size_t)ndims))) - H5_JNI_FATAL_ERROR(ENVONLY, "h5str_print_region_data_blocks: failed to allocate hyperslab count buffer"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "h5str_print_region_data_blocks: failed to allocate hyperslab count buffer"); for (blkndx = 0; blkndx < (hsize_t) nblocks; blkndx++) { for (indx = 0; indx < (unsigned) ndims; indx++) { @@ -1445,7 +1454,7 @@ h5str_dump_region_blocks_data alloc_size = (hsize_t)nblocks * (hsize_t)ndims * 2 * (hsize_t)sizeof(ptdata[0]); if (alloc_size == (hsize_t)((size_t) alloc_size)) { if (NULL == (ptdata = (hsize_t *) HDmalloc((size_t) alloc_size))) - H5_JNI_FATAL_ERROR(ENVONLY, "h5str_dump_region_blocks_data: failed to allocate region block buffer"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "h5str_dump_region_blocks_data: failed to allocate region block buffer"); if (H5Sget_select_hyper_blocklist(region, (hsize_t) 0, (hsize_t) nblocks, ptdata) < 0) H5_LIBRARY_ERROR(ENVONLY); @@ -1505,7 +1514,7 @@ h5str_dump_region_blocks int i; if (NULL == (ptdata = (hsize_t *) HDmalloc((size_t) alloc_size))) - H5_JNI_FATAL_ERROR(ENVONLY, "h5str_dump_region_blocks: failed to allocate region block buffer"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "h5str_dump_region_blocks: failed to allocate region block buffer"); if (H5Sget_select_hyper_blocklist(region, (hsize_t) 0, (hsize_t) nblocks, ptdata) < 0) H5_LIBRARY_ERROR(ENVONLY); @@ -1590,7 +1599,7 @@ h5str_print_region_data_points /* Allocate space for the dimension array */ if (NULL == (dims1 = (hsize_t *) HDmalloc(sizeof(hsize_t) * (size_t)ndims))) - H5_JNI_FATAL_ERROR(ENVONLY, "h5str_print_region_data_points: failed to allocate dimension array buffer"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "h5str_print_region_data_points: failed to allocate dimension array buffer"); dims1[0] = (hsize_t)npoints; @@ -1602,7 +1611,7 @@ h5str_print_region_data_points H5_LIBRARY_ERROR(ENVONLY); if (NULL == (region_buf = HDmalloc(type_size * (size_t)npoints))) - H5_JNI_FATAL_ERROR(ENVONLY, "h5str_print_region_data_points: failed to allocate region buffer"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "h5str_print_region_data_points: failed to allocate region buffer"); if (H5Dread(region_id, type_id, mem_space, region_space, H5P_DEFAULT, region_buf) < 0) H5_LIBRARY_ERROR(ENVONLY); @@ -1662,7 +1671,7 @@ h5str_dump_region_points_data alloc_size = (hsize_t)npoints * (hsize_t)ndims * (hsize_t)sizeof(ptdata[0]); if (alloc_size == (hsize_t)((size_t) alloc_size)) { if (NULL == (ptdata = (hsize_t *) HDmalloc((size_t) alloc_size))) - H5_JNI_FATAL_ERROR(ENVONLY, "h5str_dump_region_points_data: failed to allocate region point data buffer"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "h5str_dump_region_points_data: failed to allocate region point data buffer"); if (H5Sget_select_elem_pointlist(region, (hsize_t) 0, (hsize_t) npoints, ptdata) < 0) H5_LIBRARY_ERROR(ENVONLY); @@ -1725,7 +1734,7 @@ h5str_dump_region_points alloc_size = (hsize_t)npoints * (hsize_t)ndims * (hsize_t)sizeof(ptdata[0]); if (alloc_size == (hsize_t)((size_t) alloc_size)) { if (NULL == (ptdata = (hsize_t *) HDmalloc((size_t) alloc_size))) - H5_JNI_FATAL_ERROR(ENVONLY, "h5str_dump_region_points: failed to allocate region point buffer"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "h5str_dump_region_points: failed to allocate region point buffer"); if (H5Sget_select_elem_pointlist(region, (hsize_t) 0, (hsize_t) npoints, ptdata) < 0) H5_LIBRARY_ERROR(ENVONLY); @@ -2833,7 +2842,7 @@ h5str_dump_simple_dset if (sm_nbytes > 0) { if (NULL == (sm_buf = (unsigned char *) HDmalloc((size_t)sm_nbytes))) - H5_JNI_FATAL_ERROR(ENVONLY, "h5str_dump_simple_dset: failed to allocate sm_buf"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "h5str_dump_simple_dset: failed to allocate sm_buf"); sm_nelmts = sm_nbytes / p_type_nbytes; @@ -2964,7 +2973,7 @@ h5tools_dump_simple_data h5str_new(&buffer, 32 * size); if (!buffer.s) - H5_JNI_FATAL_ERROR(ENVONLY, "h5tools_dump_simple_data: failed to allocate buffer"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "h5tools_dump_simple_data: failed to allocate buffer"); if (!(bytes_in = h5str_sprintf(ENVONLY, &buffer, container, type, memref, 0, 1))) CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); @@ -3035,7 +3044,7 @@ Java_hdf_hdf5lib_H5_H5AreadComplex } if (NULL == (readBuf = (char *) HDmalloc((size_t)n * size))) - H5_JNI_FATAL_ERROR(ENVONLY, "H5AreadComplex: failed to allocate read buffer"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5AreadComplex: failed to allocate read buffer"); if ((status = H5Aread(attr_id, mem_type_id, readBuf)) < 0) H5_LIBRARY_ERROR(ENVONLY); @@ -3043,7 +3052,7 @@ Java_hdf_hdf5lib_H5_H5AreadComplex h5str_new(&h5str, 4 * size); if (!h5str.s) - H5_JNI_FATAL_ERROR(ENVONLY, "H5AreadComplex: failed to allocate string buffer"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5AreadComplex: failed to allocate string buffer"); for (i = 0; i < (size_t) n; i++) { h5str.s[0] = '\0'; @@ -3104,7 +3113,7 @@ Java_hdf_hdf5lib_H5_H5Acopy total_size = (hsize_t)npoints * (hsize_t)type_size; if (NULL == (buf = (jbyte *) HDmalloc((size_t)total_size * sizeof(jbyte)))) - H5_JNI_FATAL_ERROR(ENVONLY, "H5Acopy: failed to allocate buffer"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Acopy: failed to allocate buffer"); if ((retVal = H5Aread((hid_t)src_id, tid, buf)) < 0) H5_LIBRARY_ERROR(ENVONLY); @@ -3151,7 +3160,7 @@ Java_hdf_hdf5lib_H5_H5Dcopy UNUSED(clss); if (!(total_allocated_size = H5Dget_storage_size((hid_t)src_id))) - return 0; // nothing to write + return 0; /* nothing to write */ if ((sid = H5Dget_space((hid_t)src_id)) < 0) H5_LIBRARY_ERROR(ENVONLY); @@ -3166,7 +3175,7 @@ Java_hdf_hdf5lib_H5_H5Dcopy total_size = (hsize_t)npoints * (hsize_t)type_size; if (NULL == (buf = (jbyte *) HDmalloc((size_t)total_size * sizeof(jbyte)))) - H5_JNI_FATAL_ERROR(ENVONLY, "H5Dcopy: failed to allocate buffer"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Dcopy: failed to allocate buffer"); if ((retVal = H5Dread((hid_t)src_id, tid, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf)) < 0) H5_LIBRARY_ERROR(ENVONLY); @@ -3204,15 +3213,15 @@ done: */ #ifdef __cplusplus - herr_t obj_info_all(hid_t g_id, const char *name, const H5L_info_t *linfo, void *op_data); - herr_t obj_info_max(hid_t g_id, const char *name, const H5L_info_t *linfo, void *op_data); - int H5Gget_obj_info_max(hid_t, char **, int *, int *, unsigned long *, long); - int H5Gget_obj_info_full( hid_t loc_id, char **objname, int *otype, int *ltype, unsigned long *fno, unsigned long *objno, int indexType, int indexOrder); + herr_t obj_info_all(hid_t g_id, const char *name, const H5L_info2_t *linfo, void *op_data); + herr_t obj_info_max(hid_t g_id, const char *name, const H5L_info2_t *linfo, void *op_data); + int H5Gget_obj_info_max(hid_t, char **, int *, int *, H5O_token_t *, long); + int H5Gget_obj_info_full( hid_t loc_id, char **objname, int *otype, int *ltype, unsigned long *fno, H5O_token_t *obj_token, int indexType, int indexOrder); #else - static herr_t obj_info_all(hid_t g_id, const char *name, const H5L_info_t *linfo, void *op_data); - static herr_t obj_info_max(hid_t g_id, const char *name, const H5L_info_t *linfo, void *op_data); - static int H5Gget_obj_info_max(hid_t, char **, int *, int *, unsigned long *, long); - static int H5Gget_obj_info_full( hid_t loc_id, char **objname, int *otype, int *ltype, unsigned long *fno, unsigned long *objno, int indexType, int indexOrder); + static herr_t obj_info_all(hid_t g_id, const char *name, const H5L_info2_t *linfo, void *op_data); + static herr_t obj_info_max(hid_t g_id, const char *name, const H5L_info2_t *linfo, void *op_data); + static int H5Gget_obj_info_max(hid_t, char **, int *, int *, H5O_token_t *, long); + static int H5Gget_obj_info_full( hid_t loc_id, char **objname, int *otype, int *ltype, unsigned long *fno, H5O_token_t *obj_token, int indexType, int indexOrder); #endif typedef struct info_all @@ -3220,7 +3229,7 @@ typedef struct info_all char **objname; int *otype; int *ltype; - unsigned long *objno; + H5O_token_t *obj_token; unsigned long *fno; unsigned long idxnum; int count; @@ -3241,17 +3250,17 @@ JNIEXPORT jint JNICALL Java_hdf_hdf5lib_H5_H5Gget_1obj_1info_1full (JNIEnv *env, jclass clss, jlong loc_id, jstring group_name, jobjectArray objName, jintArray oType, jintArray lType, jlongArray fNo, - jlongArray oRef, jint n, jint indx_type, jint indx_order) + jobjectArray oToken, jint n, jint indx_type, jint indx_order) { - unsigned long *refs = NULL; unsigned long *fnos = NULL; + H5O_token_t *tokens = NULL; const char *gName = NULL; char **oName = NULL; jboolean isCopy; jstring str; + jobject token; jint *otarr = NULL; jint *ltarr = NULL; - jlong *refP = NULL; jlong *fnoP = NULL; hid_t gid = (hid_t)loc_id; int i; @@ -3265,24 +3274,23 @@ Java_hdf_hdf5lib_H5_H5Gget_1obj_1info_1full H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Gget_obj_info_full: oType is NULL"); if (NULL == lType) H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Gget_obj_info_full: lType is NULL"); - if (NULL == oRef) - H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Gget_obj_info_full: oRef is NULL"); + if (NULL == oToken) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Gget_obj_info_full: oToken is NULL"); if (NULL == fNo) H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Gget_obj_info_full: fNo is NULL"); PIN_INT_ARRAY(ENVONLY, oType, otarr, &isCopy, "H5Gget_obj_info_full: oType not pinned"); PIN_INT_ARRAY(ENVONLY, lType, ltarr, &isCopy, "H5Gget_obj_info_full: lType not pinned"); - PIN_LONG_ARRAY(ENVONLY, oRef, refP, &isCopy, "H5Gget_obj_info_full: oRef not pinned"); PIN_LONG_ARRAY(ENVONLY, fNo, fnoP, &isCopy, "H5Gget_obj_info_full: fNo not pinned"); if (NULL == (oName = (char **) HDcalloc((size_t)n, sizeof(*oName)))) - H5_JNI_FATAL_ERROR(ENVONLY, "H5Gget_obj_info_full: failed to allocate buffer for object name"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Gget_obj_info_full: failed to allocate buffer for object name"); - if (NULL == (refs = (unsigned long *) HDcalloc((size_t)n, sizeof(unsigned long)))) - H5_JNI_FATAL_ERROR(ENVONLY, "H5Gget_obj_info_full: failed to allocate buffer for ref. info"); + if (NULL == (tokens = (H5O_token_t *) HDcalloc((size_t)n, sizeof(H5O_token_t)))) + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Gget_obj_info_full: failed to allocate buffer for object tokens"); if (NULL == (fnos = (unsigned long *) HDcalloc((size_t)n, sizeof(unsigned long)))) - H5_JNI_FATAL_ERROR(ENVONLY, "H5Gget_obj_info_full: failed to allocate buffer for file number info"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Gget_obj_info_full: failed to allocate buffer for file number info"); if (group_name) { PIN_JAVA_STRING(ENVONLY, group_name, gName, &isCopy, "H5Gget_obj_info_full: group_name not pinned"); @@ -3291,11 +3299,10 @@ Java_hdf_hdf5lib_H5_H5Gget_1obj_1info_1full H5_LIBRARY_ERROR(ENVONLY); } - if ((ret_val = H5Gget_obj_info_full(gid, oName, (int *)otarr, (int *)ltarr, fnos, refs, indexType, indexOrder)) < 0) + if ((ret_val = H5Gget_obj_info_full(gid, oName, (int *)otarr, (int *)ltarr, fnos, tokens, indexType, indexOrder)) < 0) H5_JNI_FATAL_ERROR(ENVONLY, "H5Gget_obj_info_full: retrieval of object info failed"); for (i = 0; i < n; i++) { - refP[i] = (jlong)refs[i]; fnoP[i] = (jlong)fnos[i]; if (oName[i]) { @@ -3307,6 +3314,15 @@ Java_hdf_hdf5lib_H5_H5Gget_1obj_1info_1full ENVPTR->DeleteLocalRef(ENVONLY, str); } /* end if */ + + /* Create an H5O_token_t object */ + if (NULL == (token = create_H5O_token_t(ENVONLY, &tokens[i], TRUE))) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + ENVPTR->SetObjectArrayElement(ENVONLY, oToken, i, token); + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + ENVPTR->DeleteLocalRef(ENVONLY, token); } done: @@ -3316,14 +3332,12 @@ done: } if (fnos) HDfree(fnos); - if (refs) - HDfree(refs); + if (tokens) + HDfree(tokens); if (oName) h5str_array_free(oName, (size_t)n); if (fnoP) UNPIN_LONG_ARRAY(ENVONLY, fNo, fnoP, (ret_val < 0) ? JNI_ABORT : 0); - if (refP) - UNPIN_LONG_ARRAY(ENVONLY, oRef, refP, (ret_val < 0) ? JNI_ABORT : 0); if (ltarr) UNPIN_INT_ARRAY(ENVONLY, lType, ltarr, (ret_val < 0) ? JNI_ABORT : 0); if (otarr) @@ -3345,17 +3359,17 @@ done: JNIEXPORT jint JNICALL Java_hdf_hdf5lib_H5_H5Gget_1obj_1info_1max (JNIEnv *env, jclass clss, jlong loc_id, jobjectArray objName, - jintArray oType, jintArray lType, jlongArray oRef, jlong maxnum, jint n) + jintArray oType, jintArray lType, jobjectArray oToken, jlong maxnum, jint n) { - unsigned long *refs = NULL; - jboolean isCopy; - jstring str; - jlong *refP = NULL; - char **oName = NULL; - jint *otarr = NULL; - jint *ltarr = NULL; - int i; - herr_t ret_val = FAIL; + H5O_token_t *tokens = NULL; + jboolean isCopy; + jstring str; + jobject token; + char **oName = NULL; + jint *otarr = NULL; + jint *ltarr = NULL; + int i; + herr_t ret_val = FAIL; UNUSED(clss); @@ -3363,25 +3377,22 @@ Java_hdf_hdf5lib_H5_H5Gget_1obj_1info_1max H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Gget_obj_info_max: oType is NULL"); if (NULL == lType) H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Gget_obj_info_max: lType is NULL"); - if (NULL == oRef) - H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Gget_obj_info_max: oRef is NULL"); + if (NULL == oToken) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Gget_obj_info_max: oToken is NULL"); PIN_INT_ARRAY(ENVONLY, oType, otarr, &isCopy, "H5Gget_obj_info_max: oType not pinned"); PIN_INT_ARRAY(ENVONLY, lType, ltarr, &isCopy, "H5Gget_obj_info_max: lType not pinned"); - PIN_LONG_ARRAY(ENVONLY, oRef, refP, &isCopy, "H5Gget_obj_info_max: oRef not pinned"); if (NULL == (oName = (char **) HDcalloc((size_t)n, sizeof(*oName)))) - H5_JNI_FATAL_ERROR(ENVONLY, "H5Gget_obj_info_max: failed to allocate buffer for object name"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Gget_obj_info_max: failed to allocate buffer for object name"); - if (NULL == (refs = (unsigned long *) HDcalloc((size_t)n, sizeof(unsigned long)))) - H5_JNI_FATAL_ERROR(ENVONLY, "H5Gget_obj_info_max: failed to allocate buffer for ref. info"); + if (NULL == (tokens = (H5O_token_t *) HDcalloc((size_t)n, sizeof(H5O_token_t)))) + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Gget_obj_info_max: failed to allocate buffer for object tokens"); - if ((ret_val = H5Gget_obj_info_max((hid_t)loc_id, oName, (int *)otarr, (int *)ltarr, refs, maxnum)) < 0) + if ((ret_val = H5Gget_obj_info_max((hid_t)loc_id, oName, (int *)otarr, (int *)ltarr, tokens, maxnum)) < 0) H5_JNI_FATAL_ERROR(ENVONLY, "H5Gget_obj_info_max: retrieval of object info failed"); for (i = 0; i < n; i++) { - refP[i] = (jlong) refs[i]; - if (oName[i]) { if (NULL == (str = ENVPTR->NewStringUTF(ENVONLY, oName[i]))) CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); @@ -3391,15 +3402,22 @@ Java_hdf_hdf5lib_H5_H5Gget_1obj_1info_1max ENVPTR->DeleteLocalRef(ENVONLY, str); } + + /* Create an H5O_token_t object */ + if (NULL == (token = create_H5O_token_t(ENVONLY, &tokens[i], TRUE))) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + ENVPTR->SetObjectArrayElement(ENVONLY, oToken, i, token); + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + ENVPTR->DeleteLocalRef(ENVONLY, token); } /* end for */ done: - if (refs) - HDfree(refs); + if (tokens) + HDfree(tokens); if (oName) h5str_array_free(oName, (size_t)n); - if (refP) - UNPIN_LONG_ARRAY(ENVONLY, oRef, refP, (ret_val < 0) ? JNI_ABORT : 0); if (ltarr) UNPIN_INT_ARRAY(ENVONLY, lType, ltarr, (ret_val < 0) ? JNI_ABORT : 0); if (otarr) @@ -3410,7 +3428,7 @@ done: int H5Gget_obj_info_full - (hid_t loc_id, char **objname, int *otype, int *ltype, unsigned long *fno, unsigned long *objno, int indexType, int indexOrder) + (hid_t loc_id, char **objname, int *otype, int *ltype, unsigned long *fno, H5O_token_t *obj_token, int indexType, int indexOrder) { info_all_t info; @@ -3419,10 +3437,10 @@ H5Gget_obj_info_full info.ltype = ltype; info.idxnum = 0; info.fno = fno; - info.objno = objno; + info.obj_token = obj_token; info.count = 0; - if (H5Literate(loc_id, (H5_index_t)indexType, (H5_iter_order_t)indexOrder, NULL, obj_info_all, (void *)&info) < 0) { + if (H5Literate2(loc_id, (H5_index_t)indexType, (H5_iter_order_t)indexOrder, NULL, obj_info_all, (void *)&info) < 0) { /* * Reset info stats; most importantly, reset the count. */ @@ -3431,11 +3449,11 @@ H5Gget_obj_info_full info.ltype = ltype; info.idxnum = 0; info.fno = fno; - info.objno = objno; + info.obj_token = obj_token; info.count = 0; /* Iteration failed, try normal alphabetical order */ - if (H5Literate(loc_id, H5_INDEX_NAME, H5_ITER_INC, NULL, obj_info_all, (void *)&info) < 0) + if (H5Literate2(loc_id, H5_INDEX_NAME, H5_ITER_INC, NULL, obj_info_all, (void *)&info) < 0) return -1; } @@ -3444,7 +3462,7 @@ H5Gget_obj_info_full int H5Gget_obj_info_max - (hid_t loc_id, char **objname, int *otype, int *ltype, unsigned long *objno, long maxnum) + (hid_t loc_id, char **objname, int *otype, int *ltype, H5O_token_t *obj_token, long maxnum) { info_all_t info; @@ -3452,10 +3470,10 @@ H5Gget_obj_info_max info.otype = otype; info.ltype = ltype; info.idxnum = (unsigned long)maxnum; - info.objno = objno; + info.obj_token = obj_token; info.count = 0; - if (H5Lvisit(loc_id, H5_INDEX_NAME, H5_ITER_NATIVE, obj_info_max, (void *)&info) < 0) + if (H5Lvisit2(loc_id, H5_INDEX_NAME, H5_ITER_NATIVE, obj_info_max, (void *)&info) < 0) return -1; return info.count; @@ -3463,16 +3481,16 @@ H5Gget_obj_info_max herr_t obj_info_all - (hid_t loc_id, const char *name, const H5L_info_t *info, void *op_data) + (hid_t loc_id, const char *name, const H5L_info2_t *info, void *op_data) { - info_all_t *datainfo = (info_all_t *)op_data; - H5O_info_t object_info; - htri_t object_exists; - size_t str_len; + info_all_t *datainfo = (info_all_t *)op_data; + H5O_info2_t object_info; + htri_t object_exists; + size_t str_len; datainfo->otype[datainfo->count] = -1; datainfo->ltype[datainfo->count] = -1; - datainfo->objno[datainfo->count] = (unsigned long)-1; + datainfo->obj_token[datainfo->count] = H5O_TOKEN_UNDEF; str_len = HDstrlen(name); if (NULL == (datainfo->objname[datainfo->count] = (char *) HDmalloc(str_len + 1))) @@ -3485,21 +3503,15 @@ obj_info_all goto done; if (object_exists) { - if (H5Oget_info_by_name2(loc_id, name, &object_info, H5O_INFO_ALL, H5P_DEFAULT) < 0) + if (H5Oget_info_by_name3(loc_id, name, &object_info, H5O_INFO_ALL, H5P_DEFAULT) < 0) goto done; datainfo->otype[datainfo->count] = object_info.type; datainfo->ltype[datainfo->count] = info->type; datainfo->fno[datainfo->count] = object_info.fileno; - datainfo->objno[datainfo->count] = (unsigned long)object_info.addr; - } - /* - if (info->type == H5L_TYPE_HARD) - datainfo->objno[datainfo->count] = (unsigned long)info->u.address; - else - datainfo->objno[datainfo->count] = info->u.val_size; - */ + HDmemcpy(&datainfo->obj_token[datainfo->count], &object_info.token, sizeof(object_info.token)); + } done: datainfo->count++; @@ -3509,16 +3521,16 @@ done: herr_t obj_info_max - (hid_t loc_id, const char *name, const H5L_info_t *info, void *op_data) + (hid_t loc_id, const char *name, const H5L_info2_t *info, void *op_data) { - info_all_t *datainfo = (info_all_t *)op_data; - H5O_info_t object_info; - size_t str_len; + info_all_t *datainfo = (info_all_t *)op_data; + H5O_info2_t object_info; + size_t str_len; datainfo->otype[datainfo->count] = -1; datainfo->ltype[datainfo->count] = -1; datainfo->objname[datainfo->count] = NULL; - datainfo->objno[datainfo->count] = (unsigned long)-1; + datainfo->obj_token[datainfo->count] = H5O_TOKEN_UNDEF; /* This will be freed by h5str_array_free(oName, n) */ str_len = HDstrlen(name); @@ -3528,16 +3540,13 @@ obj_info_max HDstrncpy(datainfo->objname[datainfo->count], name, str_len); (datainfo->objname[datainfo->count])[str_len] = '\0'; - if (H5Oget_info2(loc_id, &object_info, H5O_INFO_ALL) < 0) + if (H5Oget_info3(loc_id, &object_info, H5O_INFO_ALL) < 0) goto done; datainfo->otype[datainfo->count] = object_info.type; datainfo->ltype[datainfo->count] = info->type; - if (info->type == H5L_TYPE_HARD) - datainfo->objno[datainfo->count] = (unsigned long)info->u.address; - else - datainfo->objno[datainfo->count] = info->u.val_size; + HDmemcpy(&datainfo->obj_token[datainfo->count], &object_info.token, sizeof(object_info.token)); done: datainfo->count++; diff --git a/java/src/jni/h5util.h b/java/src/jni/h5util.h index c26cd5d..51b6594 100644 --- a/java/src/jni/h5util.h +++ b/java/src/jni/h5util.h @@ -96,7 +96,7 @@ Java_hdf_hdf5lib_H5_H5Dcopy */ JNIEXPORT jint JNICALL Java_hdf_hdf5lib_H5_H5Gget_1obj_1info_1full - (JNIEnv*, jclass, jlong, jstring, jobjectArray, jintArray, jintArray, jlongArray, jlongArray, jint, jint, jint); + (JNIEnv*, jclass, jlong, jstring, jobjectArray, jintArray, jintArray, jlongArray, jobjectArray, jint, jint, jint); /* * Class: hdf_hdf5lib_H5 diff --git a/java/src/jni/h5vlImp.c b/java/src/jni/h5vlImp.c index 92e456e..0fee343 100644 --- a/java/src/jni/h5vlImp.c +++ b/java/src/jni/h5vlImp.c @@ -110,10 +110,30 @@ done: /* * Class: hdf_hdf5lib_H5 * Method: H5VLget_connector_id - * Signature: (Ljava/lang/String;)J + * Signature: (J)J */ JNIEXPORT jlong JNICALL Java_hdf_hdf5lib_H5_H5VLget_1connector_1id + (JNIEnv *env, jclass clss, jlong obj_id) +{ + hid_t status = H5I_INVALID_HID; + + UNUSED(clss); + + if ((status = H5VLget_connector_id((hid_t)obj_id)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + return (jlong)status; +} /* end Java_hdf_hdf5lib_H5_H5VLget_1connector_1id */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5VLget_connector_id_by_name + * Signature: (Ljava/lang/String;)J + */ +JNIEXPORT jlong JNICALL +Java_hdf_hdf5lib_H5_H5VLget_1connector_1id_1by_1name (JNIEnv *env, jclass clss, jobject connector_name) { const char *volName = NULL; @@ -122,11 +142,11 @@ Java_hdf_hdf5lib_H5_H5VLget_1connector_1id UNUSED(clss); if (NULL == connector_name) - H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5VLget_connector_id: VOL connector name is NULL"); + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5VLget_connector_id_by_name: VOL connector name is NULL"); - PIN_JAVA_STRING(ENVONLY, connector_name, volName, NULL, "H5VLget_connector_id: VOL connector name not pinned"); + PIN_JAVA_STRING(ENVONLY, connector_name, volName, NULL, "H5VLget_connector_id_by_name: VOL connector name not pinned"); - if ((status = H5VLget_connector_id(volName)) < 0) + if ((status = H5VLget_connector_id_by_name(volName)) < 0) H5_LIBRARY_ERROR(ENVONLY); done: @@ -134,7 +154,7 @@ done: UNPIN_JAVA_STRING(ENVONLY, connector_name, volName); return (jlong)status; -} /* end Java_hdf_hdf5lib_H5_H5VLget_1connector_1id */ +} /* end Java_hdf_hdf5lib_H5_H5VLget_1connector_1id_1by_1name */ /* * Class: hdf_hdf5lib_H5 @@ -158,7 +178,7 @@ Java_hdf_hdf5lib_H5_H5VLget_1connector_1name if (buf_size > 0) { if (NULL == (volName = (char *) HDmalloc(sizeof(char) * (size_t)buf_size + 1))) - H5_JNI_FATAL_ERROR(ENVONLY, "H5VLget_connector_name: failed to allocated VOL connector name buffer"); + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5VLget_connector_name: failed to allocated VOL connector name buffer"); if ((status = H5VLget_connector_name((hid_t)object_id, volName, (size_t)buf_size + 1)) < 0) H5_LIBRARY_ERROR(ENVONLY); diff --git a/java/src/jni/h5vlImp.h b/java/src/jni/h5vlImp.h index 207efa5..6dd7529 100644 --- a/java/src/jni/h5vlImp.h +++ b/java/src/jni/h5vlImp.h @@ -50,10 +50,19 @@ Java_hdf_hdf5lib_H5_H5VLis_1connector_1registered /* * Class: hdf_hdf5lib_H5 * Method: H5VLget_connector_id - * Signature: (Ljava/lang/String;)J + * Signature: (J)J */ JNIEXPORT jlong JNICALL Java_hdf_hdf5lib_H5_H5VLget_1connector_1id + (JNIEnv *, jclass, jlong); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5VLget_connector_id_by_name + * Signature: (Ljava/lang/String;)J + */ +JNIEXPORT jlong JNICALL +Java_hdf_hdf5lib_H5_H5VLget_1connector_1id_1by_1name (JNIEnv *, jclass, jobject); /* diff --git a/java/src/jni/nativeData.c b/java/src/jni/nativeData.c index ad01b01..3c3d3d5 100644 --- a/java/src/jni/nativeData.c +++ b/java/src/jni/nativeData.c @@ -327,7 +327,7 @@ Java_hdf_hdf5lib_HDFNativeData_byteToInt__II_3B } if ((start < 0) || ((int)(start + (len * (int)sizeof(jint))) > blen)) - H5_JNI_FATAL_ERROR(ENVONLY, "byteToInt: start < 0 or len exceeded buffer length"); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "byteToInt: start < 0 or len exceeded buffer length"); bp = (char *)barr + start; @@ -379,7 +379,7 @@ Java_hdf_hdf5lib_HDFNativeData_byteToShort__II_3B } if ((start < 0) || ((int)(start + (len * (int)sizeof(jshort))) > blen)) - H5_JNI_FATAL_ERROR(ENVONLY, "byteToShort: start < 0 or len exceeded buffer length"); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "byteToShort: start < 0 or len exceeded buffer length"); bp = (char *)barr + start; @@ -431,7 +431,7 @@ Java_hdf_hdf5lib_HDFNativeData_byteToFloat__II_3B } if ((start < 0) || ((int)(start + (len * (int)sizeof(jfloat))) > blen)) - H5_JNI_FATAL_ERROR(ENVONLY, "byteToFloat: start < 0 or len exceeded buffer length"); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "byteToFloat: start < 0 or len exceeded buffer length"); bp = (char *)barr + start; @@ -483,7 +483,7 @@ Java_hdf_hdf5lib_HDFNativeData_byteToLong__II_3B } if ((start < 0) || ((int)(start + (len * (int)sizeof(jlong))) > blen)) - H5_JNI_FATAL_ERROR(ENVONLY, "byteToLong: start < 0 or len exceeded buffer length"); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "byteToLong: start < 0 or len exceeded buffer length"); bp = (char *)barr + start; @@ -535,7 +535,7 @@ Java_hdf_hdf5lib_HDFNativeData_byteToDouble__II_3B } if ((start < 0) || ((int)(start + (len * (int)sizeof(jdouble))) > blen)) - H5_JNI_FATAL_ERROR(ENVONLY, "byteToDouble: start < 0 or len exceeded buffer length"); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "byteToDouble: start < 0 or len exceeded buffer length"); bp = (char *)barr + start; @@ -593,7 +593,7 @@ Java_hdf_hdf5lib_HDFNativeData_intToByte__II_3I } if ((start < 0) || (((start + len)) > ilen)) - H5_JNI_FATAL_ERROR(ENVONLY, "intToByte: start < 0 or len exceeded buffer length"); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "intToByte: start < 0 or len exceeded buffer length"); ip = iarr + start; @@ -655,7 +655,7 @@ Java_hdf_hdf5lib_HDFNativeData_shortToByte__II_3S } if ((start < 0) || (((start + len)) > ilen)) - H5_JNI_FATAL_ERROR(ENVONLY, "shortToByte: start < 0 or len exceeded buffer length"); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "shortToByte: start < 0 or len exceeded buffer length"); ip = sarr + start; @@ -717,7 +717,7 @@ Java_hdf_hdf5lib_HDFNativeData_floatToByte__II_3F } if ((start < 0) || (((start + len)) > ilen)) - H5_JNI_FATAL_ERROR(ENVONLY, "floatToByte: start < 0 or len exceeded buffer length"); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "floatToByte: start < 0 or len exceeded buffer length"); ip = farr + start; @@ -779,7 +779,7 @@ Java_hdf_hdf5lib_HDFNativeData_doubleToByte__II_3D } if ((start < 0) || (((start + len)) > ilen)) - H5_JNI_FATAL_ERROR(ENVONLY, "doubleToByte: start < 0 or len exceeded buffer length"); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "doubleToByte: start < 0 or len exceeded buffer length"); ip = darr + start; @@ -841,7 +841,7 @@ Java_hdf_hdf5lib_HDFNativeData_longToByte__II_3J } if ((start < 0) || (((start + len)) > ilen)) - H5_JNI_FATAL_ERROR(ENVONLY, "longToByte: start < 0 or len exceeded buffer length"); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "longToByte: start < 0 or len exceeded buffer length"); ip = larr + start; diff --git a/java/test/TestH5E.java b/java/test/TestH5E.java index fd015c0..6f4f473 100644 --- a/java/test/TestH5E.java +++ b/java/test/TestH5E.java @@ -74,7 +74,6 @@ public class TestH5E { @Test public void testH5Eget_msg_major() { - try { H5.H5Fopen("test", HDF5Constants.H5F_ACC_RDWR, HDF5Constants.H5P_DEFAULT); } @@ -90,8 +89,17 @@ public class TestH5E { fail("H5.H5Eget_msg(Throwable): " + err); } assertNotNull("H5.H5Eget_msg: " + msg, msg); - assertEquals("H5.H5Eget_msg: ", "File accessibility", msg); assertEquals("H5.H5Eget_msg: ", HDF5Constants.H5E_MAJOR, error_msg_type[0]); + + /* + * If HDF5_VOL_CONNECTOR is set, this might not be the + * native connector and the error string might be different. + * Only check for the specific error message if the native + * connector is being used. + */ + String connector = System.getenv("HDF5_VOL_CONNECTOR"); + if (connector == null) + assertEquals("H5.H5Eget_msg: ", "File accessibility", msg); } catch (Throwable err) { err.printStackTrace(); @@ -116,8 +124,17 @@ public class TestH5E { fail("H5.H5Eget_msg: " + err); } assertNotNull("H5.H5Eget_msg: " + msg, msg); - assertEquals("H5.H5Eget_msg: ", "Unable to open file", msg); assertEquals("H5.H5Eget_msg: ", HDF5Constants.H5E_MINOR, error_msg_type[0]); + + /* + * If HDF5_VOL_CONNECTOR is set, this might not be the + * native connector and the error string might be different. + * Only check for the specific error message if the native + * connector is being used. + */ + String connector = System.getenv("HDF5_VOL_CONNECTOR"); + if (connector == null) + assertEquals("H5.H5Eget_msg: ", "Unable to open file", msg); } catch (Throwable err) { err.printStackTrace(); diff --git a/java/test/TestH5Edefault.java b/java/test/TestH5Edefault.java index 6f968b1..0e55bcc 100644 --- a/java/test/TestH5Edefault.java +++ b/java/test/TestH5Edefault.java @@ -24,6 +24,7 @@ import org.junit.After; import org.junit.Before; import org.junit.Rule; import org.junit.Test; +import org.junit.Ignore; import org.junit.rules.TestName; public class TestH5Edefault { @@ -55,20 +56,29 @@ public class TestH5Edefault { H5.H5Eprint2(-1, null); } - @Test + @Ignore public void testH5Eprint() { - try { - H5.H5Fopen("test", HDF5Constants.H5F_ACC_RDWR, HDF5Constants.H5P_DEFAULT); - } - catch (Throwable err) { - } - try { - H5.H5Eprint2(HDF5Constants.H5E_DEFAULT, null); - } - catch (Throwable err) { - err.printStackTrace(); - fail("H5.H5Eprint: " + err); - } + /* + * If HDF5_VOL_CONNECTOR is set, this might not be the + * native connector and the error stack might be different. + * Only check for the specific error stack if the native + * connector is being used. + */ + String connector = System.getenv("HDF5_VOL_CONNECTOR"); + if (connector == null) { + try { + H5.H5Fopen("test", HDF5Constants.H5F_ACC_RDWR, HDF5Constants.H5P_DEFAULT); + } + catch (Throwable err) { + } + try { + H5.H5Eprint2(HDF5Constants.H5E_DEFAULT, null); + } + catch (Throwable err) { + err.printStackTrace(); + fail("H5.H5Eprint: " + err); + } + } } @Test @@ -427,20 +437,29 @@ public class TestH5Edefault { H5.H5Eprint2(-1, null); } - @Test + @Ignore public void testH5EprintInt() { - try { - H5.H5Fopen("test", HDF5Constants.H5F_ACC_RDWR, HDF5Constants.H5P_DEFAULT); - } - catch (Throwable err) { - } - try { - H5.H5Eprint2(HDF5Constants.H5E_DEFAULT, null); - } - catch (Throwable err) { - err.printStackTrace(); - fail("H5.H5EprintInt: " + err); - } + /* + * If HDF5_VOL_CONNECTOR is set, this might not be the + * native connector and the error stack might be different. + * Only check for the specific error stack if the native + * connector is being used. + */ + String connector = System.getenv("HDF5_VOL_CONNECTOR"); + if (connector == null) { + try { + H5.H5Fopen("test", HDF5Constants.H5F_ACC_RDWR, HDF5Constants.H5P_DEFAULT); + } + catch (Throwable err) { + } + try { + H5.H5Eprint2(HDF5Constants.H5E_DEFAULT, null); + } + catch (Throwable err) { + err.printStackTrace(); + fail("H5.H5EprintInt: " + err); + } + } } @Test diff --git a/java/test/TestH5G.java b/java/test/TestH5G.java index 6c30187..4b6d470 100644 --- a/java/test/TestH5G.java +++ b/java/test/TestH5G.java @@ -24,6 +24,7 @@ import hdf.hdf5lib.H5; import hdf.hdf5lib.HDF5Constants; import hdf.hdf5lib.exceptions.HDF5LibraryException; import hdf.hdf5lib.structs.H5G_info_t; +import hdf.hdf5lib.structs.H5O_token_t; import org.junit.After; import org.junit.Before; @@ -286,12 +287,12 @@ public class TestH5G { String objNames[] = new String[(int) info.nlinks]; int objTypes[] = new int[(int) info.nlinks]; int lnkTypes[] = new int[(int) info.nlinks]; - long objRefs[] = new long[(int) info.nlinks]; + H5O_token_t objTokens[] = new H5O_token_t[(int) info.nlinks]; int names_found = 0; try { names_found = H5.H5Gget_obj_info_all(H5fid, GROUPS[0], objNames, - objTypes, lnkTypes, objRefs, HDF5Constants.H5_INDEX_NAME); + objTypes, lnkTypes, objTokens, HDF5Constants.H5_INDEX_NAME); } catch (Throwable err) { err.printStackTrace(); @@ -317,14 +318,14 @@ public class TestH5G { assertNotNull("TestH5G.testH5Gget_obj_info_all_gid: ", info); assertTrue("TestH5G.testH5Gget_obj_info_all_gid: number of links is empty", info.nlinks > 0); String objNames[] = new String[(int) info.nlinks]; - long objRefs[] = new long[(int) info.nlinks]; + H5O_token_t objTokens[] = new H5O_token_t[(int) info.nlinks]; int lnkTypes[] = new int[(int) info.nlinks]; int objTypes[] = new int[(int) info.nlinks]; int names_found = 0; try { names_found = H5.H5Gget_obj_info_all(gid, null, objNames, objTypes, lnkTypes, - objRefs, HDF5Constants.H5_INDEX_NAME); + objTokens, HDF5Constants.H5_INDEX_NAME); } catch (Throwable err) { err.printStackTrace(); @@ -358,14 +359,14 @@ public class TestH5G { assertNotNull("TestH5G.testH5Gget_obj_info_all_gid2: ", info); assertTrue("TestH5G.testH5Gget_obj_info_all_gid2: number of links is empty", info.nlinks > 0); String objNames[] = new String[(int) info.nlinks]; - long objRefs[] = new long[(int) info.nlinks]; + H5O_token_t objTokens[] = new H5O_token_t[(int) info.nlinks]; int lnkTypes[] = new int[(int) info.nlinks]; int objTypes[] = new int[(int) info.nlinks]; int names_found = 0; try { names_found = H5.H5Gget_obj_info_all(gid, null, objNames, objTypes, lnkTypes, - objRefs, HDF5Constants.H5_INDEX_NAME); + objTokens, HDF5Constants.H5_INDEX_NAME); } catch (Throwable err) { err.printStackTrace(); @@ -395,12 +396,12 @@ public class TestH5G { String objNames[] = new String[(int)groups_max_size]; int objTypes[] = new int[(int)groups_max_size]; int lnkTypes[] = new int[(int)groups_max_size]; - long objRefs[] = new long[(int)groups_max_size]; + H5O_token_t objTokens[] = new H5O_token_t[(int)groups_max_size]; int names_found = 0; try { names_found = H5.H5Gget_obj_info_max(gid, objNames, objTypes, lnkTypes, - objRefs, groups_max_size); + objTokens, groups_max_size); } catch (Throwable err) { err.printStackTrace(); @@ -426,12 +427,12 @@ public class TestH5G { String objNames[] = new String[(int)groups_max_size]; int objTypes[] = new int[(int)groups_max_size]; int lnkTypes[] = new int[(int)groups_max_size]; - long objRefs[] = new long[(int)groups_max_size]; + H5O_token_t objTokens[] = new H5O_token_t[(int)groups_max_size]; int names_found = 0; try { names_found = H5.H5Gget_obj_info_max(gid, objNames, objTypes, lnkTypes, - objRefs, groups_max_size); + objTokens, groups_max_size); } catch (Throwable err) { err.printStackTrace(); @@ -471,11 +472,11 @@ public class TestH5G { String objNames[] = new String[(int) info.nlinks]; int objTypes[] = new int[(int) info.nlinks]; int lnkTypes[] = new int[(int) info.nlinks]; - long objRefs[] = new long[(int) info.nlinks]; + H5O_token_t objTokens[] = new H5O_token_t[(int) info.nlinks]; try { H5.H5Gget_obj_info_all(H5fid2, GROUPS2[0], objNames, - objTypes, lnkTypes, objRefs, HDF5Constants.H5_INDEX_CRT_ORDER); + objTypes, lnkTypes, objTokens, HDF5Constants.H5_INDEX_CRT_ORDER); } catch (Throwable err) { err.printStackTrace(); @@ -488,7 +489,7 @@ public class TestH5G { try { H5.H5Gget_obj_info_all(H5fid2, GROUPS2[0], objNames, - objTypes, lnkTypes, objRefs, HDF5Constants.H5_INDEX_NAME); + objTypes, lnkTypes, objTokens, HDF5Constants.H5_INDEX_NAME); } catch (Throwable err) { err.printStackTrace(); diff --git a/java/test/TestH5Giterate.java b/java/test/TestH5Giterate.java index 06c59e7..9514837 100644 --- a/java/test/TestH5Giterate.java +++ b/java/test/TestH5Giterate.java @@ -20,6 +20,7 @@ import hdf.hdf5lib.H5; import hdf.hdf5lib.HDF5Constants; import hdf.hdf5lib.exceptions.HDF5LibraryException; import hdf.hdf5lib.structs.H5G_info_t; +import hdf.hdf5lib.structs.H5O_token_t; import org.junit.After; import org.junit.Before; @@ -93,12 +94,12 @@ public class TestH5Giterate { String objNames[] = new String[(int) info.nlinks]; int objTypes[] = new int[(int) info.nlinks]; int lnkTypes[] = new int[(int) info.nlinks]; - long objRefs[] = new long[(int) info.nlinks]; + H5O_token_t objTokens[] = new H5O_token_t[(int) info.nlinks]; int names_found = 0; try { names_found = H5.H5Gget_obj_info_all(H5fid, "/", objNames, - objTypes, lnkTypes, objRefs, HDF5Constants.H5_INDEX_NAME); + objTypes, lnkTypes, objTokens, HDF5Constants.H5_INDEX_NAME); } catch (Throwable err) { err.printStackTrace(); diff --git a/java/test/TestH5Lbasic.java b/java/test/TestH5Lbasic.java index 0a836c1..3bea1ee 100644 --- a/java/test/TestH5Lbasic.java +++ b/java/test/TestH5Lbasic.java @@ -21,8 +21,8 @@ import java.util.ArrayList; import hdf.hdf5lib.H5; import hdf.hdf5lib.HDF5Constants; -import hdf.hdf5lib.callbacks.H5L_iterate_cb; import hdf.hdf5lib.callbacks.H5L_iterate_t; +import hdf.hdf5lib.callbacks.H5L_iterate_opdata_t; import hdf.hdf5lib.exceptions.HDF5LibraryException; import hdf.hdf5lib.structs.H5L_info_t; @@ -119,9 +119,8 @@ public class TestH5Lbasic { err.printStackTrace(); fail("H5.H5Lget_info: " + err); } - assertFalse("H5Lget_info ",link_info==null); + assertFalse("H5Lget_info",link_info==null); assertTrue("H5Lget_info link type",link_info.type==HDF5Constants.H5L_TYPE_HARD); - assertTrue("Link Address ",link_info.address_val_size>0); } @Test(expected = HDF5LibraryException.class) @@ -155,7 +154,7 @@ public class TestH5Lbasic { err.printStackTrace(); fail("H5.H5Lget_info_by_idx: " + err); } - assertFalse("H5Lget_info_by_idx ",link_info==null); + assertFalse("H5Lget_info_by_idx",link_info==null); assertTrue("H5Lget_info_by_idx link type",link_info.type==HDF5Constants.H5L_TYPE_HARD); try { link_info2 = H5.H5Lget_info(H5fid, "DS1", HDF5Constants.H5P_DEFAULT); @@ -164,7 +163,7 @@ public class TestH5Lbasic { err.printStackTrace(); fail("H5.H5Lget_info: " + err); } - assertTrue("Link Address ",link_info.address_val_size==link_info2.address_val_size); + assertTrue("Link Value Size", link_info.val_size == link_info2.val_size); } @Test @@ -178,7 +177,7 @@ public class TestH5Lbasic { err.printStackTrace(); fail("H5.H5Lget_info_by_idx: " + err); } - assertFalse("H5Lget_info_by_idx ",link_info==null); + assertFalse("H5Lget_info_by_idx",link_info==null); assertTrue("H5Lget_info_by_idx link type",link_info.type==HDF5Constants.H5L_TYPE_HARD); try { link_info2 = H5.H5Lget_info(H5fid, "L1", HDF5Constants.H5P_DEFAULT); @@ -187,7 +186,7 @@ public class TestH5Lbasic { err.printStackTrace(); fail("H5.H5Lget_info: " + err); } - assertTrue("Link Address ",link_info.address_val_size==link_info2.address_val_size); + assertTrue("Link Value Size", link_info.val_size == link_info2.val_size); } @Test(expected = HDF5LibraryException.class) @@ -233,18 +232,18 @@ public class TestH5Lbasic { this.link_type = type; } } - class H5L_iter_data implements H5L_iterate_t { + class H5L_iter_data implements H5L_iterate_opdata_t { public ArrayList iterdata = new ArrayList(); } - H5L_iterate_t iter_data = new H5L_iter_data(); - class H5L_iter_callback implements H5L_iterate_cb { - public int callback(long group, String name, H5L_info_t info, H5L_iterate_t op_data) { + H5L_iterate_opdata_t iter_data = new H5L_iter_data(); + class H5L_iter_callback implements H5L_iterate_t { + public int callback(long group, String name, H5L_info_t info, H5L_iterate_opdata_t op_data) { idata id = new idata(name, info.type); ((H5L_iter_data)op_data).iterdata.add(id); return 0; } } - H5L_iterate_cb iter_cb = new H5L_iter_callback(); + H5L_iterate_t iter_cb = new H5L_iter_callback(); try { H5.H5Lvisit(H5fid, HDF5Constants.H5_INDEX_NAME, HDF5Constants.H5_ITER_INC, iter_cb, iter_data); } @@ -271,18 +270,18 @@ public class TestH5Lbasic { this.link_type = type; } } - class H5L_iter_data implements H5L_iterate_t { + class H5L_iter_data implements H5L_iterate_opdata_t { public ArrayList iterdata = new ArrayList(); } - H5L_iterate_t iter_data = new H5L_iter_data(); - class H5L_iter_callback implements H5L_iterate_cb { - public int callback(long group, String name, H5L_info_t info, H5L_iterate_t op_data) { + H5L_iterate_opdata_t iter_data = new H5L_iter_data(); + class H5L_iter_callback implements H5L_iterate_t { + public int callback(long group, String name, H5L_info_t info, H5L_iterate_opdata_t op_data) { idata id = new idata(name, info.type); ((H5L_iter_data)op_data).iterdata.add(id); return 0; } } - H5L_iterate_cb iter_cb = new H5L_iter_callback(); + H5L_iterate_t iter_cb = new H5L_iter_callback(); try { H5.H5Lvisit_by_name(H5fid, "G1", HDF5Constants.H5_INDEX_NAME, HDF5Constants.H5_ITER_INC, iter_cb, iter_data, HDF5Constants.H5P_DEFAULT); } @@ -305,18 +304,18 @@ public class TestH5Lbasic { this.link_type = type; } } - class H5L_iter_data implements H5L_iterate_t { + class H5L_iter_data implements H5L_iterate_opdata_t { public ArrayList iterdata = new ArrayList(); } - H5L_iterate_t iter_data = new H5L_iter_data(); - class H5L_iter_callback implements H5L_iterate_cb { - public int callback(long group, String name, H5L_info_t info, H5L_iterate_t op_data) { + H5L_iterate_opdata_t iter_data = new H5L_iter_data(); + class H5L_iter_callback implements H5L_iterate_t { + public int callback(long group, String name, H5L_info_t info, H5L_iterate_opdata_t op_data) { idata id = new idata(name, info.type); ((H5L_iter_data)op_data).iterdata.add(id); return 0; } } - H5L_iterate_cb iter_cb = new H5L_iter_callback(); + H5L_iterate_t iter_cb = new H5L_iter_callback(); try { H5.H5Literate(H5fid, HDF5Constants.H5_INDEX_NAME, HDF5Constants.H5_ITER_INC, 0L, iter_cb, iter_data); } @@ -342,18 +341,18 @@ public class TestH5Lbasic { this.link_type = type; } } - class H5L_iter_data implements H5L_iterate_t { + class H5L_iter_data implements H5L_iterate_opdata_t { public ArrayList iterdata = new ArrayList(); } - H5L_iterate_t iter_data = new H5L_iter_data(); - class H5L_iter_callback implements H5L_iterate_cb { - public int callback(long group, String name, H5L_info_t info, H5L_iterate_t op_data) { + H5L_iterate_opdata_t iter_data = new H5L_iter_data(); + class H5L_iter_callback implements H5L_iterate_t { + public int callback(long group, String name, H5L_info_t info, H5L_iterate_opdata_t op_data) { idata id = new idata(name, info.type); ((H5L_iter_data)op_data).iterdata.add(id); return 0; } } - H5L_iterate_cb iter_cb = new H5L_iter_callback(); + H5L_iterate_t iter_cb = new H5L_iter_callback(); try { H5.H5Literate_by_name(H5fid, "G1", HDF5Constants.H5_INDEX_NAME, HDF5Constants.H5_ITER_INC, 0L, iter_cb, iter_data, HDF5Constants.H5P_DEFAULT); } diff --git a/java/test/TestH5Lcreate.java b/java/test/TestH5Lcreate.java index 06c4ac1..c8f2348 100644 --- a/java/test/TestH5Lcreate.java +++ b/java/test/TestH5Lcreate.java @@ -22,8 +22,8 @@ import java.util.ArrayList; import hdf.hdf5lib.H5; import hdf.hdf5lib.HDF5Constants; -import hdf.hdf5lib.callbacks.H5L_iterate_cb; import hdf.hdf5lib.callbacks.H5L_iterate_t; +import hdf.hdf5lib.callbacks.H5L_iterate_opdata_t; import hdf.hdf5lib.exceptions.HDF5Exception; import hdf.hdf5lib.exceptions.HDF5LibraryException; import hdf.hdf5lib.structs.H5L_info_t; @@ -320,9 +320,9 @@ public class TestH5Lcreate { err.printStackTrace(); fail("H5.H5Lget_info: " + err); } - assertFalse("H5Lget_info ", link_info==null); + assertFalse("H5Lget_info", link_info==null); assertTrue("H5Lget_info link type", link_info.type==HDF5Constants.H5L_TYPE_SOFT); - assertTrue("Link Address ", link_info.address_val_size>0); + assertTrue("Link Value Size", link_info.val_size > 0); } @Test @@ -383,9 +383,9 @@ public class TestH5Lcreate { err.printStackTrace(); fail("H5.H5Lget_info: " + err); } - assertFalse("H5Lget_info ", link_info==null); + assertFalse("H5Lget_info", link_info==null); assertTrue("H5Lget_info link type", link_info.type==HDF5Constants.H5L_TYPE_SOFT); - assertTrue("Link Address ", link_info.address_val_size>0); + assertTrue("Link Value Size", link_info.val_size > 0); } @Test @@ -431,9 +431,9 @@ public class TestH5Lcreate { err.printStackTrace(); fail("H5.H5Lget_info: " + err); } - assertFalse("H5Lget_info ", link_info==null); + assertFalse("H5Lget_info", link_info==null); assertTrue("H5Lget_info link type", link_info.type==HDF5Constants.H5L_TYPE_EXTERNAL); - assertTrue("Link Address ", link_info.address_val_size>0); + assertTrue("Link Value Size", link_info.val_size > 0); } @Test @@ -740,18 +740,18 @@ public class TestH5Lcreate { this.link_type = type; } } - class H5L_iter_data implements H5L_iterate_t { + class H5L_iter_data implements H5L_iterate_opdata_t { public ArrayList iterdata = new ArrayList(); } - H5L_iterate_t iter_data = new H5L_iter_data(); - class H5L_iter_callback implements H5L_iterate_cb { - public int callback(long group, String name, H5L_info_t info, H5L_iterate_t op_data) { + H5L_iterate_opdata_t iter_data = new H5L_iter_data(); + class H5L_iter_callback implements H5L_iterate_t { + public int callback(long group, String name, H5L_info_t info, H5L_iterate_opdata_t op_data) { idata id = new idata(name, info.type); ((H5L_iter_data)op_data).iterdata.add(id); return 0; } } - H5L_iterate_cb iter_cb = new H5L_iter_callback(); + H5L_iterate_t iter_cb = new H5L_iter_callback(); try { H5.H5Lvisit(H5fid, HDF5Constants.H5_INDEX_CRT_ORDER, HDF5Constants.H5_ITER_INC, iter_cb, iter_data); } @@ -792,18 +792,18 @@ public class TestH5Lcreate { this.link_type = type; } } - class H5L_iter_data implements H5L_iterate_t { + class H5L_iter_data implements H5L_iterate_opdata_t { public ArrayList iterdata = new ArrayList(); } - H5L_iterate_t iter_data = new H5L_iter_data(); - class H5L_iter_callback implements H5L_iterate_cb { - public int callback(long group, String name, H5L_info_t info, H5L_iterate_t op_data) { + H5L_iterate_opdata_t iter_data = new H5L_iter_data(); + class H5L_iter_callback implements H5L_iterate_t { + public int callback(long group, String name, H5L_info_t info, H5L_iterate_opdata_t op_data) { idata id = new idata(name, info.type); ((H5L_iter_data)op_data).iterdata.add(id); return 0; } } - H5L_iterate_cb iter_cb = new H5L_iter_callback(); + H5L_iterate_t iter_cb = new H5L_iter_callback(); try { H5.H5Literate(H5fid, HDF5Constants.H5_INDEX_CRT_ORDER, HDF5Constants.H5_ITER_INC, 0, iter_cb, iter_data); } diff --git a/java/test/TestH5Obasic.java b/java/test/TestH5Obasic.java index 8c6689f..20ffc41 100644 --- a/java/test/TestH5Obasic.java +++ b/java/test/TestH5Obasic.java @@ -21,10 +21,14 @@ import java.util.ArrayList; import hdf.hdf5lib.H5; import hdf.hdf5lib.HDF5Constants; -import hdf.hdf5lib.callbacks.H5O_iterate_cb; import hdf.hdf5lib.callbacks.H5O_iterate_t; +import hdf.hdf5lib.callbacks.H5O_iterate_opdata_t; import hdf.hdf5lib.exceptions.HDF5LibraryException; import hdf.hdf5lib.structs.H5O_info_t; +import hdf.hdf5lib.structs.H5O_native_info_t; +import hdf.hdf5lib.structs.H5O_token_t; +import hdf.hdf5lib.structs.H5O_hdr_info_t; +import hdf.hdf5lib.structs.H5_ih_info_t; import org.junit.After; import org.junit.Before; @@ -35,10 +39,8 @@ import org.junit.rules.TestName; public class TestH5Obasic { @Rule public TestName testname = new TestName(); private static final String H5_FILE = "h5ex_g_iterateO1.hdf"; - private static long H5la_ds1 = -1; - private static long H5la_l1 = -1; - private static long H5la_dt1 = -1; - private static long H5la_g1 = -1; + private static H5O_token_t H5la_ds1 = null; + private static H5O_token_t H5la_l1 = null; long H5fid = -1; @Before @@ -242,7 +244,7 @@ public class TestH5Obasic { err.printStackTrace(); fail("testH5Oget_info_by_idx_n0:H5.H5Oget_info: " + err); } - H5la_ds1 = obj_info.addr; + H5la_ds1 = obj_info.token; try {H5.H5Oclose(oid);} catch (Exception ex) {} try { obj_info = H5.H5Oget_info_by_idx(H5fid, "/", HDF5Constants.H5_INDEX_NAME, HDF5Constants.H5_ITER_INC, 0, HDF5Constants.H5P_DEFAULT); @@ -253,7 +255,7 @@ public class TestH5Obasic { } assertFalse("testH5Oget_info_by_idx_n0:H5Oget_info_by_idx ",obj_info==null); assertTrue("testH5Oget_info_by_idx_n0:H5Oget_info_by_idx link type",obj_info.type==HDF5Constants.H5O_TYPE_DATASET); - assertTrue("testH5Oget_info_by_idx_n0:Link Address ",obj_info.addr==H5la_ds1); + assertTrue("testH5Oget_info_by_idx_n0:Link Object token", obj_info.token.equals(H5la_ds1)); } @Test @@ -268,7 +270,7 @@ public class TestH5Obasic { err.printStackTrace(); fail("testH5Oget_info_by_idx_n3:H5.H5Oget_info: " + err); } - H5la_l1 = obj_info.addr; + H5la_l1 = obj_info.token; try {H5.H5Oclose(oid);} catch (Exception ex) {} try { obj_info = H5.H5Oget_info_by_idx(H5fid, "/", HDF5Constants.H5_INDEX_NAME, HDF5Constants.H5_ITER_INC, 3, HDF5Constants.H5P_DEFAULT); @@ -279,7 +281,263 @@ public class TestH5Obasic { } assertFalse("testH5Oget_info_by_idx_n3:H5Oget_info_by_idx ",obj_info==null); assertTrue("testH5Oget_info_by_idx_n3:H5Oget_info_by_idx link type",obj_info.type==HDF5Constants.H5O_TYPE_DATASET); - assertTrue("testH5Oget_info_by_idx_n3:Link Address ",obj_info.addr==H5la_l1); + assertTrue("testH5Oget_info_by_idx_n3:Link Object Token", obj_info.token.equals(H5la_l1)); + } + + @Test + public void testH5Oget_native_info_dataset() { + long oid = -1; + H5O_native_info_t native_info = null; + + try { + oid = H5.H5Oopen(H5fid, "DS1", HDF5Constants.H5P_DEFAULT); + native_info = H5.H5Oget_native_info(oid); + } + catch (Throwable err) { + err.printStackTrace(); + fail("H5.H5Oget_native_info: " + err); + } + assertFalse("H5Oget_native_info ", native_info == null); + assertFalse("H5Oget_native_info ", native_info.hdr_info == null); + assertFalse("H5Oget_native_info ", native_info.obj_info == null); + assertFalse("H5Oget_native_info ", native_info.attr_info == null); + try {H5.H5Oclose(oid);} catch (Exception ex) {} + } + + @Test + public void testH5Oget_native_info_hardlink() { + long oid = -1; + H5O_native_info_t native_info = null; + + try { + oid = H5.H5Oopen(H5fid, "L1", HDF5Constants.H5P_DEFAULT); + native_info = H5.H5Oget_native_info(oid); + } + catch (Throwable err) { + err.printStackTrace(); + fail("H5.H5Oget_native_info: " + err); + } + assertFalse("H5Oget_native_info ", native_info == null); + assertFalse("H5Oget_native_info ", native_info.hdr_info == null); + assertFalse("H5Oget_native_info ", native_info.obj_info == null); + assertFalse("H5Oget_native_info ", native_info.attr_info == null); + try {H5.H5Oclose(oid);} catch (Exception ex) {} + } + + @Test + public void testH5Oget_native_info_group() { + long oid = -1; + H5O_native_info_t native_info = null; + + try { + oid = H5.H5Oopen(H5fid, "G1", HDF5Constants.H5P_DEFAULT); + native_info = H5.H5Oget_native_info(oid); + } + catch (Throwable err) { + err.printStackTrace(); + fail("H5.H5Oget_native_info: " + err); + } + assertFalse("H5Oget_native_info ", native_info == null); + assertFalse("H5Oget_native_info ", native_info.hdr_info == null); + assertFalse("H5Oget_native_info ", native_info.obj_info == null); + assertFalse("H5Oget_native_info ", native_info.attr_info == null); + try {H5.H5Oclose(oid);} catch (Exception ex) {} + } + + @Test + public void testH5Oget_native_info_datatype() { + long oid = -1; + H5O_native_info_t native_info = null; + + try { + oid = H5.H5Oopen(H5fid, "DT1", HDF5Constants.H5P_DEFAULT); + native_info = H5.H5Oget_native_info(oid); + } + catch (Throwable err) { + err.printStackTrace(); + fail("H5.H5Oget_native_info: " + err); + } + assertFalse("H5Oget_native_info ", native_info == null); + assertFalse("H5Oget_native_info ", native_info.hdr_info == null); + assertFalse("H5Oget_native_info ", native_info.obj_info == null); + assertFalse("H5Oget_native_info ", native_info.attr_info == null); + try {H5.H5Oclose(oid);} catch (Exception ex) {} + } + + @Test(expected = HDF5LibraryException.class) + public void testH5Oget_native_info_by_name_not_exist_name() throws Throwable { + H5.H5Oget_native_info_by_name(H5fid, "None", HDF5Constants.H5P_DEFAULT); + } + + @Test(expected = HDF5LibraryException.class) + public void testH5Oget_native_info_by_name_not_exists() throws Throwable { + H5.H5Oget_native_info_by_name(H5fid, "Bogus", HDF5Constants.H5P_DEFAULT); + } + + @Test + public void testH5Oget_native_info_by_name_dataset() { + H5O_native_info_t native_info = null; + + try { + native_info = H5.H5Oget_native_info_by_name(H5fid, "DS1", HDF5Constants.H5P_DEFAULT); + } + catch (Throwable err) { + err.printStackTrace(); + fail("H5.H5Oget_native_info_by_name: " + err); + } + assertFalse("H5Oget_native_info_by_name ", native_info == null); + assertFalse("H5Oget_native_info_by_name ", native_info.hdr_info == null); + assertFalse("H5Oget_native_info_by_name ", native_info.obj_info == null); + assertFalse("H5Oget_native_info_by_name ", native_info.attr_info == null); + } + + @Test + public void testH5Oget_native_info_by_name_hardlink() { + H5O_native_info_t native_info = null; + + try { + native_info = H5.H5Oget_native_info_by_name(H5fid, "L1", HDF5Constants.H5P_DEFAULT); + } + catch (Throwable err) { + err.printStackTrace(); + fail("H5.H5Oget_native_info_by_name: " + err); + } + assertFalse("H5Oget_native_info_by_name ", native_info == null); + assertFalse("H5Oget_native_info_by_name ", native_info.hdr_info == null); + assertFalse("H5Oget_native_info_by_name ", native_info.obj_info == null); + assertFalse("H5Oget_native_info_by_name ", native_info.attr_info == null); + } + + @Test + public void testH5Oget_native_info_by_name_group() { + H5O_native_info_t native_info = null; + + try { + native_info = H5.H5Oget_native_info_by_name(H5fid, "G1", HDF5Constants.H5P_DEFAULT); + } + catch (Throwable err) { + err.printStackTrace(); + fail("H5.H5Oget_native_info_by_name: " + err); + } + assertFalse("H5Oget_native_info_by_name ", native_info == null); + assertFalse("H5Oget_native_info_by_name ", native_info.hdr_info == null); + assertFalse("H5Oget_native_info_by_name ", native_info.obj_info == null); + assertFalse("H5Oget_native_info_by_name ", native_info.attr_info == null); + } + + @Test + public void testH5Oget_native_info_by_name_datatype() { + H5O_native_info_t native_info = null; + + try { + native_info = H5.H5Oget_native_info_by_name(H5fid, "DT1", HDF5Constants.H5P_DEFAULT); + } + catch (Throwable err) { + err.printStackTrace(); + fail("H5.H5Oget_native_info_by_name: " + err); + } + assertFalse("H5Oget_native_info_by_name ", native_info == null); + assertFalse("H5Oget_native_info_by_name ", native_info.hdr_info == null); + assertFalse("H5Oget_native_info_by_name ", native_info.obj_info == null); + assertFalse("H5Oget_native_info_by_name ", native_info.attr_info == null); + } + + @Test(expected = HDF5LibraryException.class) + public void testH5Oget_native_info_by_idx_name_not_exist_name() throws Throwable { + H5.H5Oget_native_info_by_idx(H5fid, "None", HDF5Constants.H5_INDEX_NAME, HDF5Constants.H5_ITER_INC, 0, HDF5Constants.H5P_DEFAULT); + } + + @Test(expected = HDF5LibraryException.class) + public void testH5Oget_native_info_by_idx_name_not_exist_create() throws Throwable { + H5.H5Oget_native_info_by_idx(H5fid, "None", HDF5Constants.H5_INDEX_CRT_ORDER, HDF5Constants.H5_ITER_INC, 0, HDF5Constants.H5P_DEFAULT); + } + + @Test(expected = HDF5LibraryException.class) + public void testH5Oget_native_info_by_idx_not_exist_name() throws Throwable { + H5.H5Oget_native_info_by_idx(H5fid, "/", HDF5Constants.H5_INDEX_NAME, HDF5Constants.H5_ITER_INC, 5, HDF5Constants.H5P_DEFAULT); + } + + @Test(expected = HDF5LibraryException.class) + public void testH5Oget_native_info_by_idx_not_exist_create() throws Throwable { + H5.H5Oget_native_info_by_idx(H5fid, "/", HDF5Constants.H5_INDEX_CRT_ORDER, HDF5Constants.H5_ITER_INC, 5, HDF5Constants.H5P_DEFAULT); + } + + @Test + public void testH5Oget_native_info_by_idx_n0() { + long oid = -1; + H5O_native_info_t native_info = null; + H5O_hdr_info_t ohdr; + H5_ih_info_t oinfo; + H5_ih_info_t ainfo; + + try { + oid = H5.H5Oopen(H5fid, "DS1", HDF5Constants.H5P_DEFAULT); + native_info = H5.H5Oget_native_info(oid); + } + catch (Throwable err) { + err.printStackTrace(); + fail("testH5Oget_native_info_by_idx_n0:H5.H5Oget_native_info: " + err); + } + + ohdr = native_info.hdr_info; + oinfo = native_info.obj_info; + ainfo = native_info.attr_info; + + try {H5.H5Oclose(oid);} catch (Exception ex) {} + + try { + native_info = H5.H5Oget_native_info_by_idx(H5fid, "/", HDF5Constants.H5_INDEX_NAME, HDF5Constants.H5_ITER_INC, 0, HDF5Constants.H5P_DEFAULT); + } + catch (Throwable err) { + err.printStackTrace(); + fail("testH5Oget_native_info_by_idx_n0:H5.H5Oget_native_info_by_idx: " + err); + } + assertFalse("H5Oget_native_info_by_idx ", native_info == null); + assertFalse("H5Oget_native_info_by_idx ", native_info.hdr_info == null); + assertFalse("H5Oget_native_info_by_idx ", native_info.obj_info == null); + assertFalse("H5Oget_native_info_by_idx ", native_info.attr_info == null); + assertTrue("testH5Oget_native_info_by_idx_n0:Object Header Info", native_info.hdr_info.equals(ohdr)); + assertTrue("testH5Oget_native_info_by_idx_n0:Object Info", native_info.obj_info.equals(oinfo)); + assertTrue("testH5Oget_native_info_by_idx_n0:Attribute Info", native_info.attr_info.equals(ainfo)); + } + + @Test + public void testH5Oget_native_info_by_idx_n3() { + long oid = -1; + H5O_native_info_t native_info = null; + H5O_hdr_info_t ohdr; + H5_ih_info_t oinfo; + H5_ih_info_t ainfo; + + try { + oid = H5.H5Oopen(H5fid, "L1", HDF5Constants.H5P_DEFAULT); + native_info = H5.H5Oget_native_info(oid); + } + catch (Throwable err) { + err.printStackTrace(); + fail("testH5Oget_native_info_by_idx_n3:H5.H5Oget_native_info: " + err); + } + + ohdr = native_info.hdr_info; + oinfo = native_info.obj_info; + ainfo = native_info.attr_info; + + try {H5.H5Oclose(oid);} catch (Exception ex) {} + + try { + native_info = H5.H5Oget_native_info_by_idx(H5fid, "/", HDF5Constants.H5_INDEX_NAME, HDF5Constants.H5_ITER_INC, 3, HDF5Constants.H5P_DEFAULT); + } + catch (Throwable err) { + err.printStackTrace(); + fail("testH5Oget_native_info_by_idx_n3:H5.H5Oget_native_info_by_idx: " + err); + } + assertFalse("H5Oget_native_info_by_idx ", native_info == null); + assertFalse("H5Oget_native_info_by_idx ", native_info.hdr_info == null); + assertFalse("H5Oget_native_info_by_idx ", native_info.obj_info == null); + assertFalse("H5Oget_native_info_by_idx ", native_info.attr_info == null); + assertTrue("testH5Oget_native_info_by_idx_n3:Object Header Info", native_info.hdr_info.equals(ohdr)); + assertTrue("testH5Oget_native_info_by_idx_n3:Object Info", native_info.obj_info.equals(oinfo)); + assertTrue("testH5Oget_native_info_by_idx_n3:Attribute Info", native_info.attr_info.equals(ainfo)); } @Test @@ -292,18 +550,18 @@ public class TestH5Obasic { this.link_type = type; } } - class H5O_iter_data implements H5O_iterate_t { + class H5O_iter_data implements H5O_iterate_opdata_t { public ArrayList iterdata = new ArrayList(); } - H5O_iterate_t iter_data = new H5O_iter_data(); - class H5O_iter_callback implements H5O_iterate_cb { - public int callback(long group, String name, H5O_info_t info, H5O_iterate_t op_data) { + H5O_iterate_opdata_t iter_data = new H5O_iter_data(); + class H5O_iter_callback implements H5O_iterate_t { + public int callback(long group, String name, H5O_info_t info, H5O_iterate_opdata_t op_data) { idata id = new idata(name, info.type); ((H5O_iter_data)op_data).iterdata.add(id); return 0; } } - H5O_iterate_cb iter_cb = new H5O_iter_callback(); + H5O_iterate_t iter_cb = new H5O_iter_callback(); try { H5.H5Ovisit(H5fid, HDF5Constants.H5_INDEX_NAME, HDF5Constants.H5_ITER_INC, iter_cb, iter_data); } @@ -331,18 +589,18 @@ public class TestH5Obasic { this.link_type = type; } } - class H5O_iter_data implements H5O_iterate_t { + class H5O_iter_data implements H5O_iterate_opdata_t { public ArrayList iterdata = new ArrayList(); } - H5O_iterate_t iter_data = new H5O_iter_data(); - class H5O_iter_callback implements H5O_iterate_cb { - public int callback(long group, String name, H5O_info_t info, H5O_iterate_t op_data) { + H5O_iterate_opdata_t iter_data = new H5O_iter_data(); + class H5O_iter_callback implements H5O_iterate_t { + public int callback(long group, String name, H5O_info_t info, H5O_iterate_opdata_t op_data) { idata id = new idata(name, info.type); ((H5O_iter_data)op_data).iterdata.add(id); return 0; } } - H5O_iterate_cb iter_cb = new H5O_iter_callback(); + H5O_iterate_t iter_cb = new H5O_iter_callback(); try { H5.H5Ovisit_by_name(H5fid, "G1", HDF5Constants.H5_INDEX_NAME, HDF5Constants.H5_ITER_INC, iter_cb, iter_data, HDF5Constants.H5P_DEFAULT); } @@ -371,7 +629,7 @@ public class TestH5Obasic { } @Test - public void testH5Oopen_by_addr() { + public void testH5Oopen_by_token() { long oid = -1; H5O_info_t obj_info = null; try { @@ -381,32 +639,32 @@ public class TestH5Obasic { } catch (Throwable err) { err.printStackTrace(); - fail("testH5Oopen_by_addr: H5.H5Oget_info: " + err); + fail("testH5Oopen_by_token: H5.H5Oget_info: " + err); } - H5la_ds1 = obj_info.addr; + H5la_ds1 = obj_info.token; try {H5.H5Oclose(oid);} catch (Exception ex) {} try { - oid = H5.H5Oopen_by_addr(H5fid, H5la_ds1); + oid = H5.H5Oopen_by_token(H5fid, H5la_ds1); } catch (Throwable err) { err.printStackTrace(); - fail("testH5Oopen_by_addr: H5.H5Oopen_by_addr: " + err); + fail("testH5Oopen_by_token: H5.H5Oopen_by_token: " + err); } try { obj_info = H5.H5Oget_info(oid); } catch (Throwable err) { err.printStackTrace(); - fail("testH5Oopen_by_addr: H5.H5Oget_info: " + err); + fail("testH5Oopen_by_token: H5.H5Oget_info: " + err); } - assertFalse("testH5Oopen_by_addr: H5Oget_info ",obj_info==null); - assertTrue("testH5Oopen_by_addr: H5Oget_info link type",obj_info.type==HDF5Constants.H5O_TYPE_DATASET); - assertTrue("testH5Oopen_by_addr: Link Address ",obj_info.addr==H5la_ds1); + assertFalse("testH5Oopen_by_token: H5Oget_info ",obj_info==null); + assertTrue("testH5Oopen_by_token: H5Oget_info link type",obj_info.type==HDF5Constants.H5O_TYPE_DATASET); + assertTrue("testH5Oopen_by_token: Link Object Token", obj_info.token.equals(H5la_ds1)); } finally { try{H5.H5Oclose(oid);} catch (Exception ex) {} } - } + } @Test public void testH5Oopen_by_idx_n0() { @@ -421,14 +679,14 @@ public class TestH5Obasic { err.printStackTrace(); fail("testH5Oopen_by_idx_n0: H5.H5Oget_info: " + err); } - H5la_ds1 = obj_info.addr; + H5la_ds1 = obj_info.token; try {H5.H5Oclose(oid);} catch (Exception ex) {} try { oid = H5.H5Oopen_by_idx(H5fid, "/", HDF5Constants.H5_INDEX_NAME, HDF5Constants.H5_ITER_INC, 0, HDF5Constants.H5P_DEFAULT); } catch (Throwable err) { err.printStackTrace(); - fail("testH5Oopen_by_addr: H5.H5Oopen_by_addr: " + err); + fail("testH5Oopen_by_idx_n0: H5.H5Oopen_by_idx: " + err); } try { obj_info = H5.H5Oget_info(oid); @@ -439,7 +697,7 @@ public class TestH5Obasic { } assertFalse("testH5Oopen_by_idx_n0: H5Oget_info_by_idx ",obj_info==null); assertTrue("testH5Oopen_by_idx_n0: H5Oget_info_by_idx link type",obj_info.type==HDF5Constants.H5O_TYPE_DATASET); - assertTrue("testH5Oopen_by_idx_n0: Link Address ",obj_info.addr==H5la_ds1); + assertTrue("testH5Oopen_by_idx_n0: Link Object Token", obj_info.token.equals(H5la_ds1)); } finally { try{H5.H5Oclose(oid);} catch (Exception ex) {} @@ -459,14 +717,14 @@ public class TestH5Obasic { err.printStackTrace(); fail("testH5Oopen_by_idx_n3:H5.H5Oget_info: " + err); } - H5la_l1 = obj_info.addr; + H5la_l1 = obj_info.token; try {H5.H5Oclose(oid);} catch (Exception ex) {} try { oid = H5.H5Oopen_by_idx(H5fid, "/", HDF5Constants.H5_INDEX_NAME, HDF5Constants.H5_ITER_INC, 3, HDF5Constants.H5P_DEFAULT); } catch (Throwable err) { err.printStackTrace(); - fail("testH5Oopen_by_addr: H5.H5Oopen_by_addr: " + err); + fail("testH5Oopen_by_idx_n3: H5.H5Oopen_by_idx: " + err); } try { obj_info = H5.H5Oget_info(oid); @@ -477,7 +735,7 @@ public class TestH5Obasic { } assertFalse("testH5Oopen_by_idx_n3:H5Oget_info_by_idx ",obj_info==null); assertTrue("testH5Oopen_by_idx_n3:H5Oget_info_by_idx link type",obj_info.type==HDF5Constants.H5O_TYPE_DATASET); - assertTrue("testH5Oopen_by_idx_n3:Link Address ",obj_info.addr==H5la_l1); + assertTrue("testH5Oopen_by_idx_n3:Link Object Token", obj_info.token.equals(H5la_l1)); } finally { try{H5.H5Oclose(oid);} catch (Exception ex) {} diff --git a/java/test/TestH5Ocreate.java b/java/test/TestH5Ocreate.java index de17d8b..5e9fdf2 100644 --- a/java/test/TestH5Ocreate.java +++ b/java/test/TestH5Ocreate.java @@ -22,8 +22,8 @@ import java.util.ArrayList; import hdf.hdf5lib.H5; import hdf.hdf5lib.HDF5Constants; -import hdf.hdf5lib.callbacks.H5O_iterate_cb; import hdf.hdf5lib.callbacks.H5O_iterate_t; +import hdf.hdf5lib.callbacks.H5O_iterate_opdata_t; import hdf.hdf5lib.exceptions.HDF5Exception; import hdf.hdf5lib.exceptions.HDF5LibraryException; import hdf.hdf5lib.structs.H5O_info_t; @@ -264,9 +264,9 @@ public class TestH5Ocreate { err.printStackTrace(); fail("H5.H5Oget_info: " + err); } - assertFalse("H5Oget_info ", obj_info==null); + assertFalse("H5Oget_info", obj_info==null); assertTrue("H5Oget_info link type", obj_info.type==HDF5Constants.H5O_TYPE_DATASET); - assertTrue("Link Address ", obj_info.addr>0); + assertTrue("Link Object Token", obj_info.token != null); } @Test(expected = HDF5LibraryException.class) @@ -286,9 +286,9 @@ public class TestH5Ocreate { err.printStackTrace(); fail("H5.H5Oget_info: " + err); } - assertFalse("H5Oget_info ", obj_info==null); + assertFalse("H5Oget_info", obj_info==null); assertTrue("H5Oget_info link type", obj_info.type==HDF5Constants.H5O_TYPE_NAMED_DATATYPE); - assertTrue("Link Address ", obj_info.addr>0); + assertTrue("Link Object Token", obj_info.token != null); } @Test @@ -351,18 +351,18 @@ public class TestH5Ocreate { this.link_type = type; } } - class H5O_iter_data implements H5O_iterate_t { + class H5O_iter_data implements H5O_iterate_opdata_t { public ArrayList iterdata = new ArrayList(); } - H5O_iterate_t iter_data = new H5O_iter_data(); - class H5O_iter_callback implements H5O_iterate_cb { - public int callback(long group, String name, H5O_info_t info, H5O_iterate_t op_data) { + H5O_iterate_opdata_t iter_data = new H5O_iter_data(); + class H5O_iter_callback implements H5O_iterate_t { + public int callback(long group, String name, H5O_info_t info, H5O_iterate_opdata_t op_data) { idata id = new idata(name, info.type); ((H5O_iter_data)op_data).iterdata.add(id); return 0; } } - H5O_iterate_cb iter_cb = new H5O_iter_callback(); + H5O_iterate_t iter_cb = new H5O_iter_callback(); try { H5.H5Ovisit(H5fid, HDF5Constants.H5_INDEX_CRT_ORDER, HDF5Constants.H5_ITER_INC, iter_cb, iter_data); } diff --git a/java/test/TestH5Oparams.java b/java/test/TestH5Oparams.java index cac3dcd..1f379d3 100644 --- a/java/test/TestH5Oparams.java +++ b/java/test/TestH5Oparams.java @@ -95,6 +95,31 @@ public class TestH5Oparams { } @Test(expected = HDF5LibraryException.class) + public void testH5Oget_native_info_invalid() throws Throwable { + H5.H5Oget_native_info(-1, 0); + } + + @Test(expected = NullPointerException.class) + public void testH5Oget_native_info_by_name_null() throws Throwable { + H5.H5Oget_native_info_by_name(-1, null, 0, HDF5Constants.H5P_DEFAULT); + } + + @Test(expected = HDF5LibraryException.class) + public void testH5Oget_native_info_by_name_invalid() throws Throwable { + H5.H5Oget_native_info_by_name(-1, "/testH5Gcreate", 0, HDF5Constants.H5P_DEFAULT); + } + + @Test(expected = HDF5LibraryException.class) + public void testH5Oget_native_info_by_idx_invalid() throws Throwable { + H5.H5Oget_native_info_by_idx(-1, "Bogus", -1, -1, -1L, 0, -1); + } + + @Test(expected = NullPointerException.class) + public void testH5Oget_native_info_by_idx_null() throws Throwable { + H5.H5Oget_native_info_by_idx(-1, null, 0, 0, 0L, 0, 0); + } + + @Test(expected = HDF5LibraryException.class) public void testH5Olink_invalid() throws Throwable { H5.H5Olink(-1, -1, "Bogus", -1, -1); } diff --git a/java/test/TestH5VL.java b/java/test/TestH5VL.java index 0397be1..d774dbb 100644 --- a/java/test/TestH5VL.java +++ b/java/test/TestH5VL.java @@ -69,14 +69,46 @@ public class TestH5VL { @Test public void testH5VLget_connector_id() { + String H5_FILE = "testFvl.h5"; + + long H5fid = H5.H5Fcreate(H5_FILE, HDF5Constants.H5F_ACC_TRUNC, + HDF5Constants.H5P_DEFAULT, HDF5Constants.H5P_DEFAULT); + + try { + long native_id = H5.H5VLget_connector_id(H5fid); + assertTrue("H5.H5VLget_connector_id", native_id >= 0); + + /* + * If HDF5_VOL_CONNECTOR is set, this might not be the + * native connector. Only check for the native connector + * if this isn't set. + */ + String connector = System.getenv("HDF5_VOL_CONNECTOR"); + if (connector == null) + assertEquals(HDF5Constants.H5VL_NATIVE, native_id); + } + catch (Throwable err) { + err.printStackTrace(); + fail("H5.H5VLget_connector_id " + err); + } + finally { + if (H5fid > 0) { + try {H5.H5Fclose(H5fid);} catch (Exception ex) {} + } + _deleteFile(H5_FILE); + } + } + + @Test + public void testH5VLget_connector_id_by_name() { try { - long native_id = H5.H5VLget_connector_id(HDF5Constants.H5VL_NATIVE_NAME); - assertTrue("H5.H5VLget_connector_id H5VL_NATIVE_NAME", native_id >= 0); + long native_id = H5.H5VLget_connector_id_by_name(HDF5Constants.H5VL_NATIVE_NAME); + assertTrue("H5.H5VLget_connector_id_by_name H5VL_NATIVE_NAME", native_id >= 0); assertEquals(HDF5Constants.H5VL_NATIVE, native_id); } catch (Throwable err) { err.printStackTrace(); - fail("H5.H5VLget_connector_id " + err); + fail("H5.H5VLget_connector_id_by_name " + err); } } @@ -90,7 +122,15 @@ public class TestH5VL { try { String native_name = H5.H5VLget_connector_name(H5fid); - assertTrue("H5.H5VLget_connector_name H5VL_NATIVE", native_name.compareToIgnoreCase(HDF5Constants.H5VL_NATIVE_NAME)==0); + + /* + * If HDF5_VOL_CONNECTOR is set, this might not be the + * native connector. Only check for the native connector + * if this isn't set. + */ + String connector = System.getenv("HDF5_VOL_CONNECTOR"); + if (connector == null) + assertTrue("H5.H5VLget_connector_name H5VL_NATIVE", native_name.compareToIgnoreCase(HDF5Constants.H5VL_NATIVE_NAME)==0); } catch (Throwable err) { err.printStackTrace(); diff --git a/java/test/testfiles/JUnit-TestH5Edefault.txt b/java/test/testfiles/JUnit-TestH5Edefault.txt index 48c6254..bb43c64 100644 --- a/java/test/testfiles/JUnit-TestH5Edefault.txt +++ b/java/test/testfiles/JUnit-TestH5Edefault.txt @@ -1,10 +1,8 @@ JUnit version 4.11 -.testH5EprintInt .testH5Eset_current_stack_invalid_stkid .testH5Eset_current_stack .testH5Eget_num .testH5Eclear -.testH5Eprint .testH5Epush_null_name .testH5Eget_num_with_msg .testH5Eclear2_with_msg @@ -30,49 +28,5 @@ JUnit version 4.11 Time: XXXX -OK (28 tests) +OK (26 tests) -HDF5-DIAG: Error detected in HDF5 (version (number)) thread (IDs): - #000: (file name) line (number) in H5Fopen(): unable to open file - major: File accessibility - minor: Unable to open file - #001: (file name) line (number) in H5VL_file_open(): open failed - major: Virtual Object Layer - minor: Can't open object - #002: (file name) line (number) in H5VL__file_open(): open failed - major: Virtual Object Layer - minor: Can't open object - #003: (file name) line (number) in H5VL__native_file_open(): unable to open file - major: File accessibility - minor: Unable to open file - #004: (file name) line (number) in H5F_open(): unable to open file: name = 'test', tent_flags = 1 - major: File accessibility - minor: Unable to open file - #005: (file name) line (number) in H5FD_open(): open failed - major: Virtual File Layer - minor: Unable to initialize object - #006: (file name) line (number) in H5FD_sec2_open(): unable to open file: name = 'test', errno = 2, error message = 'No such file or directory', flags = 1, o_flags = 2 - major: File accessibility - minor: Unable to open file -HDF5-DIAG: Error detected in HDF5 (version (number)) thread (IDs): - #000: (file name) line (number) in H5Fopen(): unable to open file - major: File accessibility - minor: Unable to open file - #001: (file name) line (number) in H5VL_file_open(): open failed - major: Virtual Object Layer - minor: Can't open object - #002: (file name) line (number) in H5VL__file_open(): open failed - major: Virtual Object Layer - minor: Can't open object - #003: (file name) line (number) in H5VL__native_file_open(): unable to open file - major: File accessibility - minor: Unable to open file - #004: (file name) line (number) in H5F_open(): unable to open file: name = 'test', tent_flags = 1 - major: File accessibility - minor: Unable to open file - #005: (file name) line (number) in H5FD_open(): open failed - major: Virtual File Layer - minor: Unable to initialize object - #006: (file name) line (number) in H5FD_sec2_open(): unable to open file: name = 'test', errno = 2, error message = 'No such file or directory', flags = 1, o_flags = 2 - major: File accessibility - minor: Unable to open file diff --git a/java/test/testfiles/JUnit-TestH5Obasic.txt b/java/test/testfiles/JUnit-TestH5Obasic.txt index d015bdd..c39c01d 100644 --- a/java/test/testfiles/JUnit-TestH5Obasic.txt +++ b/java/test/testfiles/JUnit-TestH5Obasic.txt @@ -1,29 +1,45 @@ JUnit version 4.11 .testH5Oexists_by_name +.testH5Oget_native_info_dataset +.testH5Oopen_by_token .testH5Oget_info_by_idx_n0 .testH5Oget_info_by_idx_n3 +.testH5Oget_native_info_datatype .testH5Oget_info_by_name_not_exist_name .testH5Ovisit_by_name +.testH5Oget_native_info_by_name_datatype .testH5Oget_info_by_idx_name_not_exist_name .testH5Oget_info_datatype .testH5Oget_info_by_idx_not_exist_name .testH5Oopen_by_idx_n0 .testH5Oopen_by_idx_n3 +.testH5Oget_native_info_by_name_not_exist_name .testH5Oopen_not_exists .testH5Ovisit .testH5Oget_info_by_idx_not_exist_create +.testH5Oget_native_info_by_idx_not_exist_name .testH5Oget_info_by_name_hardlink .testH5Oget_info_by_name_group -.testH5Oopen_by_addr .testH5Oget_info_by_name_not_exists +.testH5Oget_native_info_by_idx_not_exist_create .testH5Oget_info_by_name_dataset .testH5Oget_info_group +.testH5Oget_native_info_hardlink +.testH5Oget_native_info_by_name_hardlink +.testH5Oget_native_info_by_idx_name_not_exist_name .testH5Oget_info_by_name_datatype .testH5Oget_info_hardlink +.testH5Oget_native_info_group +.testH5Oget_native_info_by_name_not_exists +.testH5Oget_native_info_by_name_dataset .testH5Oget_info_by_idx_name_not_exist_create +.testH5Oget_native_info_by_idx_n0 +.testH5Oget_native_info_by_idx_n3 .testH5Oget_info_dataset +.testH5Oget_native_info_by_name_group +.testH5Oget_native_info_by_idx_name_not_exist_create Time: XXXX -OK (23 tests) +OK (39 tests) diff --git a/java/test/testfiles/JUnit-TestH5Oparams.txt b/java/test/testfiles/JUnit-TestH5Oparams.txt index bc23695..b756bcf 100644 --- a/java/test/testfiles/JUnit-TestH5Oparams.txt +++ b/java/test/testfiles/JUnit-TestH5Oparams.txt @@ -1,22 +1,27 @@ JUnit version 4.11 .testH5Oget_comment_by_name_null +.testH5Oget_native_info_by_name_invalid .testH5Ovisit_by_name_nullname .testH5Oget_info_invalid .testH5Ovisit_by_name_null .testH5Odisable_mdc_flushes .testH5Oget_comment_invalid +.testH5Oget_native_info_invalid .testH5Oset_comment_by_name_invalid .testH5Oare_mdc_flushes_disabled .testH5Oopen_null .testH5Oclose_invalid .testH5Oflush_invalid +.testH5Oget_native_info_by_name_null .testH5Oget_comment_by_name_invalid .testH5Orefresh_invalid .testH5Ocopy_null_dest +.testH5Oget_native_info_by_idx_null .testH5Olink_invalid .testH5Oget_info_by_idx_invalid .testH5Oget_info_by_idx_null .testH5Olink_null_dest +.testH5Oget_native_info_by_idx_invalid .testH5Oget_info_by_name_invalid .testH5Oget_info_by_name_null .testH5Ocopy_invalid @@ -29,5 +34,5 @@ JUnit version 4.11 Time: XXXX -OK (27 tests) +OK (32 tests) diff --git a/java/test/testfiles/JUnit-TestH5VL.txt b/java/test/testfiles/JUnit-TestH5VL.txt index caadf26..f646009 100644 --- a/java/test/testfiles/JUnit-TestH5VL.txt +++ b/java/test/testfiles/JUnit-TestH5VL.txt @@ -1,4 +1,5 @@ JUnit version 4.11 +.testH5VLget_connector_id_by_name .testH5VLget_connector_id .testH5VLnative_init .testH5VLget_connector_name @@ -7,5 +8,5 @@ JUnit version 4.11 Time: XXXX -OK (5 tests) +OK (6 tests) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4b020fa..070cf62 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -386,6 +386,7 @@ IDE_GENERATED_PROPERTIES ("H5I" "${H5I_HDRS}" "${H5I_SOURCES}" ) set (H5L_SOURCES ${HDF5_SRC_DIR}/H5L.c + ${HDF5_SRC_DIR}/H5Ldeprec.c ${HDF5_SRC_DIR}/H5Lexternal.c ) set (H5L_HDRS @@ -659,6 +660,7 @@ set (H5VL_SOURCES ${HDF5_SRC_DIR}/H5VLnative_link.c ${HDF5_SRC_DIR}/H5VLnative_introspect.c ${HDF5_SRC_DIR}/H5VLnative_object.c + ${HDF5_SRC_DIR}/H5VLnative_token.c ${HDF5_SRC_DIR}/H5VLpassthru.c ) set (H5VL_HDRS diff --git a/src/H5A.c b/src/H5A.c index 32bc8d0..f99fb7d 100644 --- a/src/H5A.c +++ b/src/H5A.c @@ -276,7 +276,7 @@ H5Acreate2(hid_t loc_id, const char *attr_name, hid_t type_id, hid_t space_id, hid_t acpl_id, hid_t aapl_id) { void *attr = NULL; /* Attribute created */ - H5VL_object_t *vol_obj = NULL; /* Object token of loc_id */ + H5VL_object_t *vol_obj = NULL; /* Object of loc_id */ H5VL_loc_params_t loc_params; hid_t ret_value = H5I_INVALID_HID; /* Return value */ @@ -360,8 +360,8 @@ H5Acreate_by_name(hid_t loc_id, const char *obj_name, const char *attr_name, hid_t type_id, hid_t space_id, hid_t acpl_id, hid_t aapl_id, hid_t lapl_id) { - void *attr = NULL; /* attr token from VOL connector */ - H5VL_object_t *vol_obj = NULL; /* object token of loc_id */ + void *attr = NULL; /* attr object from VOL connector */ + H5VL_object_t *vol_obj = NULL; /* object of loc_id */ H5VL_loc_params_t loc_params; hid_t ret_value = H5I_INVALID_HID; /* Return value */ @@ -437,8 +437,8 @@ done: hid_t H5Aopen(hid_t loc_id, const char *attr_name, hid_t aapl_id) { - void *attr = NULL; /* attr token from VOL connector */ - H5VL_object_t *vol_obj = NULL; /* object token of loc_id */ + void *attr = NULL; /* attr object from VOL connector */ + H5VL_object_t *vol_obj = NULL; /* object of loc_id */ H5VL_loc_params_t loc_params; hid_t ret_value = H5I_INVALID_HID; @@ -508,8 +508,8 @@ hid_t H5Aopen_by_name(hid_t loc_id, const char *obj_name, const char *attr_name, hid_t aapl_id, hid_t lapl_id) { - void *attr = NULL; /* attr token from VOL connector */ - H5VL_object_t *vol_obj = NULL; /* object token of loc_id */ + void *attr = NULL; /* attr object from VOL connector */ + H5VL_object_t *vol_obj = NULL; /* object of loc_id */ H5VL_loc_params_t loc_params; hid_t ret_value = H5I_INVALID_HID; @@ -587,7 +587,7 @@ H5Aopen_by_idx(hid_t loc_id, const char *obj_name, H5_index_t idx_type, H5_iter_order_t order, hsize_t n, hid_t aapl_id, hid_t lapl_id) { void *attr = NULL; /* Attribute opened */ - H5VL_object_t *vol_obj = NULL; /* object token of loc_id */ + H5VL_object_t *vol_obj = NULL; /* object of loc_id */ H5VL_loc_params_t loc_params; hid_t ret_value = H5I_INVALID_HID; /* Return value */ @@ -1328,7 +1328,7 @@ herr_t H5Aiterate2(hid_t loc_id, H5_index_t idx_type, H5_iter_order_t order, hsize_t *idx, H5A_operator2_t op, void *op_data) { - H5VL_object_t *vol_obj = NULL; /* object token of loc_id */ + H5VL_object_t *vol_obj = NULL; /* object of loc_id */ H5VL_loc_params_t loc_params; herr_t ret_value; /* Return value */ @@ -1407,7 +1407,7 @@ H5Aiterate_by_name(hid_t loc_id, const char *obj_name, H5_index_t idx_type, H5_iter_order_t order, hsize_t *idx, H5A_operator2_t op, void *op_data, hid_t lapl_id) { - H5VL_object_t *vol_obj = NULL; /* object token of loc_id */ + H5VL_object_t *vol_obj = NULL; /* object of loc_id */ H5VL_loc_params_t loc_params; herr_t ret_value = SUCCEED; /* Return value */ diff --git a/src/H5Adeprec.c b/src/H5Adeprec.c index 5fc2823..e0a0f55 100644 --- a/src/H5Adeprec.c +++ b/src/H5Adeprec.c @@ -116,8 +116,8 @@ hid_t H5Acreate1(hid_t loc_id, const char *name, hid_t type_id, hid_t space_id, hid_t acpl_id) { - void *attr = NULL; /* attr token from VOL connector */ - H5VL_object_t *vol_obj = NULL; /* Object token of loc_id */ + void *attr = NULL; /* attr object from VOL connector */ + H5VL_object_t *vol_obj = NULL; /* Object of loc_id */ H5VL_loc_params_t loc_params; hid_t ret_value = H5I_INVALID_HID; /* Return value */ @@ -190,8 +190,8 @@ done: hid_t H5Aopen_name(hid_t loc_id, const char *name) { - void *attr = NULL; /* attr token from VOL connector */ - H5VL_object_t *vol_obj = NULL; /* Object token of loc_id */ + void *attr = NULL; /* attr object from VOL connector */ + H5VL_object_t *vol_obj = NULL; /* Object of loc_id */ H5VL_loc_params_t loc_params; hid_t ret_value = H5I_INVALID_HID; /* Return value */ @@ -256,8 +256,8 @@ done: hid_t H5Aopen_idx(hid_t loc_id, unsigned idx) { - void *attr = NULL; /* attr token from VOL connector */ - H5VL_object_t *vol_obj = NULL; /* Object token of loc_id */ + void *attr = NULL; /* attr object from VOL connector */ + H5VL_object_t *vol_obj = NULL; /* Object of loc_id */ H5VL_loc_params_t loc_params; hid_t ret_value = H5I_INVALID_HID; /* Return value */ @@ -321,9 +321,9 @@ done: int H5Aget_num_attrs(hid_t loc_id) { - H5VL_object_t *vol_obj = NULL; /* Object token of loc_id */ + H5VL_object_t *vol_obj = NULL; /* Object of loc_id */ H5VL_loc_params_t loc_params; - H5O_info_t oinfo; + H5O_info2_t oinfo; int ret_value = -1; FUNC_ENTER_API((-1)) @@ -337,7 +337,7 @@ H5Aget_num_attrs(hid_t loc_id) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, (-1), "invalid location identifier") /* Get the number of attributes for the object */ - if(H5VL_object_optional(vol_obj, H5VL_NATIVE_OBJECT_GET_INFO, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, &loc_params, &oinfo, H5O_INFO_ALL) < 0) + if(H5VL_object_get(vol_obj, &loc_params, H5VL_OBJECT_GET_INFO, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, &oinfo, H5O_INFO_NUM_ATTRS) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, (-1), "unable to get attribute count for object") H5_CHECKED_ASSIGN(ret_value, int, oinfo.num_attrs, hsize_t); @@ -387,7 +387,7 @@ done: herr_t H5Aiterate1(hid_t loc_id, unsigned *attr_num, H5A_operator1_t op, void *op_data) { - H5VL_object_t *vol_obj = NULL; /* Object token of loc_id */ + H5VL_object_t *vol_obj = NULL; /* Object of loc_id */ herr_t ret_value; /* Return value */ FUNC_ENTER_API(H5_ITER_ERROR) diff --git a/src/H5Cpkg.h b/src/H5Cpkg.h index 9156c0d..cafc6d5 100644 --- a/src/H5Cpkg.h +++ b/src/H5Cpkg.h @@ -4923,7 +4923,7 @@ H5_DLL herr_t H5C__untag_entry(H5C_t *cache, H5C_cache_entry_t *entry); /* Testing functions */ #ifdef H5C_TESTING -H5_DLL herr_t H5C__verify_cork_tag_test(hid_t fid, haddr_t tag, hbool_t status); +H5_DLL herr_t H5C__verify_cork_tag_test(hid_t fid, H5O_token_t tag_token, hbool_t status); #endif /* H5C_TESTING */ #endif /* _H5Cpkg_H */ diff --git a/src/H5Ctest.c b/src/H5Ctest.c index 340071a..7f24302 100644 --- a/src/H5Ctest.c +++ b/src/H5Ctest.c @@ -35,12 +35,13 @@ /***********/ /* Headers */ /***********/ -#include "H5private.h" /* Generic Functions */ -#include "H5Cpkg.h" /* Cache */ -#include "H5Eprivate.h" /* Error handling */ -#include "H5Fpkg.h" /* Files */ -#include "H5Iprivate.h" /* IDs */ +#include "H5private.h" /* Generic Functions */ +#include "H5Cpkg.h" /* Cache */ +#include "H5Eprivate.h" /* Error handling */ +#include "H5Fpkg.h" /* Files */ +#include "H5Iprivate.h" /* IDs */ #include "H5VLprivate.h" /* Virtual Object Layer */ +#include "H5VLnative_private.h" /* Native VOL connector */ /****************/ @@ -132,11 +133,12 @@ done: *------------------------------------------------------------------------- */ herr_t -H5C__verify_cork_tag_test(hid_t fid, haddr_t tag, hbool_t status) +H5C__verify_cork_tag_test(hid_t fid, H5O_token_t tag_token, hbool_t status) { H5F_t * f; /* File Pointer */ H5C_t * cache; /* Cache Pointer */ H5C_tag_iter_vct_ctx_t ctx; /* Context for iterator callback */ + haddr_t tag; /* Tagged address */ herr_t ret_value = SUCCEED; /* Return value */ /* Function enter macro */ @@ -146,6 +148,11 @@ H5C__verify_cork_tag_test(hid_t fid, haddr_t tag, hbool_t status) if(NULL == (f = (H5F_t *)H5VL_object_verify(fid, H5I_FILE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file") + /* Convert token to address */ + tag = HADDR_UNDEF; + if(H5VL_native_token_to_addr(f, H5I_FILE, tag_token, &tag) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_CANTGET, FAIL, "can't get address for token") + /* Get cache pointer */ cache = f->shared->cache; diff --git a/src/H5D.c b/src/H5D.c index 97bc0df..178bb30 100644 --- a/src/H5D.c +++ b/src/H5D.c @@ -100,7 +100,7 @@ H5Dcreate2(hid_t loc_id, const char *name, hid_t type_id, hid_t space_id, hid_t lcpl_id, hid_t dcpl_id, hid_t dapl_id) { void *dset = NULL; /* New dataset's info */ - H5VL_object_t *vol_obj = NULL; /* object token of loc_id */ + H5VL_object_t *vol_obj = NULL; /* object of loc_id */ H5VL_loc_params_t loc_params; hid_t ret_value = H5I_INVALID_HID; /* Return value */ @@ -199,8 +199,8 @@ hid_t H5Dcreate_anon(hid_t loc_id, hid_t type_id, hid_t space_id, hid_t dcpl_id, hid_t dapl_id) { - void *dset = NULL; /* dset token from VOL connector */ - H5VL_object_t *vol_obj = NULL; /* object token of loc_id */ + void *dset = NULL; /* dset object from VOL connector */ + H5VL_object_t *vol_obj = NULL; /* object of loc_id */ H5VL_loc_params_t loc_params; hid_t ret_value = H5I_INVALID_HID; /* Return value */ @@ -265,8 +265,8 @@ done: hid_t H5Dopen2(hid_t loc_id, const char *name, hid_t dapl_id) { - void *dset = NULL; /* dset token from VOL connector */ - H5VL_object_t *vol_obj = NULL; /* object token of loc_id */ + void *dset = NULL; /* dset object from VOL connector */ + H5VL_object_t *vol_obj = NULL; /* object of loc_id */ H5VL_loc_params_t loc_params; hid_t ret_value = H5I_INVALID_HID; /* Return value */ diff --git a/src/H5Ddeprec.c b/src/H5Ddeprec.c index 2b50559..f4f4223 100644 --- a/src/H5Ddeprec.c +++ b/src/H5Ddeprec.c @@ -113,8 +113,8 @@ hid_t H5Dcreate1(hid_t loc_id, const char *name, hid_t type_id, hid_t space_id, hid_t dcpl_id) { - void *dset = NULL; /* dset token from VOL connector */ - H5VL_object_t *vol_obj = NULL; /* object token of loc_id */ + void *dset = NULL; /* dset object from VOL connector */ + H5VL_object_t *vol_obj = NULL; /* object of loc_id */ H5VL_loc_params_t loc_params; hid_t ret_value = H5I_INVALID_HID; /* Return value */ @@ -186,8 +186,8 @@ done: hid_t H5Dopen1(hid_t loc_id, const char *name) { - void *dset = NULL; /* dset token from VOL connector */ - H5VL_object_t *vol_obj = NULL; /* object token of loc_id */ + void *dset = NULL; /* dset object from VOL connector */ + H5VL_object_t *vol_obj = NULL; /* object of loc_id */ H5VL_loc_params_t loc_params; hid_t ret_value = H5I_INVALID_HID; /* Return value */ diff --git a/src/H5Epkg.h b/src/H5Epkg.h index ac98496..86b5b73 100644 --- a/src/H5Epkg.h +++ b/src/H5Epkg.h @@ -77,7 +77,7 @@ typedef struct { } H5E_auto_op_t; #else /* H5_NO_DEPRECATED_SYMBOLS */ typedef struct { - H5E_auto_t func2; /* Only the new style callback function is available. */ + H5E_auto2_t func2; /* Only the new style callback function is available. */ } H5E_auto_op_t; #endif /* H5_NO_DEPRECATED_SYMBOLS */ diff --git a/src/H5Epublic.h b/src/H5Epublic.h index 3eae2da..ed14217 100644 --- a/src/H5Epublic.h +++ b/src/H5Epublic.h @@ -100,14 +100,14 @@ H5_DLLVAR hid_t H5E_ERR_CLS_g; } #else /* H5_NO_DEPRECATED_SYMBOLS */ #define H5E_BEGIN_TRY { \ - H5E_auto_t saved_efunc; \ + H5E_auto2_t saved_efunc; \ void *H5E_saved_edata; \ \ - (void)H5Eget_auto(H5E_DEFAULT, &saved_efunc, &H5E_saved_edata); \ - (void)H5Eset_auto(H5E_DEFAULT, NULL, NULL); + (void)H5Eget_auto2(H5E_DEFAULT, &saved_efunc, &H5E_saved_edata); \ + (void)H5Eset_auto2(H5E_DEFAULT, NULL, NULL); #define H5E_END_TRY \ - (void)H5Eset_auto(H5E_DEFAULT, saved_efunc, H5E_saved_edata); \ + (void)H5Eset_auto2(H5E_DEFAULT, saved_efunc, H5E_saved_edata); \ } #endif /* H5_NO_DEPRECATED_SYMBOLS */ diff --git a/src/H5Fint.c b/src/H5Fint.c index 8b3d927..1fd8f48 100644 --- a/src/H5Fint.c +++ b/src/H5Fint.c @@ -3581,78 +3581,6 @@ done: } /* H5F__format_convert() */ -/*--------------------------------------------------------------------------- - * Function: H5F__get_file - * - * Purpose: Utility routine to get file struct for an object - * - * Returns: SUCCESS: A pointer to the H5F_t struct for the file - * associated with the object. - * FAILURE: NULL - * - *--------------------------------------------------------------------------- - */ -H5F_t * -H5F__get_file(void *obj, H5I_type_t type) -{ - H5F_t *ret_value = NULL; /* File pointer */ - H5O_loc_t *oloc = NULL; /* Object location for ID */ - - FUNC_ENTER_PACKAGE - - switch(type) { - case H5I_FILE: - ret_value = (H5F_t *)obj; - break; - - case H5I_GROUP: - oloc = H5G_oloc((H5G_t *)obj); - break; - - case H5I_DATATYPE: - oloc = H5T_oloc((H5T_t *)obj); - break; - - case H5I_DATASET: - oloc = H5D_oloc((H5D_t *)obj); - break; - - case H5I_ATTR: - oloc = H5A_oloc((H5A_t *)obj); - break; - - case H5I_MAP: - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "maps not supported in native VOL connector") - - case H5I_UNINIT: - case H5I_BADID: - case H5I_DATASPACE: - case H5I_VFL: - case H5I_VOL: - case H5I_GENPROP_CLS: - case H5I_GENPROP_LST: - case H5I_ERROR_CLASS: - case H5I_ERROR_MSG: - case H5I_ERROR_STACK: - case H5I_SPACE_SEL_ITER: - case H5I_NTYPES: - default: - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a file or file object") - } /* end switch */ - - /* Set return value for objects (not files) */ - if(oloc) - ret_value = oloc->file; - - /* Couldn't find a file struct */ - if(!ret_value) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "object is not associated with a file") - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* H5F__get_file */ - - /*------------------------------------------------------------------------- * Function: H5F_get_file_id * diff --git a/src/H5Fpkg.h b/src/H5Fpkg.h index 6e2c994..b85305e 100644 --- a/src/H5Fpkg.h +++ b/src/H5Fpkg.h @@ -411,7 +411,6 @@ H5_DLL herr_t H5F__format_convert(H5F_t *f); H5_DLL herr_t H5F__start_swmr_write(H5F_t *f); H5_DLL herr_t H5F__close(H5F_t *f); H5_DLL herr_t H5F__set_libver_bounds(H5F_t *f, H5F_libver_t low, H5F_libver_t high); -H5_DLL H5F_t *H5F__get_file(void *obj, H5I_type_t type); H5_DLL herr_t H5F__get_cont_info(const H5F_t *f, H5VL_file_cont_info_t *info); /* File mount related routines */ diff --git a/src/H5G.c b/src/H5G.c index f2245ea..a766e8a 100644 --- a/src/H5G.c +++ b/src/H5G.c @@ -341,7 +341,7 @@ H5Gcreate2(hid_t loc_id, const char *name, hid_t lcpl_id, hid_t gcpl_id, hid_t gapl_id) { void *grp = NULL; /* Structure for new group */ - H5VL_object_t *vol_obj = NULL; /* object token of loc_id */ + H5VL_object_t *vol_obj = NULL; /* object of loc_id */ H5VL_loc_params_t loc_params; hid_t ret_value = H5I_INVALID_HID; /* Return value */ @@ -436,7 +436,7 @@ hid_t H5Gcreate_anon(hid_t loc_id, hid_t gcpl_id, hid_t gapl_id) { void *grp = NULL; /* Structure for new group */ - H5VL_object_t *vol_obj = NULL; /* Object token for loc_id */ + H5VL_object_t *vol_obj = NULL; /* Object for loc_id */ H5VL_loc_params_t loc_params; hid_t ret_value = H5I_INVALID_HID; /* Return value */ @@ -498,8 +498,8 @@ done: hid_t H5Gopen2(hid_t loc_id, const char *name, hid_t gapl_id) { - void *grp = NULL; /* Group opened */ - H5VL_object_t *vol_obj = NULL; /* object token of loc_id */ + void *grp = NULL; /* Group opened */ + H5VL_object_t *vol_obj = NULL; /* object of loc_id */ H5VL_loc_params_t loc_params; hid_t ret_value = H5I_INVALID_HID; /* Return value */ diff --git a/src/H5Gdeprec.c b/src/H5Gdeprec.c index 830b0eb..126456b 100644 --- a/src/H5Gdeprec.c +++ b/src/H5Gdeprec.c @@ -173,7 +173,7 @@ hid_t H5Gcreate1(hid_t loc_id, const char *name, size_t size_hint) { void *grp = NULL; /* New group created */ - H5VL_object_t *vol_obj; /* Object token of loc_id */ + H5VL_object_t *vol_obj; /* Object of loc_id */ H5VL_loc_params_t loc_params; hid_t tmp_gcpl = H5I_INVALID_HID; /* Temporary group creation property list */ hid_t ret_value = H5I_INVALID_HID; /* Return value */ @@ -269,7 +269,7 @@ hid_t H5Gopen1(hid_t loc_id, const char *name) { void *grp = NULL; /* Group opened */ - H5VL_object_t *vol_obj = NULL; /* Object token of loc_id */ + H5VL_object_t *vol_obj = NULL; /* Object of loc_id */ H5VL_loc_params_t loc_params; hid_t ret_value = H5I_INVALID_HID; /* Return value */ @@ -334,10 +334,10 @@ H5Glink(hid_t cur_loc_id, H5G_link_t type, const char *cur_name, const char *new /* Create link */ if(type == H5L_TYPE_HARD) { - H5VL_object_t *vol_obj; /* Object token of loc_id */ + H5VL_object_t *vol_obj; /* Object of loc_id */ H5VL_loc_params_t loc_params1; H5VL_loc_params_t loc_params2; - H5VL_object_t tmp_vol_obj; /* Temporary object token of */ + H5VL_object_t tmp_vol_obj; /* Temporary object */ loc_params1.type = H5VL_OBJECT_BY_NAME; loc_params1.obj_type = H5I_get_type(cur_loc_id); @@ -362,7 +362,7 @@ H5Glink(hid_t cur_loc_id, H5G_link_t type, const char *cur_name, const char *new HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create link") } /* end if */ else if(type == H5L_TYPE_SOFT) { - H5VL_object_t *vol_obj; /* Object token of loc_id */ + H5VL_object_t *vol_obj; /* Object of loc_id */ H5VL_loc_params_t loc_params; loc_params.type = H5VL_OBJECT_BY_NAME; @@ -416,8 +416,8 @@ H5Glink2(hid_t cur_loc_id, const char *cur_name, H5G_link_t type, /* Create the appropriate kind of link */ if(type == H5L_TYPE_HARD) { - H5VL_object_t *vol_obj1; /* Object token of loc_id */ - H5VL_object_t *vol_obj2; /* Object token of loc_id */ + H5VL_object_t *vol_obj1; /* Object of loc_id */ + H5VL_object_t *vol_obj2; /* Object of loc_id */ H5VL_loc_params_t loc_params1; H5VL_loc_params_t loc_params2; @@ -443,7 +443,7 @@ H5Glink2(hid_t cur_loc_id, const char *cur_name, H5G_link_t type, HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create link") } /* end if */ else if(type == H5L_TYPE_SOFT) { - H5VL_object_t *vol_obj; /* Object token of loc_id */ + H5VL_object_t *vol_obj; /* Object of loc_id */ H5VL_loc_params_t loc_params; /* Soft links only need one location, the new_loc_id, but it's possible that @@ -483,7 +483,7 @@ done: herr_t H5Gmove(hid_t src_loc_id, const char *src_name, const char *dst_name) { - H5VL_object_t *vol_obj; /* Object token of loc_id */ + H5VL_object_t *vol_obj; /* Object of loc_id */ H5VL_loc_params_t loc_params1; H5VL_loc_params_t loc_params2; herr_t ret_value = SUCCEED; /* Return value */ @@ -529,9 +529,9 @@ herr_t H5Gmove2(hid_t src_loc_id, const char *src_name, hid_t dst_loc_id, const char *dst_name) { - H5VL_object_t *vol_obj1 = NULL; /* Object token of src_id */ + H5VL_object_t *vol_obj1 = NULL; /* Object of src_id */ H5VL_loc_params_t loc_params1; - H5VL_object_t *vol_obj2 = NULL; /* Object token of dst_id */ + H5VL_object_t *vol_obj2 = NULL; /* Object of dst_id */ H5VL_loc_params_t loc_params2; herr_t ret_value = SUCCEED; /* Return value */ @@ -583,7 +583,7 @@ done: herr_t H5Gunlink(hid_t loc_id, const char *name) { - H5VL_object_t *vol_obj; /* Object token of loc_id */ + H5VL_object_t *vol_obj; /* Object of loc_id */ H5VL_loc_params_t loc_params; herr_t ret_value = SUCCEED; /* Return value */ @@ -627,7 +627,7 @@ done: herr_t H5Gget_linkval(hid_t loc_id, const char *name, size_t size, char *buf/*out*/) { - H5VL_object_t *vol_obj; /* Object token of loc_id */ + H5VL_object_t *vol_obj; /* Object of loc_id */ H5VL_loc_params_t loc_params; herr_t ret_value = SUCCEED; /* Return value */ @@ -680,7 +680,7 @@ done: herr_t H5Gset_comment(hid_t loc_id, const char *name, const char *comment) { - H5VL_object_t *vol_obj; /* Object token of loc_id */ + H5VL_object_t *vol_obj; /* Object of loc_id */ H5VL_loc_params_t loc_params; herr_t ret_value = SUCCEED; /* Return value */ @@ -739,7 +739,7 @@ done: int H5Gget_comment(hid_t loc_id, const char *name, size_t bufsize, char *buf) { - H5VL_object_t *vol_obj; /* Object token of loc_id */ + H5VL_object_t *vol_obj; /* Object of loc_id */ H5VL_loc_params_t loc_params; ssize_t op_ret; /* Return value from operation */ int ret_value; /* Return value */ @@ -806,7 +806,7 @@ herr_t H5Giterate(hid_t loc_id, const char *name, int *idx_p, H5G_iterate_t op, void *op_data) { - H5VL_object_t *vol_obj; /* Object token of loc_id */ + H5VL_object_t *vol_obj; /* Object of loc_id */ H5VL_loc_params_t loc_params; H5G_link_iterate_t lnk_op; /* Link operator */ hsize_t last_obj; /* Index of last object looked at */ @@ -874,7 +874,7 @@ done: herr_t H5Gget_num_objs(hid_t loc_id, hsize_t *num_objs) { - H5VL_object_t *vol_obj; /* Object token of loc_id */ + H5VL_object_t *vol_obj; /* Object of loc_id */ H5I_type_t id_type; /* Type of ID */ H5VL_loc_params_t loc_params; H5G_info_t grp_info; /* Group information */ @@ -931,7 +931,7 @@ herr_t H5Gget_objinfo(hid_t loc_id, const char *name, hbool_t follow_link, H5G_stat_t *statbuf/*out*/) { - H5VL_object_t *vol_obj = NULL; /* Object token of loc_id */ + H5VL_object_t *vol_obj = NULL; /* Object of loc_id */ H5VL_loc_params_t loc_params; herr_t ret_value = SUCCEED; /* Return value */ @@ -1003,38 +1003,45 @@ H5G__get_objinfo_cb(H5G_loc_t H5_ATTR_UNUSED *grp_loc/*in*/, const char *name, c /* Info for soft and UD links is gotten by H5L_get_info. If we have * a hard link, follow it and get info on the object */ - if (udata->follow_link || !lnk || (lnk->type == H5L_TYPE_HARD)) { - H5O_info_t oinfo; /* Object information */ + if(udata->follow_link || !lnk || (lnk->type == H5L_TYPE_HARD)) { + H5O_info2_t dm_info; /* Data model information */ + H5O_native_info_t nat_info; /* Native information */ + haddr_t obj_addr; /* Address of object */ - /* Go retrieve the object information */ + /* Go retrieve the data model & native object information */ /* (don't need index & heap info) */ HDassert(obj_loc); - if (H5O_get_info(obj_loc->oloc, &oinfo, H5O_INFO_BASIC|H5O_INFO_TIME|H5O_INFO_HDR) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "unable to get object info"); + if(H5O_get_info(obj_loc->oloc, &dm_info, H5O_INFO_BASIC | H5O_INFO_TIME) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "unable to get data model object info") + if(H5O_get_native_info(obj_loc->oloc, &nat_info, H5O_INFO_HDR) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "unable to get native object info") /* Get mapped object type */ - statbuf->type = H5G_map_obj_type(oinfo.type); + statbuf->type = H5G_map_obj_type(dm_info.type); /* Get object number (i.e. address) for object */ - statbuf->objno[0] = (unsigned long)(oinfo.addr); + if(H5VL_native_token_to_addr(obj_loc->oloc->file, H5I_FILE, dm_info.token, &obj_addr) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTUNSERIALIZE, FAIL, "can't deserialize object token into address") + + statbuf->objno[0] = (unsigned long)(obj_addr); #if H5_SIZEOF_UINT64_T > H5_SIZEOF_LONG - statbuf->objno[1] = (unsigned long)(oinfo.addr >> 8 * sizeof(long)); + statbuf->objno[1] = (unsigned long)(obj_addr >> 8 * sizeof(long)); #else statbuf->objno[1] = 0; #endif /* Get # of hard links pointing to object */ - statbuf->nlink = oinfo.rc; + statbuf->nlink = dm_info.rc; /* Get modification time for object */ - statbuf->mtime = oinfo.ctime; + statbuf->mtime = dm_info.ctime; /* Retrieve the object header information */ - statbuf->ohdr.size = oinfo.hdr.space.total; - statbuf->ohdr.free = oinfo.hdr.space.free; - statbuf->ohdr.nmesgs = oinfo.hdr.nmesgs; - statbuf->ohdr.nchunks = oinfo.hdr.nchunks; - } - } + statbuf->ohdr.size = nat_info.hdr.space.total; + statbuf->ohdr.free = nat_info.hdr.space.free; + statbuf->ohdr.nmesgs = nat_info.hdr.nmesgs; + statbuf->ohdr.nchunks = nat_info.hdr.nchunks; + } /* end if */ + } /* end if */ done: /* Indicate that this callback didn't take ownership of the group * @@ -1089,7 +1096,7 @@ H5G__get_objinfo(const H5G_loc_t *loc, const char *name, hbool_t follow_link, /* If we're pointing at a soft or UD link, get the real link length and type */ if (statbuf && follow_link == 0) { - H5L_info_t linfo; /* Link information buffer */ + H5L_info2_t linfo; /* Link information buffer */ herr_t ret; /* Get information about link to the object. If this fails, e.g. @@ -1142,7 +1149,7 @@ done: ssize_t H5Gget_objname_by_idx(hid_t loc_id, hsize_t idx, char *name, size_t size) { - H5VL_object_t *vol_obj; /* Object token of loc_id */ + H5VL_object_t *vol_obj; /* Object of loc_id */ H5VL_loc_params_t loc_params; ssize_t ret_value; /* Return value */ @@ -1193,10 +1200,9 @@ done: H5G_obj_t H5Gget_objtype_by_idx(hid_t loc_id, hsize_t idx) { - H5VL_object_t *vol_obj; /* Object token of loc_id */ + H5VL_object_t *vol_obj; /* Object of loc_id */ H5VL_loc_params_t loc_params; - H5O_info_t oinfo; /* Object info (contains object type) */ - unsigned fields; /* Which fields in object info to populate */ + H5O_info2_t oinfo; /* Object info (contains object type) */ H5G_obj_t ret_value; /* Return value */ FUNC_ENTER_API(H5G_UNKNOWN) @@ -1216,8 +1222,7 @@ H5Gget_objtype_by_idx(hid_t loc_id, hsize_t idx) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5G_UNKNOWN, "invalid location identifier") /* Retrieve the object's basic information (which includes its type) */ - fields = H5O_INFO_BASIC; - if(H5VL_object_optional(vol_obj, H5VL_NATIVE_OBJECT_GET_INFO, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, &loc_params, &oinfo, fields) < 0) + if(H5VL_object_get(vol_obj, &loc_params, H5VL_OBJECT_GET_INFO, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, &oinfo, H5O_INFO_BASIC) < 0) HGOTO_ERROR(H5E_SYM, H5E_BADTYPE, H5G_UNKNOWN, "can't get object info") /* Map to group object type */ diff --git a/src/H5Gint.c b/src/H5Gint.c index 049c696..e0b8bd7 100644 --- a/src/H5Gint.c +++ b/src/H5Gint.c @@ -58,6 +58,7 @@ typedef struct { /* User data for application-style iteration over links in a group */ typedef struct { hid_t gid; /* The group ID for the application callback */ + H5O_loc_t *link_loc; /* The object location for the link */ H5G_link_iterate_t lnk_op; /* Application callback */ void *op_data; /* Application's op data */ } H5G_iter_appcall_ud_t; @@ -72,7 +73,7 @@ typedef struct { char *path; /* Path name of the link */ size_t curr_path_len; /* Current length of the path in the buffer */ size_t path_buf_size; /* Size of path buffer */ - H5L_iterate_t op; /* Application callback */ + H5L_iterate2_t op; /* Application callback */ void *op_data; /* Application's op data */ } H5G_iter_visit_ud_t; @@ -752,10 +753,10 @@ H5G_iterate_cb(const H5O_link_t *lnk, void *_udata) case H5G_LINK_OP_NEW: { - H5L_info_t info; /* Link info */ + H5L_info2_t info; /* Link info */ /* Retrieve the info for the link */ - if(H5G_link_to_info(lnk, &info) < 0) + if(H5G_link_to_info(udata->link_loc, lnk, &info) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTGET, H5_ITER_ERROR, "unable to get info for link") /* Make the application callback */ @@ -812,6 +813,7 @@ H5G_iterate(H5G_loc_t *loc, const char *group_name, /* Set up user data for callback */ udata.gid = gid; + udata.link_loc = &grp->oloc; udata.lnk_op = *lnk_op; udata.op_data = op_data; @@ -872,7 +874,7 @@ static herr_t H5G_visit_cb(const H5O_link_t *lnk, void *_udata) { H5G_iter_visit_ud_t *udata = (H5G_iter_visit_ud_t *)_udata; /* User data for callback */ - H5L_info_t info; /* Link info */ + H5L_info2_t info; /* Link info */ H5G_loc_t obj_loc; /* Location of object */ H5G_name_t obj_path; /* Object's group hier. path */ H5O_loc_t obj_oloc; /* Object's object location */ @@ -908,7 +910,7 @@ H5G_visit_cb(const H5O_link_t *lnk, void *_udata) udata->curr_path_len += link_name_len; /* Construct the link info from the link message */ - if(H5G_link_to_info(lnk, &info) < 0) + if(H5G_link_to_info(udata->curr_loc->oloc, lnk, &info) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTGET, H5_ITER_ERROR, "unable to get info for link") /* Make the application callback */ @@ -1044,7 +1046,7 @@ done: */ herr_t H5G_visit(H5G_loc_t *loc, const char *group_name, H5_index_t idx_type, - H5_iter_order_t order, H5L_iterate_t op, void *op_data) + H5_iter_order_t order, H5L_iterate2_t op, void *op_data) { H5G_iter_visit_ud_t udata; /* User data for callback */ H5O_linfo_t linfo; /* Link info message */ diff --git a/src/H5Glink.c b/src/H5Glink.c index 04ccbc5..6c42f1d 100644 --- a/src/H5Glink.c +++ b/src/H5Glink.c @@ -41,6 +41,8 @@ #include "H5MMprivate.h" /* Memory management */ #include "H5Ppublic.h" /* Property Lists */ +#include "H5VLnative_private.h" /* Native VOL connector */ + /****************/ /* Local Macros */ @@ -290,13 +292,14 @@ done: *------------------------------------------------------------------------- */ herr_t -H5G_link_to_info(const H5O_link_t *lnk, H5L_info_t *info) +H5G_link_to_info(const H5O_loc_t *link_loc, const H5O_link_t *lnk, H5L_info2_t *info) { herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ + HDassert(link_loc); HDassert(lnk); /* Get information from the link */ @@ -308,7 +311,9 @@ H5G_link_to_info(const H5O_link_t *lnk, H5L_info_t *info) switch(lnk->type) { case H5L_TYPE_HARD: - info->u.address = lnk->u.hard.addr; + /* Serialize the address into a VOL token */ + if(H5VL_native_addr_to_token(link_loc->file, H5I_FILE, lnk->u.hard.addr, &info->u.token) < 0) + HGOTO_ERROR(H5E_LINK, H5E_CANTSERIALIZE, FAIL, "can't serialize address into object token") break; case H5L_TYPE_SOFT: diff --git a/src/H5Gloc.c b/src/H5Gloc.c index 56608e2..4d89abb 100644 --- a/src/H5Gloc.c +++ b/src/H5Gloc.c @@ -73,15 +73,24 @@ typedef struct { H5G_loc_t *loc; /* Group location to set */ } H5G_loc_fbi_t; -/* User data for getting an object's info in a group */ +/* User data for getting an object's data model info in a group */ typedef struct { /* downward */ - unsigned fields; /* which fields in H5O_info_t struct to fill in */ + unsigned fields; /* which fields in H5O_info2_t struct to fill in */ /* upward */ - H5O_info_t *oinfo; /* Object information to retrieve */ + H5O_info2_t *oinfo; /* Object information to retrieve */ } H5G_loc_info_t; +/* User data for getting an object's native info in a group */ +typedef struct { + /* downward */ + unsigned fields; /* which fields in H5O_native_info_t struct to fill in */ + + /* upward */ + H5O_native_info_t *oinfo; /* Object information to retrieve */ +} H5G_loc_native_info_t; + /* User data for setting an object's comment in a group */ typedef struct { /* downward */ @@ -116,6 +125,8 @@ static herr_t H5G__loc_addr_cb(H5G_loc_t *grp_loc, const char *name, const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata, H5G_own_loc_t *own_loc); static herr_t H5G__loc_info_cb(H5G_loc_t *grp_loc, const char *name, const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata, H5G_own_loc_t *own_loc); +static herr_t H5G__loc_native_info_cb(H5G_loc_t *grp_loc, const char *name, + const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata, H5G_own_loc_t *own_loc); static herr_t H5G__loc_set_comment_cb(H5G_loc_t *grp_loc, const char *name, const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata, H5G_own_loc_t *own_loc); @@ -762,7 +773,7 @@ done: /*------------------------------------------------------------------------- * Function: H5G__loc_info_cb * - * Purpose: Callback for retrieving object info for an object in a group + * Purpose: Callback for retrieving data model info for an object in a group * * Return: Non-negative on success/Negative on failure * @@ -800,7 +811,7 @@ done: /*------------------------------------------------------------------------- * Function: H5G_loc_info * - * Purpose: Retrieve the information for an object from a group location + * Purpose: Retrieve the data model information for an object from a group location * and path to that object * * Return: Non-negative on success/Negative on failure @@ -811,7 +822,7 @@ done: *------------------------------------------------------------------------- */ herr_t -H5G_loc_info(const H5G_loc_t *loc, const char *name, H5O_info_t *oinfo/*out*/, unsigned fields) +H5G_loc_info(const H5G_loc_t *loc, const char *name, H5O_info2_t *oinfo/*out*/, unsigned fields) { H5G_loc_info_t udata; /* User data for traversal callback */ herr_t ret_value = SUCCEED; /* Return value */ @@ -837,6 +848,84 @@ done: /*------------------------------------------------------------------------- + * Function: H5G__loc_native_info_cb + * + * Purpose: Callback for retrieving native info for an object in a group + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * Thursday, November 23, 2006 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5G__loc_native_info_cb(H5G_loc_t H5_ATTR_UNUSED *grp_loc/*in*/, const char H5_ATTR_UNUSED *name, const H5O_link_t H5_ATTR_UNUSED *lnk, + H5G_loc_t *obj_loc, void *_udata/*in,out*/, H5G_own_loc_t *own_loc/*out*/) +{ + H5G_loc_native_info_t *udata = (H5G_loc_native_info_t *)_udata; /* User data passed in */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + /* Check if the name in this group resolved to a valid link */ + if(obj_loc == NULL) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "name doesn't exist") + + /* Query object information */ + if(H5O_get_native_info(obj_loc->oloc, udata->oinfo, udata->fields) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't get object info") + +done: + /* Indicate that this callback didn't take ownership of the group * + * location for the object */ + *own_loc = H5G_OWN_NONE; + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5G__loc_native_info_cb() */ + + +/*------------------------------------------------------------------------- + * Function: H5G_loc_native_info + * + * Purpose: Retrieve the native information for an object from a group location + * and path to that object + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * Thursday, November 23, 2006 + * + *------------------------------------------------------------------------- + */ +herr_t +H5G_loc_native_info(const H5G_loc_t *loc, const char *name, H5O_native_info_t *oinfo/*out*/, + unsigned fields) +{ + H5G_loc_native_info_t udata; /* User data for traversal callback */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Check args. */ + HDassert(loc); + HDassert(name && *name); + HDassert(oinfo); + + /* Set up user data for locating object */ + udata.fields = fields; + udata.oinfo = oinfo; + + /* Traverse group hierarchy to locate object */ + if(H5G_traverse(loc, name, H5G_TARGET_NORMAL, H5G__loc_native_info_cb, &udata) < 0) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "can't find object") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5G_loc_native_info() */ + + +/*------------------------------------------------------------------------- * Function: H5G__loc_set_comment_cb * * Purpose: Callback for (re)setting object comment for an object in a group diff --git a/src/H5Gname.c b/src/H5Gname.c index ab8ddf4..4b0f04c 100644 --- a/src/H5Gname.c +++ b/src/H5Gname.c @@ -42,6 +42,8 @@ #include "H5Lprivate.h" /* Links */ #include "H5MMprivate.h" /* Memory wrappers */ +#include "H5VLnative_private.h" /* Native VOL connector */ + /****************/ /* Local Macros */ @@ -1204,7 +1206,7 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5G_get_name_by_addr_cb(hid_t gid, const char *path, const H5L_info_t *linfo, +H5G_get_name_by_addr_cb(hid_t gid, const char *path, const H5L_info2_t *linfo, void *_udata) { H5G_gnba_iter_t *udata = (H5G_gnba_iter_t *)_udata; /* User data for iteration */ @@ -1212,7 +1214,7 @@ H5G_get_name_by_addr_cb(hid_t gid, const char *path, const H5L_info_t *linfo, H5G_name_t obj_path; /* Object's group hier. path */ H5O_loc_t obj_oloc; /* Object's object location */ hbool_t obj_found = FALSE; /* Object at 'path' found */ - herr_t ret_value = H5_ITER_CONT; /* Return value */ + herr_t ret_value = H5_ITER_CONT; /* Return value */ FUNC_ENTER_NOAPI_NOINIT @@ -1223,31 +1225,39 @@ H5G_get_name_by_addr_cb(hid_t gid, const char *path, const H5L_info_t *linfo, HDassert(udata->path == NULL); /* Check for hard link with correct address */ - if(linfo->type == H5L_TYPE_HARD && udata->loc->addr == linfo->u.address) { - H5G_loc_t grp_loc; /* Location of group */ - - /* Get group's location */ - if(H5G_loc(gid, &grp_loc) < 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5_ITER_ERROR, "bad group location") - - /* Set up opened object location to fill in */ - obj_loc.oloc = &obj_oloc; - obj_loc.path = &obj_path; - H5G_loc_reset(&obj_loc); - - /* Find the object */ - if(H5G_loc_find(&grp_loc, path, &obj_loc/*out*/) < 0) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, H5_ITER_ERROR, "object not found") - obj_found = TRUE; - - /* Check for object in same file (handles mounted files) */ - /* (re-verify address, in case we traversed a file mount) */ - if(udata->loc->addr == obj_loc.oloc->addr && udata->loc->file == obj_loc.oloc->file) { - if(NULL == (udata->path = H5MM_strdup(path))) - HGOTO_ERROR(H5E_SYM, H5E_CANTALLOC, H5_ITER_ERROR, "can't duplicate path string") - - /* We found a match so we return immediately */ - HGOTO_DONE(H5_ITER_STOP) + if(linfo->type == H5L_TYPE_HARD) { + haddr_t link_addr; + + /* Retrieve hard link address from VOL token */ + if(H5VL_native_token_to_addr(udata->loc->file, H5I_FILE, linfo->u.token, &link_addr) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTUNSERIALIZE, FAIL, "can't deserialize object token into address") + + if(udata->loc->addr == link_addr) { + H5G_loc_t grp_loc; /* Location of group */ + + /* Get group's location */ + if(H5G_loc(gid, &grp_loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5_ITER_ERROR, "bad group location") + + /* Set up opened object location to fill in */ + obj_loc.oloc = &obj_oloc; + obj_loc.path = &obj_path; + H5G_loc_reset(&obj_loc); + + /* Find the object */ + if(H5G_loc_find(&grp_loc, path, &obj_loc/*out*/) < 0) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, H5_ITER_ERROR, "object not found") + obj_found = TRUE; + + /* Check for object in same file (handles mounted files) */ + /* (re-verify address, in case we traversed a file mount) */ + if(udata->loc->addr == obj_loc.oloc->addr && udata->loc->file == obj_loc.oloc->file) { + if(NULL == (udata->path = H5MM_strdup(path))) + HGOTO_ERROR(H5E_SYM, H5E_CANTALLOC, H5_ITER_ERROR, "can't duplicate path string") + + /* We found a match so we return immediately */ + HGOTO_DONE(H5_ITER_STOP) + } /* end if */ } /* end if */ } /* end if */ diff --git a/src/H5Gprivate.h b/src/H5Gprivate.h index b735dbd..19b120c 100644 --- a/src/H5Gprivate.h +++ b/src/H5Gprivate.h @@ -174,7 +174,7 @@ typedef struct { #ifndef H5_NO_DEPRECATED_SYMBOLS H5G_iterate_t op_old; /* "Old" application callback for each link */ #endif /* H5_NO_DEPRECATED_SYMBOLS */ - H5L_iterate_t op_new; /* "New" application callback for each link */ + H5L_iterate2_t op_new; /* "New" application callback for each link */ } op_func; } H5G_link_iterate_t; @@ -214,12 +214,12 @@ H5_DLL herr_t H5G_iterate(H5G_loc_t *loc, const char *group_name, H5_index_t idx_type, H5_iter_order_t order, hsize_t skip, hsize_t *last_lnk, const H5G_link_iterate_t *lnk_op, void *op_data); H5_DLL herr_t H5G_visit(H5G_loc_t *loc, const char *group_name, - H5_index_t idx_type, H5_iter_order_t order, H5L_iterate_t op, void *op_data); + H5_index_t idx_type, H5_iter_order_t order, H5L_iterate2_t op, void *op_data); /* * Functions that understand links in groups */ -H5_DLL herr_t H5G_link_to_info(const struct H5O_link_t *lnk, H5L_info_t *linfo); +H5_DLL herr_t H5G_link_to_info(const struct H5O_loc_t *link_loc, const struct H5O_link_t *lnk, H5L_info2_t *linfo); /* * Functions that understand group objects @@ -279,7 +279,9 @@ H5_DLL herr_t H5G_loc_find_by_idx(const H5G_loc_t *loc, const char *group_name, H5G_loc_t *obj_loc/*out*/); H5_DLL htri_t H5G_loc_exists(const H5G_loc_t *loc, const char *name); H5_DLL herr_t H5G_loc_info(const H5G_loc_t *loc, const char *name, - H5O_info_t *oinfo/*out*/, unsigned fields); + H5O_info2_t *oinfo/*out*/, unsigned fields); +H5_DLL herr_t H5G_loc_native_info(const H5G_loc_t *loc, const char *name, + H5O_native_info_t *oinfo/*out*/, unsigned fields); H5_DLL herr_t H5G_loc_set_comment(const H5G_loc_t *loc, const char *name, const char *comment); H5_DLL ssize_t H5G_loc_get_comment(const H5G_loc_t *loc, const char *name, diff --git a/src/H5Gtraverse.c b/src/H5Gtraverse.c index 492b5b9..7482e27 100644 --- a/src/H5Gtraverse.c +++ b/src/H5Gtraverse.c @@ -201,11 +201,15 @@ H5G__traverse_ud(const H5G_loc_t *grp_loc/*in,out*/, const H5O_link_t *lnk, HGOTO_ERROR(H5E_SYM, H5E_CANTREGISTER, FAIL, "unable to register group") /* User-defined callback function */ +#ifndef H5_NO_DEPRECATED_SYMBOLS /* (Backwardly compatible with v0 H5L_class_t traverssal callback) */ if(link_class->version == H5L_LINK_CLASS_T_VERS_0) cb_return = (((const H5L_class_0_t *)link_class)->trav_func)(lnk->name, cur_grp, lnk->u.ud.udata, lnk->u.ud.size, H5CX_get_lapl()); else cb_return = (link_class->trav_func)(lnk->name, cur_grp, lnk->u.ud.udata, lnk->u.ud.size, H5CX_get_lapl(), H5CX_get_dxpl()); +#else /* H5_NO_DEPRECATED_SYMBOLS */ + cb_return = (link_class->trav_func)(lnk->name, cur_grp, lnk->u.ud.udata, lnk->u.ud.size, H5CX_get_lapl(), H5CX_get_dxpl()); +#endif /* H5_NO_DEPRECATED_SYMBOLS */ /* Check for failing to locate the object */ if(cb_return < 0) { diff --git a/src/H5I.c b/src/H5I.c index eaa4cdf..2ba8a2a 100644 --- a/src/H5I.c +++ b/src/H5I.c @@ -2219,7 +2219,7 @@ done: ssize_t H5Iget_name(hid_t id, char *name/*out*/, size_t size) { - H5VL_object_t *vol_obj; /* Object token of loc_id */ + H5VL_object_t *vol_obj; /* Object of loc_id */ H5VL_loc_params_t loc_params; ssize_t ret_value; /* Return value */ @@ -2269,7 +2269,7 @@ H5Iget_file_id(hid_t obj_id) /* Call internal function */ if(H5I_FILE == type || H5I_DATATYPE == type || H5I_GROUP == type || H5I_DATASET == type || H5I_ATTR == type) { - H5VL_object_t *vol_obj; /* Object token of obj_id */ + H5VL_object_t *vol_obj; /* Object of obj_id */ /* Get the VOL object */ if(NULL == (vol_obj = H5VL_vol_object(obj_id))) diff --git a/src/H5Itest.c b/src/H5Itest.c index 7415303..07c1965 100644 --- a/src/H5Itest.c +++ b/src/H5Itest.c @@ -78,7 +78,7 @@ ssize_t H5I__get_name_test(hid_t id, char *name/*out*/, size_t size, hbool_t *cached) { - H5VL_object_t *vol_obj; /* Object token of id */ + H5VL_object_t *vol_obj; /* Object of id */ H5G_loc_t loc; /* Object location */ hbool_t api_ctx_pushed = FALSE; /* Whether API context pushed */ hbool_t vol_wrapper_set = FALSE;/* Whether the VOL object wrapping context was set up */ diff --git a/src/H5L.c b/src/H5L.c index 706ca09..0d5bc02 100644 --- a/src/H5L.c +++ b/src/H5L.c @@ -34,7 +34,7 @@ #include "H5Oprivate.h" /* File objects */ #include "H5Pprivate.h" /* Property lists */ #include "H5VLprivate.h" /* Virtual Object Layer */ - +#include "H5VLnative_private.h" /* Native VOL */ /****************/ /* Local Macros */ @@ -49,7 +49,7 @@ /* User data for path traversal routine for getting link info by name */ typedef struct { - H5L_info_t *linfo; /* Buffer to return to user */ + H5L_info2_t *linfo; /* Buffer to return to user */ } H5L_trav_gi_t; /* User data for path traversal callback to creating a link */ @@ -93,6 +93,7 @@ typedef struct { void *buf; /* User buffer */ } H5L_trav_gv_t; + /********************/ /* Local Prototypes */ /********************/ @@ -274,11 +275,11 @@ herr_t H5Lmove(hid_t src_loc_id, const char *src_name, hid_t dst_loc_id, const char *dst_name, hid_t lcpl_id, hid_t lapl_id) { - H5VL_object_t *vol_obj1 = NULL; /* Object token of src_id */ + H5VL_object_t *vol_obj1 = NULL; /* Object of src_id */ H5VL_loc_params_t loc_params1; - H5VL_object_t *vol_obj2 = NULL; /* Object token of dst_id */ + H5VL_object_t *vol_obj2 = NULL; /* Object of dst_id */ H5VL_loc_params_t loc_params2; - H5VL_object_t tmp_vol_obj; /* Temporary object token */ + H5VL_object_t tmp_vol_obj; /* Temporary object */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) @@ -364,11 +365,11 @@ herr_t H5Lcopy(hid_t src_loc_id, const char *src_name, hid_t dst_loc_id, const char *dst_name, hid_t lcpl_id, hid_t lapl_id) { - H5VL_object_t *vol_obj1 = NULL; /* Object token of src_id */ + H5VL_object_t *vol_obj1 = NULL; /* Object of src_id */ H5VL_loc_params_t loc_params1; - H5VL_object_t *vol_obj2 = NULL; /* Object token of dst_id */ + H5VL_object_t *vol_obj2 = NULL; /* Object of dst_id */ H5VL_loc_params_t loc_params2; - H5VL_object_t tmp_vol_obj; /* Temporary object token */ + H5VL_object_t tmp_vol_obj; /* Temporary object */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) @@ -458,7 +459,7 @@ herr_t H5Lcreate_soft(const char *link_target, hid_t link_loc_id, const char *link_name, hid_t lcpl_id, hid_t lapl_id) { - H5VL_object_t *vol_obj = NULL; /* object token of loc_id */ + H5VL_object_t *vol_obj = NULL; /* object of loc_id */ H5VL_loc_params_t loc_params; herr_t ret_value = SUCCEED; /* Return value */ @@ -529,9 +530,9 @@ herr_t H5Lcreate_hard(hid_t cur_loc_id, const char *cur_name, hid_t new_loc_id, const char *new_name, hid_t lcpl_id, hid_t lapl_id) { - H5VL_object_t *vol_obj1 = NULL; /* Object token of cur_loc_id */ - H5VL_object_t *vol_obj2 = NULL; /* Object token of new_loc_id */ - H5VL_object_t tmp_vol_obj; /* Temporary object token of */ + H5VL_object_t *vol_obj1 = NULL; /* Object of cur_loc_id */ + H5VL_object_t *vol_obj2 = NULL; /* Object of new_loc_id */ + H5VL_object_t tmp_vol_obj; /* Temporary object */ H5VL_loc_params_t loc_params1; H5VL_loc_params_t loc_params2; herr_t ret_value = SUCCEED; /* Return value */ @@ -631,7 +632,7 @@ herr_t H5Lcreate_ud(hid_t link_loc_id, const char *link_name, H5L_type_t link_type, const void *udata, size_t udata_size, hid_t lcpl_id, hid_t lapl_id) { - H5VL_object_t *vol_obj = NULL; /* Object token of loc_id */ + H5VL_object_t *vol_obj = NULL; /* Object of loc_id */ H5VL_loc_params_t loc_params; herr_t ret_value = SUCCEED; /* Return value */ @@ -696,7 +697,7 @@ done: herr_t H5Ldelete(hid_t loc_id, const char *name, hid_t lapl_id) { - H5VL_object_t *vol_obj = NULL; /* Object token of loc_id */ + H5VL_object_t *vol_obj = NULL; /* Object of loc_id */ H5VL_loc_params_t loc_params; herr_t ret_value = SUCCEED; /* Return value */ @@ -753,7 +754,7 @@ herr_t H5Ldelete_by_idx(hid_t loc_id, const char *group_name, H5_index_t idx_type, H5_iter_order_t order, hsize_t n, hid_t lapl_id) { - H5VL_object_t *vol_obj = NULL; /* object token of loc_id */ + H5VL_object_t *vol_obj = NULL; /* object of loc_id */ H5VL_loc_params_t loc_params; herr_t ret_value = SUCCEED; /* Return value */ @@ -816,7 +817,7 @@ herr_t H5Lget_val(hid_t loc_id, const char *name, void *buf/*out*/, size_t size, hid_t lapl_id) { - H5VL_object_t *vol_obj = NULL; /* object token of loc_id */ + H5VL_object_t *vol_obj = NULL; /* object of loc_id */ H5VL_loc_params_t loc_params; herr_t ret_value = SUCCEED; /* Return value */ @@ -872,7 +873,7 @@ H5Lget_val_by_idx(hid_t loc_id, const char *group_name, H5_index_t idx_type, H5_iter_order_t order, hsize_t n, void *buf/*out*/, size_t size, hid_t lapl_id) { - H5VL_object_t *vol_obj = NULL; /* object token of loc_id */ + H5VL_object_t *vol_obj = NULL; /* object of loc_id */ H5VL_loc_params_t loc_params; herr_t ret_value = SUCCEED; /* Return value */ @@ -928,7 +929,7 @@ done: htri_t H5Lexists(hid_t loc_id, const char *name, hid_t lapl_id) { - H5VL_object_t *vol_obj = NULL; /* object token of loc_id */ + H5VL_object_t *vol_obj = NULL; /* object of loc_id */ H5VL_loc_params_t loc_params; htri_t ret_value = FAIL; /* Return value */ @@ -965,13 +966,12 @@ done: /*------------------------------------------------------------------------- - * Function: H5Lget_info - * - * Purpose: Gets metadata for a link. + * Function: H5Lget_info2 * - * Return: Success: Non-negative with information in LINFO + * Purpose: Gets metadata for a link. * - * Failure: Negative + * Return: Success: Non-negative with information in LINFO + * Failure: Negative * * Programmer: James Laird * Wednesday, June 21, 2006 @@ -979,10 +979,10 @@ done: *------------------------------------------------------------------------- */ herr_t -H5Lget_info(hid_t loc_id, const char *name, H5L_info_t *linfo /*out*/, +H5Lget_info2(hid_t loc_id, const char *name, H5L_info2_t *linfo /*out*/, hid_t lapl_id) { - H5VL_object_t *vol_obj = NULL; /* object token of loc_id */ + H5VL_object_t *vol_obj = NULL; /* object of loc_id */ H5VL_loc_params_t loc_params; herr_t ret_value = SUCCEED; /* Return value */ @@ -1012,11 +1012,11 @@ H5Lget_info(hid_t loc_id, const char *name, H5L_info_t *linfo /*out*/, done: FUNC_LEAVE_API(ret_value) -} /* end H5Lget_info() */ +} /* end H5Lget_info2() */ /*------------------------------------------------------------------------- - * Function: H5Lget_info_by_idx + * Function: H5Lget_info_by_idx2 * * Purpose: Gets metadata for a link, according to the order within an * index. @@ -1030,11 +1030,11 @@ done: *------------------------------------------------------------------------- */ herr_t -H5Lget_info_by_idx(hid_t loc_id, const char *group_name, +H5Lget_info_by_idx2(hid_t loc_id, const char *group_name, H5_index_t idx_type, H5_iter_order_t order, hsize_t n, - H5L_info_t *linfo /*out*/, hid_t lapl_id) + H5L_info2_t *linfo /*out*/, hid_t lapl_id) { - H5VL_object_t *vol_obj = NULL; /* object token of loc_id */ + H5VL_object_t *vol_obj = NULL; /* object of loc_id */ H5VL_loc_params_t loc_params; herr_t ret_value = SUCCEED; /* Return value */ @@ -1072,7 +1072,7 @@ H5Lget_info_by_idx(hid_t loc_id, const char *group_name, done: FUNC_LEAVE_API(ret_value) -} /* end H5Lget_info_by_idx() */ +} /* end H5Lget_info_by_idx2() */ /*------------------------------------------------------------------------- @@ -1115,6 +1115,10 @@ H5Lregister(const H5L_class_t *cls) */ if(cls->version > H5L_LINK_CLASS_T_VERS) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid H5L_class_t version number") +#ifdef H5_NO_DEPRECATED_SYMBOLS + if(cls->version < H5L_LINK_CLASS_T_VERS) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "deprecated H5L_class_t version number (%d) and library built without deprecated symbol support", cls->version) +#endif /* H5_NO_DEPRECATED_SYMBOLS */ if(cls->id < H5L_TYPE_UD_MIN || cls->id > H5L_TYPE_MAX) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid link identification number") @@ -1229,7 +1233,7 @@ H5Lget_name_by_idx(hid_t loc_id, const char *group_name, H5_index_t idx_type, H5_iter_order_t order, hsize_t n, char *name /*out*/, size_t size, hid_t lapl_id) { - H5VL_object_t *vol_obj = NULL; /* object token of loc_id */ + H5VL_object_t *vol_obj = NULL; /* object of loc_id */ H5VL_loc_params_t loc_params; ssize_t ret_value = -1; /* Return value */ @@ -1272,7 +1276,7 @@ done: /*------------------------------------------------------------------------- - * Function: H5Literate + * Function: H5Literate2 * * Purpose: Iterates over links in a group, with user callback routine, * according to the order within an index. @@ -1290,10 +1294,10 @@ done: *------------------------------------------------------------------------- */ herr_t -H5Literate(hid_t group_id, H5_index_t idx_type, H5_iter_order_t order, - hsize_t *idx_p, H5L_iterate_t op, void *op_data) +H5Literate2(hid_t group_id, H5_index_t idx_type, H5_iter_order_t order, + hsize_t *idx_p, H5L_iterate2_t op, void *op_data) { - H5VL_object_t *vol_obj = NULL; /* Object token of loc_id */ + H5VL_object_t *vol_obj = NULL; /* Object of loc_id */ H5VL_loc_params_t loc_params; H5I_type_t id_type; /* Type of ID */ herr_t ret_value; /* Return value */ @@ -1321,16 +1325,17 @@ H5Literate(hid_t group_id, H5_index_t idx_type, H5_iter_order_t order, loc_params.obj_type = H5I_get_type(group_id); /* Iterate over the links */ - if((ret_value = H5VL_link_specific(vol_obj, &loc_params, H5VL_LINK_ITER, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, (unsigned)FALSE, (int)idx_type, (int)order, idx_p, op, op_data)) < 0) + if((ret_value = H5VL_link_specific(vol_obj, &loc_params, H5VL_LINK_ITER, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, (unsigned)FALSE, (int)idx_type, (int)order, idx_p, + op, op_data)) < 0) HGOTO_ERROR(H5E_LINK, H5E_BADITER, FAIL, "link iteration failed") done: FUNC_LEAVE_API(ret_value) -} /* end H5Literate() */ +} /* end H5Literate2() */ /*------------------------------------------------------------------------- - * Function: H5Literate_by_name + * Function: H5Literate_by_name2 * * Purpose: Iterates over links in a group, with user callback routine, * according to the order within an index. @@ -1352,11 +1357,11 @@ done: *------------------------------------------------------------------------- */ herr_t -H5Literate_by_name(hid_t loc_id, const char *group_name, +H5Literate_by_name2(hid_t loc_id, const char *group_name, H5_index_t idx_type, H5_iter_order_t order, hsize_t *idx_p, - H5L_iterate_t op, void *op_data, hid_t lapl_id) + H5L_iterate2_t op, void *op_data, hid_t lapl_id) { - H5VL_object_t *vol_obj = NULL; /* Object token of loc_id */ + H5VL_object_t *vol_obj = NULL; /* Object of loc_id */ H5VL_loc_params_t loc_params; herr_t ret_value; /* Return value */ @@ -1391,7 +1396,8 @@ H5Literate_by_name(hid_t loc_id, const char *group_name, loc_params.loc_data.loc_by_name.lapl_id = lapl_id; /* Iterate over the links */ - if((ret_value = H5VL_link_specific(vol_obj, &loc_params, H5VL_LINK_ITER, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, FALSE, idx_type, order, idx_p, op, op_data)) < 0) + if((ret_value = H5VL_link_specific(vol_obj, &loc_params, H5VL_LINK_ITER, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, FALSE, idx_type, order, idx_p, + op, op_data)) < 0) HGOTO_ERROR(H5E_LINK, H5E_BADITER, FAIL, "link iteration failed") done: @@ -1400,7 +1406,7 @@ done: /*------------------------------------------------------------------------- - * Function: H5Lvisit + * Function: H5Lvisit2 * * Purpose: Recursively visit all the links in a group and all * the groups that are linked to from that group. Links within @@ -1423,15 +1429,15 @@ done: * of the operators. * * Programmer: Quincey Koziol - * November 24 2007 + * November 24 2007 * *------------------------------------------------------------------------- */ herr_t -H5Lvisit(hid_t group_id, H5_index_t idx_type, H5_iter_order_t order, - H5L_iterate_t op, void *op_data) +H5Lvisit2(hid_t group_id, H5_index_t idx_type, H5_iter_order_t order, + H5L_iterate2_t op, void *op_data) { - H5VL_object_t *vol_obj = NULL; /* Object token of loc_id */ + H5VL_object_t *vol_obj = NULL; /* Object of loc_id */ H5VL_loc_params_t loc_params; H5I_type_t id_type; /* Type of ID */ herr_t ret_value; /* Return value */ @@ -1459,16 +1465,17 @@ H5Lvisit(hid_t group_id, H5_index_t idx_type, H5_iter_order_t order, HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") /* Iterate over the links */ - if((ret_value = H5VL_link_specific(vol_obj, &loc_params, H5VL_LINK_ITER, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, TRUE, idx_type, order, NULL, op, op_data)) < 0) + if((ret_value = H5VL_link_specific(vol_obj, &loc_params, H5VL_LINK_ITER, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, TRUE, idx_type, order, NULL, + op, op_data)) < 0) HGOTO_ERROR(H5E_LINK, H5E_BADITER, FAIL, "link visitation failed") done: FUNC_LEAVE_API(ret_value) -} /* end H5Lvisit() */ +} /* end H5Lvisit2() */ /*------------------------------------------------------------------------- - * Function: H5Lvisit_by_name + * Function: H5Lvisit_by_name2 * * Purpose: Recursively visit all the links in a group and all * the groups that are linked to from that group. Links within @@ -1496,10 +1503,10 @@ done: *------------------------------------------------------------------------- */ herr_t -H5Lvisit_by_name(hid_t loc_id, const char *group_name, H5_index_t idx_type, - H5_iter_order_t order, H5L_iterate_t op, void *op_data, hid_t lapl_id) +H5Lvisit_by_name2(hid_t loc_id, const char *group_name, H5_index_t idx_type, + H5_iter_order_t order, H5L_iterate2_t op, void *op_data, hid_t lapl_id) { - H5VL_object_t *vol_obj = NULL; /* Object token of loc_id */ + H5VL_object_t *vol_obj = NULL; /* Object of loc_id */ H5VL_loc_params_t loc_params; herr_t ret_value; /* Return value */ @@ -1534,12 +1541,13 @@ H5Lvisit_by_name(hid_t loc_id, const char *group_name, H5_index_t idx_type, loc_params.loc_data.loc_by_name.lapl_id = lapl_id; /* Visit the links */ - if((ret_value = H5VL_link_specific(vol_obj, &loc_params, H5VL_LINK_ITER, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, TRUE, idx_type, order, NULL, op, op_data)) < 0) + if((ret_value = H5VL_link_specific(vol_obj, &loc_params, H5VL_LINK_ITER, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, TRUE, idx_type, order, NULL, + op, op_data)) < 0) HGOTO_ERROR(H5E_LINK, H5E_BADITER, FAIL, "link visitation failed") done: FUNC_LEAVE_API(ret_value) -} /* end H5Lvisit_by_name() */ +} /* end H5Lvisit_by_name2() */ /* *------------------------------------------------------------------------- @@ -3143,7 +3151,7 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5L__get_info_cb(H5G_loc_t H5_ATTR_UNUSED *grp_loc/*in*/, const char H5_ATTR_UNUSED *name, +H5L__get_info_cb(H5G_loc_t *grp_loc/*in*/, const char H5_ATTR_UNUSED *name, const H5O_link_t *lnk, H5G_loc_t H5_ATTR_UNUSED *obj_loc, void *_udata/*in,out*/, H5G_own_loc_t *own_loc/*out*/) { @@ -3157,7 +3165,7 @@ H5L__get_info_cb(H5G_loc_t H5_ATTR_UNUSED *grp_loc/*in*/, const char H5_ATTR_UNU HGOTO_ERROR(H5E_LINK, H5E_NOTFOUND, FAIL, "name doesn't exist") /* Get information from the link */ - if(H5G_link_to_info(lnk, udata->linfo) < 0) + if(H5G_link_to_info(grp_loc->oloc, lnk, udata->linfo) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "can't get link info") done: @@ -3172,7 +3180,7 @@ done: /*------------------------------------------------------------------------- * Function: H5L_get_info * - * Purpose: Returns metadata about a link. + * Purpose: Returns metadata about a link. * * Return: Non-negative on success/Negative on failure * @@ -3182,7 +3190,7 @@ done: *------------------------------------------------------------------------- */ herr_t -H5L_get_info(const H5G_loc_t *loc, const char *name, H5L_info_t *linfo/*out*/) +H5L_get_info(const H5G_loc_t *loc, const char *name, H5L_info2_t *linfo/*out*/) { H5L_trav_gi_t udata; /* User data for callback */ herr_t ret_value = SUCCEED; /* Return value */ @@ -3235,7 +3243,7 @@ H5L__get_info_by_idx_cb(H5G_loc_t H5_ATTR_UNUSED *grp_loc/*in*/, const char H5_A lnk_copied = TRUE; /* Get information from the link */ - if(H5G_link_to_info(&fnd_lnk, udata->linfo) < 0) + if(H5G_link_to_info(obj_loc->oloc, &fnd_lnk, udata->linfo) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "can't get link info") done: @@ -3263,7 +3271,7 @@ done: */ herr_t H5L_get_info_by_idx(const H5G_loc_t *loc, const char *name, H5_index_t idx_type, - H5_iter_order_t order, hsize_t n, H5L_info_t *linfo /*out*/) + H5_iter_order_t order, hsize_t n, H5L_info2_t *linfo /*out*/) { H5L_trav_gibi_t udata; /* User data for callback */ herr_t ret_value = SUCCEED; /* Return value */ @@ -3516,7 +3524,7 @@ done: */ herr_t H5L_iterate(H5G_loc_t *loc, const char *group_name, H5_index_t idx_type, - H5_iter_order_t order, hsize_t *idx_p, H5L_iterate_t op, void *op_data) + H5_iter_order_t order, hsize_t *idx_p, H5L_iterate2_t op, void *op_data) { H5G_link_iterate_t lnk_op; /* Link operator */ hsize_t last_lnk; /* Index of last object looked at */ diff --git a/src/H5Ldeprec.c b/src/H5Ldeprec.c new file mode 100644 index 0000000..8b83230 --- /dev/null +++ b/src/H5Ldeprec.c @@ -0,0 +1,628 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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 COPYING file, which can be found at the root of the source code * + * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. * + * If you do not have access to either file, you may request a copy from * + * help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/*------------------------------------------------------------------------- + * + * Purpose: Deprecated functions from the H5L interface. These + * functions are here for compatibility purposes and may be + * removed in the future. Applications should switch to the + * newer APIs. + * + *------------------------------------------------------------------------- + */ + +/****************/ +/* Module Setup */ +/****************/ + +#include "H5Lmodule.h" /* This source code file is part of the H5L module */ + + +/***********/ +/* Headers */ +/***********/ +#include "H5private.h" /* Generic Functions */ +#include "H5CXprivate.h" /* API Contexts */ +#include "H5Eprivate.h" /* Error handling */ +#include "H5Iprivate.h" /* IDs */ +#include "H5Lpkg.h" /* Links */ + +#include "H5VLnative_private.h" + +#ifndef H5_NO_DEPRECATED_SYMBOLS + +/****************/ +/* Local Macros */ +/****************/ + + +/******************/ +/* Local Typedefs */ +/******************/ + +/* Shim data for using native H5Literate/visit callbacks with the VOL */ +typedef struct H5L_shim_data_t { + H5L_iterate1_t real_op; + void *real_op_data; +} H5L_shim_data_t; + + +/********************/ +/* Package Typedefs */ +/********************/ + + +/********************/ +/* Local Prototypes */ +/********************/ + + +/*********************/ +/* Package Variables */ +/*********************/ + + +/*****************************/ +/* Library Private Variables */ +/*****************************/ + + +/*******************/ +/* Local Variables */ +/*******************/ + + + +/*------------------------------------------------------------------------- + * Function: H5L__iterate2_shim + * + * Purpose: Shim function for translating between H5L_info2_t and + * H5L_info1_t structures, as used by H5Literate2/H5Lvisit2 + * and H5Literate1/H5Lvisit1, respectively. + * + * Return: Success: H5_ITER_CONT or H5_ITER_STOP + * Failure: H5_ITER_ERROR + * + *------------------------------------------------------------------------- + */ +static herr_t +H5L__iterate2_shim(hid_t group_id, const char *name, const H5L_info2_t *linfo2, void *op_data) +{ + H5L_shim_data_t *shim_data = (H5L_shim_data_t *)op_data; + H5L_info1_t linfo; + herr_t ret_value = H5_ITER_CONT; + + FUNC_ENTER_STATIC + + /* Copy the new-style members into the old-style struct */ + if (linfo2) { + linfo.type = linfo2->type; + linfo.corder_valid = linfo2->corder_valid; + linfo.corder = linfo2->corder; + linfo.cset = linfo2->cset; + if (H5L_TYPE_HARD == linfo2->type) { + if(H5VLnative_token_to_addr(group_id, linfo2->u.token, &linfo.u.address) < 0) + HGOTO_ERROR(H5E_LINK, H5E_CANTUNSERIALIZE, H5_ITER_ERROR, "can't deserialize object token into address") + } + else + linfo.u.val_size = linfo2->u.val_size; + } + + /* Invoke the real callback */ + ret_value = shim_data->real_op(group_id, name, &linfo, shim_data->real_op_data); + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5L__iterate2_shim() */ + + +/*------------------------------------------------------------------------- + * Function: H5Literate1 + * + * Purpose: Iterates over links in a group, with user callback routine, + * according to the order within an index. + * + * Same pattern of behavior as H5Giterate. + * + * Note: Deprecated in favor of H5Literate2 + * + * Return: Success: The return value of the first operator that + * returns non-zero, or zero if all members were + * processed with no operator returning non-zero. + * + * Failure: Negative if something goes wrong within the + * library, or the negative value returned by one + * of the operators. + * + *------------------------------------------------------------------------- + */ +herr_t +H5Literate1(hid_t group_id, H5_index_t idx_type, H5_iter_order_t order, + hsize_t *idx_p, H5L_iterate1_t op, void *op_data) +{ + H5VL_object_t *vol_obj = NULL; /* Object of loc_id */ + H5VL_loc_params_t loc_params; + H5I_type_t id_type; /* Type of ID */ + H5L_shim_data_t shim_data; + hbool_t is_native_vol_obj; + herr_t ret_value; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE6("e", "iIiIo*hx*x", group_id, idx_type, order, idx_p, op, op_data); + + /* Check arguments */ + id_type = H5I_get_type(group_id); + if (!(H5I_GROUP == id_type || H5I_FILE == id_type)) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid argument") + if (idx_type <= H5_INDEX_UNKNOWN || idx_type >= H5_INDEX_N) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid index type specified") + if (order <= H5_ITER_UNKNOWN || order >= H5_ITER_N) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid iteration order specified") + if (!op) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no operator specified") + + /* Get the location object */ + if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(group_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + + /* Check if the VOL object is a native VOL connector object */ + if(H5VL_object_is_native(vol_obj, &is_native_vol_obj) < 0) + HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "can't determine if VOL object is native connector object") + if(!is_native_vol_obj) + HGOTO_ERROR(H5E_LINK, H5E_BADVALUE, FAIL, "H5Literate1 is only meant to be used with the native VOL connector") + + /* Set location struct fields */ + loc_params.type = H5VL_OBJECT_BY_SELF; + loc_params.obj_type = H5I_get_type(group_id); + + /* Set up shim */ + shim_data.real_op = op; + shim_data.real_op_data = op_data; + + /* Iterate over the links */ + if((ret_value = H5VL_link_specific(vol_obj, &loc_params, H5VL_LINK_ITER, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, (unsigned)FALSE, (int)idx_type, (int)order, idx_p, + H5L__iterate2_shim, (void *)&shim_data)) < 0) + HGOTO_ERROR(H5E_LINK, H5E_BADITER, FAIL, "link iteration failed") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Literate1() */ + + +/*------------------------------------------------------------------------- + * Function: H5Literate_by_name1 + * + * Purpose: Iterates over links in a group, with user callback routine, + * according to the order within an index. + * + * Same pattern of behavior as H5Giterate. + * + * Note: Deprecated in favor of H5Literate_by_name2 + * + * Return: Success: The return value of the first operator that + * returns non-zero, or zero if all members were + * processed with no operator returning non-zero. + * + * Failure: Negative if something goes wrong within the + * library, or the negative value returned by one + * of the operators. + * + * + * Programmer: Quincey Koziol + * Thursday, November 16, 2006 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Literate_by_name1(hid_t loc_id, const char *group_name, + H5_index_t idx_type, H5_iter_order_t order, hsize_t *idx_p, + H5L_iterate1_t op, void *op_data, hid_t lapl_id) +{ + H5VL_object_t *vol_obj = NULL; /* Object of loc_id */ + H5VL_loc_params_t loc_params; + H5L_shim_data_t shim_data; + hbool_t is_native_vol_obj; + herr_t ret_value; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE8("e", "i*sIiIo*hx*xi", loc_id, group_name, idx_type, order, idx_p, op, + op_data, lapl_id); + + /* Check arguments */ + if(!group_name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "group_name parameter cannot be NULL") + if(!*group_name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "group_name parameter cannot be an empty string") + if(idx_type <= H5_INDEX_UNKNOWN || idx_type >= H5_INDEX_N) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid index type specified") + if(order <= H5_ITER_UNKNOWN || order >= H5_ITER_N) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid iteration order specified") + if(!op) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no operator specified") + + /* Verify access property list and set up collective metadata if appropriate */ + if(H5CX_set_apl(&lapl_id, H5P_CLS_LACC, loc_id, FALSE) < 0) + HGOTO_ERROR(H5E_LINK, H5E_CANTSET, FAIL, "can't set access property list info") + + /* Get the location object */ + if(NULL == (vol_obj = (H5VL_object_t *)H5I_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + + /* Check if the VOL object is a native VOL connector object */ + if(H5VL_object_is_native(vol_obj, &is_native_vol_obj) < 0) + HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "can't determine if VOL object is native connector object") + if(!is_native_vol_obj) + HGOTO_ERROR(H5E_LINK, H5E_BADVALUE, FAIL, "H5Literate_by_name1 is only meant to be used with the native VOL connector") + + /* Set location struct fields */ + loc_params.type = H5VL_OBJECT_BY_NAME; + loc_params.obj_type = H5I_get_type(loc_id); + loc_params.loc_data.loc_by_name.name = group_name; + loc_params.loc_data.loc_by_name.lapl_id = lapl_id; + + /* Set up shim */ + shim_data.real_op = op; + shim_data.real_op_data = op_data; + + /* Iterate over the links */ + if((ret_value = H5VL_link_specific(vol_obj, &loc_params, H5VL_LINK_ITER, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, FALSE, idx_type, order, idx_p, + H5L__iterate2_shim, (void *)&shim_data)) < 0) + HGOTO_ERROR(H5E_LINK, H5E_BADITER, FAIL, "link iteration failed") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Literate_by_name1() */ + + +/*------------------------------------------------------------------------- + * Function: H5Lget_info1 + * + * Purpose: Gets metadata for a link. + * + * Note: Deprecated in favor of H5Lget_info2 + * + * Return: Success: Non-negative with information in LINFO + * Failure: Negative + * + * Programmer: James Laird + * Wednesday, June 21, 2006 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Lget_info1(hid_t loc_id, const char *name, H5L_info1_t *linfo /*out*/, + hid_t lapl_id) +{ + H5VL_object_t *vol_obj = NULL; /* object of loc_id */ + H5VL_loc_params_t loc_params; + H5L_info2_t linfo2; /* New-style link info */ + hbool_t is_native_vol_obj; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE4("e", "i*sxi", loc_id, name, linfo, lapl_id); + + /* Check arguments */ + if(!name || !*name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name specified") + + /* Verify access property list and set up collective metadata if appropriate */ + if(H5CX_set_apl(&lapl_id, H5P_CLS_LACC, loc_id, TRUE) < 0) + HGOTO_ERROR(H5E_LINK, H5E_CANTSET, FAIL, "can't set access property list info") + + loc_params.type = H5VL_OBJECT_BY_NAME; + loc_params.obj_type = H5I_get_type(loc_id); + loc_params.loc_data.loc_by_name.name = name; + loc_params.loc_data.loc_by_name.lapl_id = lapl_id; + + /* get the location object */ + if(NULL == (vol_obj = (H5VL_object_t *)H5I_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + + /* Check if the VOL object is a native VOL connector object */ + if(H5VL_object_is_native(vol_obj, &is_native_vol_obj) < 0) + HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "can't determine if VOL object is native connector object") + if(!is_native_vol_obj) + HGOTO_ERROR(H5E_LINK, H5E_BADVALUE, FAIL, "H5Lget_info1 is only meant to be used with the native VOL connector") + + /* Get the link information */ + if(H5VL_link_get(vol_obj, &loc_params, H5VL_LINK_GET_INFO, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, &linfo2) < 0) + HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "unable to get link info") + + /* Copy the new-style members into the old-style struct */ + if(linfo) { + linfo->type = linfo2.type; + linfo->corder_valid = linfo2.corder_valid; + linfo->corder = linfo2.corder; + linfo->cset = linfo2.cset; + if(H5L_TYPE_HARD == linfo2.type) { + void *vol_obj_data; + + if(NULL == (vol_obj_data = H5VL_object_data(vol_obj))) + HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't get underlying VOL object") + + if(H5VL_native_token_to_addr(vol_obj_data, loc_params.obj_type, linfo2.u.token, &linfo->u.address) < 0) + HGOTO_ERROR(H5E_LINK, H5E_CANTUNSERIALIZE, FAIL, "can't deserialize object token into address") + } /* end if */ + else + linfo->u.val_size = linfo2.u.val_size; + } /* end if */ + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Lget_info1() */ + + +/*------------------------------------------------------------------------- + * Function: H5Lget_info_by_idx1 + * + * Purpose: Gets metadata for a link, according to the order within an + * index. + * + * Note: Deprecated in favor of H5Lget_info_by_idx2 + * + * Return: Success: Non-negative with information in LINFO + * Failure: Negative + * + * Programmer: Quincey Koziol + * Monday, November 6, 2006 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Lget_info_by_idx1(hid_t loc_id, const char *group_name, + H5_index_t idx_type, H5_iter_order_t order, hsize_t n, + H5L_info1_t *linfo /*out*/, hid_t lapl_id) +{ + H5VL_object_t *vol_obj = NULL; /* object of loc_id */ + H5VL_loc_params_t loc_params; + H5L_info2_t linfo2; /* New-style link info */ + hbool_t is_native_vol_obj; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE7("e", "i*sIiIohxi", loc_id, group_name, idx_type, order, n, linfo, + lapl_id); + + /* Check arguments */ + if(!group_name || !*group_name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name specified") + if(idx_type <= H5_INDEX_UNKNOWN || idx_type >= H5_INDEX_N) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid index type specified") + if(order <= H5_ITER_UNKNOWN || order >= H5_ITER_N) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid iteration order specified") + + /* Verify access property list and set up collective metadata if appropriate */ + if(H5CX_set_apl(&lapl_id, H5P_CLS_LACC, loc_id, FALSE) < 0) + HGOTO_ERROR(H5E_LINK, H5E_CANTSET, FAIL, "can't set access property list info") + + loc_params.type = H5VL_OBJECT_BY_IDX; + loc_params.loc_data.loc_by_idx.name = group_name; + loc_params.loc_data.loc_by_idx.idx_type = idx_type; + loc_params.loc_data.loc_by_idx.order = order; + loc_params.loc_data.loc_by_idx.n = n; + loc_params.loc_data.loc_by_idx.lapl_id = lapl_id; + loc_params.obj_type = H5I_get_type(loc_id); + + /* get the location object */ + if(NULL == (vol_obj = (H5VL_object_t *)H5I_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + + /* Check if the VOL object is a native VOL connector object */ + if(H5VL_object_is_native(vol_obj, &is_native_vol_obj) < 0) + HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "can't determine if VOL object is native connector object") + if(!is_native_vol_obj) + HGOTO_ERROR(H5E_LINK, H5E_BADVALUE, FAIL, "H5Lget_info_by_idx1 is only meant to be used with the native VOL connector") + + /* Get the link information */ + if(H5VL_link_get(vol_obj, &loc_params, H5VL_LINK_GET_INFO, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, &linfo2) < 0) + HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "unable to get link info") + + /* Copy the new-style members into the old-style struct */ + if(linfo) { + linfo->type = linfo2.type; + linfo->corder_valid = linfo2.corder_valid; + linfo->corder = linfo2.corder; + linfo->cset = linfo2.cset; + if(H5L_TYPE_HARD == linfo2.type) { + void *vol_obj_data; + + if(NULL == (vol_obj_data = H5VL_object_data(vol_obj))) + HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't get underlying VOL object") + + if(H5VL_native_token_to_addr(vol_obj_data, loc_params.obj_type, linfo2.u.token, &linfo->u.address) < 0) + HGOTO_ERROR(H5E_LINK, H5E_CANTUNSERIALIZE, FAIL, "can't deserialize object token into address") + } /* end if */ + else + linfo->u.val_size = linfo2.u.val_size; + } /* end if */ + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Lget_info_by_idx1() */ + + +/*------------------------------------------------------------------------- + * Function: H5Lvisit1 + * + * Purpose: Recursively visit all the links in a group and all + * the groups that are linked to from that group. Links within + * each group are visited according to the order within the + * specified index (unless the specified index does not exist for + * a particular group, then the "name" index is used). + * + * NOTE: Each _link_ reachable from the initial group will only be + * visited once. However, because an object may be reached from + * more than one link, the visitation may call the application's + * callback with more than one link that points to a particular + * _object_. + * + * Note: Deprecated in favor of H5Lvisit2 + * + * Return: Success: The return value of the first operator that + * returns non-zero, or zero if all members were + * processed with no operator returning non-zero. + * + * Failure: Negative if something goes wrong within the + * library, or the negative value returned by one + * of the operators. + * + * Programmer: Quincey Koziol + * November 24 2007 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Lvisit1(hid_t group_id, H5_index_t idx_type, H5_iter_order_t order, + H5L_iterate1_t op, void *op_data) +{ + H5VL_object_t *vol_obj = NULL; /* Object of loc_id */ + H5VL_loc_params_t loc_params; + H5I_type_t id_type; /* Type of ID */ + H5L_shim_data_t shim_data; + hbool_t is_native_vol_obj; + herr_t ret_value; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE5("e", "iIiIox*x", group_id, idx_type, order, op, op_data); + + /* Check args */ + id_type = H5I_get_type(group_id); + if(!(H5I_GROUP == id_type || H5I_FILE == id_type)) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid argument") + if(idx_type <= H5_INDEX_UNKNOWN || idx_type >= H5_INDEX_N) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid index type specified") + if(order <= H5_ITER_UNKNOWN || order >= H5_ITER_N) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid iteration order specified") + if(!op) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no callback operator specified") + + /* Set location struct fields */ + loc_params.type = H5VL_OBJECT_BY_SELF; + loc_params.obj_type = H5I_get_type(group_id); + + /* Get the location object */ + if(NULL == (vol_obj = (H5VL_object_t *)H5I_object(group_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + + /* Check if the VOL object is a native VOL connector object */ + if(H5VL_object_is_native(vol_obj, &is_native_vol_obj) < 0) + HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "can't determine if VOL object is native connector object") + if(!is_native_vol_obj) + HGOTO_ERROR(H5E_LINK, H5E_BADVALUE, FAIL, "H5Lvisit1 is only meant to be used with the native VOL connector") + + /* Set up shim */ + shim_data.real_op = op; + shim_data.real_op_data = op_data; + + /* Iterate over the links */ + if((ret_value = H5VL_link_specific(vol_obj, &loc_params, H5VL_LINK_ITER, H5P_DATASET_XFER_DEFAULT, + H5_REQUEST_NULL, TRUE, idx_type, order, NULL, H5L__iterate2_shim, (void *)&shim_data)) < 0) + HGOTO_ERROR(H5E_LINK, H5E_BADITER, FAIL, "link visitation failed") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Lvisit1() */ + + +/*------------------------------------------------------------------------- + * Function: H5Lvisit_by_name1 + * + * Purpose: Recursively visit all the links in a group and all + * the groups that are linked to from that group. Links within + * each group are visited according to the order within the + * specified index (unless the specified index does not exist for + * a particular group, then the "name" index is used). + * + * NOTE: Each _link_ reachable from the initial group will only be + * visited once. However, because an object may be reached from + * more than one link, the visitation may call the application's + * callback with more than one link that points to a particular + * _object_. + * + * Note: Deprecated in favor of H5Lvisit_by_name2 + * + * Return: Success: The return value of the first operator that + * returns non-zero, or zero if all members were + * processed with no operator returning non-zero. + * + * Failure: Negative if something goes wrong within the + * library, or the negative value returned by one + * of the operators. + * + * Programmer: Quincey Koziol + * November 3 2007 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Lvisit_by_name1(hid_t loc_id, const char *group_name, H5_index_t idx_type, + H5_iter_order_t order, H5L_iterate1_t op, void *op_data, hid_t lapl_id) +{ + H5VL_object_t *vol_obj = NULL; /* Object of loc_id */ + H5VL_loc_params_t loc_params; + H5L_shim_data_t shim_data; + hbool_t is_native_vol_obj; + herr_t ret_value; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE7("e", "i*sIiIox*xi", loc_id, group_name, idx_type, order, op, op_data, + lapl_id); + + /* Check args */ + if(!group_name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "group_name parameter cannot be NULL") + if(!*group_name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "group_name parameter cannot be an empty string") + if(idx_type <= H5_INDEX_UNKNOWN || idx_type >= H5_INDEX_N) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid index type specified") + if(order <= H5_ITER_UNKNOWN || order >= H5_ITER_N) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid iteration order specified") + if(!op) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no callback operator specified") + + /* Verify access property list and set up collective metadata if appropriate */ + if(H5CX_set_apl(&lapl_id, H5P_CLS_LACC, loc_id, FALSE) < 0) + HGOTO_ERROR(H5E_LINK, H5E_CANTSET, FAIL, "can't set access property list info") + + /* get the location object */ + if(NULL == (vol_obj = (H5VL_object_t *)H5I_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + + /* Check if the VOL object is a native VOL connector object */ + if(H5VL_object_is_native(vol_obj, &is_native_vol_obj) < 0) + HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "can't determine if VOL object is native connector object") + if(!is_native_vol_obj) + HGOTO_ERROR(H5E_LINK, H5E_BADVALUE, FAIL, "H5Lvisit_by_name1 is only meant to be used with the native VOL connector") + + /* Set location struct fields */ + loc_params.type = H5VL_OBJECT_BY_NAME; + loc_params.obj_type = H5I_get_type(loc_id); + loc_params.loc_data.loc_by_name.name = group_name; + loc_params.loc_data.loc_by_name.lapl_id = lapl_id; + + /* Set up shim */ + shim_data.real_op = op; + shim_data.real_op_data = op_data; + + /* Visit the links */ + if((ret_value = H5VL_link_specific(vol_obj, &loc_params, H5VL_LINK_ITER, H5P_DATASET_XFER_DEFAULT, + H5_REQUEST_NULL, TRUE, idx_type, order, NULL, H5L__iterate2_shim, (void *)&shim_data)) < 0) + HGOTO_ERROR(H5E_LINK, H5E_BADITER, FAIL, "link visitation failed") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Lvisit_by_name1() */ + +#endif /* H5_NO_DEPRECATED_SYMBOLS */ + diff --git a/src/H5Lexternal.c b/src/H5Lexternal.c index dc104d7..1b007b6 100644 --- a/src/H5Lexternal.c +++ b/src/H5Lexternal.c @@ -341,7 +341,7 @@ herr_t H5Lcreate_external(const char *file_name, const char *obj_name, hid_t link_loc_id, const char *link_name, hid_t lcpl_id, hid_t lapl_id) { - H5VL_object_t *vol_obj = NULL; /* Object token of loc_id */ + H5VL_object_t *vol_obj = NULL; /* Object of loc_id */ H5VL_loc_params_t loc_params; char *norm_obj_name = NULL; /* Pointer to normalized current name */ void *ext_link_buf = NULL; /* Buffer to contain external link */ diff --git a/src/H5Lprivate.h b/src/H5Lprivate.h index 6652352..ab68b84 100644 --- a/src/H5Lprivate.h +++ b/src/H5Lprivate.h @@ -68,7 +68,7 @@ typedef struct { hsize_t n; /* Offset of link within index */ /* Out */ - H5L_info_t *linfo; /* Buffer to return to user */ + H5L_info2_t *linfo; /* Buffer to return to user */ } H5L_trav_gibi_t; /* User data for path traversal routine for getting name by index */ @@ -98,7 +98,6 @@ typedef struct H5L_elink_cb_t { void *user_data; } H5L_elink_cb_t; - /*****************************/ /* Library Private Variables */ /*****************************/ @@ -124,13 +123,13 @@ H5_DLL herr_t H5L_move(const H5G_loc_t *src_loc, const char *src_name, H5_DLL htri_t H5L_exists_tolerant(const H5G_loc_t *loc, const char *name); H5_DLL htri_t H5L_exists(const H5G_loc_t *loc, const char *name); H5_DLL herr_t H5L_get_info(const H5G_loc_t *loc, const char *name, - H5L_info_t *linkbuf/*out*/); + H5L_info2_t *linkbuf/*out*/); H5_DLL herr_t H5L_delete(const H5G_loc_t *loc, const char *name); H5_DLL herr_t H5L_delete_by_idx(const H5G_loc_t *loc, const char *name, H5_index_t idx_type, H5_iter_order_t order, hsize_t n); H5_DLL herr_t H5L_get_info_by_idx(const H5G_loc_t *loc, const char *name, H5_index_t idx_type, H5_iter_order_t order, hsize_t n, - H5L_info_t *linfo /*out*/); + H5L_info2_t *linfo /*out*/); H5_DLL ssize_t H5L_get_name_by_idx(const H5G_loc_t *loc, const char *group_name, H5_index_t idx_type, H5_iter_order_t order, hsize_t n, char *name /*out*/, size_t size); @@ -142,7 +141,7 @@ H5_DLL herr_t H5L_get_val_by_idx(const H5G_loc_t *loc, const char *name, H5_DLL herr_t H5L_register_external(void); H5_DLL herr_t H5L_iterate(H5G_loc_t *loc, const char *group_name, H5_index_t idx_type, H5_iter_order_t order, hsize_t *idx_p, - H5L_iterate_t op, void *op_data); + H5L_iterate2_t op, void *op_data); /* User-defined link functions */ H5_DLL herr_t H5L_register(const H5L_class_t *cls); diff --git a/src/H5Lpublic.h b/src/H5Lpublic.h index 7bdb001..3bac5ac 100644 --- a/src/H5Lpublic.h +++ b/src/H5Lpublic.h @@ -27,6 +27,7 @@ /* Public headers needed by this file */ #include "H5public.h" /* Generic Functions */ #include "H5Ipublic.h" /* IDs */ +#include "H5Opublic.h" /* Object Headers */ #include "H5Tpublic.h" /* Datatypes */ /*****************/ @@ -43,9 +44,6 @@ /* Current version of the H5L_class_t struct */ #define H5L_LINK_CLASS_T_VERS 1 -/* Previous versions of the H5L_class_t struct */ -#define H5L_LINK_CLASS_T_VERS_0 0 - #ifdef __cplusplus extern "C" { #endif @@ -72,17 +70,19 @@ typedef enum { #define H5L_TYPE_BUILTIN_MAX H5L_TYPE_SOFT /* Maximum value link value for "built-in" link types */ #define H5L_TYPE_UD_MIN H5L_TYPE_EXTERNAL /* Link ids at or above this value are "user-defined" link types. */ -/* Information struct for link (for H5Lget_info/H5Lget_info_by_idx) */ +/* Information struct for link (for H5Lget_info2/H5Lget_info_by_idx2) + * H5O_token_t version used in VOL layer and future public API calls + */ typedef struct { H5L_type_t type; /* Type of link */ hbool_t corder_valid; /* Indicate if creation order is valid */ int64_t corder; /* Creation order */ H5T_cset_t cset; /* Character set of link name */ union { - haddr_t address; /* Address hard link points to */ + H5O_token_t token; /* Token of location that hard link points to */ size_t val_size; /* Size of a soft link or UD link value */ } u; -} H5L_info_t; +} H5L_info2_t; /* The H5L_class_t struct can be used to override the behavior of a * "user-defined" link class. Users should populate the struct with callback @@ -102,8 +102,6 @@ typedef herr_t (*H5L_copy_func_t)(const char *new_name, hid_t new_loc, const void *lnkdata, size_t lnkdata_size); /* Callback during link traversal */ -typedef hid_t (*H5L_traverse_0_func_t)(const char *link_name, hid_t cur_group, - const void *lnkdata, size_t lnkdata_size, hid_t lapl_id); typedef hid_t (*H5L_traverse_func_t)(const char *link_name, hid_t cur_group, const void *lnkdata, size_t lnkdata_size, hid_t lapl_id, hid_t dxpl_id); @@ -116,19 +114,6 @@ typedef herr_t (*H5L_delete_func_t)(const char *link_name, hid_t file, typedef ssize_t (*H5L_query_func_t)(const char *link_name, const void *lnkdata, size_t lnkdata_size, void *buf /*out*/, size_t buf_size); -/* User-defined link types */ -typedef struct { - int version; /* Version number of this struct */ - H5L_type_t id; /* Link type ID */ - const char *comment; /* Comment for debugging */ - H5L_create_func_t create_func; /* Callback during link creation */ - H5L_move_func_t move_func; /* Callback after moving link */ - H5L_copy_func_t copy_func; /* Callback after copying link */ - H5L_traverse_0_func_t trav_func; /* Callback during link traversal */ - H5L_delete_func_t del_func; /* Callback for link deletion */ - H5L_query_func_t query_func; /* Callback for queries */ -} H5L_class_0_t; - typedef struct { int version; /* Version number of this struct */ H5L_type_t id; /* Link type ID */ @@ -141,8 +126,10 @@ typedef struct { H5L_query_func_t query_func; /* Callback for queries */ } H5L_class_t; -/* Prototype for H5Literate/H5Literate_by_name() operator */ -typedef herr_t (*H5L_iterate_t)(hid_t group, const char *name, const H5L_info_t *info, +/* Prototype for H5Literate2/H5Literate_by_name2() operator + * H5O_token_t version used in VOL layer and future public API calls + */ +typedef herr_t (*H5L_iterate2_t)(hid_t group, const char *name, const H5L_info2_t *info, void *op_data); /* Callback for external link traversal */ @@ -177,23 +164,23 @@ H5_DLL herr_t H5Lget_val_by_idx(hid_t loc_id, const char *group_name, H5_index_t idx_type, H5_iter_order_t order, hsize_t n, void *buf/*out*/, size_t size, hid_t lapl_id); H5_DLL htri_t H5Lexists(hid_t loc_id, const char *name, hid_t lapl_id); -H5_DLL herr_t H5Lget_info(hid_t loc_id, const char *name, - H5L_info_t *linfo /*out*/, hid_t lapl_id); -H5_DLL herr_t H5Lget_info_by_idx(hid_t loc_id, const char *group_name, +H5_DLL herr_t H5Lget_info2(hid_t loc_id, const char *name, + H5L_info2_t *linfo /*out*/, hid_t lapl_id); +H5_DLL herr_t H5Lget_info_by_idx2(hid_t loc_id, const char *group_name, H5_index_t idx_type, H5_iter_order_t order, hsize_t n, - H5L_info_t *linfo /*out*/, hid_t lapl_id); + H5L_info2_t *linfo /*out*/, hid_t lapl_id); H5_DLL ssize_t H5Lget_name_by_idx(hid_t loc_id, const char *group_name, H5_index_t idx_type, H5_iter_order_t order, hsize_t n, char *name /*out*/, size_t size, hid_t lapl_id); -H5_DLL herr_t H5Literate(hid_t grp_id, H5_index_t idx_type, - H5_iter_order_t order, hsize_t *idx, H5L_iterate_t op, void *op_data); -H5_DLL herr_t H5Literate_by_name(hid_t loc_id, const char *group_name, +H5_DLL herr_t H5Literate2(hid_t grp_id, H5_index_t idx_type, + H5_iter_order_t order, hsize_t *idx, H5L_iterate2_t op, void *op_data); +H5_DLL herr_t H5Literate_by_name2(hid_t loc_id, const char *group_name, H5_index_t idx_type, H5_iter_order_t order, hsize_t *idx, - H5L_iterate_t op, void *op_data, hid_t lapl_id); -H5_DLL herr_t H5Lvisit(hid_t grp_id, H5_index_t idx_type, H5_iter_order_t order, - H5L_iterate_t op, void *op_data); -H5_DLL herr_t H5Lvisit_by_name(hid_t loc_id, const char *group_name, - H5_index_t idx_type, H5_iter_order_t order, H5L_iterate_t op, + H5L_iterate2_t op, void *op_data, hid_t lapl_id); +H5_DLL herr_t H5Lvisit2(hid_t grp_id, H5_index_t idx_type, H5_iter_order_t order, + H5L_iterate2_t op, void *op_data); +H5_DLL herr_t H5Lvisit_by_name2(hid_t loc_id, const char *group_name, + H5_index_t idx_type, H5_iter_order_t order, H5L_iterate2_t op, void *op_data, hid_t lapl_id); /* UD link functions */ @@ -210,6 +197,73 @@ H5_DLL herr_t H5Lunpack_elink_val(const void *ext_linkval/*in*/, size_t link_siz H5_DLL herr_t H5Lcreate_external(const char *file_name, const char *obj_name, hid_t link_loc_id, const char *link_name, hid_t lcpl_id, hid_t lapl_id); +/* Symbols defined for compatibility with previous versions of the HDF5 API. + * + * Use of these symbols is deprecated. + */ +#ifndef H5_NO_DEPRECATED_SYMBOLS + +/* Macros */ + +/* Previous versions of the H5L_class_t struct */ +#define H5L_LINK_CLASS_T_VERS_0 0 + + +/* Typedefs */ + +/* Information struct for link (for H5Lget_info1/H5Lget_info_by_idx1) */ +typedef struct { + H5L_type_t type; /* Type of link */ + hbool_t corder_valid; /* Indicate if creation order is valid */ + int64_t corder; /* Creation order */ + H5T_cset_t cset; /* Character set of link name */ + union { + haddr_t address; /* Address hard link points to */ + size_t val_size; /* Size of a soft link or UD link value */ + } u; +} H5L_info1_t; + +/* Callback during link traversal */ +typedef hid_t (*H5L_traverse_0_func_t)(const char *link_name, hid_t cur_group, + const void *lnkdata, size_t lnkdata_size, hid_t lapl_id); + +/* User-defined link types */ +typedef struct { + int version; /* Version number of this struct */ + H5L_type_t id; /* Link type ID */ + const char *comment; /* Comment for debugging */ + H5L_create_func_t create_func; /* Callback during link creation */ + H5L_move_func_t move_func; /* Callback after moving link */ + H5L_copy_func_t copy_func; /* Callback after copying link */ + H5L_traverse_0_func_t trav_func; /* Callback during link traversal */ + H5L_delete_func_t del_func; /* Callback for link deletion */ + H5L_query_func_t query_func; /* Callback for queries */ +} H5L_class_0_t; + +/* Prototype for H5Literate1/H5Literate_by_name1() operator */ +typedef herr_t (*H5L_iterate1_t)(hid_t group, const char *name, const H5L_info1_t *info, + void *op_data); + + +/* Function prototypes */ +H5_DLL herr_t H5Lget_info1(hid_t loc_id, const char *name, + H5L_info1_t *linfo /*out*/, hid_t lapl_id); +H5_DLL herr_t H5Lget_info_by_idx1(hid_t loc_id, const char *group_name, + H5_index_t idx_type, H5_iter_order_t order, hsize_t n, + H5L_info1_t *linfo /*out*/, hid_t lapl_id); +H5_DLL herr_t H5Literate1(hid_t grp_id, H5_index_t idx_type, + H5_iter_order_t order, hsize_t *idx, H5L_iterate1_t op, void *op_data); +H5_DLL herr_t H5Literate_by_name1(hid_t loc_id, const char *group_name, + H5_index_t idx_type, H5_iter_order_t order, hsize_t *idx, + H5L_iterate1_t op, void *op_data, hid_t lapl_id); +H5_DLL herr_t H5Lvisit1(hid_t grp_id, H5_index_t idx_type, H5_iter_order_t order, + H5L_iterate1_t op, void *op_data); +H5_DLL herr_t H5Lvisit_by_name1(hid_t loc_id, const char *group_name, + H5_index_t idx_type, H5_iter_order_t order, H5L_iterate1_t op, + void *op_data, hid_t lapl_id); + +#endif /* H5_NO_DEPRECATED_SYMBOLS */ + #ifdef __cplusplus } #endif diff --git a/src/H5M.c b/src/H5M.c index 62f06a1..4d76574 100644 --- a/src/H5M.c +++ b/src/H5M.c @@ -256,7 +256,7 @@ H5Mcreate(hid_t loc_id, const char *name, hid_t key_type_id, hid_t val_type_id, hid_t lcpl_id, hid_t mcpl_id, hid_t mapl_id) { void *map = NULL; /* New map's info */ - H5VL_object_t *vol_obj = NULL; /* object token of loc_id */ + H5VL_object_t *vol_obj = NULL; /* object of loc_id */ H5VL_loc_params_t loc_params; hid_t ret_value = H5I_INVALID_HID; /* Return value */ @@ -343,8 +343,8 @@ hid_t H5Mcreate_anon(hid_t loc_id, hid_t key_type_id, hid_t val_type_id, hid_t mcpl_id, hid_t mapl_id) { - void *map = NULL; /* map token from VOL connector */ - H5VL_object_t *vol_obj = NULL; /* object token of loc_id */ + void *map = NULL; /* map object from VOL connector */ + H5VL_object_t *vol_obj = NULL; /* object of loc_id */ H5VL_loc_params_t loc_params; hid_t ret_value = H5I_INVALID_HID; /* Return value */ @@ -407,8 +407,8 @@ done: hid_t H5Mopen(hid_t loc_id, const char *name, hid_t mapl_id) { - void *map = NULL; /* map token from VOL connector */ - H5VL_object_t *vol_obj = NULL; /* object token of loc_id */ + void *map = NULL; /* map object from VOL connector */ + H5VL_object_t *vol_obj = NULL; /* object of loc_id */ H5VL_loc_params_t loc_params; hid_t ret_value = H5I_INVALID_HID; /* Return value */ diff --git a/src/H5O.c b/src/H5O.c index cd577cb..d943e37 100644 --- a/src/H5O.c +++ b/src/H5O.c @@ -102,7 +102,7 @@ hid_t H5Oopen(hid_t loc_id, const char *name, hid_t lapl_id) { - H5VL_object_t *vol_obj; /* Object token of loc_id */ + H5VL_object_t *vol_obj; /* Object of loc_id */ H5I_type_t opened_type; void *opened_obj = NULL; H5VL_loc_params_t loc_params; @@ -171,7 +171,7 @@ hid_t H5Oopen_by_idx(hid_t loc_id, const char *group_name, H5_index_t idx_type, H5_iter_order_t order, hsize_t n, hid_t lapl_id) { - H5VL_object_t *vol_obj; /* Object token of loc_id */ + H5VL_object_t *vol_obj; /* Object of loc_id */ H5I_type_t opened_type; void *opened_obj = NULL; H5VL_loc_params_t loc_params; @@ -217,57 +217,34 @@ done: /*------------------------------------------------------------------------- - * Function: H5Oopen_by_addr + * Function: H5Oopen_by_token * - * Purpose: Warning! This function is EXTREMELY DANGEROUS! - * Improper use can lead to FILE CORRUPTION, INACCESSIBLE DATA, - * and other VERY BAD THINGS! - * - * This function opens an object using its address within the - * HDF5 file, similar to an HDF5 hard link. The open object - * is identical to an object opened with H5Oopen() and should - * be closed with H5Oclose() or a type-specific closing - * function (such as H5Gclose() ). - * - * This function is very dangerous if called on an invalid - * address. For this reason, H5Oincr_refcount() should be - * used to prevent HDF5 from deleting any object that is - * referenced by address (e.g. by a user-defined link). - * H5Odecr_refcount() should be used when the object is - * no longer being referenced by address (e.g. when the UD link - * is deleted). - * - * The address of the HDF5 file on disk has no effect on - * H5Oopen_by_addr(), nor does the use of any unusual file - * drivers. The "address" is really the offset within the - * HDF5 file, and HDF5's file drivers will transparently - * map this to an address on disk for the filesystem. + * Purpose: Same as H5Oopen_by_addr, but uses VOL-independent tokens. * - * Return: Success: An open object identifier - * Failure: H5I_INVALID_HID + * Return: Success: An open object identifier + * Failure: H5I_INVALID_HID * - * Programmer: James Laird - * July 14 2006 + * Programmer: Dana Robinson + * Winter 2019 * *------------------------------------------------------------------------- */ hid_t -H5Oopen_by_addr(hid_t loc_id, haddr_t addr) +H5Oopen_by_token(hid_t loc_id, H5O_token_t token) { - H5VL_object_t *vol_obj; /* Object token of loc_id */ + H5VL_object_t *vol_obj; /* Object of loc_id */ H5I_type_t vol_obj_type = H5I_BADID;/* Object type of loc_id */ H5I_type_t opened_type; /* Opened object type */ void *opened_obj = NULL; /* Opened object */ H5VL_loc_params_t loc_params; /* Location parameters */ - H5VL_token_t obj_token = {0}; /* Object token */ - hid_t file_id = H5I_INVALID_HID; /* File ID */ - void *vol_obj_file = NULL; /* Object token of file_id */ - H5F_t *f = NULL; - uint8_t *p = NULL; hid_t ret_value = H5I_INVALID_HID; /* Return value */ FUNC_ENTER_API(H5I_INVALID_HID) - H5TRACE2("i", "ia", loc_id, addr); + H5TRACE2("i", "ik", loc_id, token); + + /* Check args */ + if(H5O_IS_TOKEN_UNDEF(token)) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "can't open H5O_TOKEN_UNDEF") /* Get the location object */ if(NULL == (vol_obj = (H5VL_object_t *)H5I_object(loc_id))) @@ -277,39 +254,21 @@ H5Oopen_by_addr(hid_t loc_id, haddr_t addr) if((vol_obj_type = H5I_get_type(loc_id)) < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid location identifier") - /* Get the file for the object */ - if((file_id = H5F_get_file_id(vol_obj, vol_obj_type, FALSE)) < 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "not a file or file object") - - /* Retrieve VOL object */ - if(NULL == (vol_obj_file = H5VL_vol_object(file_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid location identifier") - - /* Retrieve file from VOL object */ - if(NULL == (f = (H5F_t *)H5VL_object_data((const H5VL_object_t *)vol_obj_file))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid VOL object") - - /* This is a native specific routine that requires serialization of the token */ - p = (uint8_t *)&obj_token; - H5F_addr_encode(f, &p, addr); - loc_params.type = H5VL_OBJECT_BY_TOKEN; - loc_params.loc_data.loc_by_token.token = &obj_token; + loc_params.loc_data.loc_by_token.token = &token; loc_params.obj_type = vol_obj_type; /* Open the object */ if(NULL == (opened_obj = H5VL_object_open(vol_obj, &loc_params, &opened_type, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL))) HGOTO_ERROR(H5E_OHDR, H5E_CANTOPENOBJ, H5I_INVALID_HID, "unable to open object") - /* Register the dataset ID */ + /* Register the object's ID */ if((ret_value = H5VL_register(opened_type, opened_obj, vol_obj->connector, TRUE)) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to atomize object handle") done: - if(file_id != H5I_INVALID_HID && H5I_dec_ref(file_id) < 0) - HDONE_ERROR(H5E_REFERENCE, H5E_CANTDEC, H5I_INVALID_HID, "unable to decrement refcount on file") FUNC_LEAVE_API(ret_value) -} /* end H5Oopen_by_addr() */ +} /* end H5Oopen_by_token() */ /*------------------------------------------------------------------------- @@ -337,9 +296,9 @@ herr_t H5Olink(hid_t obj_id, hid_t new_loc_id, const char *new_name, hid_t lcpl_id, hid_t lapl_id) { - H5VL_object_t *vol_obj1 = NULL; /* object token of obj_id */ - H5VL_object_t *vol_obj2 = NULL; /* object token of new_loc_id */ - H5VL_object_t tmp_vol_obj; /* Temporary object token of */ + H5VL_object_t *vol_obj1 = NULL; /* object of obj_id */ + H5VL_object_t *vol_obj2 = NULL; /* object of new_loc_id */ + H5VL_object_t tmp_vol_obj; /* Temporary object */ H5VL_loc_params_t loc_params1; H5VL_loc_params_t loc_params2; herr_t ret_value = SUCCEED; /* Return value */ @@ -429,7 +388,7 @@ done: herr_t H5Oincr_refcount(hid_t object_id) { - H5VL_object_t *vol_obj; /* Object token of loc_id */ + H5VL_object_t *vol_obj; /* Object of loc_id */ H5VL_loc_params_t loc_params; herr_t ret_value = SUCCEED; @@ -479,7 +438,7 @@ done: herr_t H5Odecr_refcount(hid_t object_id) { - H5VL_object_t *vol_obj; /* Object token of loc_id */ + H5VL_object_t *vol_obj; /* Object of loc_id */ H5VL_loc_params_t loc_params; herr_t ret_value = SUCCEED; /* Return value */ @@ -522,7 +481,7 @@ done: htri_t H5Oexists_by_name(hid_t loc_id, const char *name, hid_t lapl_id) { - H5VL_object_t *vol_obj; /* Object token of loc_id */ + H5VL_object_t *vol_obj; /* Object of loc_id */ H5VL_loc_params_t loc_params; htri_t ret_value = FAIL; /* Return value */ @@ -559,23 +518,21 @@ done: /*------------------------------------------------------------------------- - * Function: H5Oget_info2 + * Function: H5Oget_info3 * * Purpose: Retrieve information about an object. * - * NOTE: Add a parameter "fields" to indicate selection of object info. - * * Return: SUCCEED/FAIL * - * Programmer: Neil Fortner - * July 7 2010 + * Programmer: Dana Robinson + * Fall 2019 * *------------------------------------------------------------------------- */ herr_t -H5Oget_info2(hid_t loc_id, H5O_info_t *oinfo, unsigned fields) +H5Oget_info3(hid_t loc_id, H5O_info2_t *oinfo, unsigned fields) { - H5VL_object_t *vol_obj; /* Object token of loc_id */ + H5VL_object_t *vol_obj; /* Object of loc_id */ H5VL_loc_params_t loc_params; herr_t ret_value = SUCCEED; /* Return value */ @@ -597,33 +554,31 @@ H5Oget_info2(hid_t loc_id, H5O_info_t *oinfo, unsigned fields) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") /* Retrieve the object's information */ - if(H5VL_object_optional(vol_obj, H5VL_NATIVE_OBJECT_GET_INFO, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, &loc_params, oinfo, fields) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't get info for object") + if(H5VL_object_get(vol_obj, &loc_params, H5VL_OBJECT_GET_INFO, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, oinfo, fields) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't get data model info for object") done: FUNC_LEAVE_API(ret_value) -} /* end H5Oget_info2() */ +} /* end H5Oget_info3() */ /*------------------------------------------------------------------------- - * Function: H5Oget_info_by_name2 + * Function: H5Oget_info_by_name3 * * Purpose: Retrieve information about an object * - * NOTE: Add a parameter "fields" to indicate selection of object info. - * * Return: SUCCEED/FAIL * - * Programmer: Neil Fortner - * July 7 2010 + * Programmer: Dana Robinson + * Fall 2019 * *------------------------------------------------------------------------- */ herr_t -H5Oget_info_by_name2(hid_t loc_id, const char *name, H5O_info_t *oinfo, - unsigned fields, hid_t lapl_id) +H5Oget_info_by_name3(hid_t loc_id, const char *name, + H5O_info2_t *oinfo, unsigned fields, hid_t lapl_id) { - H5VL_object_t *vol_obj; /* Object token of loc_id */ + H5VL_object_t *vol_obj; /* Object of loc_id */ H5VL_loc_params_t loc_params; herr_t ret_value = SUCCEED; /* Return value */ @@ -655,35 +610,33 @@ H5Oget_info_by_name2(hid_t loc_id, const char *name, H5O_info_t *oinfo, HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") /* Retrieve the object's information */ - if(H5VL_object_optional(vol_obj, H5VL_NATIVE_OBJECT_GET_INFO, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, &loc_params, oinfo, fields) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't get info for object: '%s'", name) + if(H5VL_object_get(vol_obj, &loc_params, H5VL_OBJECT_GET_INFO, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, oinfo, fields) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't get data model info for object") done: FUNC_LEAVE_API(ret_value) -} /* end H5Oget_info_by_name2() */ +} /* end H5Oget_info_by_name3() */ /*------------------------------------------------------------------------- - * Function: H5Oget_info_by_idx2 - * - * Purpose: Retrieve information about an object, according to the order - * of an index. + * Function: H5Oget_info_by_idx3 * - * NOTE: Add a parameter "fields" to indicate selection of object info. + * Purpose: Retrieve information about an object, according to + * the order of an index. * * Return: Success: Non-negative * Failure: Negative * - * Programmer: Quincey Koziol - * November 26 2006 + * Programmer: Dana Robinson + * Fall 2019 * *------------------------------------------------------------------------- */ herr_t -H5Oget_info_by_idx2(hid_t loc_id, const char *group_name, H5_index_t idx_type, - H5_iter_order_t order, hsize_t n, H5O_info_t *oinfo, unsigned fields, hid_t lapl_id) +H5Oget_info_by_idx3(hid_t loc_id, const char *group_name, H5_index_t idx_type, + H5_iter_order_t order, hsize_t n, H5O_info2_t *oinfo, unsigned fields, hid_t lapl_id) { - H5VL_object_t *vol_obj; /* Object token of loc_id */ + H5VL_object_t *vol_obj; /* Object of loc_id */ H5VL_loc_params_t loc_params; herr_t ret_value = SUCCEED; /* Return value */ @@ -720,12 +673,176 @@ H5Oget_info_by_idx2(hid_t loc_id, const char *group_name, H5_index_t idx_type, HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") /* Retrieve the object's information */ - if(H5VL_object_optional(vol_obj, H5VL_NATIVE_OBJECT_GET_INFO, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, &loc_params, oinfo, fields) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't get info for object") + if(H5VL_object_get(vol_obj, &loc_params, H5VL_OBJECT_GET_INFO, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, oinfo, fields) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't get data model info for object") done: FUNC_LEAVE_API(ret_value) -} /* end H5Oget_info_by_idx2() */ +} /* end H5Oget_info_by_idx3() */ + + +/*------------------------------------------------------------------------- + * Function: H5Oget_native_info + * + * Purpose: Retrieve native file format information about an object. + * + * Return: SUCCEED/FAIL + * + * Programmer: Dana Robinson + * Fall 2019 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Oget_native_info(hid_t loc_id, H5O_native_info_t *oinfo, unsigned fields) +{ + H5VL_object_t *vol_obj; /* Object of loc_id */ + H5VL_loc_params_t loc_params; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE3("e", "i*xIu", loc_id, oinfo, fields); + + /* Check args */ + if(!oinfo) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "oinfo parameter cannot be NULL") + if(fields & ~H5O_NATIVE_INFO_ALL) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid fields") + + /* Set location struct fields */ + loc_params.type = H5VL_OBJECT_BY_SELF; + loc_params.obj_type = H5I_get_type(loc_id); + + /* Get the location object */ + if(NULL == (vol_obj = H5VL_vol_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + + /* Retrieve the object's information */ + if(H5VL_object_optional(vol_obj, H5VL_NATIVE_OBJECT_GET_NATIVE_INFO, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, &loc_params, oinfo, fields) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't get native file format info for object") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Oget_native_info() */ + + +/*------------------------------------------------------------------------- + * Function: H5Oget_native_info_by_name + * + * Purpose: Retrieve native file format information about an object + * + * Return: SUCCEED/FAIL + * + * Programmer: Dana Robinson + * Fall 2019 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Oget_native_info_by_name(hid_t loc_id, const char *name, H5O_native_info_t *oinfo, + unsigned fields, hid_t lapl_id) +{ + H5VL_object_t *vol_obj; /* Object of loc_id */ + H5VL_loc_params_t loc_params; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE5("e", "i*s*xIui", loc_id, name, oinfo, fields, lapl_id); + + /* Check args */ + if(!name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "name parameter cannot be NULL") + if(!*name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "name parameter cannot be an empty string") + if(!oinfo) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "oinfo parameter cannot be NULL") + if(fields & ~H5O_NATIVE_INFO_ALL) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid fields") + + /* Verify access property list and set up collective metadata if appropriate */ + if(H5CX_set_apl(&lapl_id, H5P_CLS_LACC, loc_id, FALSE) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTSET, FAIL, "can't set access property list info") + + /* Fill out location struct */ + loc_params.type = H5VL_OBJECT_BY_NAME; + loc_params.loc_data.loc_by_name.name = name; + loc_params.loc_data.loc_by_name.lapl_id = lapl_id; + loc_params.obj_type = H5I_get_type(loc_id); + + /* Get the location object */ + if(NULL == (vol_obj = H5VL_vol_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + + /* Retrieve the object's information */ + if(H5VL_object_optional(vol_obj, H5VL_NATIVE_OBJECT_GET_NATIVE_INFO, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, &loc_params, oinfo, fields) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't get native file format info for object: '%s'", name) + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Oget_native_info_by_name() */ + + +/*------------------------------------------------------------------------- + * Function: H5Oget_native_info_by_idx + * + * Purpose: Retrieve native file format information about an object, + * according to the order of an index. + * + * Return: Success: Non-negative + * Failure: Negative + * + * Programmer: Dana Robinson + * Fall 2019 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Oget_native_info_by_idx(hid_t loc_id, const char *group_name, H5_index_t idx_type, + H5_iter_order_t order, hsize_t n, H5O_native_info_t *oinfo, unsigned fields, hid_t lapl_id) +{ + H5VL_object_t *vol_obj; /* Object of loc_id */ + H5VL_loc_params_t loc_params; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE8("e", "i*sIiIoh*xIui", loc_id, group_name, idx_type, order, n, oinfo, + fields, lapl_id); + + /* Check args */ + if(!group_name || !*group_name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name specified") + if(idx_type <= H5_INDEX_UNKNOWN || idx_type >= H5_INDEX_N) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid index type specified") + if(order <= H5_ITER_UNKNOWN || order >= H5_ITER_N) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid iteration order specified") + if(!oinfo) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no info struct") + if(fields & ~H5O_NATIVE_INFO_ALL) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid fields") + + /* Verify access property list and set up collective metadata if appropriate */ + if(H5CX_set_apl(&lapl_id, H5P_CLS_LACC, loc_id, FALSE) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTSET, FAIL, "can't set access property list info") + + loc_params.type = H5VL_OBJECT_BY_IDX; + loc_params.loc_data.loc_by_idx.name = group_name; + loc_params.loc_data.loc_by_idx.idx_type = idx_type; + loc_params.loc_data.loc_by_idx.order = order; + loc_params.loc_data.loc_by_idx.n = n; + loc_params.loc_data.loc_by_idx.lapl_id = lapl_id; + loc_params.obj_type = H5I_get_type(loc_id); + + /* Get the location object */ + if(NULL == (vol_obj = H5VL_vol_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + + /* Retrieve the object's information */ + if(H5VL_object_optional(vol_obj, H5VL_NATIVE_OBJECT_GET_NATIVE_INFO, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, &loc_params, oinfo, fields) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't get native file format info for object") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Oget_native_info_by_idx() */ /*------------------------------------------------------------------------- @@ -748,7 +865,7 @@ done: herr_t H5Oset_comment(hid_t obj_id, const char *comment) { - H5VL_object_t *vol_obj; /* Object token of loc_id */ + H5VL_object_t *vol_obj; /* Object of loc_id */ H5VL_loc_params_t loc_params; herr_t ret_value = SUCCEED; /* Return value */ @@ -797,7 +914,7 @@ herr_t H5Oset_comment_by_name(hid_t loc_id, const char *name, const char *comment, hid_t lapl_id) { - H5VL_object_t *vol_obj; /* Object token of loc_id */ + H5VL_object_t *vol_obj; /* Object of loc_id */ H5VL_loc_params_t loc_params; herr_t ret_value = SUCCEED; /* Return value */ @@ -850,9 +967,9 @@ done: ssize_t H5Oget_comment(hid_t obj_id, char *comment, size_t bufsize) { - H5VL_object_t *vol_obj; /* Object token of loc_id */ + H5VL_object_t *vol_obj; /* Object of loc_id */ H5VL_loc_params_t loc_params; - ssize_t ret_value = -1; /* Return value */ + ssize_t ret_value = -1; /* Return value */ FUNC_ENTER_API((-1)) H5TRACE3("Zs", "i*sz", obj_id, comment, bufsize); @@ -894,9 +1011,9 @@ ssize_t H5Oget_comment_by_name(hid_t loc_id, const char *name, char *comment, size_t bufsize, hid_t lapl_id) { - H5VL_object_t *vol_obj; /* Object token of loc_id */ + H5VL_object_t *vol_obj; /* Object of loc_id */ H5VL_loc_params_t loc_params; - ssize_t ret_value = -1; /* Return value */ + ssize_t ret_value = -1; /* Return value */ FUNC_ENTER_API((-1)) H5TRACE5("Zs", "i*s*szi", loc_id, name, comment, bufsize, lapl_id); @@ -929,7 +1046,7 @@ done: /*------------------------------------------------------------------------- - * Function: H5Ovisit2 + * Function: H5Ovisit3 * * Purpose: Recursively visit an object and all the objects reachable * from it. If the starting object is a group, all the objects @@ -964,12 +1081,12 @@ done: *------------------------------------------------------------------------- */ herr_t -H5Ovisit2(hid_t obj_id, H5_index_t idx_type, H5_iter_order_t order, - H5O_iterate_t op, void *op_data, unsigned fields) +H5Ovisit3(hid_t obj_id, H5_index_t idx_type, H5_iter_order_t order, + H5O_iterate2_t op, void *op_data, unsigned fields) { - H5VL_object_t *vol_obj; /* Object token of loc_id */ + H5VL_object_t *vol_obj; /* Object of loc_id */ H5VL_loc_params_t loc_params; - herr_t ret_value; /* Return value */ + herr_t ret_value; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE6("e", "iIiIox*xIu", obj_id, idx_type, order, op, op_data, fields); @@ -998,11 +1115,11 @@ H5Ovisit2(hid_t obj_id, H5_index_t idx_type, H5_iter_order_t order, done: FUNC_LEAVE_API(ret_value) -} /* end H5Ovisit2() */ +} /* end H5Ovisit3() */ /*------------------------------------------------------------------------- - * Function: H5Ovisit_by_name2 + * Function: H5Ovisit_by_name3 * * Purpose: Recursively visit an object and all the objects reachable * from it. If the starting object is a group, all the objects @@ -1037,12 +1154,12 @@ done: *------------------------------------------------------------------------- */ herr_t -H5Ovisit_by_name2(hid_t loc_id, const char *obj_name, H5_index_t idx_type, - H5_iter_order_t order, H5O_iterate_t op, void *op_data, unsigned fields, hid_t lapl_id) +H5Ovisit_by_name3(hid_t loc_id, const char *obj_name, H5_index_t idx_type, + H5_iter_order_t order, H5O_iterate2_t op, void *op_data, unsigned fields, hid_t lapl_id) { - H5VL_object_t *vol_obj; /* Object token of loc_id */ - H5VL_loc_params_t loc_params; - herr_t ret_value; /* Return value */ + H5VL_object_t *vol_obj; /* Object of loc_id */ + H5VL_loc_params_t loc_params; + herr_t ret_value; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE8("e", "i*sIiIox*xIui", loc_id, obj_name, idx_type, order, op, op_data, @@ -1082,7 +1199,7 @@ H5Ovisit_by_name2(hid_t loc_id, const char *obj_name, H5_index_t idx_type, done: FUNC_LEAVE_API(ret_value) -} /* end H5Ovisit_by_name2() */ +} /* end H5Ovisit_by_name3() */ /*------------------------------------------------------------------------- @@ -1187,7 +1304,7 @@ done: herr_t H5Odisable_mdc_flushes(hid_t object_id) { - H5VL_object_t *vol_obj; /* Object token of loc_id */ + H5VL_object_t *vol_obj; /* Object of loc_id */ H5VL_loc_params_t loc_params; /* Location parameters */ herr_t ret_value = SUCCEED; /* Return value */ @@ -1256,7 +1373,7 @@ done: herr_t H5Oenable_mdc_flushes(hid_t object_id) { - H5VL_object_t *vol_obj; /* Object token of loc_id */ + H5VL_object_t *vol_obj; /* Object of loc_id */ H5VL_loc_params_t loc_params; /* Location parameters */ herr_t ret_value = SUCCEED; /* Return value */ @@ -1330,7 +1447,7 @@ done: herr_t H5Oare_mdc_flushes_disabled(hid_t object_id, hbool_t *are_disabled) { - H5VL_object_t *vol_obj; /* Object token of loc_id */ + H5VL_object_t *vol_obj; /* Object of loc_id */ H5VL_loc_params_t loc_params; /* Location parameters */ herr_t ret_value = SUCCEED; /* Return value */ @@ -1361,3 +1478,125 @@ done: FUNC_LEAVE_API(ret_value) } /* H5Oare_mdc_flushes_disabled() */ + +/*--------------------------------------------------------------------------- + * Function: H5Otoken_cmp + * + * Purpose: Compares two VOL connector object tokens + * + * Note: Both object tokens must be from the same VOL connector class + * + * Return: Success: Non-negative, with *cmp_value set to positive if + * token1 is greater than token2, negative if token2 + * is greater than token1 and zero if token1 and + * token2 are equal. + * Failure: Negative + * + *--------------------------------------------------------------------------- + */ +herr_t +H5Otoken_cmp(hid_t loc_id, const H5O_token_t *token1, const H5O_token_t *token2, + int *cmp_value) +{ + H5VL_object_t *vol_obj; /* VOL object for ID */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE4("e", "i*k*k*Is", loc_id, token1, token2, cmp_value); + + /* Get the location object */ + if(NULL == (vol_obj = H5VL_vol_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + if(NULL == cmp_value) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid cmp_value pointer") + + /* Compare the two tokens */ + if(H5VL_token_cmp(vol_obj, token1, token2, cmp_value) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTCOMPARE, FAIL, "object token comparison failed") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Otoken_cmp() */ + + +/*--------------------------------------------------------------------------- + * Function: H5Otoken_to_str + * + * Purpose: Serialize a connector's object token into a string + * + * Return: Success: Non-negative + * Failure: Negative + * + *--------------------------------------------------------------------------- + */ +herr_t +H5Otoken_to_str(hid_t loc_id, const H5O_token_t *token, char **token_str) +{ + H5VL_object_t *vol_obj; /* VOL object for ID */ + H5I_type_t vol_obj_type; /* VOL object's type */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE3("e", "i*k**s", loc_id, token, token_str); + + /* Get the location object */ + if(NULL == (vol_obj = H5VL_vol_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + if(NULL == token) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid token pointer") + if(NULL == token_str) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid token string pointer") + + /* Get object type */ + if((vol_obj_type = H5I_get_type(loc_id)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't get underlying VOL object type") + + /* Serialize the token */ + if(H5VL_token_to_str(vol_obj, vol_obj_type, token, token_str) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTSERIALIZE, FAIL, "object token serialization failed") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Otoken_to_str() */ + + +/*--------------------------------------------------------------------------- + * Function: H5Otoken_from_str + * + * Purpose: Deserialize a string into a connector object token + * + * Return: Success: Non-negative + * Failure: Negative + * + *--------------------------------------------------------------------------- + */ +herr_t +H5Otoken_from_str(hid_t loc_id, const char *token_str, H5O_token_t *token) +{ + H5VL_object_t *vol_obj; /* VOL object for ID */ + H5I_type_t vol_obj_type; /* VOL object's type */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE3("e", "i*s*k", loc_id, token_str, token); + + /* Get the location object */ + if(NULL == (vol_obj = H5VL_vol_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + if(NULL == token) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid token pointer") + if(NULL == token_str) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid token string pointer") + + /* Get object type */ + if((vol_obj_type = H5I_get_type(loc_id)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't get underlying VOL object type") + + /* Deserialize the token */ + if(H5VL_token_from_str(vol_obj, vol_obj_type, token_str, token) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTUNSERIALIZE, FAIL, "object token deserialization failed") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Otoken_from_str() */ + diff --git a/src/H5Oattribute.c b/src/H5Oattribute.c index 71cbc1d..a4a746e 100644 --- a/src/H5Oattribute.c +++ b/src/H5Oattribute.c @@ -86,19 +86,6 @@ typedef struct { hbool_t found; /* Whether the attribute was found */ } H5O_iter_ren_t; -/* User data for iteration when iterating over attributes */ -typedef struct { - /* down */ - H5F_t *f; /* Pointer to file attribute is in */ - hid_t loc_id; /* ID of object being iterated over */ - unsigned skip; /* # of attributes to skip over */ - H5A_operator_t op; /* Callback routine for each attribute */ - void *op_data; /* User data for callback */ - - /* up */ - unsigned count; /* Count of attributes examined */ -} H5O_iter_itr_t; - /* User data for iteration when removing an attribute */ typedef struct { /* down */ @@ -109,15 +96,6 @@ typedef struct { hbool_t found; /* Found attribute to delete */ } H5O_iter_rm_t; -/* User data for iteration when checking if an attribute exists */ -typedef struct { - /* down */ - const char *name; /* Name of attribute to open */ - - /* up */ - hbool_t found; /* Found attribute */ -} H5O_iter_xst_t; - /********************/ /* Package Typedefs */ diff --git a/src/H5Ocopy.c b/src/H5Ocopy.c index 55013c9..469a9e0 100644 --- a/src/H5Ocopy.c +++ b/src/H5Ocopy.c @@ -88,7 +88,7 @@ static herr_t H5O__copy_obj(H5G_loc_t *src_loc, H5G_loc_t *dst_loc, static herr_t H5O__copy_free_comm_dt_cb(void *item, void *key, void *op_data); static int H5O__copy_comm_dt_cmp(const void *dt1, const void *dt2); static herr_t H5O__copy_search_comm_dt_cb(hid_t group, const char *name, - const H5L_info_t *linfo, void *udata); + const H5L_info2_t *linfo, void *udata); static htri_t H5O__copy_search_comm_dt(H5F_t *file_src, H5O_t *oh_src, H5O_loc_t *oloc_dst/*in, out*/, H5O_copy_t *cpy_info); static herr_t H5O__copy_insert_comm_dt(H5F_t *file_src, H5O_t *oh_src, @@ -197,9 +197,9 @@ herr_t H5Ocopy(hid_t src_loc_id, const char *src_name, hid_t dst_loc_id, const char *dst_name, hid_t ocpypl_id, hid_t lcpl_id) { - H5VL_object_t *vol_obj1 = NULL; /* object token of src_id */ + H5VL_object_t *vol_obj1 = NULL; /* object of src_id */ H5VL_loc_params_t loc_params1; - H5VL_object_t *vol_obj2 = NULL; /* object token of dst_id */ + H5VL_object_t *vol_obj2 = NULL; /* object of dst_id */ H5VL_loc_params_t loc_params2; herr_t ret_value = SUCCEED; /* Return value */ @@ -1523,7 +1523,7 @@ done: */ static herr_t H5O__copy_search_comm_dt_cb(hid_t H5_ATTR_UNUSED group, const char *name, - const H5L_info_t *linfo, void *_udata) + const H5L_info2_t *linfo, void *_udata) { H5O_copy_search_comm_dt_ud_t *udata = (H5O_copy_search_comm_dt_ud_t *)_udata; /* Skip list of dtypes in dest file */ H5G_loc_t obj_loc; /* Location of object */ diff --git a/src/H5Ocopy_ref.c b/src/H5Ocopy_ref.c index f53eb4a..0de661f 100644 --- a/src/H5Ocopy_ref.c +++ b/src/H5Ocopy_ref.c @@ -38,6 +38,8 @@ #include "H5Opkg.h" /* Object headers */ #include "H5Rpkg.h" /* References */ +#include "H5VLnative_private.h" /* Native VOL connector */ + /****************/ /* Local Macros */ @@ -165,7 +167,7 @@ H5O__copy_expand_ref_object1(H5O_loc_t *src_oloc, const void *buf_src, size_t buf_size = H5R_OBJ_REF_BUF_SIZE; size_t i; /* Local index variable */ size_t token_size = H5F_SIZEOF_ADDR(src_oloc->file); - herr_t ret_value = SUCCEED; + herr_t ret_value = SUCCEED; FUNC_ENTER_STATIC @@ -173,8 +175,7 @@ H5O__copy_expand_ref_object1(H5O_loc_t *src_oloc, const void *buf_src, for(i = 0; i < ref_count; i++) { const unsigned char *src_buf = (const unsigned char *)&src_ref[i]; unsigned char *dst_buf = (unsigned char *)&dst_ref[i]; - H5VL_token_t tmp_token = { 0 }; - uint8_t *p; + H5O_token_t tmp_token = { 0 }; /* If data is not initialized, copy zeros and skip */ if(0 == HDmemcmp(src_buf, zeros, buf_size)) { @@ -185,8 +186,9 @@ H5O__copy_expand_ref_object1(H5O_loc_t *src_oloc, const void *buf_src, /* Set up for the object copy for the reference */ if(H5R__decode_token_obj_compat(src_buf, &buf_size, &tmp_token, token_size) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, FAIL, "unable to decode src object address") - p = (uint8_t *)&tmp_token; - H5F_addr_decode(src_oloc->file, (const uint8_t **)&p, &src_oloc->addr); + if(H5VL_native_token_to_addr(src_oloc->file, H5I_FILE, tmp_token, &src_oloc->addr) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTUNSERIALIZE, FAIL, "can't deserialize object token into address") + if(!H5F_addr_defined(src_oloc->addr) || src_oloc->addr == 0) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "undefined reference pointer") dst_oloc->addr = HADDR_UNDEF; @@ -196,9 +198,9 @@ H5O__copy_expand_ref_object1(H5O_loc_t *src_oloc, const void *buf_src, HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object") /* Set the object reference info for the destination file */ - p = (uint8_t *)&tmp_token; - H5F_addr_encode(dst_oloc->file, &p, dst_oloc->addr); - if(H5R__encode_token_obj_compat((const H5VL_token_t *)&tmp_token, token_size, dst_buf, &buf_size) < 0) + if(H5VL_native_addr_to_token(dst_oloc->file, H5I_FILE, dst_oloc->addr, &tmp_token) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTSERIALIZE, FAIL, "can't serialize address into object token") + if(H5R__encode_token_obj_compat((const H5O_token_t *)&tmp_token, token_size, dst_buf, &buf_size) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, FAIL, "unable to encode dst object address") } /* end for */ @@ -365,23 +367,22 @@ H5O__copy_expand_ref_object2(H5O_loc_t *src_oloc, hid_t tid_src, H5T_t *dt_src, for(i = 0; i < ref_count; i++) { H5R_ref_t *ref_ptr = (H5R_ref_t *)conv_buf; H5R_ref_priv_t *ref = (H5R_ref_priv_t *)&ref_ptr[i]; - H5VL_token_t tmp_token = { 0 }; - uint8_t *p; + H5O_token_t tmp_token = { 0 }; /* Get src object address */ if(H5R__get_obj_token(ref, &tmp_token, &token_size) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "unable to get object token") - p = (uint8_t *)&tmp_token; - H5F_addr_decode(src_oloc->file, (const uint8_t **)&p, &src_oloc->addr); + if(H5VL_native_token_to_addr(src_oloc->file, H5I_FILE, tmp_token, &src_oloc->addr) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTUNSERIALIZE, FAIL, "can't deserialize object token into address") /* Attempt to copy object from source to destination file */ if(H5O__copy_obj_by_ref(src_oloc, dst_oloc, dst_root_loc, cpy_info) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object") /* Set dst object address */ - p = (uint8_t *)&tmp_token; - H5F_addr_encode(dst_oloc->file, &p, dst_oloc->addr); - if(H5R__set_obj_token(ref, (const H5VL_token_t *)&tmp_token, token_size) < 0) + if(H5VL_native_addr_to_token(dst_oloc->file, H5I_FILE, dst_oloc->addr, &tmp_token) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTSERIALIZE, FAIL, "can't serialize address into object token") + if(H5R__set_obj_token(ref, (const H5O_token_t *)&tmp_token, token_size) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTSET, FAIL, "unable to set object token") /* Do not set app_ref since references are released once the copy is done */ if(H5R__set_loc_id(ref, dst_loc_id, TRUE, FALSE) < 0) diff --git a/src/H5Odeprec.c b/src/H5Odeprec.c index e4e8f96..e43213d 100644 --- a/src/H5Odeprec.c +++ b/src/H5Odeprec.c @@ -39,6 +39,7 @@ #include "H5VLnative_private.h" /* Native VOL connector */ +#ifndef H5_NO_DEPRECATED_SYMBOLS /****************/ /* Local Macros */ @@ -49,6 +50,13 @@ /* Local Typedefs */ /******************/ +/* Adapter for using deprecated H5Ovisit1 callbacks with the VOL */ +typedef struct H5O_visit1_adapter_t { + H5O_iterate1_t real_op; /* Application callback to invoke */ + unsigned fields; /* Original fields passed to H5Ovisit */ + void *real_op_data; /* Application op_data */ +} H5O_visit1_adapter_t; + /********************/ /* Package Typedefs */ @@ -58,7 +66,10 @@ /********************/ /* Local Prototypes */ /********************/ - +static herr_t H5O__reset_info1(H5O_info1_t *oinfo); +static herr_t H5O__iterate1_adapter(hid_t obj_id, const char *name, const H5O_info2_t *oinfo2, void *op_data); +static herr_t H5O__get_info_old(H5VL_object_t *vol_obj, H5VL_loc_params_t *loc_params, + H5O_info1_t *oinfo, unsigned fields); /*********************/ /* Package Variables */ @@ -75,7 +86,295 @@ /*******************/ -#ifndef H5_NO_DEPRECATED_SYMBOLS +/*------------------------------------------------------------------------- + * Function: H5O__reset_info1 + * + * Purpose: Resets/initializes an H5O_info1_t struct. + * + * Return: SUCCEED/FAIL + * + *------------------------------------------------------------------------- + */ +static herr_t +H5O__reset_info1(H5O_info1_t *oinfo) +{ + FUNC_ENTER_STATIC_NOERR; + + /* Reset the passed-in info struct */ + HDmemset(oinfo, 0, sizeof(H5O_info1_t)); + oinfo->type = H5O_TYPE_UNKNOWN; + oinfo->addr = HADDR_UNDEF; + + FUNC_LEAVE_NOAPI(SUCCEED); +} /* end H5O__reset_info1() */ + + +/*------------------------------------------------------------------------- + * Function: H5O__iterate1_adapter + * + * Purpose: Retrieve information about an object, according to the order + * of an index. + * + * Return: Success: Non-negative + * Failure: Negative + * + * Programmer: Quincey Koziol + * November 26 2006 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5O__iterate1_adapter(hid_t obj_id, const char *name, const H5O_info2_t *oinfo2, + void *op_data) +{ + H5O_visit1_adapter_t *shim_data = (H5O_visit1_adapter_t *)op_data; + H5O_info1_t oinfo; /* Deprecated object info struct */ + unsigned dm_fields; /* Fields for data model query */ + unsigned nat_fields; /* Fields for native query */ + H5VL_object_t *vol_obj; /* Object of obj_id */ + H5VL_loc_params_t loc_params; /* Location parameters for VOL callback */ + herr_t ret_value = H5_ITER_CONT; /* Return value */ + + FUNC_ENTER_STATIC + + /* Sanity check */ + HDassert(oinfo2); + HDassert(op_data); + + /* Reset the legacy info struct */ + if(H5O__reset_info1(&oinfo) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTSET, FAIL, "can't reset object data struct") + + /* Check for retrieving data model information */ + dm_fields = shim_data->fields & (H5O_INFO_BASIC | H5O_INFO_TIME | H5O_INFO_NUM_ATTRS); + if(dm_fields) { + /* Set the data model fields */ + if(shim_data->fields & H5O_INFO_BASIC) { + oinfo.fileno = oinfo2->fileno; + oinfo.type = oinfo2->type; + oinfo.rc = oinfo2->rc; + + /* Deserialize VOL object token into object address */ + if(H5VLnative_token_to_addr(obj_id, oinfo2->token, &oinfo.addr) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTUNSERIALIZE, FAIL, "can't deserialize object token into address") + } + if(shim_data->fields & H5O_INFO_TIME) { + oinfo.atime = oinfo2->atime; + oinfo.mtime = oinfo2->mtime; + oinfo.ctime = oinfo2->ctime; + oinfo.btime = oinfo2->btime; + } + if(shim_data->fields & H5O_INFO_NUM_ATTRS) + oinfo.num_attrs = oinfo2->num_attrs; + } + + /* Fill out location struct */ + loc_params.type = H5VL_OBJECT_BY_NAME; + loc_params.loc_data.loc_by_name.name = name; + loc_params.loc_data.loc_by_name.lapl_id = H5P_LINK_ACCESS_DEFAULT; + loc_params.obj_type = H5I_get_type(obj_id); + + /* Get the location object */ + if(NULL == (vol_obj = H5VL_vol_object(obj_id))) + HGOTO_ERROR(H5E_OHDR, H5E_BADTYPE, H5_ITER_ERROR, "invalid location identifier") + + /* Check for retrieving native information */ + nat_fields = shim_data->fields & (H5O_INFO_HDR | H5O_INFO_META_SIZE); + if(nat_fields) { + H5O_native_info_t nat_info; /* Native object info */ + + /* Retrieve the object's native information */ + if(H5VL_object_optional(vol_obj, H5VL_NATIVE_OBJECT_GET_NATIVE_INFO, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, &loc_params, &nat_info, nat_fields) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't get native info for object") + + /* Set the native fields */ + if(shim_data->fields & H5O_INFO_HDR) + HDmemcpy(&(oinfo.hdr), &(nat_info.hdr), sizeof(H5O_hdr_info_t)); + if(shim_data->fields & H5O_INFO_META_SIZE) { + HDmemcpy(&(oinfo.meta_size.obj), &(nat_info.meta_size.obj), sizeof(H5_ih_info_t)); + HDmemcpy(&(oinfo.meta_size.attr), &(nat_info.meta_size.attr), sizeof(H5_ih_info_t)); + } + } + + /* Invoke the application callback */ + ret_value = (shim_data->real_op)(obj_id, name, &oinfo, shim_data->real_op_data); + +done: + FUNC_LEAVE_NOAPI(ret_value); +} /* end H5O__iterate1_adapter() */ + + +/*------------------------------------------------------------------------- + * Function: H5O__get_info_old + * + * Purpose: Retrieve deprecated info about an object. + * + * Return: SUCCEED/FAIL + * + * Programmer: Quincey Koziol + * December 21 2019 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5O__get_info_old(H5VL_object_t *vol_obj, H5VL_loc_params_t *loc_params, + H5O_info1_t *oinfo, unsigned fields) +{ + unsigned dm_fields; /* Fields for data model query */ + unsigned nat_fields; /* Fields for native query */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + /* Sanity check */ + HDassert(vol_obj); + HDassert(loc_params); + + /* Reset the passed-in info struct */ + if(H5O__reset_info1(oinfo) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTSET, FAIL, "can't reset object data struct") + + /* Check for retrieving data model information */ + dm_fields = fields & (H5O_INFO_BASIC | H5O_INFO_TIME | H5O_INFO_NUM_ATTRS); + if(dm_fields) { + H5O_info2_t dm_info; /* Data model object info */ + + /* Retrieve the object's data model information */ + if(H5VL_object_get(vol_obj, loc_params, H5VL_OBJECT_GET_INFO, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, &dm_info, dm_fields) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't get data model info for object") + + /* Set the data model fields */ + if(fields & H5O_INFO_BASIC) { + void *vol_obj_data; + + if(NULL == (vol_obj_data = H5VL_object_data(vol_obj))) + HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't get underlying VOL object") + + oinfo->fileno = dm_info.fileno; + oinfo->type = dm_info.type; + oinfo->rc = dm_info.rc; + + /* Deserialize VOL object token into object address */ + if(H5VL_native_token_to_addr(vol_obj_data, loc_params->obj_type, dm_info.token, &oinfo->addr) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTUNSERIALIZE, FAIL, "can't deserialize object token into address") + } /* end if */ + if(fields & H5O_INFO_TIME) { + oinfo->atime = dm_info.atime; + oinfo->mtime = dm_info.mtime; + oinfo->ctime = dm_info.ctime; + oinfo->btime = dm_info.btime; + } /* end if */ + if(fields & H5O_INFO_NUM_ATTRS) + oinfo->num_attrs = dm_info.num_attrs; + } /* end if */ + + /* Check for retrieving native information */ + nat_fields = fields & (H5O_INFO_HDR | H5O_INFO_META_SIZE); + if(nat_fields) { + H5O_native_info_t nat_info; /* Native object info */ + + /* Retrieve the object's native information */ + if(H5VL_object_optional(vol_obj, H5VL_NATIVE_OBJECT_GET_NATIVE_INFO, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, loc_params, &nat_info, nat_fields) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't get native info for object") + + /* Set the native fields */ + if(fields & H5O_INFO_HDR) + HDmemcpy(&(oinfo->hdr), &(nat_info.hdr), sizeof(H5O_hdr_info_t)); + if(fields & H5O_INFO_META_SIZE) { + HDmemcpy(&(oinfo->meta_size.obj), &(nat_info.meta_size.obj), sizeof(H5_ih_info_t)); + HDmemcpy(&(oinfo->meta_size.attr), &(nat_info.meta_size.attr), sizeof(H5_ih_info_t)); + } /* end if */ + } /* end if */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5O__get_info_old() */ + + +/*------------------------------------------------------------------------- + * Function: H5Oopen_by_addr + * + * Purpose: Warning! This function is EXTREMELY DANGEROUS! + * Improper use can lead to FILE CORRUPTION, INACCESSIBLE DATA, + * and other VERY BAD THINGS! + * + * This function opens an object using its address within the + * HDF5 file, similar to an HDF5 hard link. The open object + * is identical to an object opened with H5Oopen() and should + * be closed with H5Oclose() or a type-specific closing + * function (such as H5Gclose() ). + * + * This function is very dangerous if called on an invalid + * address. For this reason, H5Oincr_refcount() should be + * used to prevent HDF5 from deleting any object that is + * referenced by address (e.g. by a user-defined link). + * H5Odecr_refcount() should be used when the object is + * no longer being referenced by address (e.g. when the UD link + * is deleted). + * + * The address of the HDF5 file on disk has no effect on + * H5Oopen_by_addr(), nor does the use of any unusual file + * drivers. The "address" is really the offset within the + * HDF5 file, and HDF5's file drivers will transparently + * map this to an address on disk for the filesystem. + * + * Return: Success: An open object identifier + * Failure: H5I_INVALID_HID + * + * Programmer: James Laird + * July 14 2006 + * + *------------------------------------------------------------------------- + */ +hid_t +H5Oopen_by_addr(hid_t loc_id, haddr_t addr) +{ + H5VL_object_t *vol_obj; /* Object of loc_id */ + H5I_type_t vol_obj_type = H5I_BADID;/* Object type of loc_id */ + H5I_type_t opened_type; /* Opened object type */ + void *opened_obj = NULL; /* Opened object */ + H5VL_loc_params_t loc_params; /* Location parameters */ + H5O_token_t obj_token = {0}; /* Object token */ + hbool_t is_native_vol_obj; + hid_t ret_value = H5I_INVALID_HID; /* Return value */ + + FUNC_ENTER_API(H5I_INVALID_HID) + H5TRACE2("i", "ia", loc_id, addr); + + /* Get the location object */ + if(NULL == (vol_obj = (H5VL_object_t *)H5I_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid location identifier") + + /* Get object type */ + if((vol_obj_type = H5I_get_type(loc_id)) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid location identifier") + + /* Check if the VOL object is a native VOL connector object */ + if(H5VL_object_is_native(vol_obj, &is_native_vol_obj) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, H5I_INVALID_HID, "can't determine if VOL object is native connector object") + if(is_native_vol_obj) { + /* This is a native-specific routine that requires serialization of the token */ + if(H5VLnative_addr_to_token(loc_id, addr, &obj_token) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTSERIALIZE, H5I_INVALID_HID, "can't serialize address into object token") + } /* end if */ + else + HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, H5I_INVALID_HID, "H5Oopen_by_addr is only meant to be used with the native VOL connector") + + loc_params.type = H5VL_OBJECT_BY_TOKEN; + loc_params.loc_data.loc_by_token.token = &obj_token; + loc_params.obj_type = vol_obj_type; + + /* Open the object */ + if(NULL == (opened_obj = H5VL_object_open(vol_obj, &loc_params, &opened_type, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL))) + HGOTO_ERROR(H5E_OHDR, H5E_CANTOPENOBJ, H5I_INVALID_HID, "unable to open object") + + /* Register the object's ID */ + if((ret_value = H5VL_register(opened_type, opened_obj, vol_obj->connector, TRUE)) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to atomize object handle") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Oopen_by_addr() */ /*------------------------------------------------------------------------- @@ -89,9 +388,9 @@ *------------------------------------------------------------------------- */ herr_t -H5Oget_info1(hid_t loc_id, H5O_info_t *oinfo) +H5Oget_info1(hid_t loc_id, H5O_info1_t *oinfo) { - H5VL_object_t *vol_obj = NULL; /* Object token of loc_id */ + H5VL_object_t *vol_obj = NULL; /* Object of loc_id */ H5VL_loc_params_t loc_params; herr_t ret_value = SUCCEED; /* Return value */ @@ -111,8 +410,8 @@ H5Oget_info1(hid_t loc_id, H5O_info_t *oinfo) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") /* Retrieve the object's information */ - if(H5VL_object_optional(vol_obj, H5VL_NATIVE_OBJECT_GET_INFO, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, &loc_params, oinfo, H5O_INFO_ALL) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't get info for object") + if(H5O__get_info_old(vol_obj, &loc_params, oinfo, H5O_INFO_ALL) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't get deprecated info for object") done: FUNC_LEAVE_API(ret_value) @@ -130,9 +429,9 @@ done: *------------------------------------------------------------------------- */ herr_t -H5Oget_info_by_name1(hid_t loc_id, const char *name, H5O_info_t *oinfo, hid_t lapl_id) +H5Oget_info_by_name1(hid_t loc_id, const char *name, H5O_info1_t *oinfo, hid_t lapl_id) { - H5VL_object_t *vol_obj = NULL; /* object token of loc_id */ + H5VL_object_t *vol_obj = NULL; /* object of loc_id */ H5VL_loc_params_t loc_params; herr_t ret_value = SUCCEED; /* Return value */ @@ -162,8 +461,8 @@ H5Oget_info_by_name1(hid_t loc_id, const char *name, H5O_info_t *oinfo, hid_t la HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") /* Retrieve the object's information */ - if(H5VL_object_optional(vol_obj, H5VL_NATIVE_OBJECT_GET_INFO, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, &loc_params, oinfo, H5O_INFO_ALL) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't get info for object: '%s'", name) + if(H5O__get_info_old(vol_obj, &loc_params, oinfo, H5O_INFO_ALL) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't get deprecated info for object") done: FUNC_LEAVE_API(ret_value) @@ -186,9 +485,9 @@ done: */ herr_t H5Oget_info_by_idx1(hid_t loc_id, const char *group_name, H5_index_t idx_type, - H5_iter_order_t order, hsize_t n, H5O_info_t *oinfo, hid_t lapl_id) + H5_iter_order_t order, hsize_t n, H5O_info1_t *oinfo, hid_t lapl_id) { - H5VL_object_t *vol_obj = NULL; /* object token of loc_id */ + H5VL_object_t *vol_obj = NULL; /* object of loc_id */ H5VL_loc_params_t loc_params; herr_t ret_value = SUCCEED; /* Return value */ @@ -223,8 +522,8 @@ H5Oget_info_by_idx1(hid_t loc_id, const char *group_name, H5_index_t idx_type, HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") /* Retrieve the object's information */ - if(H5VL_object_optional(vol_obj, H5VL_NATIVE_OBJECT_GET_INFO, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, &loc_params, oinfo, H5O_INFO_ALL) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't get info for object") + if(H5O__get_info_old(vol_obj, &loc_params, oinfo, H5O_INFO_ALL) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't get deprecated info for object") done: FUNC_LEAVE_API(ret_value) @@ -232,6 +531,197 @@ done: /*------------------------------------------------------------------------- + * Function: H5Oget_info2 + * + * Purpose: Retrieve information about an object. + * + * NOTE: Add a parameter "fields" to indicate selection of object info. + * + * Return: SUCCEED/FAIL + * + * Programmer: Neil Fortner + * July 7 2010 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Oget_info2(hid_t loc_id, H5O_info1_t *oinfo, unsigned fields) +{ + H5VL_object_t *vol_obj; /* Object of loc_id */ + H5VL_loc_params_t loc_params; + hbool_t is_native_vol_obj; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE3("e", "i*xIu", loc_id, oinfo, fields); + + /* Check args */ + if(!oinfo) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "oinfo parameter cannot be NULL") + if(fields & ~H5O_INFO_ALL) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid fields") + + /* Set location struct fields */ + loc_params.type = H5VL_OBJECT_BY_SELF; + loc_params.obj_type = H5I_get_type(loc_id); + + /* Get the location object */ + if(NULL == (vol_obj = H5VL_vol_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + + /* Check if the VOL object is a native VOL connector object */ + if(H5VL_object_is_native(vol_obj, &is_native_vol_obj) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, H5I_INVALID_HID, "can't determine if VOL object is native connector object") + if(!is_native_vol_obj) + HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, H5I_INVALID_HID, "H5Oget_info2 is only meant to be used with the native VOL connector") + + /* Retrieve deprecated info struct */ + if(H5O__get_info_old(vol_obj, &loc_params, oinfo, fields) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't get deprecated info for object") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Oget_info2() */ + + +/*------------------------------------------------------------------------- + * Function: H5Oget_info_by_name2 + * + * Purpose: Retrieve information about an object + * + * NOTE: Add a parameter "fields" to indicate selection of object info. + * + * Return: SUCCEED/FAIL + * + * Programmer: Neil Fortner + * July 7 2010 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Oget_info_by_name2(hid_t loc_id, const char *name, H5O_info1_t *oinfo, + unsigned fields, hid_t lapl_id) +{ + H5VL_object_t *vol_obj; /* Object of loc_id */ + H5VL_loc_params_t loc_params; + hbool_t is_native_vol_obj; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE5("e", "i*s*xIui", loc_id, name, oinfo, fields, lapl_id); + + /* Check args */ + if(!name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "name parameter cannot be NULL") + if(!*name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "name parameter cannot be an empty string") + if(!oinfo) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "oinfo parameter cannot be NULL") + if(fields & ~H5O_INFO_ALL) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid fields") + + /* Verify access property list and set up collective metadata if appropriate */ + if(H5CX_set_apl(&lapl_id, H5P_CLS_LACC, loc_id, FALSE) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTSET, FAIL, "can't set access property list info") + + /* Fill out location struct */ + loc_params.type = H5VL_OBJECT_BY_NAME; + loc_params.loc_data.loc_by_name.name = name; + loc_params.loc_data.loc_by_name.lapl_id = lapl_id; + loc_params.obj_type = H5I_get_type(loc_id); + + /* Get the location object */ + if(NULL == (vol_obj = H5VL_vol_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + + /* Check if the VOL object is a native VOL connector object */ + if(H5VL_object_is_native(vol_obj, &is_native_vol_obj) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, H5I_INVALID_HID, "can't determine if VOL object is native connector object") + if(!is_native_vol_obj) + HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, H5I_INVALID_HID, "H5Oget_info_by_name2 is only meant to be used with the native VOL connector") + + /* Retrieve deprecated info struct */ + if(H5O__get_info_old(vol_obj, &loc_params, oinfo, fields) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't get deprecated info for object") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Oget_info_by_name2() */ + + +/*------------------------------------------------------------------------- + * Function: H5Oget_info_by_idx2 + * + * Purpose: Retrieve information about an object, according to the order + * of an index. + * + * NOTE: Add a parameter "fields" to indicate selection of object info. + * + * Return: Success: Non-negative + * Failure: Negative + * + * Programmer: Quincey Koziol + * November 26 2006 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Oget_info_by_idx2(hid_t loc_id, const char *group_name, H5_index_t idx_type, + H5_iter_order_t order, hsize_t n, H5O_info1_t *oinfo, unsigned fields, hid_t lapl_id) +{ + H5VL_object_t *vol_obj; /* Object of loc_id */ + H5VL_loc_params_t loc_params; + hbool_t is_native_vol_obj; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE8("e", "i*sIiIoh*xIui", loc_id, group_name, idx_type, order, n, oinfo, + fields, lapl_id); + + /* Check args */ + if(!group_name || !*group_name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name specified") + if(idx_type <= H5_INDEX_UNKNOWN || idx_type >= H5_INDEX_N) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid index type specified") + if(order <= H5_ITER_UNKNOWN || order >= H5_ITER_N) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid iteration order specified") + if(!oinfo) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no info struct") + if(fields & ~H5O_INFO_ALL) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid fields") + + /* Verify access property list and set up collective metadata if appropriate */ + if(H5CX_set_apl(&lapl_id, H5P_CLS_LACC, loc_id, FALSE) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTSET, FAIL, "can't set access property list info") + + loc_params.type = H5VL_OBJECT_BY_IDX; + loc_params.loc_data.loc_by_idx.name = group_name; + loc_params.loc_data.loc_by_idx.idx_type = idx_type; + loc_params.loc_data.loc_by_idx.order = order; + loc_params.loc_data.loc_by_idx.n = n; + loc_params.loc_data.loc_by_idx.lapl_id = lapl_id; + loc_params.obj_type = H5I_get_type(loc_id); + + /* Get the location object */ + if(NULL == (vol_obj = H5VL_vol_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + + /* Check if the VOL object is a native VOL connector object */ + if(H5VL_object_is_native(vol_obj, &is_native_vol_obj) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, H5I_INVALID_HID, "can't determine if VOL object is native connector object") + if(!is_native_vol_obj) + HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, H5I_INVALID_HID, "H5Oget_info_by_idx2 is only meant to be used with the native VOL connector") + + /* Retrieve deprecated info struct */ + if(H5O__get_info_old(vol_obj, &loc_params, oinfo, fields) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't get deprecated info for object") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Oget_info_by_idx2() */ + + +/*------------------------------------------------------------------------- * Function: H5Ovisit1 * * Purpose: Recursively visit an object and all the objects reachable @@ -265,10 +755,11 @@ done: */ herr_t H5Ovisit1(hid_t obj_id, H5_index_t idx_type, H5_iter_order_t order, - H5O_iterate_t op, void *op_data) + H5O_iterate1_t op, void *op_data) { - H5VL_object_t *vol_obj = NULL; /* Object token of loc_id */ + H5VL_object_t *vol_obj = NULL; /* Object of loc_id */ H5VL_loc_params_t loc_params; + H5O_visit1_adapter_t shim_data; /* Adapter for passing app callback & user data */ herr_t ret_value; /* Return value */ FUNC_ENTER_API(FAIL) @@ -290,8 +781,13 @@ H5Ovisit1(hid_t obj_id, H5_index_t idx_type, H5_iter_order_t order, loc_params.type = H5VL_OBJECT_BY_SELF; loc_params.obj_type = H5I_get_type(obj_id); + /* Set up adapter */ + shim_data.real_op = op; + shim_data.fields = H5O_INFO_ALL; + shim_data.real_op_data = op_data; + /* Visit the objects */ - if((ret_value = H5VL_object_specific(vol_obj, &loc_params, H5VL_OBJECT_VISIT, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, (int)idx_type, (int)order, op, op_data, H5O_INFO_ALL)) < 0) + if((ret_value = H5VL_object_specific(vol_obj, &loc_params, H5VL_OBJECT_VISIT, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, (int)idx_type, (int)order, H5O__iterate1_adapter, (void *)&shim_data, H5O_INFO_ALL)) < 0) HGOTO_ERROR(H5E_OHDR, H5E_BADITER, FAIL, "object visitation failed") done: @@ -333,10 +829,11 @@ done: */ herr_t H5Ovisit_by_name1(hid_t loc_id, const char *obj_name, H5_index_t idx_type, - H5_iter_order_t order, H5O_iterate_t op, void *op_data, hid_t lapl_id) + H5_iter_order_t order, H5O_iterate1_t op, void *op_data, hid_t lapl_id) { - H5VL_object_t *vol_obj = NULL; /* Object token of loc_id */ - H5VL_loc_params_t loc_params; + H5VL_object_t *vol_obj = NULL; /* Object of loc_id */ + H5VL_loc_params_t loc_params; + H5O_visit1_adapter_t shim_data; /* Adapter for passing app callback & user data */ herr_t ret_value; /* Return value */ FUNC_ENTER_API(FAIL) @@ -369,13 +866,203 @@ H5Ovisit_by_name1(hid_t loc_id, const char *obj_name, H5_index_t idx_type, loc_params.loc_data.loc_by_name.lapl_id = lapl_id; loc_params.obj_type = H5I_get_type(loc_id); + /* Set up adapter */ + shim_data.real_op = op; + shim_data.fields = H5O_INFO_ALL; + shim_data.real_op_data = op_data; + /* Visit the objects */ - if((ret_value = H5VL_object_specific(vol_obj, &loc_params, H5VL_OBJECT_VISIT, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, (int)idx_type, (int)order, op, op_data, H5O_INFO_ALL)) < 0) + if((ret_value = H5VL_object_specific(vol_obj, &loc_params, H5VL_OBJECT_VISIT, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, (int)idx_type, (int)order, H5O__iterate1_adapter, (void *)&shim_data, H5O_INFO_ALL)) < 0) HGOTO_ERROR(H5E_OHDR, H5E_BADITER, FAIL, "object visitation failed") done: FUNC_LEAVE_API(ret_value) } /* end H5Ovisit_by_name1() */ + +/*------------------------------------------------------------------------- + * Function: H5Ovisit2 + * + * Purpose: Recursively visit an object and all the objects reachable + * from it. If the starting object is a group, all the objects + * linked to from that group will be visited. Links within + * each group are visited according to the order within the + * specified index (unless the specified index does not exist for + * a particular group, then the "name" index is used). + * + * NOTE: Soft links and user-defined links are ignored during + * this operation. + * + * NOTE: Each _object_ reachable from the initial group will only + * be visited once. If multiple hard links point to the same + * object, the first link to the object's path (according to the + * iteration index and iteration order given) will be used to in + * the callback about the object. + * + * NOTE: Add a a parameter "fields" to indicate selection of + * object info to be retrieved to the callback "op". + * + * Return: Success: The return value of the first operator that + * returns non-zero, or zero if all members were + * processed with no operator returning non-zero. + * + * Failure: Negative if something goes wrong within the + * library, or the negative value returned by one + * of the operators. + * + * Programmer: Quincey Koziol + * November 25 2007 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Ovisit2(hid_t obj_id, H5_index_t idx_type, H5_iter_order_t order, + H5O_iterate1_t op, void *op_data, unsigned fields) +{ + H5VL_object_t *vol_obj; /* Object of loc_id */ + H5VL_loc_params_t loc_params; + H5O_visit1_adapter_t shim_data; /* Adapter for passing app callback & user data */ + hbool_t is_native_vol_obj; + herr_t ret_value; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE6("e", "iIiIox*xIu", obj_id, idx_type, order, op, op_data, fields); + + /* Check args */ + if(idx_type <= H5_INDEX_UNKNOWN || idx_type >= H5_INDEX_N) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid index type specified") + if(order <= H5_ITER_UNKNOWN || order >= H5_ITER_N) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid iteration order specified") + if(!op) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no callback operator specified") + if(fields & ~H5O_INFO_ALL) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid fields") + + /* Get the location object */ + if(NULL == (vol_obj = H5VL_vol_object(obj_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + + /* Check if the VOL object is a native VOL connector object */ + if(H5VL_object_is_native(vol_obj, &is_native_vol_obj) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, H5I_INVALID_HID, "can't determine if VOL object is native connector object") + if(!is_native_vol_obj) + HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, H5I_INVALID_HID, "H5Ovisit2 is only meant to be used with the native VOL connector") + + /* Set location parameters */ + loc_params.type = H5VL_OBJECT_BY_SELF; + loc_params.obj_type = H5I_get_type(obj_id); + + /* Set up adapter */ + shim_data.real_op = op; + shim_data.fields = fields; + shim_data.real_op_data = op_data; + + /* Visit the objects */ + if((ret_value = H5VL_object_specific(vol_obj, &loc_params, H5VL_OBJECT_VISIT, H5P_DATASET_XFER_DEFAULT, + H5_REQUEST_NULL, (int)idx_type, (int)order, H5O__iterate1_adapter, (void *)&shim_data, fields)) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_BADITER, FAIL, "object iteration failed") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Ovisit2() */ + + +/*------------------------------------------------------------------------- + * Function: H5Ovisit_by_name2 + * + * Purpose: Recursively visit an object and all the objects reachable + * from it. If the starting object is a group, all the objects + * linked to from that group will be visited. Links within + * each group are visited according to the order within the + * specified index (unless the specified index does not exist for + * a particular group, then the "name" index is used). + * + * NOTE: Soft links and user-defined links are ignored during + * this operation. + * + * NOTE: Each _object_ reachable from the initial group will only + * be visited once. If multiple hard links point to the same + * object, the first link to the object's path (according to the + * iteration index and iteration order given) will be used to in + * the callback about the object. + * + * NOTE: Add a a parameter "fields" to indicate selection of + * object info to be retrieved to the callback "op". + * + * Return: Success: The return value of the first operator that + * returns non-zero, or zero if all members were + * processed with no operator returning non-zero. + * + * Failure: Negative if something goes wrong within the + * library, or the negative value returned by one + * of the operators. + * + * Programmer: Quincey Koziol + * November 24 2007 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Ovisit_by_name2(hid_t loc_id, const char *obj_name, H5_index_t idx_type, + H5_iter_order_t order, H5O_iterate1_t op, void *op_data, unsigned fields, hid_t lapl_id) +{ + H5VL_object_t *vol_obj; /* Object of loc_id */ + H5VL_loc_params_t loc_params; + H5O_visit1_adapter_t shim_data; /* Adapter for passing app callback & user data */ + hbool_t is_native_vol_obj; + herr_t ret_value; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE8("e", "i*sIiIox*xIui", loc_id, obj_name, idx_type, order, op, op_data, + fields, lapl_id); + + /* Check args */ + if(!obj_name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "obj_name parameter cannot be NULL") + if(!*obj_name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "obj_name parameter cannot be an empty string") + if(idx_type <= H5_INDEX_UNKNOWN || idx_type >= H5_INDEX_N) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid index type specified") + if(order <= H5_ITER_UNKNOWN || order >= H5_ITER_N) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid iteration order specified") + if(!op) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no callback operator specified") + if(fields & ~H5O_INFO_ALL) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid fields") + + /* Verify access property list and set up collective metadata if appropriate */ + if(H5CX_set_apl(&lapl_id, H5P_CLS_LACC, loc_id, FALSE) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTSET, FAIL, "can't set access property list info") + + /* Get the location object */ + if(NULL == (vol_obj = H5VL_vol_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + + /* Check if the VOL object is a native VOL connector object */ + if(H5VL_object_is_native(vol_obj, &is_native_vol_obj) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, H5I_INVALID_HID, "can't determine if VOL object is native connector object") + if(!is_native_vol_obj) + HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, H5I_INVALID_HID, "H5Ovisit_by_name2 is only meant to be used with the native VOL connector") + + /* Set location parameters */ + loc_params.type = H5VL_OBJECT_BY_NAME; + loc_params.loc_data.loc_by_name.name = obj_name; + loc_params.loc_data.loc_by_name.lapl_id = lapl_id; + loc_params.obj_type = H5I_get_type(loc_id); + + /* Set up adapter */ + shim_data.real_op = op; + shim_data.fields = fields; + shim_data.real_op_data = op_data; + + /* Visit the objects */ + if((ret_value = H5VL_object_specific(vol_obj, &loc_params, H5VL_OBJECT_VISIT, H5P_DATASET_XFER_DEFAULT, + H5_REQUEST_NULL, (int)idx_type, (int)order, H5O__iterate1_adapter, (void *)&shim_data, fields)) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_BADITER, FAIL, "object iteration failed") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Ovisit_by_name2() */ + #endif /* H5_NO_DEPRECATED_SYMBOLS */ diff --git a/src/H5Oflush.c b/src/H5Oflush.c index a03cfa1..b441840 100644 --- a/src/H5Oflush.c +++ b/src/H5Oflush.c @@ -72,7 +72,7 @@ static herr_t H5O__refresh_metadata_close(hid_t oid, H5O_loc_t oloc, herr_t H5Oflush(hid_t obj_id) { - H5VL_object_t *vol_obj = NULL; /* Object token */ + H5VL_object_t *vol_obj = NULL; /* Object of obj_id */ H5VL_loc_params_t loc_params; herr_t ret_value = SUCCEED; /* Return value */ @@ -236,7 +236,7 @@ done: herr_t H5Orefresh(hid_t oid) { - H5VL_object_t *vol_obj = NULL; /* Object token */ + H5VL_object_t *vol_obj = NULL; /* Object of oid */ H5VL_loc_params_t loc_params; herr_t ret_value = SUCCEED; /* Return value */ diff --git a/src/H5Oint.c b/src/H5Oint.c index a16102a..d5a3a71 100644 --- a/src/H5Oint.c +++ b/src/H5Oint.c @@ -43,6 +43,8 @@ #include "H5Opkg.h" /* Object headers */ #include "H5VLprivate.h" /* Virtual Object Layer */ +#include "H5VLnative_private.h" /* Native VOL connector */ + /****************/ /* Local Macros */ @@ -58,7 +60,7 @@ typedef struct { hid_t obj_id; /* The ID for the starting group */ H5G_loc_t *start_loc; /* Location of starting group */ H5SL_t *visited; /* Skip list for tracking visited nodes */ - H5O_iterate_t op; /* Application callback */ + H5O_iterate2_t op; /* Application callback */ void *op_data; /* Application's op data */ unsigned fields; /* Selection of object info */ } H5O_iter_visit_ud_t; @@ -78,9 +80,11 @@ static herr_t H5O__obj_type_real(const H5O_t *oh, H5O_type_t *obj_type); static herr_t H5O__get_hdr_info_real(const H5O_t *oh, H5O_hdr_info_t *hdr); static herr_t H5O__free_visit_visited(void *item, void *key, void *operator_data/*in,out*/); -static herr_t H5O__visit_cb(hid_t group, const char *name, const H5L_info_t *linfo, +static herr_t H5O__visit_cb(hid_t group, const char *name, const H5L_info2_t *linfo, void *_udata); static const H5O_obj_class_t *H5O__obj_class_real(const H5O_t *oh); +static herr_t H5O__reset_info2(H5O_info2_t *oinfo); + /*********************/ /* Package Variables */ @@ -151,6 +155,13 @@ H5FL_BLK_DEFINE(chunk_image); /* Declare external the free list for H5O_cont_t sequences */ H5FL_SEQ_EXTERN(H5O_cont_t); +/* The canonical 'undefined' token */ +const H5O_token_t H5O_TOKEN_UNDEF_g = {{ + 255, 255, 255, 255, + 255, 255, 255, 255, + 255, 255, 255, 255, + 255, 255, 255, 255}}; + /*****************************/ /* Library Private Variables */ @@ -2155,9 +2166,7 @@ H5O__get_hdr_info_real(const H5O_t *oh, H5O_hdr_info_t *hdr) /*------------------------------------------------------------------------- * Function: H5O_get_info * - * Purpose: Retrieve the information for an object - * - * Note: Add a parameter "fields" to indicate selection of object info. + * Purpose: Retrieve the data model information for an object * * Return: Success: Non-negative * Failure: Negative @@ -2168,7 +2177,7 @@ H5O__get_hdr_info_real(const H5O_t *oh, H5O_hdr_info_t *hdr) *------------------------------------------------------------------------- */ herr_t -H5O_get_info(const H5O_loc_t *loc, H5O_info_t *oinfo, unsigned fields) +H5O_get_info(const H5O_loc_t *loc, H5O_info2_t *oinfo, unsigned fields) { const H5O_obj_class_t *obj_class; /* Class of object for header */ H5O_t *oh = NULL; /* Object header */ @@ -2189,15 +2198,17 @@ H5O_get_info(const H5O_loc_t *loc, H5O_info_t *oinfo, unsigned fields) HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "unable to determine object class") /* Reset the object info structure */ - HDmemset(oinfo, 0, sizeof(*oinfo)); + if(H5O__reset_info2(oinfo) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTSET, FAIL, "can't reset object data struct") /* Get basic information, if requested */ if(fields & H5O_INFO_BASIC) { /* Retrieve the file's fileno */ H5F_GET_FILENO(loc->file, oinfo->fileno); - /* Set the object's address */ - oinfo->addr = loc->addr; + /* Set the object's address into the token */ + if(H5VL_native_addr_to_token(loc->file, H5I_FILE, loc->addr, &oinfo->token) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTSERIALIZE, FAIL, "can't serialize address into object token") /* Retrieve the type of the object */ oinfo->type = obj_class->type; @@ -2249,18 +2260,63 @@ H5O_get_info(const H5O_loc_t *loc, H5O_info_t *oinfo, unsigned fields) } /* end else */ } /* end if */ - /* Get the information for the object header, if requested */ - if(fields & H5O_INFO_HDR) - if(H5O__get_hdr_info_real(oh, &oinfo->hdr) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't retrieve object header info") - /* Retrieve # of attributes */ if(fields & H5O_INFO_NUM_ATTRS) if(H5O__attr_count_real(loc->file, oh, &oinfo->num_attrs) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't retrieve attribute count") +done: + if(oh && H5O_unprotect(loc, oh, H5AC__NO_FLAGS_SET) < 0) + HDONE_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to release object header") + + FUNC_LEAVE_NOAPI_TAG(ret_value) +} /* end H5O_get_info() */ + + +/*------------------------------------------------------------------------- + * Function: H5O_get_native_info + * + * Purpose: Retrieve the native file-format information for an object + * + * Return: Success: Non-negative + * Failure: Negative + * + * Programmer: Quincey Koziol + * November 21 2006 + * + *------------------------------------------------------------------------- + */ +herr_t +H5O_get_native_info(const H5O_loc_t *loc, H5O_native_info_t *oinfo, unsigned fields) +{ + const H5O_obj_class_t *obj_class; /* Class of object for header */ + H5O_t *oh = NULL; /* Object header */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_TAG(loc->addr, FAIL) + + /* Check args */ + HDassert(loc); + HDassert(oinfo); + + /* Get the object header */ + if(NULL == (oh = H5O_protect(loc, H5AC__READ_ONLY_FLAG, FALSE))) + HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to load object header") + + /* Get class for object */ + if(NULL == (obj_class = H5O__obj_class_real(oh))) + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "unable to determine object class") + + /* Reset the object info structure */ + HDmemset(oinfo, 0, sizeof(*oinfo)); + + /* Get the information for the object header, if requested */ + if(fields & H5O_NATIVE_INFO_HDR) + if(H5O__get_hdr_info_real(oh, &oinfo->hdr) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't retrieve object header info") + /* Get B-tree & heap metadata storage size, if requested */ - if(fields & H5O_INFO_META_SIZE) { + if(fields & H5O_NATIVE_INFO_META_SIZE) { /* Check for 'bh_info' callback for this type of object */ if(obj_class->bh_info) /* Call the object's class 'bh_info' routine */ @@ -2268,10 +2324,8 @@ H5O_get_info(const H5O_loc_t *loc, H5O_info_t *oinfo, unsigned fields) HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't retrieve object's btree & heap info") /* Get B-tree & heap info for any attributes */ - if(!(fields & H5O_INFO_NUM_ATTRS) || oinfo->num_attrs > 0) { - if(H5O__attr_bh_info(loc->file, oh, &oinfo->meta_size.attr) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't retrieve attribute btree & heap info") - } /* end if */ + if(H5O__attr_bh_info(loc->file, oh, &oinfo->meta_size.attr) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't retrieve attribute btree & heap info") } /* end if */ done: @@ -2279,7 +2333,7 @@ done: HDONE_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to release object header") FUNC_LEAVE_NOAPI_TAG(ret_value) -} /* end H5O_get_info() */ +} /* end H5O_get_native_info() */ /*------------------------------------------------------------------------- @@ -2593,7 +2647,7 @@ H5O__free_visit_visited(void *item, void H5_ATTR_UNUSED *key, void H5_ATTR_UNUSE *------------------------------------------------------------------------- */ static herr_t -H5O__visit_cb(hid_t H5_ATTR_UNUSED group, const char *name, const H5L_info_t *linfo, +H5O__visit_cb(hid_t H5_ATTR_UNUSED group, const char *name, const H5L_info2_t *linfo, void *_udata) { H5O_iter_visit_ud_t *udata = (H5O_iter_visit_ud_t *)_udata; /* User data for callback */ @@ -2631,7 +2685,7 @@ H5O__visit_cb(hid_t H5_ATTR_UNUSED group, const char *name, const H5L_info_t *li /* Check if we've seen the object the link references before */ if(NULL == H5SL_search(udata->visited, &obj_pos)) { - H5O_info_t oinfo; /* Object info */ + H5O_info2_t oinfo; /* Object info */ /* Get the object's info */ if(H5O_get_info(&obj_oloc, &oinfo, udata->fields) < 0) @@ -2707,14 +2761,14 @@ done: */ herr_t H5O__visit(H5G_loc_t *loc, const char *obj_name, H5_index_t idx_type, - H5_iter_order_t order, H5O_iterate_t op, void *op_data, unsigned fields) + H5_iter_order_t order, H5O_iterate2_t op, void *op_data, unsigned fields) { H5O_iter_visit_ud_t udata; /* User data for callback */ H5G_loc_t obj_loc; /* Location used to open object */ H5G_name_t obj_path; /* Opened object group hier. path */ H5O_loc_t obj_oloc; /* Opened object object location */ hbool_t loc_found = FALSE; /* Entry at 'name' found */ - H5O_info_t oinfo; /* Object info struct */ + H5O_info2_t oinfo; /* Object info struct */ void *obj = NULL; /* Object */ H5I_type_t opened_type; /* ID type of object */ hid_t obj_id = H5I_INVALID_HID; /* ID of object */ @@ -2790,7 +2844,10 @@ H5O__visit(H5G_loc_t *loc, const char *obj_name, H5_index_t idx_type, /* Construct unique "position" for this object */ obj_pos->fileno = oinfo.fileno; - obj_pos->addr = oinfo.addr; + + /* De-serialize object token into an object address */ + if(H5VL_native_token_to_addr(loc->oloc->file, H5I_FILE, oinfo.token, &(obj_pos->addr)) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTUNSERIALIZE, FAIL, "can't deserialize object token into address") /* Add to list of visited objects */ if(H5SL_insert(udata.visited, obj_pos, obj_pos) < 0) @@ -3027,3 +3084,25 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5O__free() */ +/*------------------------------------------------------------------------- + * Function: H5O__reset_info2 + * + * Purpose: Resets/initializes an H5O_info2_t struct. + * + * Return: SUCCEED/FAIL + * + *------------------------------------------------------------------------- + */ +static herr_t +H5O__reset_info2(H5O_info2_t *oinfo) +{ + FUNC_ENTER_STATIC_NOERR; + + /* Reset the passed-in info struct */ + HDmemset(oinfo, 0, sizeof(H5O_info2_t)); + oinfo->type = H5O_TYPE_UNKNOWN; + oinfo->token = H5O_TOKEN_UNDEF; + + FUNC_LEAVE_NOAPI(SUCCEED); +} /* end H5O__reset_info2() */ + diff --git a/src/H5Opkg.h b/src/H5Opkg.h index c7167c7..fb08f7d 100644 --- a/src/H5Opkg.h +++ b/src/H5Opkg.h @@ -557,7 +557,7 @@ H5_DLLVAR const H5O_obj_class_t H5O_OBJ_DATATYPE[1]; H5_DLL const H5O_obj_class_t *H5O__obj_class(const H5O_loc_t *loc); H5_DLL int H5O__link_oh(H5F_t *f, int adjust, H5O_t *oh, hbool_t *deleted); H5_DLL herr_t H5O__visit(H5G_loc_t *loc, const char *obj_name, H5_index_t idx_type, - H5_iter_order_t order, H5O_iterate_t op, void *op_data, unsigned fields); + H5_iter_order_t order, H5O_iterate2_t op, void *op_data, unsigned fields); H5_DLL herr_t H5O__inc_rc(H5O_t *oh); H5_DLL herr_t H5O__dec_rc(H5O_t *oh); H5_DLL herr_t H5O__free(H5O_t *oh); diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h index 5965fc6..52a72b2 100644 --- a/src/H5Oprivate.h +++ b/src/H5Oprivate.h @@ -907,7 +907,8 @@ H5_DLL herr_t H5O_bogus_oh(H5F_t *f, H5O_t *oh, unsigned mesg_id, unsigned mesg_ #endif /* H5O_ENABLE_BOGUS */ H5_DLL herr_t H5O_delete(H5F_t *f, haddr_t addr); H5_DLL herr_t H5O_get_hdr_info(const H5O_loc_t *oloc, H5O_hdr_info_t *hdr); -H5_DLL herr_t H5O_get_info(const H5O_loc_t *oloc, H5O_info_t *oinfo, unsigned fields); +H5_DLL herr_t H5O_get_info(const H5O_loc_t *oloc, H5O_info2_t *oinfo, unsigned fields); +H5_DLL herr_t H5O_get_native_info(const H5O_loc_t *oloc, H5O_native_info_t *oinfo, unsigned fields); H5_DLL herr_t H5O_obj_type(const H5O_loc_t *loc, H5O_type_t *obj_type); H5_DLL herr_t H5O_get_create_plist(const H5O_loc_t *loc, struct H5P_genplist_t *oc_plist); H5_DLL void *H5O_open_name(const H5G_loc_t *loc, const char *name, H5I_type_t *opened_type/*out*/); diff --git a/src/H5Opublic.h b/src/H5Opublic.h index cda446b..d0f8ab3 100644 --- a/src/H5Opublic.h +++ b/src/H5Opublic.h @@ -80,9 +80,19 @@ #define H5O_INFO_BASIC 0x0001u /* Fill in the fileno, addr, type, and rc fields */ #define H5O_INFO_TIME 0x0002u /* Fill in the atime, mtime, ctime, and btime fields */ #define H5O_INFO_NUM_ATTRS 0x0004u /* Fill in the num_attrs field */ -#define H5O_INFO_HDR 0x0008u /* Fill in the hdr field */ -#define H5O_INFO_META_SIZE 0x0010u /* Fill in the meta_size field */ -#define H5O_INFO_ALL (H5O_INFO_BASIC | H5O_INFO_TIME | H5O_INFO_NUM_ATTRS | H5O_INFO_HDR | H5O_INFO_META_SIZE) +#define H5O_INFO_ALL (H5O_INFO_BASIC | H5O_INFO_TIME | H5O_INFO_NUM_ATTRS) + +/* Flags for H5Oget_native_info. + * Theses flags determine which fields will be filled in in the H5O_native_info_t + * struct. + */ +#define H5O_NATIVE_INFO_HDR 0x0008u /* Fill in the hdr field */ +#define H5O_NATIVE_INFO_META_SIZE 0x0010u /* Fill in the meta_size field */ +#define H5O_NATIVE_INFO_ALL (H5O_NATIVE_INFO_HDR | H5O_NATIVE_INFO_META_SIZE) + +/* Convenience macro to check if the token is the 'undefined' token value */ +#define H5O_IS_TOKEN_UNDEF(token) (!HDmemcmp(&(token), &(H5O_TOKEN_UNDEF), sizeof(H5O_token_t))) + /*******************/ /* Public Typedefs */ @@ -116,30 +126,36 @@ typedef struct H5O_hdr_info_t { } mesg; } H5O_hdr_info_t; -/* Information struct for object (for H5Oget_info/H5Oget_info_by_name/H5Oget_info_by_idx) */ -typedef struct H5O_info_t { - unsigned long fileno; /* File number that object is located in */ - haddr_t addr; /* Object address in file */ - H5O_type_t type; /* Basic object type (group, dataset, etc.) */ - unsigned rc; /* Reference count of object */ - time_t atime; /* Access time */ - time_t mtime; /* Modification time */ - time_t ctime; /* Change time */ - time_t btime; /* Birth time */ - hsize_t num_attrs; /* # of attributes attached to object */ +/* Data model information struct for objects */ +/* (For H5Oget_info / H5Oget_info_by_name / H5Oget_info_by_idx version 3) */ +typedef struct H5O_info2_t { + unsigned long fileno; /* File number that object is located in */ + H5O_token_t token; /* Token representing the object */ + H5O_type_t type; /* Basic object type (group, dataset, etc.) */ + unsigned rc; /* Reference count of object */ + time_t atime; /* Access time */ + time_t mtime; /* Modification time */ + time_t ctime; /* Change time */ + time_t btime; /* Birth time */ + hsize_t num_attrs; /* # of attributes attached to object */ +} H5O_info2_t; + +/* Native file format information struct for objects */ +/* (For H5Oget_native_info / H5Oget_native_info_by_name / H5Oget_native_info_by_idx) */ +typedef struct H5O_native_info_t { H5O_hdr_info_t hdr; /* Object header information */ /* Extra metadata storage for obj & attributes */ struct { H5_ih_info_t obj; /* v1/v2 B-tree & local/fractal heap for groups, B-tree for chunked datasets */ H5_ih_info_t attr; /* v2 B-tree & heap for attributes */ } meta_size; -} H5O_info_t; +} H5O_native_info_t; /* Typedef for message creation indexes */ typedef uint32_t H5O_msg_crt_idx_t; -/* Prototype for H5Ovisit/H5Ovisit_by_name() operator */ -typedef herr_t (*H5O_iterate_t)(hid_t obj, const char *name, const H5O_info_t *info, +/* Prototype for H5Ovisit/H5Ovisit_by_name() operator (version 3) */ +typedef herr_t (*H5O_iterate2_t)(hid_t obj, const char *name, const H5O_info2_t *info, void *op_data); typedef enum H5O_mcdt_search_ret_t { @@ -165,15 +181,21 @@ extern "C" { #endif H5_DLL hid_t H5Oopen(hid_t loc_id, const char *name, hid_t lapl_id); -H5_DLL hid_t H5Oopen_by_addr(hid_t loc_id, haddr_t addr); +H5_DLL hid_t H5Oopen_by_token(hid_t loc_id, H5O_token_t token); H5_DLL hid_t H5Oopen_by_idx(hid_t loc_id, const char *group_name, H5_index_t idx_type, H5_iter_order_t order, hsize_t n, hid_t lapl_id); H5_DLL htri_t H5Oexists_by_name(hid_t loc_id, const char *name, hid_t lapl_id); -H5_DLL herr_t H5Oget_info2(hid_t loc_id, H5O_info_t *oinfo, unsigned fields); -H5_DLL herr_t H5Oget_info_by_name2(hid_t loc_id, const char *name, H5O_info_t *oinfo, +H5_DLL herr_t H5Oget_info3(hid_t loc_id, H5O_info2_t *oinfo, unsigned fields); +H5_DLL herr_t H5Oget_info_by_name3(hid_t loc_id, const char *name, H5O_info2_t *oinfo, unsigned fields, hid_t lapl_id); -H5_DLL herr_t H5Oget_info_by_idx2(hid_t loc_id, const char *group_name, - H5_index_t idx_type, H5_iter_order_t order, hsize_t n, H5O_info_t *oinfo, +H5_DLL herr_t H5Oget_info_by_idx3(hid_t loc_id, const char *group_name, + H5_index_t idx_type, H5_iter_order_t order, hsize_t n, H5O_info2_t *oinfo, + unsigned fields, hid_t lapl_id); +H5_DLL herr_t H5Oget_native_info(hid_t loc_id, H5O_native_info_t *oinfo, unsigned fields); +H5_DLL herr_t H5Oget_native_info_by_name(hid_t loc_id, const char *name, H5O_native_info_t *oinfo, + unsigned fields, hid_t lapl_id); +H5_DLL herr_t H5Oget_native_info_by_idx(hid_t loc_id, const char *group_name, + H5_index_t idx_type, H5_iter_order_t order, hsize_t n, H5O_native_info_t *oinfo, unsigned fields, hid_t lapl_id); H5_DLL herr_t H5Olink(hid_t obj_id, hid_t new_loc_id, const char *new_name, hid_t lcpl_id, hid_t lapl_id); @@ -187,10 +209,10 @@ H5_DLL herr_t H5Oset_comment_by_name(hid_t loc_id, const char *name, H5_DLL ssize_t H5Oget_comment(hid_t obj_id, char *comment, size_t bufsize); H5_DLL ssize_t H5Oget_comment_by_name(hid_t loc_id, const char *name, char *comment, size_t bufsize, hid_t lapl_id); -H5_DLL herr_t H5Ovisit2(hid_t obj_id, H5_index_t idx_type, H5_iter_order_t order, - H5O_iterate_t op, void *op_data, unsigned fields); -H5_DLL herr_t H5Ovisit_by_name2(hid_t loc_id, const char *obj_name, - H5_index_t idx_type, H5_iter_order_t order, H5O_iterate_t op, +H5_DLL herr_t H5Ovisit3(hid_t obj_id, H5_index_t idx_type, H5_iter_order_t order, + H5O_iterate2_t op, void *op_data, unsigned fields); +H5_DLL herr_t H5Ovisit_by_name3(hid_t loc_id, const char *obj_name, + H5_index_t idx_type, H5_iter_order_t order, H5O_iterate2_t op, void *op_data, unsigned fields, hid_t lapl_id); H5_DLL herr_t H5Oclose(hid_t object_id); H5_DLL herr_t H5Oflush(hid_t obj_id); @@ -198,6 +220,14 @@ H5_DLL herr_t H5Orefresh(hid_t oid); H5_DLL herr_t H5Odisable_mdc_flushes(hid_t object_id); H5_DLL herr_t H5Oenable_mdc_flushes(hid_t object_id); H5_DLL herr_t H5Oare_mdc_flushes_disabled(hid_t object_id, hbool_t *are_disabled); +H5_DLL herr_t H5Otoken_cmp(hid_t loc_id, const H5O_token_t *token1, const H5O_token_t *token2, + int *cmp_value); +H5_DLL herr_t H5Otoken_to_str(hid_t loc_id, const H5O_token_t *token, char **token_str); +H5_DLL herr_t H5Otoken_from_str(hid_t loc_id, const char *token_str, H5O_token_t *token); + +/* The canonical 'undefined' token value */ +#define H5O_TOKEN_UNDEF (H5OPEN H5O_TOKEN_UNDEF_g) +H5_DLLVAR const H5O_token_t H5O_TOKEN_UNDEF_g; /* Symbols defined for compatibility with previous versions of the HDF5 API. * @@ -207,6 +237,12 @@ H5_DLL herr_t H5Oare_mdc_flushes_disabled(hid_t object_id, hbool_t *are_disabled /* Macros */ +/* Deprecated flags for earlier versions of H5Oget_info* */ +#define H5O_INFO_HDR 0x0008u /* Fill in the hdr field */ +#define H5O_INFO_META_SIZE 0x0010u /* Fill in the meta_size field */ +#undef H5O_INFO_ALL +#define H5O_INFO_ALL (H5O_INFO_BASIC | H5O_INFO_TIME | H5O_INFO_NUM_ATTRS | H5O_INFO_HDR | H5O_INFO_META_SIZE) + /* Typedefs */ /* A struct that's part of the H5G_stat_t structure (deprecated) */ @@ -217,19 +253,56 @@ typedef struct H5O_stat_t { unsigned nchunks; /* Number of object header chunks */ } H5O_stat_t; +/* Information struct for object */ +/* (For H5Oget_info/H5Oget_info_by_name/H5Oget_info_by_idx versions 1 & 2) */ +typedef struct H5O_info1_t { + unsigned long fileno; /* File number that object is located in */ + haddr_t addr; /* Object address in file */ + H5O_type_t type; /* Basic object type (group, dataset, etc.) */ + unsigned rc; /* Reference count of object */ + time_t atime; /* Access time */ + time_t mtime; /* Modification time */ + time_t ctime; /* Change time */ + time_t btime; /* Birth time */ + hsize_t num_attrs; /* # of attributes attached to object */ + H5O_hdr_info_t hdr; /* Object header information */ + /* Extra metadata storage for obj & attributes */ + struct { + H5_ih_info_t obj; /* v1/v2 B-tree & local/fractal heap for groups, B-tree for chunked datasets */ + H5_ih_info_t attr; /* v2 B-tree & heap for attributes */ + } meta_size; +} H5O_info1_t; + +/* Prototype for H5Ovisit/H5Ovisit_by_name() operator (versions 1 & 2) */ +typedef herr_t (*H5O_iterate1_t)(hid_t obj, const char *name, const H5O_info1_t *info, + void *op_data); + + /* Function prototypes */ -H5_DLL herr_t H5Oget_info1(hid_t loc_id, H5O_info_t *oinfo); -H5_DLL herr_t H5Oget_info_by_name1(hid_t loc_id, const char *name, H5O_info_t *oinfo, +H5_DLL hid_t H5Oopen_by_addr(hid_t loc_id, haddr_t addr); +H5_DLL herr_t H5Oget_info1(hid_t loc_id, H5O_info1_t *oinfo); +H5_DLL herr_t H5Oget_info_by_name1(hid_t loc_id, const char *name, H5O_info1_t *oinfo, hid_t lapl_id); H5_DLL herr_t H5Oget_info_by_idx1(hid_t loc_id, const char *group_name, - H5_index_t idx_type, H5_iter_order_t order, hsize_t n, H5O_info_t *oinfo, + H5_index_t idx_type, H5_iter_order_t order, hsize_t n, H5O_info1_t *oinfo, hid_t lapl_id); - +H5_DLL herr_t H5Oget_info2(hid_t loc_id, H5O_info1_t *oinfo, unsigned fields); +H5_DLL herr_t H5Oget_info_by_name2(hid_t loc_id, const char *name, H5O_info1_t *oinfo, + unsigned fields, hid_t lapl_id); +H5_DLL herr_t H5Oget_info_by_idx2(hid_t loc_id, const char *group_name, + H5_index_t idx_type, H5_iter_order_t order, hsize_t n, H5O_info1_t *oinfo, + unsigned fields, hid_t lapl_id); H5_DLL herr_t H5Ovisit1(hid_t obj_id, H5_index_t idx_type, H5_iter_order_t order, - H5O_iterate_t op, void *op_data); + H5O_iterate1_t op, void *op_data); H5_DLL herr_t H5Ovisit_by_name1(hid_t loc_id, const char *obj_name, - H5_index_t idx_type, H5_iter_order_t order, H5O_iterate_t op, + H5_index_t idx_type, H5_iter_order_t order, H5O_iterate1_t op, void *op_data, hid_t lapl_id); +H5_DLL herr_t H5Ovisit2(hid_t obj_id, H5_index_t idx_type, H5_iter_order_t order, + H5O_iterate1_t op, void *op_data, unsigned fields); +H5_DLL herr_t H5Ovisit_by_name2(hid_t loc_id, const char *obj_name, + H5_index_t idx_type, H5_iter_order_t order, H5O_iterate1_t op, + void *op_data, unsigned fields, hid_t lapl_id); + #endif /* H5_NO_DEPRECATED_SYMBOLS */ #ifdef __cplusplus diff --git a/src/H5R.c b/src/H5R.c index 3a022eb..8b9c979 100644 --- a/src/H5R.c +++ b/src/H5R.c @@ -66,22 +66,22 @@ /*------------------------------------------------------------------------- * Function: H5Rcreate_object * - * Purpose: Creates an object reference. The LOC_ID and NAME are used to locate - * the object pointed to. + * Purpose: Creates an object reference. The LOC_ID and NAME are used + * to locate the object pointed to. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success / Negative on failure * *------------------------------------------------------------------------- */ herr_t H5Rcreate_object(hid_t loc_id, const char *name, hid_t oapl_id, H5R_ref_t *ref_ptr) { - H5VL_object_t *vol_obj = NULL; /* Object token of loc_id */ + H5VL_object_t *vol_obj = NULL; /* Object of loc_id */ H5I_type_t obj_type; /* Object type of loc_id */ hid_t file_id = H5I_INVALID_HID;/* File ID */ - H5VL_object_t *vol_obj_file = NULL; /* Object token of file_id */ + H5VL_object_t *vol_obj_file = NULL; /* Object of file_id */ H5VL_loc_params_t loc_params; /* Location parameters */ - H5VL_token_t obj_token = {0}; /* Object token */ + H5O_token_t obj_token = {0}; /* Object token */ H5VL_file_cont_info_t cont_info = {H5VL_CONTAINER_INFO_VERSION, 0, 0, 0}; herr_t ret_value = SUCCEED; /* Return value */ @@ -135,7 +135,7 @@ H5Rcreate_object(hid_t loc_id, const char *name, hid_t oapl_id, H5R_ref_t *ref_p /* Create the reference (do not pass filename, since file_id is attached) */ HDmemset(ref_ptr, 0, H5R_REF_BUF_SIZE); - if(H5R__create_object((const H5VL_token_t *)&obj_token, cont_info.token_size, (H5R_ref_priv_t *)ref_ptr) < 0) + if(H5R__create_object((const H5O_token_t *)&obj_token, cont_info.token_size, (H5R_ref_priv_t *)ref_ptr) < 0) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTCREATE, FAIL, "unable to create object reference") /* Attach loc_id to reference and hold reference to it */ @@ -152,11 +152,11 @@ done: /*------------------------------------------------------------------------- * Function: H5Rcreate_region * - * Purpose: Creates a region reference. The LOC_ID and NAME are used to locate - * the object pointed to and the SPACE_ID is used to choose the region pointed - * to. + * Purpose: Creates a region reference. The LOC_ID and NAME are used to + * locate the object pointed to and the SPACE_ID is used to + * choose the region pointed to. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success / Negative on failure * *------------------------------------------------------------------------- */ @@ -164,12 +164,12 @@ herr_t H5Rcreate_region(hid_t loc_id, const char *name, hid_t space_id, hid_t oapl_id, H5R_ref_t *ref_ptr) { - H5VL_object_t *vol_obj = NULL; /* Object token of loc_id */ + H5VL_object_t *vol_obj = NULL; /* Object of loc_id */ H5I_type_t obj_type; /* Object type of loc_id */ hid_t file_id = H5I_INVALID_HID;/* File ID */ - H5VL_object_t *vol_obj_file = NULL; /* Object token of file_id */ + H5VL_object_t *vol_obj_file = NULL; /* Object of file_id */ H5VL_loc_params_t loc_params; /* Location parameters */ - H5VL_token_t obj_token = {0}; /* Object token */ + H5O_token_t obj_token = {0}; /* Object token */ H5VL_file_cont_info_t cont_info = {H5VL_CONTAINER_INFO_VERSION, 0, 0, 0}; struct H5S_t *space = NULL; /* Pointer to dataspace containing region */ herr_t ret_value = SUCCEED; /* Return value */ @@ -228,7 +228,7 @@ H5Rcreate_region(hid_t loc_id, const char *name, hid_t space_id, /* Create the reference (do not pass filename, since file_id is attached) */ HDmemset(ref_ptr, 0, H5R_REF_BUF_SIZE); - if(H5R__create_region((const H5VL_token_t *)&obj_token, cont_info.token_size, space, (H5R_ref_priv_t *)ref_ptr) < 0) + if(H5R__create_region((const H5O_token_t *)&obj_token, cont_info.token_size, space, (H5R_ref_priv_t *)ref_ptr) < 0) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTCREATE, FAIL, "unable to create region reference") /* Attach loc_id to reference and hold reference to it */ @@ -245,10 +245,10 @@ done: /*------------------------------------------------------------------------- * Function: H5Rcreate_attr * - * Purpose: Creates an attribute reference. The LOC_ID, NAME and ATTR_NAME are - * used to locate the attribute pointed to. + * Purpose: Creates an attribute reference. The LOC_ID, NAME and + * ATTR_NAME are used to locate the attribute pointed to. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success / Negative on failure * *------------------------------------------------------------------------- */ @@ -256,12 +256,12 @@ herr_t H5Rcreate_attr(hid_t loc_id, const char *name, const char *attr_name, hid_t oapl_id, H5R_ref_t *ref_ptr) { - H5VL_object_t *vol_obj = NULL; /* Object token of loc_id */ + H5VL_object_t *vol_obj = NULL; /* Object of loc_id */ H5I_type_t obj_type; /* Object type of loc_id */ hid_t file_id = H5I_INVALID_HID;/* File ID */ - H5VL_object_t *vol_obj_file = NULL; /* Object token of file_id */ + H5VL_object_t *vol_obj_file = NULL; /* Object of file_id */ H5VL_loc_params_t loc_params; /* Location parameters */ - H5VL_token_t obj_token = {0}; /* Object token */ + H5O_token_t obj_token = {0}; /* Object token */ H5VL_file_cont_info_t cont_info = {H5VL_CONTAINER_INFO_VERSION, 0, 0, 0}; herr_t ret_value = SUCCEED; /* Return value */ @@ -317,7 +317,7 @@ H5Rcreate_attr(hid_t loc_id, const char *name, const char *attr_name, /* Create the reference (do not pass filename, since file_id is attached) */ HDmemset(ref_ptr, 0, H5R_REF_BUF_SIZE); - if(H5R__create_attr((const H5VL_token_t *)&obj_token, cont_info.token_size, attr_name, (H5R_ref_priv_t *)ref_ptr) < 0) + if(H5R__create_attr((const H5O_token_t *)&obj_token, cont_info.token_size, attr_name, (H5R_ref_priv_t *)ref_ptr) < 0) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTCREATE, FAIL, "unable to create attribute reference") /* Attach loc_id to reference and hold reference to it */ @@ -334,9 +334,10 @@ done: /*------------------------------------------------------------------------- * Function: H5Rdestroy * - * Purpose: Destroy reference and free resources allocated during H5Rcreate. + * Purpose: Destroy reference and free resources allocated during + * H5Rcreate. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success / Negative on failure * *------------------------------------------------------------------------- */ @@ -367,9 +368,10 @@ done: /*------------------------------------------------------------------------- * Function: H5Rget_type * - * Purpose: Given a reference to some object, return the type of that reference. + * Purpose: Given a reference to some object, return the type of that + * reference. * - * Return: Reference type/H5R_BADTYPE on failure + * Return: Reference type / H5R_BADTYPE on failure * *------------------------------------------------------------------------- */ @@ -398,9 +400,9 @@ done: /*------------------------------------------------------------------------- * Function: H5Requal * - * Purpose: Compare two references + * Purpose: Compare two references * - * Return: TRUE if equal, FALSE if unequal, FAIL if error + * Return: TRUE if equal, FALSE if unequal, FAIL if error * *------------------------------------------------------------------------- */ @@ -428,9 +430,9 @@ done: /*------------------------------------------------------------------------- * Function: H5Rcopy * - * Purpose: Copy a reference + * Purpose: Copy a reference * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success / Negative on failure * *------------------------------------------------------------------------- */ @@ -458,20 +460,20 @@ done: /*------------------------------------------------------------------------- * Function: H5Ropen_object * - * Purpose: Given a reference to some object, open that object and return an - * ID for that object. + * Purpose: Given a reference to some object, open that object and + * return an ID for that object. * - * Return: Valid ID on success/Negative on failure + * Return: Valid ID on success / H5I_INVALID_HID on failure * *------------------------------------------------------------------------- */ hid_t -H5Ropen_object(const H5R_ref_t *ref_ptr, hid_t rapl_id, hid_t oapl_id) +H5Ropen_object(H5R_ref_t *ref_ptr, hid_t rapl_id, hid_t oapl_id) { hid_t loc_id; /* Reference location ID */ - H5VL_object_t *vol_obj = NULL; /* Object token of loc_id */ + H5VL_object_t *vol_obj = NULL; /* Object of loc_id */ H5VL_loc_params_t loc_params; /* Location parameters */ - H5VL_token_t obj_token = {0}; /* Object token */ + H5O_token_t obj_token = {0}; /* Object token */ H5I_type_t opened_type; /* Opened object type */ void *opened_obj = NULL; /* Opened object */ hid_t ret_value = H5I_INVALID_HID; /* Return value */ @@ -530,21 +532,21 @@ done: /*------------------------------------------------------------------------- * Function: H5Ropen_region * - * Purpose: Given a reference to some object, creates a copy of the dataset - * pointed to's dataspace and defines a selection in the copy which is the - * region pointed to. + * Purpose: Given a reference to some object, creates a copy of the dataset + * pointed to's dataspace and defines a selection in the copy + * which is the region pointed to. * - * Return: Valid ID on success/Negative on failure + * Return: Valid ID on success / H5I_INVALID_HID on failure * *------------------------------------------------------------------------- */ hid_t -H5Ropen_region(const H5R_ref_t *ref_ptr, hid_t rapl_id, hid_t oapl_id) +H5Ropen_region(H5R_ref_t *ref_ptr, hid_t rapl_id, hid_t oapl_id) { hid_t loc_id; /* Reference location ID */ - H5VL_object_t *vol_obj = NULL; /* Object token of loc_id */ + H5VL_object_t *vol_obj = NULL; /* Object of loc_id */ H5VL_loc_params_t loc_params; /* Location parameters */ - H5VL_token_t obj_token = {0}; /* Object token */ + H5O_token_t obj_token = {0}; /* Object token */ H5I_type_t opened_type; /* Opened object type */ void *opened_obj = NULL; /* Opened object */ hid_t opened_obj_id = H5I_INVALID_HID; /* Opened object ID */ @@ -625,20 +627,20 @@ done: /*------------------------------------------------------------------------- * Function: H5Ropen_attr * - * Purpose: Given a reference to some attribute, open that attribute and - * return an ID for that attribute. + * Purpose: Given a reference to some attribute, open that attribute and + * return an ID for that attribute. * - * Return: Valid ID on success/Negative on failure + * Return: Valid ID on success / H5I_INVALID_HID on failure * *------------------------------------------------------------------------- */ hid_t -H5Ropen_attr(const H5R_ref_t *ref_ptr, hid_t rapl_id, hid_t aapl_id) +H5Ropen_attr(H5R_ref_t *ref_ptr, hid_t rapl_id, hid_t aapl_id) { hid_t loc_id; /* Reference location ID */ - H5VL_object_t *vol_obj = NULL; /* Object token of loc_id */ + H5VL_object_t *vol_obj = NULL; /* Object of loc_id */ H5VL_loc_params_t loc_params; /* Location parameters */ - H5VL_token_t obj_token = {0}; /* Object token */ + H5O_token_t obj_token = {0}; /* Object token */ H5I_type_t opened_type; /* Opened object type */ void *opened_obj = NULL; /* Opened object */ hid_t opened_obj_id = H5I_INVALID_HID; /* Opened object ID */ @@ -720,20 +722,20 @@ done: /*------------------------------------------------------------------------- * Function: H5Rget_obj_type3 * - * Purpose: Given a reference to some object, this function returns the type - * of object pointed to. + * Purpose: Given a reference to some object, this function returns the + * type of object pointed to. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success / Negative on failure * *------------------------------------------------------------------------- */ herr_t -H5Rget_obj_type3(const H5R_ref_t *ref_ptr, hid_t rapl_id, H5O_type_t *obj_type) +H5Rget_obj_type3(H5R_ref_t *ref_ptr, hid_t rapl_id, H5O_type_t *obj_type) { hid_t loc_id; /* Reference location ID */ - H5VL_object_t *vol_obj = NULL; /* Object token of loc_id */ + H5VL_object_t *vol_obj = NULL; /* Object of loc_id */ H5VL_loc_params_t loc_params; /* Location parameters */ - H5VL_token_t obj_token = {0}; /* Object token */ + H5O_token_t obj_token = {0}; /* Object token */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) @@ -780,10 +782,10 @@ done: /*------------------------------------------------------------------------- * Function: H5Rget_file_name * - * Purpose: Given a reference to some object, determine a file name of the - * object located into. + * Purpose: Given a reference to some object, determine a file name of the + * object located into. * - * Return: Non-negative length of the path on success/Negative on failure + * Return: Non-negative length of the path on success / -1 on failure * *------------------------------------------------------------------------- */ @@ -809,8 +811,9 @@ H5Rget_file_name(const H5R_ref_t *ref_ptr, char *buf, size_t size) * copy of the filename */ if((ret_value = H5R__get_file_name((const H5R_ref_priv_t *)ref_ptr, buf, size)) < 0) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, (-1), "unable to retrieve file name") - } else { - H5VL_object_t *vol_obj = NULL; /* Object token of loc_id */ + } + else { + H5VL_object_t *vol_obj = NULL; /* Object of loc_id */ /* Retrieve VOL file object */ if(NULL == (vol_obj = H5VL_vol_object(loc_id))) @@ -828,21 +831,21 @@ done: /*------------------------------------------------------------------------- * Function: H5Rget_obj_name * - * Purpose: Given a reference to some object, determine a path to the object - * referenced in the file. + * Purpose: Given a reference to some object, determine a path to the + * object referenced in the file. * - * Return: Non-negative length of the path on success/Negative on failure + * Return: Non-negative length of the path on success / -1 on failure * *------------------------------------------------------------------------- */ ssize_t -H5Rget_obj_name(const H5R_ref_t *ref_ptr, hid_t rapl_id, char *buf, size_t size) +H5Rget_obj_name(H5R_ref_t *ref_ptr, hid_t rapl_id, char *buf, size_t size) { hid_t loc_id; /* Reference location ID */ - H5VL_object_t *vol_obj = NULL; /* Object token of loc_id */ + H5VL_object_t *vol_obj = NULL; /* Object of loc_id */ H5VL_loc_params_t loc_params; /* Location parameters */ - H5VL_token_t obj_token = {0}; /* Object token */ - ssize_t ret_value; /* Return value */ + H5O_token_t obj_token = {0}; /* Object token */ + ssize_t ret_value = 0; /* Return value */ FUNC_ENTER_API((-1)) H5TRACE4("Zs", "*Rri*sz", ref_ptr, rapl_id, buf, size); @@ -864,7 +867,7 @@ H5Rget_obj_name(const H5R_ref_t *ref_ptr, hid_t rapl_id, char *buf, size_t size) } /* Get object token */ - if((ret_value = H5R__get_obj_token((const H5R_ref_priv_t *)ref_ptr, &obj_token, NULL)) < 0) + if(H5R__get_obj_token((const H5R_ref_priv_t *)ref_ptr, &obj_token, NULL) < 0) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, (-1), "unable to get object token") /* Get the VOL object */ @@ -888,9 +891,9 @@ done: /*------------------------------------------------------------------------- * Function: H5Rget_attr_name * - * Purpose: Given a reference to some attribute, determine its name. + * Purpose: Given a reference to some attribute, determine its name. * - * Return: Non-negative length of the path on success/Negative on failure + * Return: Non-negative length of the path on success / -1 on failure * *------------------------------------------------------------------------- */ diff --git a/src/H5Rdeprec.c b/src/H5Rdeprec.c index 256c930..4e44683 100644 --- a/src/H5Rdeprec.c +++ b/src/H5Rdeprec.c @@ -87,20 +87,20 @@ /*------------------------------------------------------------------------- * Function: H5Rget_obj_type1 * - * Purpose: Retrieves the type of the object that a reference points to. + * Purpose: Retrieves the type of the object that a reference points to. * - * Return: Object type (as defined in H5Gpublic.h) on success - * H5G_UNKNOWN on failure + * Return: Success: Object type (as defined in H5Gpublic.h) + * Failure: H5G_UNKNOWN * *------------------------------------------------------------------------- */ H5G_obj_t H5Rget_obj_type1(hid_t id, H5R_type_t ref_type, const void *ref) { - H5VL_object_t *vol_obj = NULL; /* Object token of loc_id */ + H5VL_object_t *vol_obj = NULL; /* Object of loc_id */ H5I_type_t vol_obj_type = H5I_BADID;/* Object type of loc_id */ H5VL_loc_params_t loc_params; /* Location parameters */ - H5VL_token_t obj_token = {0}; /* Object token */ + H5O_token_t obj_token = {0}; /* Object token */ H5O_type_t obj_type; /* Object type */ const unsigned char *buf = (const unsigned char *)ref; /* Reference buffer */ H5G_obj_t ret_value; /* Return value */ @@ -146,20 +146,21 @@ done: /*------------------------------------------------------------------------- * Function: H5Rdereference1 * - * Purpose: Given a reference to some object, open that object and return an - * ID for that object. + * Purpose: Given a reference to some object, open that object and return + * an ID for that object. * - * Return: Valid ID on success/Negative on failure + * Return: Success: Valid ID + * Failure: H5I_INVALID_HID * *------------------------------------------------------------------------- */ hid_t H5Rdereference1(hid_t obj_id, H5R_type_t ref_type, const void *ref) { - H5VL_object_t *vol_obj = NULL; /* Object token of loc_id */ + H5VL_object_t *vol_obj = NULL; /* Object of loc_id */ H5I_type_t vol_obj_type = H5I_BADID;/* Object type of loc_id */ H5VL_loc_params_t loc_params; /* Location parameters */ - H5VL_token_t obj_token = {0}; /* Object token */ + H5O_token_t obj_token = {0}; /* Object token */ H5I_type_t opened_type; /* Opened object type */ void *opened_obj = NULL; /* Opened object */ const unsigned char *buf = (const unsigned char *)ref; /* Reference buffer */ @@ -209,12 +210,12 @@ done: /*------------------------------------------------------------------------- * Function: H5Rcreate * - * Purpose: Creates a particular type of reference specified with REF_TYPE, - * in the space pointed to by REF. The LOC_ID and NAME are used to locate the - * object pointed to and the SPACE_ID is used to choose the region pointed to - * (for Dataset Region references). + * Purpose: Creates a particular type of reference specified with REF_TYPE, + * in the space pointed to by REF. The LOC_ID and NAME are used to + * locate the object pointed to and the SPACE_ID is used to choose + * the region pointed to (for Dataset Region references). * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success / negative on failure * *------------------------------------------------------------------------- */ @@ -222,10 +223,10 @@ herr_t H5Rcreate(void *ref, hid_t loc_id, const char *name, H5R_type_t ref_type, hid_t space_id) { - H5VL_object_t *vol_obj = NULL; /* Object token of loc_id */ + H5VL_object_t *vol_obj = NULL; /* Object of loc_id */ H5I_type_t vol_obj_type = H5I_BADID;/* Object type of loc_id */ H5VL_loc_params_t loc_params; /* Location parameters */ - H5VL_token_t obj_token = {0}; /* Object token */ + H5O_token_t obj_token = {0}; /* Object token */ H5VL_file_cont_info_t cont_info = {H5VL_CONTAINER_INFO_VERSION, 0, 0, 0}; hid_t file_id = H5I_INVALID_HID; /* File ID for region reference */ void *vol_obj_file = NULL; @@ -294,7 +295,7 @@ H5Rcreate(void *ref, hid_t loc_id, const char *name, H5R_type_t ref_type, if(ref_type == H5R_OBJECT1) { size_t buf_size = H5R_OBJ_REF_BUF_SIZE; - if((ret_value = H5R__encode_token_obj_compat((const H5VL_token_t *)&obj_token, cont_info.token_size, buf, &buf_size)) < 0) + if((ret_value = H5R__encode_token_obj_compat((const H5O_token_t *)&obj_token, cont_info.token_size, buf, &buf_size)) < 0) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTENCODE, FAIL, "unable to encode object reference") } /* end if */ else { @@ -313,7 +314,7 @@ H5Rcreate(void *ref, hid_t loc_id, const char *name, H5R_type_t ref_type, HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid VOL object") /* Encode dataset region */ - if((ret_value = H5R__encode_token_region_compat(f, (const H5VL_token_t *)&obj_token, cont_info.token_size, space, buf, &buf_size)) < 0) + if((ret_value = H5R__encode_token_region_compat(f, (const H5O_token_t *)&obj_token, cont_info.token_size, space, buf, &buf_size)) < 0) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTENCODE, FAIL, "unable to encode region reference") } /* end else */ @@ -327,10 +328,10 @@ done: /*------------------------------------------------------------------------- * Function: H5Rget_obj_type2 * - * Purpose: Given a reference to some object, this function returns the type - * of object pointed to. + * Purpose: Given a reference to some object, this function returns the + * type of object pointed to. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success / negative on failure * *------------------------------------------------------------------------- */ @@ -338,10 +339,10 @@ herr_t H5Rget_obj_type2(hid_t id, H5R_type_t ref_type, const void *ref, H5O_type_t *obj_type) { - H5VL_object_t *vol_obj = NULL; /* Object token of loc_id */ + H5VL_object_t *vol_obj = NULL; /* Object of loc_id */ H5I_type_t vol_obj_type = H5I_BADID;/* Object type of loc_id */ H5VL_loc_params_t loc_params; /* Location parameters */ - H5VL_token_t obj_token = {0}; /* Object token */ + H5O_token_t obj_token = {0}; /* Object token */ const unsigned char *buf = (const unsigned char *)ref; /* Reference pointer */ herr_t ret_value = SUCCEED; /* Return value */ @@ -383,10 +384,11 @@ done: /*------------------------------------------------------------------------- * Function: H5Rdereference2 * - * Purpose: Given a reference to some object, open that object and return an - * ID for that object. + * Purpose: Given a reference to some object, open that object and return + * an ID for that object. * - * Return: Valid ID on success/Negative on failure + * Return: Success: Valid ID + * Failure: H5I_INVALID_HID * *------------------------------------------------------------------------- */ @@ -394,10 +396,10 @@ hid_t H5Rdereference2(hid_t obj_id, hid_t oapl_id, H5R_type_t ref_type, const void *ref) { - H5VL_object_t *vol_obj = NULL; /* Object token of loc_id */ + H5VL_object_t *vol_obj = NULL; /* Object of loc_id */ H5I_type_t vol_obj_type = H5I_BADID;/* Object type of loc_id */ H5VL_loc_params_t loc_params; /* Location parameters */ - H5VL_token_t obj_token = {0}; /* Object token */ + H5O_token_t obj_token = {0}; /* Object token */ H5I_type_t opened_type; /* Opened object type */ void *opened_obj = NULL; /* Opened object */ const unsigned char *buf = (const unsigned char *)ref; /* Reference pointer */ @@ -451,18 +453,19 @@ done: /*------------------------------------------------------------------------- * Function: H5Rget_region * - * Purpose: Given a reference to some object, creates a copy of the dataset - * pointed to's dataspace and defines a selection in the copy which is the - * region pointed to. + * Purpose: Given a reference to some object, creates a copy of the dataset + * pointed to's dataspace and defines a selection in the copy + * which is the region pointed to. * - * Return: Valid ID on success/Negative on failure + * Return: Success: Valid ID + * Failure: H5I_INVALID_HID * *------------------------------------------------------------------------- */ hid_t H5Rget_region(hid_t id, H5R_type_t ref_type, const void *ref) { - H5VL_object_t *vol_obj = NULL; /* Object token of loc_id */ + H5VL_object_t *vol_obj = NULL; /* Object of loc_id */ H5I_type_t vol_obj_type = H5I_BADID;/* Object type of loc_id */ void *vol_obj_file = NULL; /* VOL file */ H5VL_file_cont_info_t cont_info = {H5VL_CONTAINER_INFO_VERSION, 0, 0, 0}; @@ -537,10 +540,11 @@ done: /*------------------------------------------------------------------------- * Function: H5Rget_name * - * Purpose: Given a reference to some object, determine a path to the object - * referenced in the file. + * Purpose: Given a reference to some object, determine a path to the + * object referenced in the file. * - * Return: Non-negative length of the path on success/Negative on failure + * Return: Success: Non-negative length of the path + * Failure: -1 * *------------------------------------------------------------------------- */ @@ -548,10 +552,10 @@ ssize_t H5Rget_name(hid_t id, H5R_type_t ref_type, const void *ref, char *name, size_t size) { - H5VL_object_t *vol_obj = NULL; /* Object token of loc_id */ + H5VL_object_t *vol_obj = NULL; /* Object of loc_id */ H5I_type_t vol_obj_type = H5I_BADID;/* Object type of loc_id */ H5VL_loc_params_t loc_params; /* Location parameters */ - H5VL_token_t obj_token = {0}; /* Object token */ + H5O_token_t obj_token = {0}; /* Object token */ const unsigned char *buf = (const unsigned char *)ref; /* Reference pointer */ ssize_t ret_value = -1; /* Return value */ @@ -588,3 +592,4 @@ H5Rget_name(hid_t id, H5R_type_t ref_type, const void *ref, char *name, done: FUNC_LEAVE_API(ret_value) } /* end H5Rget_name() */ + diff --git a/src/H5Rint.c b/src/H5Rint.c index cef1f0a..33ebe53 100644 --- a/src/H5Rint.c +++ b/src/H5Rint.c @@ -35,6 +35,8 @@ #include "H5Sprivate.h" /* Dataspaces */ #include "H5Tprivate.h" /* Datatypes */ +#include "H5VLnative_private.h" /* Native VOL connector */ + /****************/ /* Local Macros */ /****************/ @@ -93,9 +95,29 @@ HDfflush(stdout); \ } while (0) static const char * -H5R__print_token(const H5VL_token_t token) { +H5R__print_token(const H5O_token_t token) { static char string[64]; - HDsnprintf(string, 64, "%zu", *(haddr_t *)token); + + /* Print the raw token. */ + HDsnprintf(string, 64, "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X", + (unsigned char)token.__data[15], + (unsigned char)token.__data[14], + (unsigned char)token.__data[13], + (unsigned char)token.__data[12], + (unsigned char)token.__data[11], + (unsigned char)token.__data[10], + (unsigned char)token.__data[9], + (unsigned char)token.__data[8], + (unsigned char)token.__data[7], + (unsigned char)token.__data[6], + (unsigned char)token.__data[5], + (unsigned char)token.__data[4], + (unsigned char)token.__data[3], + (unsigned char)token.__data[2], + (unsigned char)token.__data[1], + (unsigned char)token.__data[0] + ); + return string; } #else @@ -110,8 +132,8 @@ H5R__print_token(const H5VL_token_t token) { /* Local Prototypes */ /********************/ -static herr_t H5R__encode_obj_token(const H5VL_token_t *obj_token, size_t token_size, unsigned char *buf, size_t *nalloc); -static herr_t H5R__decode_obj_token(const unsigned char *buf, size_t *nbytes, H5VL_token_t *obj_token, uint8_t *token_size); +static herr_t H5R__encode_obj_token(const H5O_token_t *obj_token, size_t token_size, unsigned char *buf, size_t *nalloc); +static herr_t H5R__decode_obj_token(const unsigned char *buf, size_t *nbytes, H5O_token_t *obj_token, uint8_t *token_size); static herr_t H5R__encode_region(H5S_t *space, unsigned char *buf, size_t *nalloc); static herr_t H5R__decode_region(const unsigned char *buf, size_t *nbytes, H5S_t **space_ptr); static herr_t H5R__encode_string(const char *string, unsigned char *buf, size_t *nalloc); @@ -240,14 +262,14 @@ H5R_term_package(void) /*------------------------------------------------------------------------- * Function: H5R__create_object * - * Purpose: Creates an object reference. + * Purpose: Creates an object reference * - * Return: Non-negative on success/Negative on failure + * Return: SUCCEED/FAIL * *------------------------------------------------------------------------- */ herr_t -H5R__create_object(const H5VL_token_t *obj_token, size_t token_size, +H5R__create_object(const H5O_token_t *obj_token, size_t token_size, H5R_ref_priv_t *ref) { size_t encode_size; @@ -258,11 +280,11 @@ H5R__create_object(const H5VL_token_t *obj_token, size_t token_size, HDassert(ref); /* Create new reference */ - H5MM_memcpy(&ref->ref.obj.token, obj_token, token_size); - ref->ref.obj.filename = NULL; + ref->info.obj.filename = NULL; ref->loc_id = H5I_INVALID_HID; ref->type = (uint8_t)H5R_OBJECT2; - ref->token_size = (uint8_t)token_size; + if(H5R__set_obj_token(ref, obj_token, token_size) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTSET, FAIL, "unable to set object token") /* Cache encoding size (assume no external reference) */ if(H5R__encode(NULL, ref, NULL, &encode_size, 0) < 0) @@ -270,7 +292,7 @@ H5R__create_object(const H5VL_token_t *obj_token, size_t token_size, ref->encode_size = (uint32_t)encode_size; H5R_LOG_DEBUG("Created object reference, %d, filename=%s, obj_addr=%s, encode size=%u", - (int)sizeof(H5R_ref_priv_t), ref->ref.obj.filename, H5R__print_token(ref->ref.obj.token), + (int)sizeof(H5R_ref_priv_t), ref->info.obj.filename, H5R__print_token(ref->info.obj.token), ref->encode_size); done: @@ -281,14 +303,14 @@ done: /*------------------------------------------------------------------------- * Function: H5R__create_region * - * Purpose: Creates a region reference. + * Purpose: Creates a region reference * - * Return: Non-negative on success/Negative on failure + * Return: SUCCEED/FAIL * *------------------------------------------------------------------------- */ herr_t -H5R__create_region(const H5VL_token_t *obj_token, size_t token_size, +H5R__create_region(const H5O_token_t *obj_token, size_t token_size, H5S_t *space, H5R_ref_priv_t *ref) { size_t encode_size; @@ -300,14 +322,14 @@ H5R__create_region(const H5VL_token_t *obj_token, size_t token_size, HDassert(ref); /* Create new reference */ - H5MM_memcpy(&ref->ref.obj.token, obj_token, token_size); - ref->ref.obj.filename = NULL; - if(NULL == (ref->ref.reg.space = H5S_copy(space, FALSE, TRUE))) + ref->info.obj.filename = NULL; + if(NULL == (ref->info.reg.space = H5S_copy(space, FALSE, TRUE))) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTCOPY, FAIL, "unable to copy dataspace") ref->loc_id = H5I_INVALID_HID; ref->type = (uint8_t)H5R_DATASET_REGION2; - ref->token_size = (uint8_t)token_size; + if(H5R__set_obj_token(ref, obj_token, token_size) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTSET, FAIL, "unable to set object token") /* Cache encoding size (assume no external reference) */ if(H5R__encode(NULL, ref, NULL, &encode_size, 0) < 0) @@ -315,14 +337,14 @@ H5R__create_region(const H5VL_token_t *obj_token, size_t token_size, ref->encode_size = (uint32_t)encode_size; H5R_LOG_DEBUG("Created region reference, %d, filename=%s, obj_addr=%s, encode size=%u", - (int)sizeof(H5R_ref_priv_t), ref->ref.obj.filename, H5R__print_token(ref->ref.obj.token), + (int)sizeof(H5R_ref_priv_t), ref->info.obj.filename, H5R__print_token(ref->info.obj.token), ref->encode_size); done: if(ret_value < 0) - if(ref->ref.reg.space) { - H5S_close(ref->ref.reg.space); - ref->ref.reg.space = NULL; + if(ref->info.reg.space) { + H5S_close(ref->info.reg.space); + ref->info.reg.space = NULL; } /* end if */ FUNC_LEAVE_NOAPI(ret_value) @@ -332,14 +354,14 @@ done: /*------------------------------------------------------------------------- * Function: H5R__create_attr * - * Purpose: Creates an attribute reference. + * Purpose: Creates an attribute reference * - * Return: Non-negative on success/Negative on failure + * Return: SUCCEED/FAIL * *------------------------------------------------------------------------- */ herr_t -H5R__create_attr(const H5VL_token_t *obj_token, size_t token_size, +H5R__create_attr(const H5O_token_t *obj_token, size_t token_size, const char *attr_name, H5R_ref_priv_t *ref) { size_t encode_size; @@ -355,14 +377,14 @@ H5R__create_attr(const H5VL_token_t *obj_token, size_t token_size, HGOTO_ERROR(H5E_REFERENCE, H5E_ARGS, FAIL, "attribute name too long (%d > %d)", (int)HDstrlen(attr_name), H5R_MAX_STRING_LEN) /* Create new reference */ - H5MM_memcpy(&ref->ref.obj.token, obj_token, token_size); - ref->ref.obj.filename = NULL; - if(NULL == (ref->ref.attr.name = HDstrdup(attr_name))) + ref->info.obj.filename = NULL; + if(NULL == (ref->info.attr.name = HDstrdup(attr_name))) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTCOPY, FAIL, "Cannot copy attribute name") ref->loc_id = H5I_INVALID_HID; ref->type = (uint8_t)H5R_ATTR; - ref->token_size = (uint8_t)token_size; + if(H5R__set_obj_token(ref, obj_token, token_size) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTSET, FAIL, "unable to set object token") /* Cache encoding size (assume no external reference) */ if(H5R__encode(NULL, ref, NULL, &encode_size, 0) < 0) @@ -370,13 +392,13 @@ H5R__create_attr(const H5VL_token_t *obj_token, size_t token_size, ref->encode_size = (uint32_t)encode_size; H5R_LOG_DEBUG("Created attribute reference, %d, filename=%s, obj_addr=%s, attr name=%s, encode size=%u", - (int)sizeof(H5R_ref_priv_t), ref->ref.obj.filename, H5R__print_token(ref->ref.obj.token), - ref->ref.attr.name, ref->encode_size); + (int)sizeof(H5R_ref_priv_t), ref->info.obj.filename, H5R__print_token(ref->info.obj.token), + ref->info.attr.name, ref->encode_size); done: if(ret_value < 0) { - H5MM_xfree(ref->ref.attr.name); - ref->ref.attr.name = NULL; + H5MM_xfree(ref->info.attr.name); + ref->info.attr.name = NULL; } /* end if */ FUNC_LEAVE_NOAPI(ret_value) @@ -386,9 +408,9 @@ done: /*------------------------------------------------------------------------- * Function: H5R__destroy * - * Purpose: Destroy reference. + * Purpose: Destroy a reference * - * Return: Non-negative on success/Negative on failure + * Return: SUCCEED/FAIL * *------------------------------------------------------------------------- */ @@ -401,22 +423,22 @@ H5R__destroy(H5R_ref_priv_t *ref) HDassert(ref != NULL); - H5MM_xfree(ref->ref.obj.filename); - ref->ref.obj.filename = NULL; + H5MM_xfree(ref->info.obj.filename); + ref->info.obj.filename = NULL; switch(ref->type) { case H5R_OBJECT2: break; case H5R_DATASET_REGION2: - if(H5S_close(ref->ref.reg.space) < 0) + if(H5S_close(ref->info.reg.space) < 0) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTFREE, FAIL, "Cannot close dataspace") - ref->ref.reg.space = NULL; + ref->info.reg.space = NULL; break; case H5R_ATTR: - H5MM_xfree(ref->ref.attr.name); - ref->ref.attr.name = NULL; + H5MM_xfree(ref->info.attr.name); + ref->info.attr.name = NULL; break; case H5R_OBJECT1: @@ -451,9 +473,9 @@ done: /*------------------------------------------------------------------------- * Function: H5R__set_loc_id * - * Purpose: Attach location ID to reference and increment location refcount. + * Purpose: Attach location ID to reference and increment location refcount. * - * Return: Non-negative on success/Negative on failure + * Return: SUCCEED/FAIL * *------------------------------------------------------------------------- */ @@ -496,9 +518,9 @@ done: /*------------------------------------------------------------------------- * Function: H5R__get_loc_id * - * Purpose: Retrieve location ID attached to existing reference. + * Purpose: Retrieve location ID attached to existing reference. * - * Return: Valid ID on success/Negative on failure + * Return: Valid ID on success / H5I_INVALID_HID on failure * *------------------------------------------------------------------------- */ @@ -520,9 +542,9 @@ H5R__get_loc_id(const H5R_ref_priv_t *ref) /*------------------------------------------------------------------------- * Function: H5R__reopen_file * - * Purpose: Re-open referenced file using file access property list. + * Purpose: Re-open referenced file using file access property list. * - * Return: Valid ID on success/Negative on failure + * Return: Valid ID on success / H5I_INVALID_HID on failure * *------------------------------------------------------------------------- */ @@ -589,9 +611,10 @@ done: /*------------------------------------------------------------------------- * Function: H5R__get_type * - * Purpose: Given a reference to some object, return the type of that reference. + * Purpose: Given a reference to some object, return the type of that + * reference. * - * Return: Type of the reference + * Return: Type of the reference * *------------------------------------------------------------------------- */ @@ -612,9 +635,9 @@ H5R__get_type(const H5R_ref_priv_t *ref) /*------------------------------------------------------------------------- * Function: H5R__equal * - * Purpose: Compare two references + * Purpose: Compare two references * - * Return: TRUE if equal, FALSE if unequal, FAIL if error + * Return: TRUE if equal, FALSE if unequal, FAIL if error * *------------------------------------------------------------------------- */ @@ -635,27 +658,27 @@ H5R__equal(const H5R_ref_priv_t *ref1, const H5R_ref_priv_t *ref2) /* Compare object addresses */ if(ref1->token_size != ref2->token_size) HGOTO_DONE(FALSE); - if(0 != HDmemcmp(&ref1->ref.obj.token, &ref2->ref.obj.token, ref1->token_size)) + if(0 != HDmemcmp(&ref1->info.obj.token, &ref2->info.obj.token, ref1->token_size)) HGOTO_DONE(FALSE); /* Compare filenames */ - if((ref1->ref.obj.filename && (NULL == ref2->ref.obj.filename)) - || ((NULL == ref1->ref.obj.filename) && ref2->ref.obj.filename)) + if((ref1->info.obj.filename && (NULL == ref2->info.obj.filename)) + || ((NULL == ref1->info.obj.filename) && ref2->info.obj.filename)) HGOTO_DONE(FALSE); - if(ref1->ref.obj.filename && ref1->ref.obj.filename - && (0 != HDstrcmp(ref1->ref.obj.filename, ref2->ref.obj.filename))) + if(ref1->info.obj.filename && ref1->info.obj.filename + && (0 != HDstrcmp(ref1->info.obj.filename, ref2->info.obj.filename))) HGOTO_DONE(FALSE); switch(ref1->type) { case H5R_OBJECT2: break; case H5R_DATASET_REGION2: - if((ret_value = H5S_extent_equal(ref1->ref.reg.space, ref2->ref.reg.space)) < 0) + if((ret_value = H5S_extent_equal(ref1->info.reg.space, ref2->info.reg.space)) < 0) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTCOMPARE, FAIL, "cannot compare dataspace extents") break; case H5R_ATTR: - HDassert(ref1->ref.attr.name && ref2->ref.attr.name); - if(0 != HDstrcmp(ref1->ref.attr.name, ref2->ref.attr.name)) + HDassert(ref1->info.attr.name && ref2->info.attr.name); + if(0 != HDstrcmp(ref1->info.attr.name, ref2->info.attr.name)) HGOTO_DONE(FALSE); break; case H5R_OBJECT1: @@ -677,9 +700,9 @@ done: /*------------------------------------------------------------------------- * Function: H5R__copy * - * Purpose: Copy a reference + * Purpose: Copy a reference * - * Return: Non-negative on success/Negative on failure + * Return: SUCCEED/FAIL * *------------------------------------------------------------------------- */ @@ -692,7 +715,7 @@ H5R__copy(const H5R_ref_priv_t *src_ref, H5R_ref_priv_t *dst_ref) HDassert((src_ref != NULL) && (dst_ref != NULL)); - H5MM_memcpy(&dst_ref->ref.obj.token, &src_ref->ref.obj.token, src_ref->token_size); + H5MM_memcpy(&dst_ref->info.obj.token, &src_ref->info.obj.token, sizeof(H5O_token_t)); dst_ref->encode_size = src_ref->encode_size; dst_ref->type = src_ref->type; dst_ref->token_size = src_ref->token_size; @@ -701,11 +724,11 @@ H5R__copy(const H5R_ref_priv_t *src_ref, H5R_ref_priv_t *dst_ref) case H5R_OBJECT2: break; case H5R_DATASET_REGION2: - if(NULL == (dst_ref->ref.reg.space = H5S_copy(src_ref->ref.reg.space, FALSE, TRUE))) + if(NULL == (dst_ref->info.reg.space = H5S_copy(src_ref->info.reg.space, FALSE, TRUE))) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTCOPY, FAIL, "unable to copy dataspace") break; case H5R_ATTR: - if(NULL == (dst_ref->ref.attr.name = HDstrdup(src_ref->ref.attr.name))) + if(NULL == (dst_ref->info.attr.name = HDstrdup(src_ref->info.attr.name))) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTCOPY, FAIL, "Cannot copy attribute name") break; case H5R_OBJECT1: @@ -721,13 +744,14 @@ H5R__copy(const H5R_ref_priv_t *src_ref, H5R_ref_priv_t *dst_ref) /* We only need to keep a copy of the filename if we don't have the loc_id */ if(src_ref->loc_id == H5I_INVALID_HID) { - HDassert(src_ref->ref.obj.filename); + HDassert(src_ref->info.obj.filename); - if(NULL == (dst_ref->ref.obj.filename = HDstrdup(src_ref->ref.obj.filename))) + if(NULL == (dst_ref->info.obj.filename = HDstrdup(src_ref->info.obj.filename))) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTCOPY, FAIL, "Cannot copy filename") dst_ref->loc_id = H5I_INVALID_HID; - } else { - dst_ref->ref.obj.filename = NULL; + } + else { + dst_ref->info.obj.filename = NULL; /* Set location ID and hold reference to it */ if(H5R__set_loc_id(dst_ref, src_ref->loc_id, TRUE, TRUE) < 0) @@ -742,14 +766,14 @@ done: /*------------------------------------------------------------------------- * Function: H5R__get_obj_token * - * Purpose: Given a reference to some object, get the encoded object addr. + * Purpose: Given a reference to some object, get the encoded token. * - * Return: Non-negative on success/Negative on failure + * Return: SUCCEED/FAIL * *------------------------------------------------------------------------- */ herr_t -H5R__get_obj_token(const H5R_ref_priv_t *ref, H5VL_token_t *obj_token, +H5R__get_obj_token(const H5R_ref_priv_t *ref, H5O_token_t *obj_token, size_t *token_size) { herr_t ret_value = SUCCEED; /* Return value */ @@ -757,12 +781,12 @@ H5R__get_obj_token(const H5R_ref_priv_t *ref, H5VL_token_t *obj_token, FUNC_ENTER_PACKAGE HDassert(ref != NULL); - HDassert(ref->token_size <= H5VL_MAX_TOKEN_SIZE); + HDassert(ref->token_size <= H5O_MAX_TOKEN_SIZE); if(obj_token) { if(0 == ref->token_size) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTCOPY, FAIL, "NULL token size") - H5MM_memcpy(obj_token, &ref->ref.obj.token, ref->token_size); + H5MM_memcpy(obj_token, &ref->info.obj.token, sizeof(H5O_token_t)); } if(token_size) *token_size = ref->token_size; @@ -775,14 +799,14 @@ done: /*------------------------------------------------------------------------- * Function: H5R__set_obj_token * - * Purpose: Given a reference to some object, set the encoded object addr. + * Purpose: Given a reference to some object, set the encoded token. * - * Return: Non-negative on success/Negative on failure + * Return: SUCCEED/FAIL * *------------------------------------------------------------------------- */ herr_t -H5R__set_obj_token(H5R_ref_priv_t *ref, const H5VL_token_t *obj_token, +H5R__set_obj_token(H5R_ref_priv_t *ref, const H5O_token_t *obj_token, size_t token_size) { herr_t ret_value = SUCCEED; /* Return value */ @@ -792,9 +816,9 @@ H5R__set_obj_token(H5R_ref_priv_t *ref, const H5VL_token_t *obj_token, HDassert(ref != NULL); HDassert(obj_token); HDassert(token_size); - HDassert(token_size <= H5VL_MAX_TOKEN_SIZE); + HDassert(token_size <= H5O_MAX_TOKEN_SIZE); - H5MM_memcpy(&ref->ref.obj.token, obj_token, ref->token_size); + H5MM_memcpy(&ref->info.obj.token, obj_token, sizeof(H5O_token_t)); ref->token_size = (uint8_t)token_size; FUNC_LEAVE_NOAPI(ret_value) @@ -804,11 +828,11 @@ H5R__set_obj_token(H5R_ref_priv_t *ref, const H5VL_token_t *obj_token, /*------------------------------------------------------------------------- * Function: H5R__get_region * - * Purpose: Given a reference to some object, creates a copy of the dataset - * pointed to's dataspace and defines a selection in the copy which is the - * region pointed to. + * Purpose: Given a reference to some object, creates a copy of the + * dataset pointed to's dataspace and defines a selection in + * the copy which is the region pointed to. * - * Return: Pointer to the dataspace on success/NULL on failure + * Return: SUCCEED/FAIL * *------------------------------------------------------------------------- */ @@ -824,7 +848,7 @@ H5R__get_region(const H5R_ref_priv_t *ref, H5S_t *space) HDassert(space); /* Copy reference selection to destination */ - if(H5S_select_copy(space, ref->ref.reg.space, FALSE) < 0) + if(H5S_select_copy(space, ref->info.reg.space, FALSE) < 0) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTCOPY, FAIL, "unable to copy selection") done: @@ -835,10 +859,10 @@ done: /*------------------------------------------------------------------------- * Function: H5R__get_file_name * - * Purpose: Given a reference to some object, determine a file name of the - * object located into. + * Purpose: Given a reference to some object, determine a file name of + * the object located into. * - * Return: Non-negative length of the path on success/Negative on failure + * Return: Non-negative length of the path on success / -1 on failure * *------------------------------------------------------------------------- */ @@ -854,17 +878,17 @@ H5R__get_file_name(const H5R_ref_priv_t *ref, char *buf, size_t size) HDassert(ref != NULL); /* Return if that reference has no filename set */ - if(!ref->ref.obj.filename) + if(!ref->info.obj.filename) HGOTO_ERROR(H5E_REFERENCE, H5E_ARGS, (-1), "no filename available for that reference") /* Get the file name length */ - copy_len = HDstrlen(ref->ref.obj.filename); + copy_len = HDstrlen(ref->info.obj.filename); HDassert(copy_len <= H5R_MAX_STRING_LEN); /* Copy the file name */ if(buf) { copy_len = MIN(copy_len, size - 1); - H5MM_memcpy(buf, ref->ref.obj.filename, copy_len); + H5MM_memcpy(buf, ref->info.obj.filename, copy_len); buf[copy_len] = '\0'; } ret_value = (ssize_t)(copy_len + 1); @@ -877,9 +901,9 @@ done: /*------------------------------------------------------------------------- * Function: H5R__get_attr_name * - * Purpose: Given a reference to some attribute, determine its name. + * Purpose: Given a reference to some attribute, determine its name. * - * Return: Non-negative length of the path on success/Negative on failure + * Return: Non-negative length of the path on success / -1 on failure * *------------------------------------------------------------------------- */ @@ -896,13 +920,13 @@ H5R__get_attr_name(const H5R_ref_priv_t *ref, char *buf, size_t size) HDassert(ref->type == H5R_ATTR); /* Get the attribute name length */ - attr_name_len = HDstrlen(ref->ref.attr.name); + attr_name_len = HDstrlen(ref->info.attr.name); HDassert(attr_name_len <= H5R_MAX_STRING_LEN); /* Get the attribute name */ if(buf) { size_t copy_len = MIN(attr_name_len, size - 1); - H5MM_memcpy(buf, ref->ref.attr.name, copy_len); + H5MM_memcpy(buf, ref->info.attr.name, copy_len); buf[copy_len] = '\0'; } @@ -915,9 +939,9 @@ H5R__get_attr_name(const H5R_ref_priv_t *ref, char *buf, size_t size) /*------------------------------------------------------------------------- * Function: H5R__encode * - * Purpose: Private function for H5Rencode. + * Purpose: Private function for H5Rencode * - * Return: Non-negative on success/Negative on failure + * Return: SUCCEED/FAIL * *------------------------------------------------------------------------- */ @@ -959,7 +983,7 @@ H5R__encode(const char *filename, const H5R_ref_priv_t *ref, unsigned char *buf, encode_size += H5R_ENCODE_HEADER_SIZE; /* Encode object token */ - H5R_ENCODE_VAR(H5R__encode_obj_token, &ref->ref.obj.token, ref->token_size, + H5R_ENCODE_VAR(H5R__encode_obj_token, &ref->info.obj.token, ref->token_size, p, buf_size, encode_size, "Cannot encode object address"); /** @@ -981,13 +1005,13 @@ H5R__encode(const char *filename, const H5R_ref_priv_t *ref, unsigned char *buf, case H5R_DATASET_REGION2: /* Encode dataspace */ - H5R_ENCODE(H5R__encode_region, ref->ref.reg.space, p, buf_size, + H5R_ENCODE(H5R__encode_region, ref->info.reg.space, p, buf_size, encode_size, "Cannot encode region"); break; case H5R_ATTR: /* Encode attribute name */ - H5R_ENCODE(H5R__encode_string, ref->ref.attr.name, p, buf_size, + H5R_ENCODE(H5R__encode_string, ref->info.attr.name, p, buf_size, encode_size, "Cannot encode attribute name"); break; @@ -1013,9 +1037,9 @@ done: /*------------------------------------------------------------------------- * Function: H5R__decode * - * Purpose: Private function for H5Rdecode. + * Purpose: Private function for H5Rdecode * - * Return: Non-negative on success/Negative on failure + * Return: SUCCEED/FAIL * *------------------------------------------------------------------------- */ @@ -1050,28 +1074,29 @@ H5R__decode(const unsigned char *buf, size_t *nbytes, H5R_ref_priv_t *ref) decode_size += H5R_ENCODE_HEADER_SIZE; /* Decode object token */ - H5R_DECODE_VAR(H5R__decode_obj_token, &ref->ref.obj.token, &ref->token_size, + H5R_DECODE_VAR(H5R__decode_obj_token, &ref->info.obj.token, &ref->token_size, p, buf_size, decode_size, "Cannot decode object address"); /* We do not need to store the filename if the reference is internal */ if(flags & H5R_IS_EXTERNAL) { /* Decode file name */ - H5R_DECODE(H5R__decode_string, &ref->ref.obj.filename, p, buf_size, + H5R_DECODE(H5R__decode_string, &ref->info.obj.filename, p, buf_size, decode_size, "Cannot decode filename"); - } else - ref->ref.obj.filename = NULL; + } + else + ref->info.obj.filename = NULL; switch(ref->type) { case H5R_OBJECT2: break; case H5R_DATASET_REGION2: /* Decode dataspace */ - H5R_DECODE(H5R__decode_region, &ref->ref.reg.space, p, buf_size, + H5R_DECODE(H5R__decode_region, &ref->info.reg.space, p, buf_size, decode_size, "Cannot decode region"); break; case H5R_ATTR: /* Decode attribute name */ - H5R_DECODE(H5R__decode_string, &ref->ref.attr.name, p, buf_size, + H5R_DECODE(H5R__decode_string, &ref->info.attr.name, p, buf_size, decode_size, "Cannot decode attribute name"); break; case H5R_OBJECT1: @@ -1092,7 +1117,7 @@ H5R__decode(const unsigned char *buf, size_t *nbytes, H5R_ref_priv_t *ref) ref->encode_size = (uint32_t)decode_size; H5R_LOG_DEBUG("Decoded reference, filename=%s, obj_addr=%s, encode size=%u", - ref->ref.obj.filename, H5R__print_token(ref->ref.obj.token), + ref->info.obj.filename, H5R__print_token(ref->info.obj.token), ref->encode_size); *nbytes = decode_size; @@ -1105,14 +1130,14 @@ done: /*------------------------------------------------------------------------- * Function: H5R__encode_obj_token * - * Purpose: Encode an object address. + * Purpose: Encode an object address. * - * Return: Non-negative on success/Negative on failure + * Return: SUCCEED/FAIL * *------------------------------------------------------------------------- */ static herr_t -H5R__encode_obj_token(const H5VL_token_t *obj_token, size_t token_size, +H5R__encode_obj_token(const H5O_token_t *obj_token, size_t token_size, unsigned char *buf, size_t *nalloc) { herr_t ret_value = SUCCEED; @@ -1140,15 +1165,15 @@ H5R__encode_obj_token(const H5VL_token_t *obj_token, size_t token_size, /*------------------------------------------------------------------------- * Function: H5R__decode_obj_token * - * Purpose: Decode an object address. + * Purpose: Decode an object address. * - * Return: Non-negative on success/Negative on failure + * Return: SUCCEED/FAIL * *------------------------------------------------------------------------- */ static herr_t H5R__decode_obj_token(const unsigned char *buf, size_t *nbytes, - H5VL_token_t *obj_token, uint8_t *token_size) + H5O_token_t *obj_token, uint8_t *token_size) { const uint8_t *p = (const uint8_t *)buf; herr_t ret_value = SUCCEED; @@ -1166,9 +1191,12 @@ H5R__decode_obj_token(const unsigned char *buf, size_t *nbytes, /* Get token size */ *token_size = *p++; - if(*token_size > sizeof(H5VL_token_t)) + if(*token_size > sizeof(H5O_token_t)) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDECODE, FAIL, "Invalid token size (%u)", *token_size) + /* Make sure that token is initialized */ + HDmemset(obj_token, 0, sizeof(H5O_token_t)); + /* Decode token */ H5MM_memcpy(obj_token, p, *token_size); @@ -1182,9 +1210,9 @@ done: /*------------------------------------------------------------------------- * Function: H5R__encode_region * - * Purpose: Encode a selection. + * Purpose: Encode a selection. * - * Return: Non-negative on success/Negative on failure + * Return: SUCCEED/FAIL * *------------------------------------------------------------------------- */ @@ -1231,9 +1259,9 @@ done: /*------------------------------------------------------------------------- * Function: H5R__decode_region * - * Purpose: Decode a selection. + * Purpose: Decode a selection. * - * Return: Non-negative on success/Negative on failure + * Return: SUCCEED/FAIL * *------------------------------------------------------------------------- */ @@ -1287,9 +1315,9 @@ done: /*------------------------------------------------------------------------- * Function: H5R__encode_string * - * Purpose: Encode a string. + * Purpose: Encode a string. * - * Return: Non-negative on success/Negative on failure + * Return: SUCCEED/FAIL * *------------------------------------------------------------------------- */ @@ -1329,9 +1357,9 @@ done: /*------------------------------------------------------------------------- * Function: H5R__decode_string * - * Purpose: Decode a string. + * Purpose: Decode a string. * - * Return: Non-negative on success/Negative on failure + * Return: SUCCEED/FAIL * *------------------------------------------------------------------------- */ @@ -1376,9 +1404,9 @@ done: /*------------------------------------------------------------------------- * Function: H5R__encode_heap * - * Purpose: Encode data and insert into heap (native only). + * Purpose: Encode data and insert into heap (native only). * - * Return: Non-negative on success/Negative on failure + * Return: SUCCEED/FAIL * *------------------------------------------------------------------------- */ @@ -1417,9 +1445,9 @@ done: /*------------------------------------------------------------------------- * Function: H5R__decode_heap * - * Purpose: Decode data inserted into heap (native only). + * Purpose: Decode data inserted into heap (native only). * - * Return: Non-negative on success/Negative on failure + * Return: SUCCEED/FAIL * *------------------------------------------------------------------------- */ @@ -1464,9 +1492,9 @@ done: /*------------------------------------------------------------------------- * Function: H5R__free_heap * - * Purpose: Remove data previously inserted into heap (native only). + * Purpose: Remove data previously inserted into heap (native only). * - * Return: Non-negative on success/Negative on failure + * Return: SUCCEED/FAIL * *------------------------------------------------------------------------- */ @@ -1509,15 +1537,15 @@ done: /*------------------------------------------------------------------------- * Function: H5R__decode_token_compat * - * Purpose: Decode an object token. (native only) + * Purpose: Decode an object token. (native only) * - * Return: Non-negative on success/Negative on failure + * Return: SUCCEED/FAIL * *------------------------------------------------------------------------- */ herr_t H5R__decode_token_compat(H5VL_object_t *vol_obj, H5I_type_t type, H5R_type_t ref_type, - const unsigned char *buf, H5VL_token_t *obj_token) + const unsigned char *buf, H5O_token_t *obj_token) { hid_t file_id = H5I_INVALID_HID; /* File ID for region reference */ H5VL_object_t *vol_obj_file = NULL; @@ -1581,14 +1609,14 @@ done: /*------------------------------------------------------------------------- * Function: H5R__encode_token_obj_compat * - * Purpose: Encode an object token. (native only) + * Purpose: Encode an object token. (native only) * - * Return: Non-negative on success/Negative on failure + * Return: SUCCEED/FAIL * *------------------------------------------------------------------------- */ herr_t -H5R__encode_token_obj_compat(const H5VL_token_t *obj_token, size_t token_size, +H5R__encode_token_obj_compat(const H5O_token_t *obj_token, size_t token_size, unsigned char *buf, size_t *nalloc) { herr_t ret_value = SUCCEED; @@ -1612,15 +1640,15 @@ H5R__encode_token_obj_compat(const H5VL_token_t *obj_token, size_t token_size, /*------------------------------------------------------------------------- * Function: H5R__decode_token_obj_compat * - * Purpose: Decode an object token. (native only) + * Purpose: Decode an object token. (native only) * - * Return: Non-negative on success/Negative on failure + * Return: SUCCEED/FAIL * *------------------------------------------------------------------------- */ herr_t H5R__decode_token_obj_compat(const unsigned char *buf, size_t *nbytes, - H5VL_token_t *obj_token, size_t token_size) + H5O_token_t *obj_token, size_t token_size) { herr_t ret_value = SUCCEED; @@ -1647,14 +1675,15 @@ done: /*------------------------------------------------------------------------- * Function: H5R__encode_token_region_compat * - * Purpose: Encode dataset selection and insert data into heap (native only). + * Purpose: Encode dataset selection and insert data into heap + * (native only). * - * Return: Non-negative on success/Negative on failure + * Return: SUCCEED/FAIL * *------------------------------------------------------------------------- */ herr_t -H5R__encode_token_region_compat(H5F_t *f, const H5VL_token_t *obj_token, +H5R__encode_token_region_compat(H5F_t *f, const H5O_token_t *obj_token, size_t token_size, H5S_t *space, unsigned char *buf, size_t *nalloc) { size_t buf_size; @@ -1722,19 +1751,20 @@ done: /*------------------------------------------------------------------------- * Function: H5R__decode_token_region_compat * - * Purpose: Decode dataset selection from data inserted into heap (native only). + * Purpose: Decode dataset selection from data inserted into heap + * (native only). * - * Return: Non-negative on success/Negative on failure + * Return: SUCCEED/FAIL * *------------------------------------------------------------------------- */ herr_t H5R__decode_token_region_compat(H5F_t *f, const unsigned char *buf, - size_t *nbytes, H5VL_token_t *obj_token, size_t token_size, + size_t *nbytes, H5O_token_t *obj_token, size_t token_size, H5S_t **space_ptr) { unsigned char *data = NULL; - H5VL_token_t token = { 0 }; + H5O_token_t token = { 0 }; size_t data_size; const uint8_t *p; herr_t ret_value = SUCCEED; @@ -1758,12 +1788,13 @@ H5R__decode_token_region_compat(H5F_t *f, const unsigned char *buf, if(space_ptr) { H5O_loc_t oloc; /* Object location */ H5S_t *space = NULL; - const uint8_t *q = (const uint8_t *)&token; /* Initialize the object location */ H5O_loc_reset(&oloc); oloc.file = f; - H5F_addr_decode(f, &q, &oloc.addr); + + if(H5VL_native_token_to_addr(f, H5I_FILE, token, &oloc.addr) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTUNSERIALIZE, FAIL, "can't deserialize object token into address") /* Open and copy the dataset's dataspace */ if(NULL == (space = H5S_read(&oloc))) @@ -1776,9 +1807,10 @@ H5R__decode_token_region_compat(H5F_t *f, const unsigned char *buf, *space_ptr = space; } if(obj_token) - H5MM_memcpy(obj_token, &token, token_size); + H5MM_memcpy(obj_token, &token, sizeof(H5O_token_t)); done: H5MM_free(data); FUNC_LEAVE_NOAPI(ret_value) } /* end H5R__decode_token_region_compat() */ + diff --git a/src/H5Rpkg.h b/src/H5Rpkg.h index 4dbc656..36cf805 100644 --- a/src/H5Rpkg.h +++ b/src/H5Rpkg.h @@ -40,8 +40,8 @@ #define H5R_IS_EXTERNAL 0x1 /* Set when encoding reference to external file */ /* Macros for convenience */ -#define H5R_REF_FILENAME(x) ((x)->ref.obj.filename) -#define H5R_REF_ATTRNAME(x) ((x)->ref.attr.name) +#define H5R_REF_FILENAME(x) ((x)->info.obj.filename) +#define H5R_REF_ATTRNAME(x) ((x)->info.attr.name) /* Header size */ #define H5R_ENCODE_HEADER_SIZE (2 * H5_SIZEOF_UINT8_T) @@ -52,7 +52,7 @@ /* Object reference */ typedef struct H5R_ref_priv_obj_t { - H5VL_token_t token; /* Object token */ + H5O_token_t token; /* Object token */ char *filename; /* File name */ } H5R_ref_priv_obj_t; @@ -74,7 +74,7 @@ typedef struct H5R_ref_priv_t { H5R_ref_priv_obj_t obj;/* Object reference */ H5R_ref_priv_reg_t reg;/* Region reference */ H5R_ref_priv_attr_t attr;/* Attribute Reference */ - } ref; + } info; hid_t loc_id; /* Cached location identifier */ uint32_t encode_size; /* Cached encoding size */ int8_t type; /* Reference type */ @@ -90,9 +90,9 @@ typedef struct H5R_ref_priv_t { /******************************/ /* Package Private Prototypes */ /******************************/ -H5_DLL herr_t H5R__create_object(const H5VL_token_t *obj_token, size_t token_size, H5R_ref_priv_t *ref); -H5_DLL herr_t H5R__create_region(const H5VL_token_t *obj_token, size_t token_size, H5S_t *space, H5R_ref_priv_t *ref); -H5_DLL herr_t H5R__create_attr(const H5VL_token_t *obj_token, size_t token_size, const char *attr_name, H5R_ref_priv_t *ref); +H5_DLL herr_t H5R__create_object(const H5O_token_t *obj_token, size_t token_size, H5R_ref_priv_t *ref); +H5_DLL herr_t H5R__create_region(const H5O_token_t *obj_token, size_t token_size, H5S_t *space, H5R_ref_priv_t *ref); +H5_DLL herr_t H5R__create_attr(const H5O_token_t *obj_token, size_t token_size, const char *attr_name, H5R_ref_priv_t *ref); H5_DLL herr_t H5R__destroy(H5R_ref_priv_t *ref); H5_DLL herr_t H5R__set_loc_id(H5R_ref_priv_t *ref, hid_t id, hbool_t inc_ref, hbool_t app_ref); @@ -103,8 +103,8 @@ H5_DLL H5R_type_t H5R__get_type(const H5R_ref_priv_t *ref); H5_DLL htri_t H5R__equal(const H5R_ref_priv_t *ref1, const H5R_ref_priv_t *ref2); H5_DLL herr_t H5R__copy(const H5R_ref_priv_t *src_ref, H5R_ref_priv_t *dst_ref); -H5_DLL herr_t H5R__get_obj_token(const H5R_ref_priv_t *ref, H5VL_token_t *obj_token, size_t *token_size); -H5_DLL herr_t H5R__set_obj_token(H5R_ref_priv_t *ref, const H5VL_token_t *obj_token, size_t token_size); +H5_DLL herr_t H5R__get_obj_token(const H5R_ref_priv_t *ref, H5O_token_t *obj_token, size_t *token_size); +H5_DLL herr_t H5R__set_obj_token(H5R_ref_priv_t *ref, const H5O_token_t *obj_token, size_t token_size); H5_DLL herr_t H5R__get_region(const H5R_ref_priv_t *ref, H5S_t *space); H5_DLL ssize_t H5R__get_file_name(const H5R_ref_priv_t *ref, char *buf, size_t size); @@ -118,13 +118,13 @@ H5_DLL herr_t H5R__encode_heap(H5F_t *f, unsigned char *buf, size_t *nalloc, c H5_DLL herr_t H5R__decode_heap(H5F_t *f, const unsigned char *buf, size_t *nbytes, unsigned char **data_ptr, size_t *data_size); H5_DLL herr_t H5R__free_heap(H5F_t *f, const unsigned char *buf, size_t nbytes); -H5_DLL herr_t H5R__decode_token_compat(H5VL_object_t *vol_obj, H5I_type_t type, H5R_type_t ref_type, const unsigned char *buf, H5VL_token_t *obj_token); +H5_DLL herr_t H5R__decode_token_compat(H5VL_object_t *vol_obj, H5I_type_t type, H5R_type_t ref_type, const unsigned char *buf, H5O_token_t *obj_token); -H5_DLL herr_t H5R__encode_token_obj_compat(const H5VL_token_t *obj_token, size_t token_size, unsigned char *buf, size_t *nalloc); -H5_DLL herr_t H5R__decode_token_obj_compat(const unsigned char *buf, size_t *nbytes, H5VL_token_t *obj_token, size_t token_size); +H5_DLL herr_t H5R__encode_token_obj_compat(const H5O_token_t *obj_token, size_t token_size, unsigned char *buf, size_t *nalloc); +H5_DLL herr_t H5R__decode_token_obj_compat(const unsigned char *buf, size_t *nbytes, H5O_token_t *obj_token, size_t token_size); -H5_DLL herr_t H5R__encode_token_region_compat(H5F_t *f, const H5VL_token_t *obj_token, size_t token_size, H5S_t *space, unsigned char *buf, size_t *nalloc); -H5_DLL herr_t H5R__decode_token_region_compat(H5F_t *f, const unsigned char *buf, size_t *nbytes, H5VL_token_t *obj_token, size_t token_size, H5S_t **space_ptr); +H5_DLL herr_t H5R__encode_token_region_compat(H5F_t *f, const H5O_token_t *obj_token, size_t token_size, H5S_t *space, unsigned char *buf, size_t *nalloc); +H5_DLL herr_t H5R__decode_token_region_compat(H5F_t *f, const unsigned char *buf, size_t *nbytes, H5O_token_t *obj_token, size_t token_size, H5S_t **space_ptr); #endif /* _H5Rpkg_H */ diff --git a/src/H5Rpublic.h b/src/H5Rpublic.h index cfbf3c8..13d82d7 100644 --- a/src/H5Rpublic.h +++ b/src/H5Rpublic.h @@ -80,7 +80,10 @@ typedef struct { * should always be used with the current reference API. */ typedef struct { - uint8_t __data[H5R_REF_BUF_SIZE]; + union { + uint8_t __data[H5R_REF_BUF_SIZE]; /* opaque data */ + int64_t align; /* ensures alignment */ + } u; } H5R_ref_t; /********************/ @@ -108,16 +111,16 @@ H5_DLL htri_t H5Requal(const H5R_ref_t *ref1_ptr, const H5R_ref_t *ref2_ptr); H5_DLL herr_t H5Rcopy(const H5R_ref_t *src_ref_ptr, H5R_ref_t *dst_ref_ptr); /* Dereference */ -H5_DLL hid_t H5Ropen_object(const H5R_ref_t *ref_ptr, hid_t rapl_id, hid_t oapl_id); -H5_DLL hid_t H5Ropen_region(const H5R_ref_t *ref_ptr, hid_t rapl_id, hid_t oapl_id); -H5_DLL hid_t H5Ropen_attr(const H5R_ref_t *ref_ptr, hid_t rapl_id, hid_t aapl_id); +H5_DLL hid_t H5Ropen_object(H5R_ref_t *ref_ptr, hid_t rapl_id, hid_t oapl_id); +H5_DLL hid_t H5Ropen_region(H5R_ref_t *ref_ptr, hid_t rapl_id, hid_t oapl_id); +H5_DLL hid_t H5Ropen_attr(H5R_ref_t *ref_ptr, hid_t rapl_id, hid_t aapl_id); /* Get type */ -H5_DLL herr_t H5Rget_obj_type3(const H5R_ref_t *ref_ptr, hid_t rapl_id, H5O_type_t *obj_type); +H5_DLL herr_t H5Rget_obj_type3(H5R_ref_t *ref_ptr, hid_t rapl_id, H5O_type_t *obj_type); /* Get name */ H5_DLL ssize_t H5Rget_file_name(const H5R_ref_t *ref_ptr, char *buf, size_t size); -H5_DLL ssize_t H5Rget_obj_name(const H5R_ref_t *ref_ptr, hid_t rapl_id, char *buf, size_t size); +H5_DLL ssize_t H5Rget_obj_name(H5R_ref_t *ref_ptr, hid_t rapl_id, char *buf, size_t size); H5_DLL ssize_t H5Rget_attr_name(const H5R_ref_t *ref_ptr, char *buf, size_t size); /* Symbols defined for compatibility with previous versions of the HDF5 API. diff --git a/src/H5Tcommit.c b/src/H5Tcommit.c index 5c848c2..1b922d5 100644 --- a/src/H5Tcommit.c +++ b/src/H5Tcommit.c @@ -106,7 +106,7 @@ H5Tcommit2(hid_t loc_id, const char *name, hid_t type_id, hid_t lcpl_id, void *data = NULL; /* VOL-managed datatype data */ H5VL_object_t *new_obj = NULL; /* VOL object that holds the datatype object and the VOL info */ H5T_t *dt = NULL; /* High level datatype object that wraps the VOL object */ - H5VL_object_t *vol_obj = NULL; /* object token of loc_id */ + H5VL_object_t *vol_obj = NULL; /* object of loc_id */ H5VL_loc_params_t loc_params; herr_t ret_value = SUCCEED; /* Return value */ @@ -273,7 +273,7 @@ H5Tcommit_anon(hid_t loc_id, hid_t type_id, hid_t tcpl_id, hid_t tapl_id) void *dt = NULL; /* datatype object created by VOL connector */ H5VL_object_t *new_obj = NULL; /* VOL object that holds the datatype object and the VOL info */ H5T_t *type = NULL; /* Datatype created */ - H5VL_object_t *vol_obj = NULL; /* object token of loc_id */ + H5VL_object_t *vol_obj = NULL; /* object of loc_id */ H5VL_loc_params_t loc_params; herr_t ret_value = SUCCEED; /* Return value */ @@ -568,8 +568,8 @@ done: hid_t H5Topen2(hid_t loc_id, const char *name, hid_t tapl_id) { - void *dt = NULL; /* datatype token created by VOL connector */ - H5VL_object_t *vol_obj = NULL; /* object token of loc_id */ + void *dt = NULL; /* datatype object created by VOL connector */ + H5VL_object_t *vol_obj = NULL; /* object of loc_id */ H5VL_loc_params_t loc_params; hid_t ret_value = H5I_INVALID_HID; /* Return value */ @@ -1096,7 +1096,7 @@ H5T_construct_datatype(H5VL_object_t *vol_obj) { ssize_t nalloc; void *buf = NULL; - H5T_t *dt = NULL; /* datatype token from VOL connector */ + H5T_t *dt = NULL; /* datatype object from VOL connector */ H5T_t *ret_value = NULL; FUNC_ENTER_NOAPI(NULL) diff --git a/src/H5Tdeprec.c b/src/H5Tdeprec.c index 9998317..2c98dc0 100644 --- a/src/H5Tdeprec.c +++ b/src/H5Tdeprec.c @@ -110,7 +110,7 @@ H5Tcommit1(hid_t loc_id, const char *name, hid_t type_id) void *data = NULL; /* VOL-managed datatype data */ H5VL_object_t *new_obj = NULL; /* VOL object that holds the datatype object and the VOL info */ H5T_t *dt = NULL; /* High level datatype object that wraps the VOL object */ - H5VL_object_t *vol_obj = NULL; /* Object token of loc_id */ + H5VL_object_t *vol_obj = NULL; /* Object of loc_id */ H5VL_loc_params_t loc_params; herr_t ret_value = SUCCEED; /* Return value */ @@ -175,8 +175,8 @@ done: hid_t H5Topen1(hid_t loc_id, const char *name) { - void *dt = NULL; /* Datatype token created by VOL connector */ - H5VL_object_t *vol_obj = NULL; /* Object token of loc_id */ + void *dt = NULL; /* Datatype object created by VOL connector */ + H5VL_object_t *vol_obj = NULL; /* Object of loc_id */ H5VL_loc_params_t loc_params; hid_t ret_value = H5I_INVALID_HID; /* Return value */ diff --git a/src/H5Tref.c b/src/H5Tref.c index 8288912..83604c1 100644 --- a/src/H5Tref.c +++ b/src/H5Tref.c @@ -46,7 +46,7 @@ /* For region compatibility support */ struct H5Tref_dsetreg { - H5VL_token_t token; /* Object token */ + H5O_token_t token; /* Object token */ H5S_t *space; /* Dataspace */ }; @@ -578,7 +578,7 @@ H5T__ref_mem_write(H5VL_object_t *src_file, const void *src_buf, size_t src_size { size_t token_size = H5F_SIZEOF_ADDR(src_f); - if(H5R__create_object((const H5VL_token_t *)src_buf, token_size, dst_ref) < 0) + if(H5R__create_object((const H5O_token_t *)src_buf, token_size, dst_ref) < 0) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTCREATE, FAIL, "unable to create object reference") } break; @@ -1024,7 +1024,7 @@ H5T__ref_obj_disk_read(H5VL_object_t *src_file, const void *src_buf, size_t src_ /* Get object address */ if(H5R__decode_token_obj_compat((const unsigned char *)src_buf, &src_size, - (H5VL_token_t *)dst_buf, H5F_SIZEOF_ADDR(src_f)) < 0) + (H5O_token_t *)dst_buf, H5F_SIZEOF_ADDR(src_f)) < 0) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDECODE, FAIL, "unable to get object address") done: diff --git a/src/H5VL.c b/src/H5VL.c index 9e83858..0e36bcd 100644 --- a/src/H5VL.c +++ b/src/H5VL.c @@ -249,6 +249,38 @@ done: /*------------------------------------------------------------------------- * Function: H5VLget_connector_id * + * Purpose: Retrieves the VOL connector ID for a given object ID. + * + * Return: A valid VOL connector ID. This ID will need to be closed + * using H5VLclose(). + * + * H5I_INVALID_HID on error. + * + * Programmer: Dana Robinson + * June 17, 2017 + * + *------------------------------------------------------------------------- + */ +hid_t +H5VLget_connector_id(hid_t obj_id) +{ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ + + FUNC_ENTER_API(H5I_INVALID_HID) + H5TRACE1("i", "i", obj_id); + + /* Get connector ID */ + if((ret_value = H5VL__get_connector_id(obj_id, TRUE)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTGET, H5I_INVALID_HID, "can't get VOL id") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5VLget_connector_id() */ + + +/*------------------------------------------------------------------------- + * Function: H5VLget_connector_id_by_name + * * Purpose: Retrieves the ID for a registered VOL connector. * * Return: A valid VOL connector ID if a connector by that name has @@ -264,7 +296,7 @@ done: *------------------------------------------------------------------------- */ hid_t -H5VLget_connector_id(const char *name) +H5VLget_connector_id_by_name(const char *name) { hid_t ret_value = H5I_INVALID_HID; /* Return value */ @@ -272,12 +304,12 @@ H5VLget_connector_id(const char *name) H5TRACE1("i", "*s", name); /* Get connector ID with this name */ - if((ret_value = H5VL__get_connector_id(name, TRUE)) < 0) + if((ret_value = H5VL__get_connector_id_by_name(name, TRUE)) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTGET, H5I_INVALID_HID, "can't get VOL id") done: FUNC_LEAVE_API(ret_value) -} /* end H5VLget_connector_id() */ +} /* end H5VLget_connector_id_by_name() */ /*------------------------------------------------------------------------- @@ -411,7 +443,7 @@ H5VLunregister_connector(hid_t vol_id) HGOTO_ERROR(H5E_VOL, H5E_BADTYPE, FAIL, "not a VOL connector ID") /* For the time being, we disallow unregistering the native VOL connector */ - if(H5I_INVALID_HID == (native_id = H5VL__get_connector_id(H5VL_NATIVE_NAME, FALSE))) + if(H5I_INVALID_HID == (native_id = H5VL__get_connector_id_by_name(H5VL_NATIVE_NAME, FALSE))) HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "unable to find the native VOL connector ID") if(vol_id == native_id) HGOTO_ERROR(H5E_VOL, H5E_BADVALUE, FAIL, "unregistering the native VOL connector is not allowed") diff --git a/src/H5VLcallback.c b/src/H5VLcallback.c index 30cbae1..e4ebb95 100644 --- a/src/H5VLcallback.c +++ b/src/H5VLcallback.c @@ -189,6 +189,12 @@ static herr_t H5VL__blob_specific(void *obj, const H5VL_class_t *cls, void *blob_id, H5VL_blob_specific_t specific_type, va_list arguments); static herr_t H5VL__blob_optional(void *obj, const H5VL_class_t *cls, void *blob_id, H5VL_blob_optional_t opt_type, va_list arguments); +static herr_t H5VL__token_cmp(void *obj, const H5VL_class_t *cls, + const H5O_token_t *token1, const H5O_token_t *token2, int *cmp_value); +static herr_t H5VL__token_to_str(void *obj, H5I_type_t obj_type, const H5VL_class_t *cls, + const H5O_token_t *token, char **token_str); +static herr_t H5VL__token_from_str(void *obj, H5I_type_t obj_type, const H5VL_class_t *cls, + const char *token_str, H5O_token_t *token); static herr_t H5VL__optional(void *obj, const H5VL_class_t *cls, int op_type, hid_t dxpl_id, void **req, va_list arguments); @@ -4713,7 +4719,7 @@ H5VL_link_create(H5VL_link_create_type_t create_type, const H5VL_object_t *vol_o const H5VL_loc_params_t *loc_params, hid_t lcpl_id, hid_t lapl_id, hid_t dxpl_id, void **req, ...) { - H5VL_object_t tmp_vol_obj; /* Temporary object token of */ + H5VL_object_t tmp_vol_obj; /* Temporary object */ va_list arguments; /* Argument list passed from the API call */ hbool_t arg_started = FALSE; /* Whether the va_list has been started */ hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ @@ -7280,6 +7286,383 @@ done: /*------------------------------------------------------------------------- + * Function: H5VL__token_cmp + * + * Purpose: Compares two VOL connector object tokens. Sets *cmp_value + * to positive if token1 is greater than token2, negative if + * token2 is greater than token1 and zero if token1 and + * token2 are equal. + * + * Return: Success: Non-negative + * Failure: Negative + * + *------------------------------------------------------------------------- + */ +static herr_t +H5VL__token_cmp(void *obj, const H5VL_class_t *cls, + const H5O_token_t *token1, const H5O_token_t *token2, int *cmp_value) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + /* Sanity checks */ + HDassert(obj); + HDassert(cls); + HDassert(cmp_value); + + /* Take care of cases where one or both pointers is NULL */ + if(token1 == NULL && token2 != NULL) + *cmp_value = -1; + else if(token1 != NULL && token2 == NULL) + *cmp_value = 1; + else if(token1 == NULL && token2 == NULL) + *cmp_value = 0; + else { + /* Use the class's token comparison routine to compare the tokens, + * if there is a callback, otherwise just compare the tokens as + * memory buffers. + */ + if(cls->token_cls.cmp) { + if((cls->token_cls.cmp)(obj, token1, token2, cmp_value) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTCOMPARE, FAIL, "can't compare object tokens") + } /* end if */ + else + *cmp_value = HDmemcmp(token1, token2, sizeof(H5O_token_t)); + } /* end else */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL__token_cmp() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_token_cmp + * + * Purpose: Compares two VOL connector object tokens. Sets *cmp_value + * to positive if token1 is greater than token2, negative if + * token2 is greater than token1 and zero if token1 and + * token2 are equal. + * + * Return: Success: Non-negative + * Failure: Negative + * + *------------------------------------------------------------------------- + */ +herr_t +H5VL_token_cmp(const H5VL_object_t *vol_obj, const H5O_token_t *token1, + const H5O_token_t *token2, int *cmp_value) +{ + hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Sanity checks */ + HDassert(vol_obj); + HDassert(cmp_value); + + /* Set wrapper info in API context */ + if(H5VL_set_vol_wrapper(vol_obj) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info") + vol_wrapper_set = TRUE; + + /* Call the corresponding internal VOL routine */ + if((ret_value = H5VL__token_cmp(vol_obj->data, vol_obj->connector->cls, token1, token2, cmp_value)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTCOMPARE, FAIL, "token compare failed") + +done: + /* Reset object wrapping info in API context */ + if(vol_wrapper_set && H5VL_reset_vol_wrapper() < 0) + HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info") + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_token_cmp() */ + + +/*--------------------------------------------------------------------------- + * Function: H5VLtoken_cmp + * + * Purpose: Compares two VOL connector object tokens + * + * Note: Both object tokens must be from the same VOL connector class + * + * Return: Success: Non-negative, with *cmp_value set to positive if + * token1 is greater than token2, negative if token2 + * is greater than token1 and zero if token1 and + * token2 are equal. + * Failure: Negative + * + *--------------------------------------------------------------------------- + */ +herr_t +H5VLtoken_cmp(void *obj, hid_t connector_id, const H5O_token_t *token1, + const H5O_token_t *token2, int *cmp_value) +{ + H5VL_class_t *cls; /* VOL connector's class struct */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API_NOINIT + H5TRACE5("e", "*xi*k*k*Is", obj, connector_id, token1, token2, cmp_value); + + /* Check args and get class pointer */ + if(NULL == obj) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid object") + if(NULL == (cls = (H5VL_class_t *)H5I_object_verify(connector_id, H5I_VOL))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID") + if(NULL == cmp_value) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid cmp_value pointer") + + /* Call the corresponding internal VOL routine */ + if(H5VL__token_cmp(obj, cls, token1, token2, cmp_value) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTCOMPARE, FAIL, "object token comparison failed") + +done: + FUNC_LEAVE_API_NOINIT(ret_value) +} /* end H5VLtoken_cmp() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL__token_to_str + * + * Purpose: Serialize a connector's object token into a string + * + * Return: Success: Non-negative + * Failure: Negative + * + *------------------------------------------------------------------------- + */ +static herr_t +H5VL__token_to_str(void *obj, H5I_type_t obj_type, const H5VL_class_t *cls, + const H5O_token_t *token, char **token_str) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + /* Sanity checks */ + HDassert(obj); + HDassert(cls); + HDassert(token); + HDassert(token_str); + + /* Use the class's token serialization routine on the token if there is a + * callback, otherwise just set the token_str to NULL. + */ + if(cls->token_cls.to_str) { + if((cls->token_cls.to_str)(obj, obj_type, token, token_str) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTSERIALIZE, FAIL, "can't serialize object token") + } /* end if */ + else + *token_str = NULL; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL__token_to_str() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_token_to_str + * + * Purpose: Serialize a connector's object token into a string + * + * Return: Success: Non-negative + * Failure: Negative + * + *------------------------------------------------------------------------- + */ +herr_t +H5VL_token_to_str(const H5VL_object_t *vol_obj, H5I_type_t obj_type, + const H5O_token_t *token, char **token_str) +{ + hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Sanity checks */ + HDassert(vol_obj); + HDassert(token); + HDassert(token_str); + + /* Set wrapper info in API context */ + if(H5VL_set_vol_wrapper(vol_obj) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info") + vol_wrapper_set = TRUE; + + /* Call the corresponding internal VOL routine */ + if((ret_value = H5VL__token_to_str(vol_obj->data, obj_type, vol_obj->connector->cls, token, token_str)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTSERIALIZE, FAIL, "token serialization failed") + +done: + /* Reset object wrapping info in API context */ + if(vol_wrapper_set && H5VL_reset_vol_wrapper() < 0) + HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info") + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_token_to_str() */ + + +/*--------------------------------------------------------------------------- + * Function: H5VLtoken_to_str + * + * Purpose: Serialize a connector's object token into a string + * + * Return: Success: Non-negative + * Failure: Negative + * + *--------------------------------------------------------------------------- + */ +herr_t +H5VLtoken_to_str(void *obj, H5I_type_t obj_type, hid_t connector_id, + const H5O_token_t *token, char **token_str) +{ + H5VL_class_t *cls; /* VOL connector's class struct */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API_NOINIT + H5TRACE5("e", "*xIti*k**s", obj, obj_type, connector_id, token, token_str); + + /* Check args and get class pointer */ + if(NULL == obj) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid object") + if(NULL == (cls = (H5VL_class_t *)H5I_object_verify(connector_id, H5I_VOL))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID") + if(NULL == token) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid token pointer") + if(NULL == token_str) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid token_str pointer") + + /* Call the corresponding internal VOL routine */ + if(H5VL__token_to_str(obj, obj_type, cls, token, token_str) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTSERIALIZE, FAIL, "object token to string failed") + +done: + FUNC_LEAVE_API_NOINIT(ret_value) +} /* end H5VLtoken_to_str() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL__token_from_str + * + * Purpose: Deserialize a string into a connector object token + * + * Return: Success: Non-negative + * Failure: Negative + * + *------------------------------------------------------------------------- + */ +static herr_t +H5VL__token_from_str(void *obj, H5I_type_t obj_type, const H5VL_class_t *cls, + const char *token_str, H5O_token_t *token) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + /* Sanity checks */ + HDassert(obj); + HDassert(cls); + HDassert(token_str); + HDassert(token); + + /* Use the class's token deserialization routine on the token if there is a + * callback, otherwise just set the token to H5_TOKEN_UNDEF. + */ + if(cls->token_cls.from_str) { + if((cls->token_cls.from_str)(obj, obj_type, token_str, token) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTUNSERIALIZE, FAIL, "can't deserialize object token string") + } /* end if */ + else + *token = H5O_TOKEN_UNDEF; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL__token_from_str() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_token_from_str + * + * Purpose: Deserialize a string into a connector object token + * + * Return: Success: Non-negative + * Failure: Negative + * + *------------------------------------------------------------------------- + */ +herr_t +H5VL_token_from_str(const H5VL_object_t *vol_obj, H5I_type_t obj_type, + const char *token_str, H5O_token_t *token) +{ + hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Sanity checks */ + HDassert(vol_obj); + HDassert(token); + HDassert(token_str); + + /* Set wrapper info in API context */ + if(H5VL_set_vol_wrapper(vol_obj) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info") + vol_wrapper_set = TRUE; + + /* Call the corresponding internal VOL routine */ + if((ret_value = H5VL__token_from_str(vol_obj->data, obj_type, vol_obj->connector->cls, token_str, token)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTUNSERIALIZE, FAIL, "token deserialization failed") + +done: + /* Reset object wrapping info in API context */ + if(vol_wrapper_set && H5VL_reset_vol_wrapper() < 0) + HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info") + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_token_from_str() */ + + +/*--------------------------------------------------------------------------- + * Function: H5VLtoken_from_str + * + * Purpose: Deserialize a string into a connector object token + * + * Return: Success: Non-negative + * Failure: Negative + * + *--------------------------------------------------------------------------- + */ +herr_t +H5VLtoken_from_str(void *obj, H5I_type_t obj_type, hid_t connector_id, + const char *token_str, H5O_token_t *token) +{ + H5VL_class_t *cls; /* VOL connector's class struct */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API_NOINIT + H5TRACE5("e", "*xIti*s*k", obj, obj_type, connector_id, token_str, token); + + /* Check args and get class pointer */ + if(NULL == obj) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid object") + if(NULL == (cls = (H5VL_class_t *)H5I_object_verify(connector_id, H5I_VOL))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID") + if(NULL == token) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid token pointer") + if(NULL == token_str) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid token_str pointer") + + /* Call the corresponding internal VOL routine */ + if(H5VL__token_from_str(obj, obj_type, cls, token_str, token) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTUNSERIALIZE, FAIL, "object token from string failed") + +done: + FUNC_LEAVE_API_NOINIT(ret_value) +} /* end H5VLtoken_from_str() */ + + +/*------------------------------------------------------------------------- * Function: H5VL__optional * * Purpose: Optional operation specific to connectors. diff --git a/src/H5VLconnector.h b/src/H5VLconnector.h index 4ce6bb1..9bc3a7b 100644 --- a/src/H5VLconnector.h +++ b/src/H5VLconnector.h @@ -43,8 +43,6 @@ /* The maximum size allowed for blobs */ #define H5VL_MAX_BLOB_ID_SIZE (16) /* Allow for 128-bits blob IDs */ -/* The maximum size allowed for tokens */ -#define H5VL_MAX_TOKEN_SIZE (16) /* Allow for 128-bits tokens */ /*******************/ /* Public Typedefs */ @@ -64,15 +62,10 @@ typedef enum H5VL_subclass_t { H5VL_SUBCLS_LINK, /* 'Link' subclass */ H5VL_SUBCLS_OBJECT, /* 'Object' subclass */ H5VL_SUBCLS_REQUEST, /* 'Request' subclass */ - H5VL_SUBCLS_BLOB /* 'Blob' subclass */ + H5VL_SUBCLS_BLOB, /* 'Blob' subclass */ + H5VL_SUBCLS_TOKEN /* 'Token' subclass */ } H5VL_subclass_t; -/* type for tokens. Token are unique and permanent identifiers that are - * used to reference HDF5 objects. */ -typedef struct { - char __data[H5VL_MAX_TOKEN_SIZE]; -} H5VL_token_t; - /* types for attribute GET callback */ typedef enum H5VL_attr_get_t { H5VL_ATTR_GET_ACPL, /* creation property list */ @@ -201,7 +194,8 @@ typedef int H5VL_link_optional_t; typedef enum H5VL_object_get_t { H5VL_OBJECT_GET_FILE, /* object file */ H5VL_OBJECT_GET_NAME, /* object name */ - H5VL_OBJECT_GET_TYPE /* object type */ + H5VL_OBJECT_GET_TYPE, /* object type */ + H5VL_OBJECT_GET_INFO /* H5Oget_info(_by_idx|name)3 */ } H5VL_object_get_t; /* types for object SPECIFIC callback */ @@ -262,7 +256,7 @@ typedef struct H5VL_loc_by_idx { } H5VL_loc_by_idx_t; typedef struct H5VL_loc_by_token { - H5VL_token_t *token; + H5O_token_t *token; } H5VL_loc_by_token_t; /* Structure to hold parameters for object locations. @@ -459,6 +453,13 @@ typedef struct H5VL_blob_class_t { herr_t (*optional)(void *obj, void *blob_id, H5VL_blob_optional_t opt_type, va_list arguments); } H5VL_blob_class_t; +/* Object token routines */ +typedef struct H5VL_token_class_t { + herr_t (*cmp)(void *obj, const H5O_token_t *token1, const H5O_token_t *token2, int *cmp_value); + herr_t (*to_str)(void *obj, H5I_type_t obj_type, const H5O_token_t *token, char **token_str); + herr_t (*from_str)(void *obj, H5I_type_t obj_type, const char *token_str, H5O_token_t *token); +} H5VL_token_class_t; + /* Class information for each VOL connector */ typedef struct H5VL_class_t { /* Overall connector fields & callbacks */ @@ -486,6 +487,7 @@ typedef struct H5VL_class_t { H5VL_introspect_class_t introspect_cls; /* Container/connector introspection class callbacks */ H5VL_request_class_t request_cls; /* Asynchronous request class callbacks */ H5VL_blob_class_t blob_cls; /* 'Blob' class callbacks */ + H5VL_token_class_t token_cls; /* VOL connector object token class callbacks */ /* Catch-all */ herr_t (*optional)(void *obj, int op_type, hid_t dxpl_id, void **req, va_list arguments); /* Optional callback */ diff --git a/src/H5VLconnector_passthru.h b/src/H5VLconnector_passthru.h index 5a937bf..b04f5eb 100644 --- a/src/H5VLconnector_passthru.h +++ b/src/H5VLconnector_passthru.h @@ -170,6 +170,11 @@ H5_DLL herr_t H5VLblob_get(void *obj, hid_t connector_id, const void *blob_id, v H5_DLL herr_t H5VLblob_specific(void *obj, hid_t connector_id, void *blob_id, H5VL_blob_specific_t specific_type, va_list arguments); H5_DLL herr_t H5VLblob_optional(void *obj, hid_t connector_id, void *blob_id, H5VL_blob_optional_t opt_type, va_list arguments); +/* Public wrappers for token callbacks */ +H5_DLL herr_t H5VLtoken_cmp(void *obj, hid_t connector_id, const H5O_token_t *token1, const H5O_token_t *token2, int *cmp_value); +H5_DLL herr_t H5VLtoken_to_str(void *obj, H5I_type_t obj_type, hid_t connector_id, const H5O_token_t *token, char **token_str); +H5_DLL herr_t H5VLtoken_from_str(void *obj, H5I_type_t obj_type, hid_t connector_id, const char *token_str, H5O_token_t *token); + /* Public wrappers for generic 'optional' callback */ H5_DLL herr_t H5VLoptional(void *obj, hid_t connector_id, int op_type, hid_t dxpl_id, void **req, va_list arguments); diff --git a/src/H5VLint.c b/src/H5VLint.c index 242b1c7..9038d38 100644 --- a/src/H5VLint.c +++ b/src/H5VLint.c @@ -425,7 +425,7 @@ H5VL__set_def_conn(void) HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't check if VOL connector already registered") else if(connector_is_registered) { /* Retrieve the ID of the already-registered VOL connector */ - if((connector_id = H5VL__get_connector_id(tok, FALSE)) < 0) + if((connector_id = H5VL__get_connector_id_by_name(tok, FALSE)) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't get VOL connector ID") } /* end else-if */ else { @@ -1366,6 +1366,41 @@ done: /*------------------------------------------------------------------------- * Function: H5VL__get_connector_id * + * Purpose: Retrieves the VOL connector ID for a given object ID. + * + * Return: Positive if the VOL class has been registered + * Negative on error (if the class is not a valid class or not registered) + * + * Programmer: Dana Robinson + * June 17, 2017 + * + *------------------------------------------------------------------------- + */ +hid_t +H5VL__get_connector_id(hid_t obj_id, hbool_t is_api) +{ + H5VL_object_t *vol_obj = NULL; + hid_t ret_value = H5I_INVALID_HID; /* Return value */ + + FUNC_ENTER_PACKAGE + + /* Get the underlying VOL object for the object ID */ + if(NULL == (vol_obj = H5VL_vol_object(obj_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid location identifier") + + /* Return the VOL object's VOL class ID */ + ret_value = vol_obj->connector->id; + if(H5I_inc_ref(ret_value, is_api) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTINC, H5I_INVALID_HID, "unable to increment ref count on VOL connector") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL__get_connector_id() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL__get_connector_id_by_name + * * Purpose: Retrieves the ID for a registered VOL connector. * * Return: Positive if the VOL class has been registered @@ -1377,7 +1412,7 @@ done: *------------------------------------------------------------------------- */ hid_t -H5VL__get_connector_id(const char *name, hbool_t is_api) +H5VL__get_connector_id_by_name(const char *name, hbool_t is_api) { hid_t ret_value = H5I_INVALID_HID; /* Return value */ @@ -1393,7 +1428,7 @@ H5VL__get_connector_id(const char *name, hbool_t is_api) done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5VL__get_connector_id() */ +} /* end H5VL__get_connector_id_by_name() */ /*------------------------------------------------------------------------- diff --git a/src/H5VLnative.c b/src/H5VLnative.c index dfa57ef..616ca60 100644 --- a/src/H5VLnative.c +++ b/src/H5VLnative.c @@ -16,9 +16,15 @@ */ #include "H5private.h" /* Generic Functions */ +#include "H5Aprivate.h" /* Attributes */ +#include "H5Dprivate.h" /* Datasets */ #include "H5Eprivate.h" /* Error handling */ +#include "H5Fprivate.h" /* Files */ +#include "H5Gprivate.h" /* Groups */ #include "H5Iprivate.h" /* IDs */ +#include "H5Oprivate.h" /* Object headers */ #include "H5Pprivate.h" /* Property lists */ +#include "H5Tprivate.h" /* Datatypes */ #include "H5VLprivate.h" /* Virtual Object Layer */ #include "H5VLnative_private.h" /* Native VOL connector */ @@ -130,6 +136,11 @@ static const H5VL_class_t H5VL_native_cls_g = { H5VL__native_blob_specific, /* specific */ NULL /* optional */ }, + { /* token_cls */ + H5VL__native_token_cmp, /* cmp */ + H5VL__native_token_to_str, /* to_str */ + H5VL__native_str_to_token /* from_str */ + }, NULL /* optional */ }; @@ -212,3 +223,337 @@ H5VL__native_introspect_get_conn_cls(void H5_ATTR_UNUSED *obj, FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5VL__native_introspect_get_conn_cls() */ + +/*------------------------------------------------------------------------- + * Function: H5VL_native_get_file_addr_len + * + * Purpose: Convenience function to get a file's address length from a + * location ID. Useful when you have to encode/decode addresses + * to/from tokens. + * + * Return: SUCCEED/FAIL + * + *------------------------------------------------------------------------- + */ +herr_t +H5VL_native_get_file_addr_len(hid_t loc_id, size_t *addr_len) +{ + H5I_type_t vol_obj_type = H5I_BADID; /* Object type of loc_id */ + void *vol_obj = NULL; /* VOL Object of loc_id */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* check arguments */ + HDassert(addr_len); + + /* Get object type */ + if((vol_obj_type = H5I_get_type(loc_id)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_BADTYPE, FAIL, "invalid location identifier") + + /* Retrieve underlying VOL object */ + if(NULL == (vol_obj = H5VL_object(loc_id))) + HGOTO_ERROR(H5E_VOL, H5E_BADTYPE, FAIL, "invalid location identifier") + + /* Retrieve file address length */ + if(H5VL__native_get_file_addr_len(vol_obj, vol_obj_type, addr_len) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't get file address length") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_native_get_file_addr_len() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL__native_get_file_addr_len + * + * Purpose: Convenience function to get a file's address length from a + * VOL object. Useful when you have to encode/decode addresses + * to/from tokens. + * + * Return: SUCCEED/FAIL + * + *------------------------------------------------------------------------- + */ +herr_t +H5VL__native_get_file_addr_len(void *obj, H5I_type_t obj_type, size_t *addr_len) +{ + H5F_t *file = NULL; /* File stuct pointer */ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI(FAIL) + + /* check arguments */ + HDassert(obj); + HDassert(addr_len); + + /* Retrieve file from the VOL object */ + if(H5VL_native_get_file_struct(obj, obj_type, &file) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "couldn't get file from VOL object") + + /* Get the length of an address in this file */ + *addr_len = H5F_SIZEOF_ADDR(file); + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL__native_get_file_addr_len() */ + + +/*------------------------------------------------------------------------- + * Function: H5VLnative_addr_to_token + * + * Purpose: Converts a native VOL haddr_t address to an abstract VOL token. + * + * Return: SUCCEED/FAIL + * + *------------------------------------------------------------------------- + */ +herr_t +H5VLnative_addr_to_token(hid_t loc_id, haddr_t addr, H5O_token_t *token) +{ + H5I_type_t vol_obj_type = H5I_BADID; /* Object type of loc_id */ + void *vol_obj = NULL; /* VOL Object of loc_id */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE3("e", "ia*k", loc_id, addr, token); + + /* Check args */ + if(NULL == token) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "token pointer can't be NULL") + + /* Get object type */ + if((vol_obj_type = H5I_get_type(loc_id)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_BADTYPE, FAIL, "invalid location identifier") + + /* Retrieve underlying VOL object */ + if(NULL == (vol_obj = H5VL_object(loc_id))) + HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't get underlying VOL object") + +#ifndef NDEBUG + { + H5VL_object_t *vol_obj_container; + hbool_t is_native_vol_obj; + + /* Get the location object */ + if(NULL == (vol_obj_container = (H5VL_object_t *)H5I_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + + /* Make sure that the VOL object is a native connector object */ + if(H5VL_object_is_native(vol_obj_container, &is_native_vol_obj) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't determine if VOL object is native connector object") + + HDassert(is_native_vol_obj && "not a native VOL connector object"); + } +#endif + + /* Convert the haddr_t to an object token */ + if(H5VL_native_addr_to_token(vol_obj, vol_obj_type, addr, token) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTSERIALIZE, FAIL, "couldn't serialize haddr_t into object token") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5VLnative_addr_to_token() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_native_addr_to_token + * + * Purpose: Converts a native VOL haddr_t address to an abstract VOL token. + * + * Return: SUCCEED/FAIL + * + *------------------------------------------------------------------------- + */ +herr_t +H5VL_native_addr_to_token(void *obj, H5I_type_t obj_type, haddr_t addr, H5O_token_t *token) +{ + uint8_t *p; + size_t addr_len = 0; /* Size of haddr_t */ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI(FAIL) + + /* Check args */ + HDassert(obj); + HDassert(token); + + /* Get the length of an haddr_t in the file */ + if(H5VL__native_get_file_addr_len(obj, obj_type, &addr_len) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "couldn't get length of haddr_t from VOL object") + + /* Ensure that token is initialized */ + HDmemset(token, 0, sizeof(H5O_token_t)); + + /* Encode token */ + p = (uint8_t *)token; + H5F_addr_encode_len(addr_len, &p, addr); + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_native_addr_to_token() */ + + +/*------------------------------------------------------------------------- + * Function: H5VLnative_token_to_addr + * + * Purpose: Converts an abstract VOL token to a native VOL haddr_t address. + * + * Return: SUCCEED/FAIL + * + *------------------------------------------------------------------------- + */ +herr_t +H5VLnative_token_to_addr(hid_t loc_id, H5O_token_t token, haddr_t *addr) +{ + H5I_type_t vol_obj_type = H5I_BADID; /* Object type of loc_id */ + void *vol_obj = NULL; /* VOL Object of loc_id */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE3("e", "ik*a", loc_id, token, addr); + + /* Check args */ + if(NULL == addr) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "addr pointer can't be NULL") + + /* Get object type */ + if((vol_obj_type = H5I_get_type(loc_id)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_BADTYPE, FAIL, "invalid location identifier") + + /* Retrieve underlying VOL object */ + if(NULL == (vol_obj = H5VL_object(loc_id))) + HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't get underlying VOL object") + +#ifndef NDEBUG + { + H5VL_object_t *vol_obj_container; + hbool_t is_native_vol_obj; + + /* Get the location object */ + if(NULL == (vol_obj_container = (H5VL_object_t *)H5I_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + + /* Make sure that the VOL object is a native connector object */ + if(H5VL_object_is_native(vol_obj_container, &is_native_vol_obj) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't determine if VOL object is native connector object") + + HDassert(is_native_vol_obj && "not a native VOL connector object"); + } +#endif + + /* Convert the object token to an haddr_t */ + if(H5VL_native_token_to_addr(vol_obj, vol_obj_type, token, addr) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTUNSERIALIZE, FAIL, "couldn't deserialize object token into haddr_t") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5VLnative_token_to_addr() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_native_token_to_addr + * + * Purpose: Converts an abstract VOL token to a native VOL haddr_t address. + * + * Return: SUCCEED/FAIL + * + *------------------------------------------------------------------------- + */ +herr_t +H5VL_native_token_to_addr(void *obj, H5I_type_t obj_type, H5O_token_t token, haddr_t *addr) +{ + const uint8_t *p; + size_t addr_len = 0; /* Size of haddr_t */ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI(FAIL) + + /* Check args */ + HDassert(obj); + HDassert(addr); + + /* Get the length of an haddr_t in the file */ + if(H5VL__native_get_file_addr_len(obj, obj_type, &addr_len) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "couldn't get length of haddr_t from VOL object") + + /* Decode token */ + p = (const uint8_t *)&token; + H5F_addr_decode_len(addr_len, &p, addr); + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_native_token_to_addr() */ + + +/*--------------------------------------------------------------------------- + * Function: H5VL_native_get_file_struct + * + * Purpose: Utility routine to get file struct for an object + * + * Returns: SUCCEED/FAIL + * + *--------------------------------------------------------------------------- + */ +herr_t +H5VL_native_get_file_struct(void *obj, H5I_type_t type, H5F_t **file) +{ + H5O_loc_t *oloc = NULL; /* Object location for ID */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL); + + *file = NULL; + + switch(type) { + case H5I_FILE: + *file = (H5F_t *)obj; + break; + + case H5I_GROUP: + oloc = H5G_oloc((H5G_t *)obj); + break; + + case H5I_DATATYPE: + oloc = H5T_oloc((H5T_t *)obj); + break; + + case H5I_DATASET: + oloc = H5D_oloc((H5D_t *)obj); + break; + + case H5I_ATTR: + oloc = H5A_oloc((H5A_t *)obj); + break; + + case H5I_MAP: + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "maps not supported in native VOL connector") + + case H5I_UNINIT: + case H5I_BADID: + case H5I_DATASPACE: + case H5I_VFL: + case H5I_VOL: + case H5I_GENPROP_CLS: + case H5I_GENPROP_LST: + case H5I_ERROR_CLASS: + case H5I_ERROR_MSG: + case H5I_ERROR_STACK: + case H5I_SPACE_SEL_ITER: + case H5I_NTYPES: + default: + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") + } /* end switch */ + + /* Set return value for objects (not files) */ + if(oloc) + *file = oloc->file; + + /* Couldn't find a file struct */ + if(!*file) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "object is not associated with a file") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5VL_native_get_file_struct */ + diff --git a/src/H5VLnative.h b/src/H5VLnative.h index 44ed670..e1f3f93 100644 --- a/src/H5VLnative.h +++ b/src/H5VLnative.h @@ -88,11 +88,23 @@ /* Values for native VOL connector object optional VOL operations */ #define H5VL_NATIVE_OBJECT_GET_COMMENT 0 /* H5G|H5Oget_comment, H5Oget_comment_by_name */ -#define H5VL_NATIVE_OBJECT_GET_INFO 1 /* H5Oget_info(_by_idx, _by_name)(2) */ -#define H5VL_NATIVE_OBJECT_SET_COMMENT 2 /* H5G|H5Oset_comment, H5Oset_comment_by_name */ -#define H5VL_NATIVE_OBJECT_DISABLE_MDC_FLUSHES 3 /* H5Odisable_mdc_flushes */ -#define H5VL_NATIVE_OBJECT_ENABLE_MDC_FLUSHES 4 /* H5Oenable_mdc_flushes */ -#define H5VL_NATIVE_OBJECT_ARE_MDC_FLUSHES_DISABLED 5 /* H5Oare_mdc_flushes_disabled */ +#define H5VL_NATIVE_OBJECT_SET_COMMENT 1 /* H5G|H5Oset_comment, H5Oset_comment_by_name */ +#define H5VL_NATIVE_OBJECT_DISABLE_MDC_FLUSHES 2 /* H5Odisable_mdc_flushes */ +#define H5VL_NATIVE_OBJECT_ENABLE_MDC_FLUSHES 3 /* H5Oenable_mdc_flushes */ +#define H5VL_NATIVE_OBJECT_ARE_MDC_FLUSHES_DISABLED 4 /* H5Oare_mdc_flushes_disabled */ +#define H5VL_NATIVE_OBJECT_GET_NATIVE_INFO 5 /* H5Oget_native_info(_by_idx, _by_name) */ + +/*******************/ +/* Public Typedefs */ +/*******************/ + +/********************/ +/* Public Variables */ +/********************/ + +/*********************/ +/* Public Prototypes */ +/*********************/ /*******************/ /* Public Typedefs */ @@ -110,7 +122,11 @@ extern "C" { #endif -/* Private functions */ +/* Token <--> address converters */ +H5_DLL herr_t H5VLnative_addr_to_token(hid_t loc_id, haddr_t addr, H5O_token_t *token); +H5_DLL herr_t H5VLnative_token_to_addr(hid_t loc_id, H5O_token_t token, haddr_t *addr); + +/* Not really public but must be included here */ H5_DLL hid_t H5VL_native_register(void); #ifdef __cplusplus diff --git a/src/H5VLnative_file.c b/src/H5VLnative_file.c index 005859d..23ea37b 100644 --- a/src/H5VLnative_file.c +++ b/src/H5VLnative_file.c @@ -226,7 +226,7 @@ H5VL__native_file_get(void *obj, H5VL_file_get_t get_type, ssize_t *ret = HDva_arg(arguments, ssize_t *); size_t len; - if(NULL == (f = H5F__get_file(obj, type))) + if(H5VL_native_get_file_struct(obj, type, &f) < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") len = HDstrlen(H5F_OPEN_NAME(f)); @@ -313,7 +313,7 @@ H5VL__native_file_specific(void *obj, H5VL_file_specific_t specific_type, H5F_t *f = NULL; /* File to flush */ /* Get the file for the object */ - if(NULL == (f = H5F__get_file(obj, type))) + if(H5VL_native_get_file_struct(obj, type, &f) < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") /* Nothing to do if the file is read only. This determination is @@ -519,7 +519,7 @@ H5VL__native_file_optional(void *obj, H5VL_file_optional_t optional_type, /* Get the file struct. This call is careful to not return the file pointer * for the top file in a mount hierarchy. */ - if(NULL == (f = H5F__get_file(obj, type))) + if(H5VL_native_get_file_struct(obj, type, &f) < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "could not get a file struct") /* Get the file info */ diff --git a/src/H5VLnative_link.c b/src/H5VLnative_link.c index 9a633ac..051de19 100644 --- a/src/H5VLnative_link.c +++ b/src/H5VLnative_link.c @@ -241,16 +241,16 @@ H5VL__native_link_get(void *obj, const H5VL_loc_params_t *loc_params, H5VL_link_ /* H5Lget_info/H5Lget_info_by_idx */ case H5VL_LINK_GET_INFO: { - H5L_info_t *linfo = HDva_arg(arguments, H5L_info_t *); + H5L_info2_t *linfo2 = HDva_arg(arguments, H5L_info2_t *); /* Get the link information */ if(loc_params->type == H5VL_OBJECT_BY_NAME) { /* H5Lget_info */ - if(H5L_get_info(&loc, loc_params->loc_data.loc_by_name.name, linfo) < 0) + if(H5L_get_info(&loc, loc_params->loc_data.loc_by_name.name, linfo2) < 0) HGOTO_ERROR(H5E_LINK, H5E_NOTFOUND, FAIL, "unable to get link info") } /* end if */ else if(loc_params->type == H5VL_OBJECT_BY_IDX) { /* H5Lget_info_by_idx */ if(H5L_get_info_by_idx(&loc, loc_params->loc_data.loc_by_idx.name, loc_params->loc_data.loc_by_idx.idx_type, - loc_params->loc_data.loc_by_idx.order, loc_params->loc_data.loc_by_idx.n, linfo) < 0) + loc_params->loc_data.loc_by_idx.order, loc_params->loc_data.loc_by_idx.n, linfo2) < 0) HGOTO_ERROR(H5E_LINK, H5E_NOTFOUND, FAIL, "unable to get link info") } /* end else-if */ else @@ -341,12 +341,12 @@ H5VL__native_link_specific(void *obj, const H5VL_loc_params_t *loc_params, H5VL_ case H5VL_LINK_ITER: { H5G_loc_t loc; - hbool_t recursive = (hbool_t)HDva_arg(arguments, unsigned); - H5_index_t idx_type = (H5_index_t)HDva_arg(arguments, int); /* enum work-around */ - H5_iter_order_t order = (H5_iter_order_t)HDva_arg(arguments, int); /* enum work-around */ - hsize_t *idx_p = HDva_arg(arguments, hsize_t *); - H5L_iterate_t op = HDva_arg(arguments, H5L_iterate_t); - void *op_data = HDva_arg(arguments, void *); + hbool_t recursive = (hbool_t)HDva_arg(arguments, unsigned); + H5_index_t idx_type = (H5_index_t)HDva_arg(arguments, int); /* enum work-around */ + H5_iter_order_t order = (H5_iter_order_t)HDva_arg(arguments, int); /* enum work-around */ + hsize_t *idx_p = HDva_arg(arguments, hsize_t *); + H5L_iterate2_t op = HDva_arg(arguments, H5L_iterate2_t); + void *op_data = HDva_arg(arguments, void *); /* Get the location */ if(H5G_loc_real(obj, loc_params->obj_type, &loc) < 0) diff --git a/src/H5VLnative_object.c b/src/H5VLnative_object.c index e6b3295..3a29b6c 100644 --- a/src/H5VLnative_object.c +++ b/src/H5VLnative_object.c @@ -72,11 +72,12 @@ H5VL__native_object_open(void *obj, const H5VL_loc_params_t *loc_params, H5I_typ case H5VL_OBJECT_BY_TOKEN: { - const uint8_t *p = (const uint8_t *)loc_params->loc_data.loc_by_token.token; + H5O_token_t token = *loc_params->loc_data.loc_by_token.token; haddr_t addr; /* Decode token */ - H5F_addr_decode(loc.oloc->file, &p, &addr); + if(H5VL_native_token_to_addr(loc.oloc->file, H5I_FILE, token, &addr) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTUNSERIALIZE, NULL, "can't deserialize object token into address") /* Open the object */ if(NULL == (ret_value = H5O_open_by_addr(&loc, addr, opened_type))) @@ -184,13 +185,15 @@ H5VL__native_object_get(void *obj, const H5VL_loc_params_t *loc_params, H5VL_obj } /* end if */ else if(loc_params->type == H5VL_OBJECT_BY_TOKEN) { H5O_loc_t obj_oloc; /* Object location */ - const uint8_t *p = (const uint8_t *)loc_params->loc_data.loc_by_token.token; + H5O_token_t token = *loc_params->loc_data.loc_by_token.token; /* Initialize the object location */ H5O_loc_reset(&obj_oloc); obj_oloc.file = loc.oloc->file; + /* Decode token */ - H5F_addr_decode(obj_oloc.file, &p, &obj_oloc.addr); + if(H5VL_native_token_to_addr(obj_oloc.file, H5I_FILE, token, &obj_oloc.addr) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTUNSERIALIZE, FAIL, "can't deserialize object token into address") /* Retrieve object's name */ if((*ret = H5G_get_name_by_addr(loc.oloc->file, &obj_oloc, name, size)) < 0) @@ -209,13 +212,15 @@ H5VL__native_object_get(void *obj, const H5VL_loc_params_t *loc_params, H5VL_obj if(loc_params->type == H5VL_OBJECT_BY_TOKEN) { H5O_loc_t obj_oloc; /* Object location */ unsigned rc; /* Reference count of object */ - const uint8_t *p = (const uint8_t *)loc_params->loc_data.loc_by_token.token; + H5O_token_t token = *loc_params->loc_data.loc_by_token.token; /* Initialize the object location */ H5O_loc_reset(&obj_oloc); obj_oloc.file = loc.oloc->file; + /* Decode token */ - H5F_addr_decode(obj_oloc.file, &p, &obj_oloc.addr); + if(H5VL_native_token_to_addr(obj_oloc.file, H5I_FILE, token, &obj_oloc.addr) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTUNSERIALIZE, FAIL, "can't deserialize object token into address") /* Get the # of links for object, and its type */ /* (To check to make certain that this object hasn't been deleted) */ @@ -226,6 +231,56 @@ H5VL__native_object_get(void *obj, const H5VL_loc_params_t *loc_params, H5VL_obj break; } + /* H5Oget_info(_name|_by_idx)3 */ + case H5VL_OBJECT_GET_INFO: + { + H5O_info2_t *oinfo = HDva_arg(arguments, H5O_info2_t *); + unsigned fields = HDva_arg(arguments, unsigned); + + /* Use the original H5Oget_info code to get the data */ + + if(loc_params->type == H5VL_OBJECT_BY_SELF) { /* H5Oget_info */ + /* Retrieve the object's information */ + if(H5G_loc_info(&loc, ".", oinfo, fields) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_NOTFOUND, FAIL, "object not found") + } /* end if */ + else if(loc_params->type == H5VL_OBJECT_BY_NAME) { /* H5Oget_info_by_name */ + /* Retrieve the object's information */ + if(H5G_loc_info(&loc, loc_params->loc_data.loc_by_name.name, oinfo, fields) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_NOTFOUND, FAIL, "object not found") + } /* end else-if */ + else if(loc_params->type == H5VL_OBJECT_BY_IDX) { /* H5Oget_info_by_idx */ + H5G_loc_t obj_loc; /* Location used to open group */ + H5G_name_t obj_path; /* Opened object group hier. path */ + H5O_loc_t obj_oloc; /* Opened object object location */ + + /* Set up opened group location to fill in */ + obj_loc.oloc = &obj_oloc; + obj_loc.path = &obj_path; + H5G_loc_reset(&obj_loc); + + /* Find the object's location, according to the order in the index */ + if(H5G_loc_find_by_idx(&loc, loc_params->loc_data.loc_by_idx.name, + loc_params->loc_data.loc_by_idx.idx_type, + loc_params->loc_data.loc_by_idx.order, + loc_params->loc_data.loc_by_idx.n, &obj_loc/*out*/) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_NOTFOUND, FAIL, "group not found") + + /* Retrieve the object's information */ + if(H5O_get_info(obj_loc.oloc, oinfo, fields) < 0) { + H5G_loc_free(&obj_loc); + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't retrieve object info") + } /* end if */ + + /* Release the object location */ + if(H5G_loc_free(&obj_loc) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTRELEASE, FAIL, "can't free location") + } /* end else-if */ + else + HGOTO_ERROR(H5E_OHDR, H5E_UNSUPPORTED, FAIL, "unknown get info parameters") + break; + } + default: HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't get this type of information from object") } /* end switch */ @@ -287,7 +342,7 @@ H5VL__native_object_specific(void *obj, const H5VL_loc_params_t *loc_params, H5V /* Lookup object */ case H5VL_OBJECT_LOOKUP: { - H5VL_token_t *token = va_arg(arguments, H5VL_token_t *); + H5O_token_t *token = va_arg(arguments, H5O_token_t *); HDassert(token); @@ -295,7 +350,6 @@ H5VL__native_object_specific(void *obj, const H5VL_loc_params_t *loc_params, H5V H5G_loc_t obj_loc; /* Group hier. location of object */ H5G_name_t obj_path; /* Object group hier. path */ H5O_loc_t obj_oloc; /* Object object location */ - uint8_t *p = (uint8_t *)token; /* Pointer to token */ /* Set up opened group location to fill in */ obj_loc.oloc = &obj_oloc; @@ -307,7 +361,8 @@ H5VL__native_object_specific(void *obj, const H5VL_loc_params_t *loc_params, H5V HGOTO_ERROR(H5E_OHDR, H5E_NOTFOUND, FAIL, "object not found") /* Encode token */ - H5F_addr_encode(obj_oloc.file, &p, obj_loc.oloc->addr); + if(H5VL_native_addr_to_token(loc.oloc->file, H5I_FILE, obj_loc.oloc->addr, token) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTSERIALIZE, FAIL, "can't serialize address into object token") /* Release the object location */ if(H5G_loc_free(&obj_loc) < 0) @@ -322,7 +377,7 @@ H5VL__native_object_specific(void *obj, const H5VL_loc_params_t *loc_params, H5V { H5_index_t idx_type = (H5_index_t)HDva_arg(arguments, int); /* enum work-around */ H5_iter_order_t order = (H5_iter_order_t)HDva_arg(arguments, int); /* enum work-around */ - H5O_iterate_t op = HDva_arg(arguments, H5O_iterate_t); + H5O_iterate2_t op = HDva_arg(arguments, H5O_iterate2_t); void *op_data = HDva_arg(arguments, void *); unsigned fields = HDva_arg(arguments, unsigned); @@ -397,54 +452,6 @@ H5VL__native_object_optional(void *obj, H5VL_object_optional_t optional_type, HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") switch(optional_type) { - /* H5Oget_info / H5Oget_info_by_name / H5Oget_info_by_idx */ - case H5VL_NATIVE_OBJECT_GET_INFO: - { - H5O_info_t *obj_info = HDva_arg(arguments, H5O_info_t *); - unsigned fields = HDva_arg(arguments, unsigned); - - if(loc_params->type == H5VL_OBJECT_BY_SELF) { /* H5Oget_info */ - /* Retrieve the object's information */ - if(H5G_loc_info(&loc, ".", obj_info, fields) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_NOTFOUND, FAIL, "object not found") - } /* end if */ - else if(loc_params->type == H5VL_OBJECT_BY_NAME) { /* H5Oget_info_by_name */ - /* Retrieve the object's information */ - if(H5G_loc_info(&loc, loc_params->loc_data.loc_by_name.name, obj_info, fields) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_NOTFOUND, FAIL, "object not found") - } /* end else-if */ - else if(loc_params->type == H5VL_OBJECT_BY_IDX) { /* H5Oget_info_by_idx */ - H5G_loc_t obj_loc; /* Location used to open group */ - H5G_name_t obj_path; /* Opened object group hier. path */ - H5O_loc_t obj_oloc; /* Opened object object location */ - - /* Set up opened group location to fill in */ - obj_loc.oloc = &obj_oloc; - obj_loc.path = &obj_path; - H5G_loc_reset(&obj_loc); - - /* Find the object's location, according to the order in the index */ - if(H5G_loc_find_by_idx(&loc, loc_params->loc_data.loc_by_idx.name, - loc_params->loc_data.loc_by_idx.idx_type, - loc_params->loc_data.loc_by_idx.order, - loc_params->loc_data.loc_by_idx.n, &obj_loc/*out*/) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_NOTFOUND, FAIL, "group not found") - - /* Retrieve the object's information */ - if(H5O_get_info(obj_loc.oloc, obj_info, fields) < 0) { - H5G_loc_free(&obj_loc); - HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't retrieve object info") - } /* end if */ - - /* Release the object location */ - if(H5G_loc_free(&obj_loc) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_CANTRELEASE, FAIL, "can't free location") - } /* end else-if */ - else - HGOTO_ERROR(H5E_OHDR, H5E_UNSUPPORTED, FAIL, "unknown get info parameters") - break; - } - /* H5Oget_comment / H5Oget_comment_by_name */ case H5VL_NATIVE_OBJECT_GET_COMMENT: { @@ -520,6 +527,57 @@ H5VL__native_object_optional(void *obj, H5VL_object_optional_t optional_type, break; } + /* H5Oget_native_info(_name|_by_idx) */ + case H5VL_NATIVE_OBJECT_GET_NATIVE_INFO: + { + H5O_native_info_t *native_info = HDva_arg(arguments, H5O_native_info_t *); + unsigned fields = HDva_arg(arguments, unsigned); + + /* Use the original H5Oget_info code to get the data */ + + if(loc_params->type == H5VL_OBJECT_BY_SELF) { /* H5Oget_info */ + /* Retrieve the object's information */ + if(H5G_loc_native_info(&loc, ".", native_info, fields) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_NOTFOUND, FAIL, "object not found") + } /* end if */ + else if(loc_params->type == H5VL_OBJECT_BY_NAME) { /* H5Oget_info_by_name */ + /* Retrieve the object's information */ + if(H5G_loc_native_info(&loc, loc_params->loc_data.loc_by_name.name, native_info, fields) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_NOTFOUND, FAIL, "object not found") + } /* end else-if */ + else if(loc_params->type == H5VL_OBJECT_BY_IDX) { /* H5Oget_info_by_idx */ + H5G_loc_t obj_loc; /* Location used to open group */ + H5G_name_t obj_path; /* Opened object group hier. path */ + H5O_loc_t obj_oloc; /* Opened object object location */ + + /* Set up opened group location to fill in */ + obj_loc.oloc = &obj_oloc; + obj_loc.path = &obj_path; + H5G_loc_reset(&obj_loc); + + /* Find the object's location, according to the order in the index */ + if(H5G_loc_find_by_idx(&loc, loc_params->loc_data.loc_by_idx.name, + loc_params->loc_data.loc_by_idx.idx_type, + loc_params->loc_data.loc_by_idx.order, + loc_params->loc_data.loc_by_idx.n, &obj_loc/*out*/) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_NOTFOUND, FAIL, "group not found") + + /* Retrieve the object's information */ + if(H5O_get_native_info(obj_loc.oloc, native_info, fields) < 0) { + H5G_loc_free(&obj_loc); + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't retrieve object info") + } /* end if */ + + /* Release the object location */ + if(H5G_loc_free(&obj_loc) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTRELEASE, FAIL, "can't free location") + } /* end else-if */ + else + HGOTO_ERROR(H5E_OHDR, H5E_UNSUPPORTED, FAIL, "unknown get info parameters") + + break; + } + default: HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't perform this operation on object"); } /* end switch */ diff --git a/src/H5VLnative_private.h b/src/H5VLnative_private.h index ad9a496..30bddb6 100644 --- a/src/H5VLnative_private.h +++ b/src/H5VLnative_private.h @@ -18,7 +18,8 @@ #define _H5VLnative_private_H /* Private headers needed by this file */ -#include "H5VLnative.h" /* Native VOL connector */ +#include "H5Fprivate.h" /* Files */ +#include "H5VLnative.h" /* Native VOL connector */ /**************************/ @@ -110,6 +111,18 @@ H5_DLL herr_t H5VL__native_blob_put(void *obj, const void *buf, size_t size, voi H5_DLL herr_t H5VL__native_blob_get(void *obj, const void *blob_id, void *buf, size_t size, void *ctx); H5_DLL herr_t H5VL__native_blob_specific(void *obj, void *blob_id, H5VL_blob_specific_t specific_type, va_list arguments); +/* Token callbacks */ +H5_DLL herr_t H5VL__native_token_cmp(void *obj, const H5O_token_t *token1, const H5O_token_t *token2, int *cmp_value); +H5_DLL herr_t H5VL__native_token_to_str(void *obj, H5I_type_t obj_type, const H5O_token_t *token, char **token_str); +H5_DLL herr_t H5VL__native_str_to_token(void *obj, H5I_type_t obj_type, const char *token_str, H5O_token_t *token); + +/* Helper functions */ +H5_DLL herr_t H5VL_native_get_file_addr_len(hid_t loc_id, size_t *addr_len); +H5_DLL herr_t H5VL__native_get_file_addr_len(void *obj, H5I_type_t obj_type, size_t *addr_len); +H5_DLL herr_t H5VL_native_addr_to_token(void *obj, H5I_type_t obj_type, haddr_t addr, H5O_token_t *token); +H5_DLL herr_t H5VL_native_token_to_addr(void *obj, H5I_type_t obj_type, H5O_token_t token, haddr_t *addr); +H5_DLL herr_t H5VL_native_get_file_struct(void *obj, H5I_type_t type, H5F_t **file); + #ifdef __cplusplus } #endif diff --git a/src/H5VLnative_token.c b/src/H5VLnative_token.c new file mode 100644 index 0000000..2b5429e --- /dev/null +++ b/src/H5VLnative_token.c @@ -0,0 +1,157 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * 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 COPYING file, which can be found at the root of the source code * + * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. * + * If you do not have access to either file, you may request a copy from * + * help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * Purpose: Object token callbacks for the native VOL connector + */ + +/***********/ +/* Headers */ +/***********/ +#include "H5private.h" /* Generic Functions */ +#include "H5Eprivate.h" /* Error handling */ +#include "H5MMprivate.h" /* Memory handling */ +#include "H5VLnative_private.h" /* Native VOL connector */ + +/****************/ +/* Local Macros */ +/****************/ + + +/******************/ +/* Local Typedefs */ +/******************/ + + +/********************/ +/* Local Prototypes */ +/********************/ + + +/*********************/ +/* Package Variables */ +/*********************/ + + +/*****************************/ +/* Library Private Variables */ +/*****************************/ + + +/*******************/ +/* Local Variables */ +/*******************/ + + + +/*--------------------------------------------------------------------------- + * Function: H5VL__native_token_cmp + * + * Purpose: Compare two of the connector's object tokens, setting + * *cmp_value, following the same rules as strcmp(). + * + * Return: Success: 0 + * Failure: (can't fail) + * + *--------------------------------------------------------------------------- + */ +herr_t +H5VL__native_token_cmp(void H5_ATTR_UNUSED *obj, + const H5O_token_t *token1, const H5O_token_t *token2, int *cmp_value) +{ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_PACKAGE_NOERR + + /* Check parameters */ + HDassert(token1); + HDassert(token2); + + *cmp_value = HDmemcmp(token1, token2, sizeof(H5O_token_t)); + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL__native_token_cmp() */ + + +/*--------------------------------------------------------------------------- + * Function: H5VL__native_token_to_str + * + * Purpose: Serialize an object token into a string + * + * Return: Success: 0 + * Failure: -1 + * + *--------------------------------------------------------------------------- + */ +herr_t +H5VL__native_token_to_str(void *obj, H5I_type_t obj_type, const H5O_token_t *token, + char **token_str) +{ + haddr_t addr; + size_t addr_ndigits; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_PACKAGE + + /* Check parameters */ + HDassert(obj); + HDassert(token); + + if(H5VL_native_token_to_addr(obj, obj_type, *token, &addr) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTDECODE, FAIL, "can't convert object token to address") + + if(addr == 0) + addr_ndigits = 1; + else + addr_ndigits = (size_t)(HDfloor(HDlog10((double)addr)) + 1); + + if(NULL == (*token_str = H5MM_malloc(addr_ndigits + 1))) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't allocate buffer for token string") + + HDsnprintf(*token_str, addr_ndigits + 1, H5_PRINTF_HADDR_FMT, addr); + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL__native_token_to_str() */ + + +/*--------------------------------------------------------------------------- + * Function: H5VL__native_str_to_token + * + * Purpose: Deserialize a string into an object token + * + * Return: Success: 0 + * Failure: -1 + * + *--------------------------------------------------------------------------- + */ +herr_t +H5VL__native_str_to_token(void *obj, H5I_type_t obj_type, + const char *token_str, H5O_token_t *token) +{ + haddr_t addr; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_PACKAGE + + /* Check parameters */ + HDassert(token_str); + + HDsscanf(token_str, H5_PRINTF_HADDR_FMT, &addr); + + if(H5VL_native_addr_to_token(obj, obj_type, addr, token) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTDECODE, FAIL, "can't convert address to object token") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL__native_str_to_token() */ + diff --git a/src/H5VLpassthru.c b/src/H5VLpassthru.c index 076d6de..5c9f28c 100644 --- a/src/H5VLpassthru.c +++ b/src/H5VLpassthru.c @@ -188,6 +188,11 @@ static herr_t H5VL_pass_through_blob_get(void *obj, const void *blob_id, void *b static herr_t H5VL_pass_through_blob_specific(void *obj, void *blob_id, H5VL_blob_specific_t specific_type, va_list arguments); static herr_t H5VL_pass_through_blob_optional(void *obj, void *blob_id, H5VL_blob_optional_t opt_type, va_list arguments); +/* Token callbacks */ +static herr_t H5VL_pass_through_token_cmp(void *obj, const H5O_token_t *token1, const H5O_token_t *token2, int *cmp_value); +static herr_t H5VL_pass_through_token_to_str(void *obj, H5I_type_t obj_type, const H5O_token_t *token, char **token_str); +static herr_t H5VL_pass_through_token_from_str(void *obj, H5I_type_t obj_type, const char *token_str, H5O_token_t *token); + /* Generic optional callback */ static herr_t H5VL_pass_through_optional(void *obj, int op_type, hid_t dxpl_id, void **req, va_list arguments); @@ -296,6 +301,11 @@ static const H5VL_class_t H5VL_pass_through_g = { H5VL_pass_through_blob_specific, /* specific */ H5VL_pass_through_blob_optional /* optional */ }, + { /* token_cls */ + H5VL_pass_through_token_cmp, /* cmp */ + H5VL_pass_through_token_to_str, /* to_str */ + H5VL_pass_through_token_from_str /* from_str */ + }, H5VL_pass_through_optional /* optional */ }; @@ -3028,6 +3038,104 @@ H5VL_pass_through_blob_optional(void *obj, void *blob_id, } /* end H5VL_pass_through_blob_optional() */ +/*--------------------------------------------------------------------------- + * Function: H5VL_pass_through_token_cmp + * + * Purpose: Compare two of the connector's object tokens, setting + * *cmp_value, following the same rules as strcmp(). + * + * Return: Success: 0 + * Failure: -1 + * + *--------------------------------------------------------------------------- + */ +static herr_t +H5VL_pass_through_token_cmp(void *obj, const H5O_token_t *token1, + const H5O_token_t *token2, int *cmp_value) +{ + H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj; + herr_t ret_value; + +#ifdef ENABLE_PASSTHRU_LOGGING + printf("------- PASS THROUGH VOL TOKEN Compare\n"); +#endif + + /* Sanity checks */ + assert(obj); + assert(token1); + assert(token2); + assert(cmp_value); + + ret_value = H5VLtoken_cmp(o->under_object, o->under_vol_id, token1, token2, cmp_value); + + return ret_value; +} /* end H5VL_pass_through_token_cmp() */ + + +/*--------------------------------------------------------------------------- + * Function: H5VL_pass_through_token_to_str + * + * Purpose: Serialize the connector's object token into a string. + * + * Return: Success: 0 + * Failure: -1 + * + *--------------------------------------------------------------------------- + */ +static herr_t +H5VL_pass_through_token_to_str(void *obj, H5I_type_t obj_type, + const H5O_token_t *token, char **token_str) +{ + H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj; + herr_t ret_value; + +#ifdef ENABLE_PASSTHRU_LOGGING + printf("------- PASS THROUGH VOL TOKEN To string\n"); +#endif + + /* Sanity checks */ + assert(obj); + assert(token); + assert(token_str); + + ret_value = H5VLtoken_to_str(o->under_object, obj_type, o->under_vol_id, token, token_str); + + return ret_value; +} /* end H5VL_pass_through_token_to_str() */ + + +/*--------------------------------------------------------------------------- + * Function: H5VL_pass_through_token_from_str + * + * Purpose: Deserialize the connector's object token from a string. + * + * Return: Success: 0 + * Failure: -1 + * + *--------------------------------------------------------------------------- + */ +static herr_t +H5VL_pass_through_token_from_str(void *obj, H5I_type_t obj_type, + const char *token_str, H5O_token_t *token) +{ + H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj; + herr_t ret_value; + +#ifdef ENABLE_PASSTHRU_LOGGING + printf("------- PASS THROUGH VOL TOKEN From string\n"); +#endif + + /* Sanity checks */ + assert(obj); + assert(token); + assert(token_str); + + ret_value = H5VLtoken_from_str(o->under_object, obj_type, o->under_vol_id, token_str, token); + + return ret_value; +} /* end H5VL_pass_through_token_from_str() */ + + /*------------------------------------------------------------------------- * Function: H5VL_pass_through_optional * diff --git a/src/H5VLpkg.h b/src/H5VLpkg.h index fc3088d..5965adc 100644 --- a/src/H5VLpkg.h +++ b/src/H5VLpkg.h @@ -54,7 +54,8 @@ H5_DLL hid_t H5VL__register_connector_by_name(const char *name, hbool_t app_ref, H5_DLL hid_t H5VL__register_connector_by_value(H5VL_class_value_t value, hbool_t app_ref, hid_t vipl_id); H5_DLL htri_t H5VL__is_connector_registered(const char *name); -H5_DLL hid_t H5VL__get_connector_id(const char *name, hbool_t is_api); +H5_DLL hid_t H5VL__get_connector_id(hid_t obj_id, hbool_t is_api); +H5_DLL hid_t H5VL__get_connector_id_by_name(const char *name, hbool_t is_api); H5_DLL hid_t H5VL__peek_connector_id(const char *name); H5_DLL herr_t H5VL__connector_str_to_info(const char *str, hid_t connector_id, void **info); diff --git a/src/H5VLprivate.h b/src/H5VLprivate.h index 18d6825..24ae1f3 100644 --- a/src/H5VLprivate.h +++ b/src/H5VLprivate.h @@ -209,6 +209,14 @@ H5_DLL herr_t H5VL_blob_get(const H5VL_object_t *vol_obj, const void *blob_id, v H5_DLL herr_t H5VL_blob_specific(const H5VL_object_t *vol_obj, void *blob_id, H5VL_blob_specific_t specific_type, ...); H5_DLL herr_t H5VL_blob_optional(const H5VL_object_t *vol_obj, void *blob_id, H5VL_blob_optional_t opt_type, ...); +/* Token functions */ +H5_DLL herr_t H5VL_token_cmp(const H5VL_object_t *vol_obj, const H5O_token_t *token1, + const H5O_token_t *token2, int *cmp_value); +H5_DLL herr_t H5VL_token_to_str(const H5VL_object_t *vol_obj, H5I_type_t obj_type, + const H5O_token_t *token, char **token_str); +H5_DLL herr_t H5VL_token_from_str(const H5VL_object_t *vol_obj, H5I_type_t obj_type, + const char *token_str, H5O_token_t *token); + /* Generic functions */ H5_DLL herr_t H5VL_optional(const H5VL_object_t *vol_obj, int op_type, hid_t dxpl_id, void **req, ...); diff --git a/src/H5VLpublic.h b/src/H5VLpublic.h index 34a642e..883aac8 100644 --- a/src/H5VLpublic.h +++ b/src/H5VLpublic.h @@ -66,7 +66,8 @@ extern "C" { H5_DLL hid_t H5VLregister_connector_by_name(const char *connector_name, hid_t vipl_id); H5_DLL hid_t H5VLregister_connector_by_value(H5VL_class_value_t connector_value, hid_t vipl_id); H5_DLL htri_t H5VLis_connector_registered(const char *name); -H5_DLL hid_t H5VLget_connector_id(const char *name); +H5_DLL hid_t H5VLget_connector_id(hid_t obj_id); +H5_DLL hid_t H5VLget_connector_id_by_name(const char *name); H5_DLL ssize_t H5VLget_connector_name(hid_t id, char *name/*out*/, size_t size); H5_DLL herr_t H5VLclose(hid_t connector_id); H5_DLL herr_t H5VLunregister_connector(hid_t connector_id); diff --git a/src/H5public.h b/src/H5public.h index 8021027..86a1fbb 100644 --- a/src/H5public.h +++ b/src/H5public.h @@ -328,6 +328,18 @@ typedef struct H5_ih_info_t { hsize_t heap_size; } H5_ih_info_t; +/* Tokens are unique and permanent identifiers that are + * used to reference HDF5 objects in a container. */ + +/* The maximum size allowed for tokens */ +#define H5O_MAX_TOKEN_SIZE (16) /* Allows for 128-bit tokens */ + +/* Type for object tokens */ +/* (Hoisted here, since it's used by both the H5Lpublic.h and H5Opublic.h headers) */ +typedef struct H5O_token_t { + uint8_t __data[H5O_MAX_TOKEN_SIZE]; +} H5O_token_t; + /* Functions in H5.c */ H5_DLL herr_t H5open(void); H5_DLL herr_t H5close(void); diff --git a/src/H5system.c b/src/H5system.c index 4b5e290..9310243 100644 --- a/src/H5system.c +++ b/src/H5system.c @@ -90,6 +90,8 @@ static hbool_t H5_ntzset = FALSE; * * The conversion 't' refers to an htri_t type. * + * The conversion 'k' refers to an H5O_token_t type. + * * Return: Success: Number of characters printed * * Failure: -1 @@ -416,6 +418,32 @@ HDfprintf(FILE *stream, const char *fmt, ...) } break; + case 'k': + { + H5O_token_t token = HDva_arg(ap, H5O_token_t); + + /* Print the raw token. */ + n = fprintf(stream, "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X", + (unsigned char)token.__data[15], + (unsigned char)token.__data[14], + (unsigned char)token.__data[13], + (unsigned char)token.__data[12], + (unsigned char)token.__data[11], + (unsigned char)token.__data[10], + (unsigned char)token.__data[9], + (unsigned char)token.__data[8], + (unsigned char)token.__data[7], + (unsigned char)token.__data[6], + (unsigned char)token.__data[5], + (unsigned char)token.__data[4], + (unsigned char)token.__data[3], + (unsigned char)token.__data[2], + (unsigned char)token.__data[1], + (unsigned char)token.__data[0] + ); + } + break; + default: HDfputs(format_templ, stream); n = (int)HDstrlen(format_templ); diff --git a/src/H5trace.c b/src/H5trace.c index 83f0ac7..4a24804 100644 --- a/src/H5trace.c +++ b/src/H5trace.c @@ -1630,6 +1630,22 @@ H5_trace(const double *returning, const char *func, const char *type, ...) } /* end switch */ break; + case 'k': + if(ptr) { + if(vp) + HDfprintf(out, "0x%lx", (unsigned long)vp); + else + HDfprintf(out, "NULL"); + } /* end if */ + else { + H5O_token_t token = HDva_arg(ap, H5O_token_t); + int j; + + for (j = 0; j < H5O_MAX_TOKEN_SIZE; j++) + HDfprintf(out, "%02x", token.__data[j]); + } /* end else */ + break; + case 'L': switch(type[1]) { case 'l': @@ -3069,6 +3085,9 @@ H5_trace(const double *returning, const char *func, const char *type, ...) case H5VL_OBJECT_GET_TYPE: HDfprintf(out, "H5VL_OBJECT_GET_TYPE"); break; + case H5VL_OBJECT_GET_INFO: + HDfprintf(out, "H5VL_OBJECT_GET_INFO"); + break; default: HDfprintf(out, "%ld", (long)get); break; @@ -3209,6 +3228,9 @@ H5_trace(const double *returning, const char *func, const char *type, ...) case H5VL_SUBCLS_BLOB: HDfprintf(out, "H5VL_SUBCLS_BLOB"); break; + case H5VL_SUBCLS_TOKEN: + HDfprintf(out, "H5VL_SUBCLS_TOKEN"); + break; default: HDfprintf(out, "%ld", (long)subclass); break; @@ -3442,9 +3464,6 @@ H5_trace(const double *returning, const char *func, const char *type, ...) case H5VL_NATIVE_OBJECT_GET_COMMENT: HDfprintf(out, "H5VL_NATIVE_OBJECT_GET_COMMENT"); break; - case H5VL_NATIVE_OBJECT_GET_INFO: - HDfprintf(out, "H5VL_NATIVE_OBJECT_GET_INFO"); - break; case H5VL_NATIVE_OBJECT_SET_COMMENT: HDfprintf(out, "H5VL_NATIVE_OBJECT_SET_COMMENT"); break; @@ -3457,6 +3476,9 @@ H5_trace(const double *returning, const char *func, const char *type, ...) case H5VL_NATIVE_OBJECT_ARE_MDC_FLUSHES_DISABLED: HDfprintf(out, "H5VL_NATIVE_OBJECT_ARE_MDC_FLUSHES_DISABLED"); break; + case H5VL_NATIVE_OBJECT_GET_NATIVE_INFO: + HDfprintf(out, "H5VL_NATIVE_OBJECT_GET_NATIVE_INFO"); + break; default: HDfprintf(out, "%ld", (long)optional); break; diff --git a/src/H5vers.txt b/src/H5vers.txt index 4b2f222..0df2675 100644 --- a/src/H5vers.txt +++ b/src/H5vers.txt @@ -56,11 +56,17 @@ FUNCTION: H5Ewalk; H5E_walk, H5E_error; v10, v18 FUNCTION: H5Fget_info; H5F_info; v18, v110 FUNCTION: H5Gcreate; ; v10, v18 FUNCTION: H5Gopen; ; v10, v18 -FUNCTION: H5Oget_info; ; v18, v112 -FUNCTION: H5Oget_info_by_name; ; v18, v112 -FUNCTION: H5Oget_info_by_idx; ; v18, v112 -FUNCTION: H5Ovisit; ; v18, v112 -FUNCTION: H5Ovisit_by_name; ; v18, v112 +FUNCTION: H5Lget_info; H5L_info; v18, v112 +FUNCTION: H5Lget_info_by_idx; H5L_info; v18, v112 +FUNCTION: H5Literate; H5L_iterate; v18, v112 +FUNCTION: H5Literate_by_name; H5L_iterate; v18, v112 +FUNCTION: H5Lvisit; H5L_iterate; v18, v112 +FUNCTION: H5Lvisit_by_name; H5L_iterate; v18, v112 +FUNCTION: H5Oget_info; ; v18, v10, v112 +FUNCTION: H5Oget_info_by_name; ; v18, v10, v112 +FUNCTION: H5Oget_info_by_idx; ; v18, v10, v112 +FUNCTION: H5Ovisit; ; v18, v10, v112 +FUNCTION: H5Ovisit_by_name; ; v18, v10, v112 FUNCTION: H5Pencode; ; v110, v112 FUNCTION: H5Pget_filter; ; v10, v18 FUNCTION: H5Pget_filter_by_id; ; v16, v18 @@ -78,5 +84,7 @@ FUNCTION: H5Topen; ; v10, v18 # (although not required, it's easier to compare this file with the headers # generated if the list below is in alphanumeric sort order - QAK) TYPEDEF: H5E_auto; v10, v18 +TYPEDEF: H5O_info; v18, v112 +TYPEDEF: H5O_iterate; v18, v112 TYPEDEF: H5Z_class; v16, v18 diff --git a/src/Makefile.am b/src/Makefile.am index 8a4afbc..0c07c1b 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -38,7 +38,8 @@ MOSTLYCLEANFILES=H5Tinit.c H5lib_settings.c DISTCLEANFILES=H5pubconf.h # library sources -libhdf5_la_SOURCES= H5.c H5checksum.c H5dbg.c H5system.c H5timer.c H5trace.c \ +libhdf5_la_SOURCES= H5.c H5checksum.c H5dbg.c H5lib_settings.c H5system.c \ + H5timer.c H5trace.c \ H5A.c H5Abtree2.c H5Adense.c H5Adeprec.c H5Aint.c H5Atest.c \ H5AC.c H5ACdbg.c H5ACproxy_entry.c \ H5B.c H5Bcache.c H5Bdbg.c \ @@ -48,59 +49,49 @@ libhdf5_la_SOURCES= H5.c H5checksum.c H5dbg.c H5system.c H5timer.c H5trace.c \ H5Cprefetched.c H5Cquery.c H5Ctag.c H5Ctest.c \ H5CS.c \ H5CX.c \ - H5D.c H5Dbtree.c H5Dbtree2.c H5Dchunk.c H5Dcompact.c H5Dcontig.c H5Ddbg.c \ - H5Ddeprec.c H5Dearray.c H5Defl.c H5Dfarray.c H5Dfill.c H5Dint.c \ - H5Dio.c H5Dlayout.c H5Dnone.c \ - H5Doh.c H5Dscatgath.c H5Dselect.c \ - H5Dsingle.c H5Dtest.c H5Dvirtual.c \ + H5D.c H5Dbtree.c H5Dbtree2.c H5Dchunk.c H5Dcompact.c H5Dcontig.c \ + H5Ddbg.c H5Ddeprec.c H5Dearray.c H5Defl.c H5Dfarray.c H5Dfill.c \ + H5Dint.c H5Dio.c H5Dlayout.c H5Dnone.c H5Doh.c H5Dscatgath.c \ + H5Dselect.c H5Dsingle.c H5Dtest.c H5Dvirtual.c \ H5E.c H5Edeprec.c H5Eint.c \ H5EA.c H5EAcache.c H5EAdbg.c H5EAdblkpage.c H5EAdblock.c H5EAhdr.c \ H5EAiblock.c H5EAint.c H5EAsblock.c H5EAstat.c H5EAtest.c \ - H5F.c H5Faccum.c H5Fcwfs.c \ - H5Fdbg.c H5Fdeprec.c H5Fefc.c H5Ffake.c H5Fint.c H5Fio.c \ - H5Fmount.c H5Fquery.c \ - H5Fsfile.c H5Fspace.c H5Fsuper.c H5Fsuper_cache.c H5Ftest.c \ + H5F.c H5Faccum.c H5Fcwfs.c H5Fdbg.c H5Fdeprec.c H5Fefc.c H5Ffake.c \ + H5Fint.c H5Fio.c H5Fmount.c H5Fquery.c H5Fsfile.c H5Fspace.c \ + H5Fsuper.c H5Fsuper_cache.c H5Ftest.c \ H5FA.c H5FAcache.c H5FAdbg.c H5FAdblock.c H5FAdblkpage.c H5FAhdr.c \ H5FAint.c H5FAstat.c H5FAtest.c \ H5FD.c H5FDcore.c H5FDfamily.c H5FDhdfs.c H5FDint.c H5FDlog.c \ H5FDmulti.c H5FDsec2.c H5FDspace.c H5FDstdio.c H5FDtest.c \ H5FL.c H5FO.c H5FS.c H5FScache.c H5FSdbg.c H5FSint.c H5FSsection.c \ H5FSstat.c H5FStest.c \ - H5G.c H5Gbtree2.c H5Gcache.c \ - H5Gcompact.c H5Gdense.c H5Gdeprec.c H5Gent.c \ - H5Gint.c H5Glink.c \ - H5Gloc.c H5Gname.c H5Gnode.c H5Gobj.c H5Goh.c H5Groot.c H5Gstab.c H5Gtest.c \ - H5Gtraverse.c \ + H5G.c H5Gbtree2.c H5Gcache.c H5Gcompact.c H5Gdense.c H5Gdeprec.c \ + H5Gent.c H5Gint.c H5Glink.c H5Gloc.c H5Gname.c H5Gnode.c H5Gobj.c \ + H5Goh.c H5Groot.c H5Gstab.c H5Gtest.c H5Gtraverse.c \ H5HF.c H5HFbtree2.c H5HFcache.c H5HFdbg.c H5HFdblock.c H5HFdtable.c \ H5HFhdr.c H5HFhuge.c H5HFiblock.c H5HFiter.c H5HFman.c H5HFsection.c \ H5HFspace.c H5HFstat.c H5HFtest.c H5HFtiny.c \ H5HG.c H5HGcache.c H5HGdbg.c H5HGquery.c \ - H5HL.c H5HLcache.c H5HLdbg.c H5HLint.c H5HLprfx.c H5HLdblk.c\ - H5HP.c H5I.c H5Itest.c H5L.c H5Lexternal.c H5lib_settings.c \ + H5HL.c H5HLcache.c H5HLdbg.c H5HLint.c H5HLprfx.c H5HLdblk.c \ + H5HP.c \ + H5I.c H5Itest.c \ + H5L.c H5Ldeprec.c H5Lexternal.c \ H5M.c \ H5MF.c H5MFaggr.c H5MFdbg.c H5MFsection.c \ H5MM.c H5MP.c H5MPtest.c \ - H5O.c H5Odeprec.c H5Oainfo.c H5Oalloc.c H5Oattr.c \ - H5Oattribute.c H5Obogus.c H5Obtreek.c H5Ocache.c H5Ocache_image.c \ - H5Ochunk.c \ - H5Ocont.c H5Ocopy.c H5Ocopy_ref.c H5Odbg.c H5Odrvinfo.c H5Odtype.c H5Oefl.c \ - H5Ofill.c H5Oflush.c H5Ofsinfo.c H5Oginfo.c \ - H5Oint.c H5Olayout.c \ - H5Olinfo.c H5Olink.c H5Omessage.c H5Omtime.c \ - H5Oname.c H5Onull.c H5Opline.c H5Orefcount.c \ - H5Osdspace.c H5Oshared.c \ - H5Oshmesg.c \ - H5Ostab.c \ - H5Otest.c H5Ounknown.c \ - H5P.c H5Pacpl.c H5Pdapl.c H5Pdcpl.c \ - H5Pdeprec.c H5Pdxpl.c H5Pencdec.c \ - H5Pfapl.c H5Pfcpl.c H5Pfmpl.c \ - H5Pgcpl.c H5Pint.c H5Plapl.c H5Plcpl.c \ - H5Pmapl.c H5Pmcpl.c H5Pocpl.c H5Pocpypl.c H5Pstrcpl.c \ - H5Ptest.c \ + H5O.c H5Odeprec.c H5Oainfo.c H5Oalloc.c H5Oattr.c H5Oattribute.c \ + H5Obogus.c H5Obtreek.c H5Ocache.c H5Ocache_image.c H5Ochunk.c \ + H5Ocont.c H5Ocopy.c H5Ocopy_ref.c H5Odbg.c H5Odrvinfo.c H5Odtype.c \ + H5Oefl.c H5Ofill.c H5Oflush.c H5Ofsinfo.c H5Oginfo.c H5Oint.c \ + H5Olayout.c H5Olinfo.c H5Olink.c H5Omessage.c H5Omtime.c H5Oname.c \ + H5Onull.c H5Opline.c H5Orefcount.c H5Osdspace.c H5Oshared.c \ + H5Oshmesg.c H5Ostab.c H5Otest.c H5Ounknown.c \ + H5P.c H5Pacpl.c H5Pdapl.c H5Pdcpl.c H5Pdeprec.c H5Pdxpl.c H5Pencdec.c \ + H5Pfapl.c H5Pfcpl.c H5Pfmpl.c H5Pgcpl.c H5Pint.c H5Plapl.c H5Plcpl.c \ + H5Pmapl.c H5Pmcpl.c H5Pocpl.c H5Pocpypl.c H5Pstrcpl.c H5Ptest.c \ H5PB.c \ H5PL.c H5PLint.c H5PLpath.c H5PLplugin_cache.c \ - H5R.c H5Rint.c H5Rdeprec.c \ + H5R.c H5Rdeprec.c H5Rint.c \ H5UC.c \ H5RS.c \ H5S.c H5Sall.c H5Sdbg.c H5Sdeprec.c H5Shyper.c H5Snone.c H5Spoint.c \ @@ -109,21 +100,20 @@ libhdf5_la_SOURCES= H5.c H5checksum.c H5dbg.c H5system.c H5timer.c H5trace.c \ H5SM.c H5SMbtree2.c H5SMcache.c H5SMmessage.c H5SMtest.c \ H5ST.c \ H5T.c H5Tarray.c H5Tbit.c H5Tcommit.c H5Tcompound.c H5Tconv.c \ - H5Tcset.c H5Tdbg.c H5Tdeprec.c H5Tenum.c H5Tfields.c \ - H5Tfixed.c \ - H5Tfloat.c H5Tinit.c H5Tnative.c H5Toffset.c H5Toh.c \ - H5Topaque.c \ - H5Torder.c \ - H5Tref.c \ - H5Tpad.c H5Tprecis.c H5Tstrpad.c H5Tvisit.c H5Tvlen.c H5TS.c \ + H5Tcset.c H5Tdbg.c H5Tdeprec.c H5Tenum.c H5Tfields.c H5Tfixed.c \ + H5Tfloat.c H5Tinit.c H5Tnative.c H5Toffset.c H5Toh.c H5Topaque.c \ + H5Torder.c H5Tref.c H5Tpad.c H5Tprecis.c H5Tstrpad.c H5Tvisit.c \ + H5Tvlen.c \ + H5TS.c \ H5VL.c H5VLcallback.c H5VLint.c H5VLnative.c \ H5VLnative_attr.c H5VLnative_blob.c H5VLnative_dataset.c \ H5VLnative_datatype.c H5VLnative_file.c H5VLnative_group.c \ H5VLnative_link.c H5VLnative_introspect.c H5VLnative_object.c \ + H5VLnative_token.c \ H5VLpassthru.c \ H5VM.c H5WB.c H5Z.c \ - H5Zdeflate.c H5Zfletcher32.c H5Znbit.c H5Zshuffle.c \ - H5Zscaleoffset.c H5Zszip.c H5Ztrans.c + H5Zdeflate.c H5Zfletcher32.c H5Znbit.c H5Zshuffle.c H5Zscaleoffset.c \ + H5Zszip.c H5Ztrans.c # Only compile parallel sources if necessary if BUILD_PARALLEL_CONDITIONAL diff --git a/test/cache_tagging.c b/test/cache_tagging.c index 7ce4e88..564e5bc 100644 --- a/test/cache_tagging.c +++ b/test/cache_tagging.c @@ -24,6 +24,7 @@ #include "H5CXprivate.h" /* API Contexts */ #include "H5HLprivate.h" +#include "H5VLnative_private.h" /* Native VOL connector */ /* ============ */ /* Test Defines */ @@ -374,14 +375,15 @@ error: static int get_object_header_tag(hid_t loc_id, haddr_t *tag) { - H5O_info_t oinfo; /* Object info */ + H5O_info2_t oinfo; /* Object info */ /* Retrieve the info for the object */ - if(H5Oget_info2(loc_id, &oinfo, H5O_INFO_ALL) < 0) + if(H5Oget_info3(loc_id, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR; /* Set the tag to return */ - *tag = oinfo.addr; + if(H5VLnative_token_to_addr(loc_id, oinfo.token, tag) < 0) + TEST_ERROR; return 0; @@ -439,7 +441,9 @@ check_file_creation_tags(hid_t fcpl_id, int type) { /* Variable Declarations */ hid_t fid = -1; /* File Identifier */ +#ifndef NDEBUG int verbose = FALSE; /* verbose test outout */ +#endif /* NDEBUG */ /* end debugging functions */ hid_t fapl = -1; /* File access prop list */ haddr_t root_tag = 0; haddr_t sbe_tag = 0; @@ -526,7 +530,9 @@ check_file_open_tags(hid_t fcpl, int type) { /* Variable Declarations */ hid_t fid = -1; /* File Identifier */ +#ifndef NDEBUG int verbose = FALSE; /* verbose file outout */ +#endif /* NDEBUG */ /* end debugging functions */ hid_t fapl = -1; /* File access prop list */ haddr_t root_tag; /* Root Group Tag */ haddr_t sbe_tag; /* Sblock Extension Tag */ @@ -639,7 +645,9 @@ check_group_creation_tags(void) /* Variable Declarations */ hid_t fid = -1; /* File Identifier */ hid_t gid = -1; /* Group Identifier */ +#ifndef NDEBUG int verbose = FALSE; /* verbose file outout */ +#endif /* NDEBUG */ /* end debugging functions */ hid_t fapl = -1; /* File access prop list */ haddr_t root_tag = HADDR_UNDEF; /* Root Group Tag */ haddr_t g_tag; /* Group Tag */ @@ -740,7 +748,9 @@ check_multi_group_creation_tags(void) /* Variable Declarations */ hid_t fid = -1; /* File Identifier */ hid_t gid = -1; /* Group Identifier */ +#ifndef NDEBUG int verbose = FALSE; /* verbose file outout */ +#endif /* NDEBUG */ /* end debugging functions */ char gname[16]; /* group name buffer */ int i = 0; /* iterator */ hid_t fapl = -1; /* File access prop list */ @@ -869,7 +879,9 @@ check_link_iteration_tags(void) hid_t fid = -1; /* File Identifier */ hid_t sid = -1; /* Group Identifier */ hid_t did = -1; /* Group Identifier */ +#ifndef NDEBUG int verbose = FALSE; /* verbose file outout */ +#endif /* NDEBUG */ /* end debugging functions */ int i = 0; /* iterator */ haddr_t root_tag = 0; /* Root Group Tag Value */ char dsetname[500]; /* Name of dataset */ @@ -989,7 +1001,9 @@ check_dense_attribute_tags(void) hid_t sid = -1; /* Group Identifier */ hid_t did = -1; /* Group Identifier */ hid_t dcpl = -1; /* Group Identifier */ +#ifndef NDEBUG int verbose = FALSE; /* verbose file outout */ +#endif /* NDEBUG */ /* end debugging functions */ int i = 0; /* iterator */ hid_t fapl = -1; /* File access property list */ haddr_t d_tag = 0; /* Dataset tag value */ @@ -1171,7 +1185,9 @@ check_group_open_tags(void) /* Variable Declarations */ hid_t fid = -1; /* File Identifier */ hid_t gid = -1; /* Group Identifier */ +#ifndef NDEBUG int verbose = FALSE; /* verbose file output */ +#endif /* NDEBUG */ /* end debugging functions */ hid_t fapl = -1; /* File access prop list */ haddr_t root_tag = HADDR_UNDEF; haddr_t g_tag; @@ -1280,7 +1296,9 @@ check_attribute_creation_tags(hid_t fcpl, int type) hid_t aid = -1; /* Attribute Identifier */ hid_t gid = -1; /* Group Identifier */ hid_t sid = -1; /* Dataspace Identifier */ +#ifndef NDEBUG int verbose = FALSE; /* verbose file outout */ +#endif /* NDEBUG */ /* end debugging functions */ hid_t fapl = -1; /* File access prop list */ haddr_t root_tag = 0; /* Root group tag */ haddr_t g_tag = 0; @@ -1414,7 +1432,9 @@ check_attribute_open_tags(hid_t fcpl, int type) hid_t aid = -1; /* Attribute Identifier */ hid_t gid = -1; /* Group Identifier */ hid_t sid = -1; /* Dataspace Identifier */ +#ifndef NDEBUG int verbose = FALSE; /* verbose file outout */ +#endif /* NDEBUG */ /* end debugging functions */ hid_t fapl = -1; /* File access prop list */ haddr_t root_tag = 0; haddr_t g_tag = 0; @@ -1551,7 +1571,9 @@ check_attribute_rename_tags(hid_t fcpl, int type) hid_t gid = -1; /* Group Identifier */ hid_t aid = -1; /* Attribute Identifier */ hid_t sid = -1; /* Dataset Identifier */ +#ifndef NDEBUG int verbose = FALSE; /* verbose file outout */ +#endif /* NDEBUG */ /* end debugging functions */ int *data = NULL; /* data buffer */ int i,j,k = 0; /* iterators */ hid_t fapl = -1; /* File access prop list */ @@ -1726,7 +1748,9 @@ check_attribute_delete_tags(hid_t fcpl, int type) hid_t gid = -1; /* Group Identifier */ hid_t aid = -1; /* Attribute Identifier */ hid_t sid = -1; /* Dataset Identifier */ +#ifndef NDEBUG int verbose = FALSE; /* verbose file outout */ +#endif /* NDEBUG */ /* end debugging functions */ int *data = NULL; /* data buffer */ int i,j,k = 0; /* iterators */ hid_t fapl = -1; /* File access prop list */ @@ -1892,7 +1916,9 @@ check_dataset_creation_tags(hid_t fcpl, int type) hid_t fid = -1; /* File Identifier */ hid_t did = -1; /* Dataset Identifier */ hid_t sid = -1; /* Dataspace Identifier */ +#ifndef NDEBUG int verbose = FALSE; /* verbose file outout */ +#endif /* NDEBUG */ /* end debugging functions */ hid_t dcpl = -1; /* dataset creation pl */ hsize_t cdims[2] = {1,1}; /* chunk dimensions */ int fillval = 0; @@ -2025,7 +2051,9 @@ check_dataset_creation_earlyalloc_tags(hid_t fcpl, int type) hid_t fid = -1; /* File Identifier */ hid_t did = -1; /* Dataset Identifier */ hid_t sid = -1; /* Dataspace Identifier */ +#ifndef NDEBUG int verbose = FALSE; /* verbose file outout */ +#endif /* NDEBUG */ /* end debugging functions */ hid_t dcpl = -1; /* dataset creation pl */ hsize_t cdims[2] = {1,1}; /* chunk dimensions */ int fillval = 0; @@ -2162,7 +2190,9 @@ check_dataset_open_tags(void) hid_t fid = -1; /* File Identifier */ hid_t did = -1; /* Dataset Identifier */ hid_t sid = -1; /* Dataspace Identifier */ +#ifndef NDEBUG int verbose = FALSE; /* verbose file outout */ +#endif /* NDEBUG */ /* end debugging functions */ hid_t dcpl = -1; /* dataset creation pl */ hsize_t cdims[2] = {1,1}; /* chunk dimensions */ int fillval = 0; @@ -2288,7 +2318,9 @@ check_dataset_write_tags(void) hid_t fid = -1; /* File Identifier */ hid_t did = -1; /* Dataset Identifier */ hid_t sid = -1; /* Dataspace Identifier */ +#ifndef NDEBUG int verbose = FALSE; /* verbose file outout */ +#endif /* NDEBUG */ /* end debugging functions */ hid_t dcpl = -1; /* dataset creation pl */ hsize_t cdims[2] = {1,1}; /* chunk dimensions */ int fillval = 0; @@ -2430,7 +2462,9 @@ check_attribute_write_tags(hid_t fcpl, int type) hid_t gid = -1; /* Group Identifier */ hid_t aid = -1; /* Attribute Identifier */ hid_t sid = -1; /* Dataset Identifier */ +#ifndef NDEBUG int verbose = FALSE; /* verbose file outout */ +#endif /* NDEBUG */ /* end debugging functions */ int *data = NULL; /* data buffer */ int i,j,k = 0; /* iterators */ hid_t fapl = -1; /* File access prop list */ @@ -2583,7 +2617,9 @@ check_dataset_read_tags(void) hid_t fid = -1; /* File Identifier */ hid_t did = -1; /* Dataset Identifier */ hid_t sid = -1; /* Dataspace Identifier */ +#ifndef NDEBUG int verbose = FALSE; /* verbose file outout */ +#endif /* NDEBUG */ /* end debugging functions */ hid_t dcpl = -1; /* dataset creation pl */ hsize_t cdims[2] = {1,1}; /* chunk dimensions */ int fillval = 0; @@ -2720,7 +2756,9 @@ check_dataset_size_retrieval(void) hid_t fid = -1; /* File Identifier */ hid_t did = -1; /* Dataset Identifier */ hid_t sid = -1; /* Dataspace Identifier */ +#ifndef NDEBUG int verbose = FALSE; /* verbose file outout */ +#endif /* NDEBUG */ /* end debugging functions */ hid_t dcpl = -1; /* dataset creation pl */ hsize_t cdims[2] = {1,1}; /* chunk dimensions */ int fillval = 0; @@ -2859,7 +2897,9 @@ check_dataset_extend_tags(void) hid_t fid = -1; /* File Identifier */ hid_t did = -1; /* Dataset Identifier */ hid_t sid = -1; /* Dataspace Identifier */ +#ifndef NDEBUG int verbose = FALSE; /* verbose file outout */ +#endif /* NDEBUG */ /* end debugging functions */ hid_t dcpl = -1; /* dataset creation pl */ hsize_t cdims[2] = {1,1}; /* chunk dimensions */ int fillval = 0; @@ -2996,11 +3036,13 @@ check_object_info_tags(void) /* Variable Declarations */ hid_t fid = -1; /* File Identifier */ hid_t gid = -1; /* Group Identifier */ +#ifndef NDEBUG int verbose = FALSE; /* verbose file output */ +#endif /* NDEBUG */ /* end debugging functions */ hid_t fapl = -1; /* File access prop list */ haddr_t root_tag = HADDR_UNDEF; haddr_t g_tag; - H5O_info_t oinfo; /* Object info struct */ + H5O_native_info_t ninfo; /* Native object info struct */ /* Testing Macro */ TESTING("tag application during object info retrieval"); @@ -3040,7 +3082,10 @@ check_object_info_tags(void) /* Get information on an object by name */ /* ===================================== */ - if ( H5Oget_info_by_name2(fid, GROUPNAME, &oinfo, H5O_INFO_ALL, H5P_DEFAULT) < 0 ) TEST_ERROR; + /* Even though we do nothing with this, touching the internal + * data structures is needed for the test to pass. + */ + if ( H5Oget_native_info_by_name(fid, GROUPNAME, &ninfo, H5O_NATIVE_INFO_ALL, H5P_DEFAULT) < 0 ) TEST_ERROR; /* =================================== */ /* Verification of Metadata Tag Values */ @@ -3105,7 +3150,9 @@ check_object_copy_tags(void) /* Variable Declarations */ hid_t fid = -1; /* File Identifier */ hid_t gid = -1; /* Group Identifier */ +#ifndef NDEBUG int verbose = FALSE; /* verbose file output */ +#endif /* NDEBUG */ /* end debugging functions */ hid_t fapl = -1; /* File access prop list */ haddr_t root_tag = HADDR_UNDEF; haddr_t g_tag; @@ -3226,7 +3273,9 @@ check_link_removal_tags(hid_t fcpl, int type) hid_t did = -1; /* Dataset Identifier */ hid_t sid = -1; /* Dataspace Identifier */ hid_t gid = -1; /* Dataspace Identifier */ +#ifndef NDEBUG int verbose = FALSE; /* verbose file outout */ +#endif /* NDEBUG */ /* end debugging functions */ hid_t dcpl = -1; /* dataset creation pl */ hsize_t cdims[2] = {1,1}; /* chunk dimensions */ int fillval = 0; @@ -3385,7 +3434,9 @@ check_link_getname_tags(void) hid_t did = -1; /* Dataset Identifier */ hid_t sid = -1; /* Dataspace Identifier */ hid_t gid = -1; /* Dataspace Identifier */ +#ifndef NDEBUG int verbose = FALSE; /* verbose file outout */ +#endif /* NDEBUG */ /* end debugging functions */ hid_t dcpl = -1; /* dataset creation pl */ hsize_t cdims[2] = {1,1}; /* chunk dimensions */ int fillval = 0; @@ -3534,7 +3585,9 @@ check_external_link_creation_tags(void) hid_t fid = -1; /* File Identifier */ hid_t fid2 = -1; /* File Identifier */ hid_t gid = -1; /* Dataspace Identifier */ +#ifndef NDEBUG int verbose = FALSE; /* verbose file outout */ +#endif /* NDEBUG */ /* end debugging functions */ hid_t fapl = -1; /* File access prop list */ haddr_t root_tag = 0; @@ -3640,7 +3693,10 @@ check_external_link_open_tags(void) hid_t fid2 = -1; /* File Identifier */ hid_t gid = -1; /* Dataspace Identifier */ hid_t xid = -1; /* Dataspace Identifier */ +#ifndef NDEBUG int verbose = FALSE; /* verbose file outout */ +#endif /* NDEBUG */ /* end debugging functions */ + H5O_native_info_t ninfo; /* Native object info struct */ hid_t fapl = -1; /* File access prop list */ haddr_t root_tag = 0; haddr_t root2_tag = 0; @@ -3694,6 +3750,11 @@ check_external_link_open_tags(void) if ( (fid2 = H5Iget_file_id(xid)) < 0) TEST_ERROR; if ( get_object_header_tag(xid, &link_tag) < 0 ) TEST_ERROR; + /* Even though we do nothing with this, touching the internal + * data structures is needed for the test to pass. + */ + if ( H5Oget_native_info(xid, &ninfo, H5O_NATIVE_INFO_ALL) < 0 ) TEST_ERROR; + /* =================================== */ /* Verification of Metadata Tag Values */ /* =================================== */ @@ -3836,8 +3897,8 @@ check_invalid_tag_application(void) return 0; -error: #if H5C_DO_TAGGING_SANITY_CHECKS +error: if(api_ctx_pushed) H5CX_pop(); #endif /* H5C_DO_TAGGING_SANITY_CHECKS */ diff --git a/test/chunk_info.c b/test/chunk_info.c index 057991c..0afff66 100644 --- a/test/chunk_info.c +++ b/test/chunk_info.c @@ -119,7 +119,7 @@ const char *FILENAME[] = { #define INVALID_CHK_INDEX 5 /* For compressed data */ -#define DEFLATE_SIZE_ADJUST(s) (ceil(((double)(s))*1.001)+12) +#define DEFLATE_SIZE_ADJUST(s) (ceil(((double)(s))*1.001)+12.0) /* For use in error reporting */ #define MSG_CHK_ADDR "Chunk address should not be HADDR_UNDEF because of H5D_ALLOC_TIME_EARLY." diff --git a/test/cork.c b/test/cork.c index 78b6b01..125c53e 100644 --- a/test/cork.c +++ b/test/cork.c @@ -102,7 +102,7 @@ verify_old_dset_cork(void) int **buf = NULL; /* Data bufer (pointers to fake 2D array) */ int *buf_data = NULL; /* Data buffer (actual data) */ int i = 0, j = 0; /* Local index variables */ - H5O_info_t oinfo, oinfo2, oinfo3; /* Object metadata information */ + H5O_info2_t oinfo, oinfo2, oinfo3; /* Object metadata information */ hsize_t dims2[2] = {8, 16}; /* Dataset dimension sizes */ /* Testing Macro */ @@ -127,7 +127,7 @@ verify_old_dset_cork(void) TEST_ERROR /* Get dataset object header address: DSET_BT1 */ - if(H5Oget_info2(did, &oinfo, H5O_INFO_BASIC) < 0) + if(H5Oget_info3(did, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR /* Cork the dataset: DSET_BT1 */ @@ -135,7 +135,7 @@ verify_old_dset_cork(void) TEST_ERROR /* Verify cork status */ - if(H5C__verify_cork_tag_test(fid, oinfo.addr, TRUE) < 0) + if(H5C__verify_cork_tag_test(fid, oinfo.token, TRUE) < 0) TEST_ERROR /* Set up data array */ @@ -156,7 +156,7 @@ verify_old_dset_cork(void) TEST_ERROR /* Verify the cork status for DSET_BT1 */ - if(H5C__verify_cork_tag_test(fid, oinfo.addr, TRUE) < 0) + if(H5C__verify_cork_tag_test(fid, oinfo.token, TRUE) < 0) TEST_ERROR /* Create compact dataset: DSET_COMPACT */ @@ -172,7 +172,7 @@ verify_old_dset_cork(void) FAIL_STACK_ERROR /* Get dataset object address */ - if(H5Oget_info2(did2, &oinfo2, H5O_INFO_BASIC) < 0) + if(H5Oget_info3(did2, &oinfo2, H5O_INFO_BASIC) < 0) TEST_ERROR /* Cork the dataset: DSET_COMPACT */ @@ -180,7 +180,7 @@ verify_old_dset_cork(void) TEST_ERROR /* Verify cork status */ - if(H5C__verify_cork_tag_test(fid, oinfo2.addr, TRUE) < 0) + if(H5C__verify_cork_tag_test(fid, oinfo2.token, TRUE) < 0) TEST_ERROR /* Closing */ @@ -220,7 +220,7 @@ verify_old_dset_cork(void) FAIL_STACK_ERROR /* Get dataset object address: DSET_CONTIG */ - if(H5Oget_info2(did3, &oinfo3, H5O_INFO_BASIC) < 0) + if(H5Oget_info3(did3, &oinfo3, H5O_INFO_BASIC) < 0) TEST_ERROR /* Cork the dataset: DSET_CONTIG */ @@ -228,11 +228,11 @@ verify_old_dset_cork(void) TEST_ERROR /* Verify the cork status for DSET_CONTIG */ - if(H5C__verify_cork_tag_test(fid, oinfo3.addr, TRUE) < 0) + if(H5C__verify_cork_tag_test(fid, oinfo3.token, TRUE) < 0) TEST_ERROR /* Verify the cork status for DSET_BT1 */ - if(H5C__verify_cork_tag_test(fid, oinfo.addr, FALSE) < 0) + if(H5C__verify_cork_tag_test(fid, oinfo.token, FALSE) < 0) TEST_ERROR /* Un-cork the dataset: DSET_CONTIG */ @@ -240,7 +240,7 @@ verify_old_dset_cork(void) TEST_ERROR /* Verify the cork status for DSET_CONTIG */ - if(H5C__verify_cork_tag_test(fid, oinfo3.addr, FALSE) < 0) + if(H5C__verify_cork_tag_test(fid, oinfo3.token, FALSE) < 0) TEST_ERROR /* Closing */ @@ -307,7 +307,7 @@ verify_obj_dset_cork(hbool_t swmr) int i = 0; /* Local index variable */ hsize_t dim[1] = {100}; /* Dataset dimension size */ hsize_t chunk_dim[1] = {7}; /* Dataset chunk dimension size */ - H5O_info_t oinfo, oinfo2; /* Object metadata information */ + H5O_info2_t oinfo, oinfo2; /* Object metadata information */ char attrname[500]; /* Name of attribute */ unsigned flags; /* File access flags */ @@ -340,11 +340,11 @@ verify_obj_dset_cork(hbool_t swmr) TEST_ERROR /* Get dataset object header address */ - if(H5Oget_info2(did, &oinfo, H5O_INFO_BASIC) < 0) + if(H5Oget_info3(did, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR /* Verify cork status of the dataset: DSET */ - if(H5C__verify_cork_tag_test(fid, oinfo.addr, FALSE) < 0) + if(H5C__verify_cork_tag_test(fid, oinfo.token, FALSE) < 0) TEST_ERROR /* Cork the dataset: DSET */ @@ -356,7 +356,7 @@ verify_obj_dset_cork(hbool_t swmr) TEST_ERROR /* Verify cork status of the dataset: DSET */ - if(H5C__verify_cork_tag_test(fid, oinfo.addr, TRUE) < 0) + if(H5C__verify_cork_tag_test(fid, oinfo.token, TRUE) < 0) TEST_ERROR /* Close the attribute */ @@ -364,7 +364,7 @@ verify_obj_dset_cork(hbool_t swmr) TEST_ERROR /* Verify cork status of the dataset: DSET */ - if(H5C__verify_cork_tag_test(fid, oinfo.addr, TRUE) < 0) + if(H5C__verify_cork_tag_test(fid, oinfo.token, TRUE) < 0) TEST_ERROR /* Create dcpl */ @@ -383,7 +383,7 @@ verify_obj_dset_cork(hbool_t swmr) TEST_ERROR /* Get dataset object header address */ - if(H5Oget_info2(did2, &oinfo2, H5O_INFO_BASIC) < 0) + if(H5Oget_info3(did2, &oinfo2, H5O_INFO_BASIC) < 0) TEST_ERROR /* Cork the dataset: DSET_NONE */ @@ -402,7 +402,7 @@ verify_obj_dset_cork(hbool_t swmr) } /* end for */ /* Verify cork status of the dataset: DSET_NONE */ - if(H5C__verify_cork_tag_test(fid, oinfo2.addr, TRUE) < 0) + if(H5C__verify_cork_tag_test(fid, oinfo2.token, TRUE) < 0) TEST_ERROR /* Closing */ @@ -431,7 +431,7 @@ verify_obj_dset_cork(hbool_t swmr) TEST_ERROR /* Verify cork status of the dataset: DSET */ - if(H5C__verify_cork_tag_test(fid, oinfo2.addr, FALSE) < 0) + if(H5C__verify_cork_tag_test(fid, oinfo2.token, FALSE) < 0) TEST_ERROR /* Open the attribute attached to the dataset object: DSET_NONE */ @@ -443,7 +443,7 @@ verify_obj_dset_cork(hbool_t swmr) TEST_ERROR /* Verify cork status of the dataset: DSET_NONE */ - if(H5C__verify_cork_tag_test(fid, oinfo2.addr, TRUE) < 0) + if(H5C__verify_cork_tag_test(fid, oinfo2.token, TRUE) < 0) TEST_ERROR /* Close the attribute */ @@ -451,7 +451,7 @@ verify_obj_dset_cork(hbool_t swmr) TEST_ERROR /* Verify cork status of the dataset: DSET */ - if(H5C__verify_cork_tag_test(fid, oinfo.addr, TRUE) < 0) + if(H5C__verify_cork_tag_test(fid, oinfo.token, TRUE) < 0) TEST_ERROR /* Closing */ @@ -510,8 +510,8 @@ verify_dset_cork(hbool_t swmr, hbool_t new_format) int **buf = NULL; /* Data bufer (pointers to fake 2D array) */ int *buf_data = NULL; /* Data buffer (actual data) */ int i = 0, j = 0; /* Local index variables */ - H5O_info_t oinfo, oinfo2, oinfo3; /* Object metadata information */ - unsigned flags; /* File access flags */ + H5O_info2_t oinfo, oinfo2, oinfo3; /* Object metadata information */ + unsigned flags; /* File access flags */ /* Testing Macro */ if(swmr) { @@ -559,7 +559,7 @@ verify_dset_cork(hbool_t swmr, hbool_t new_format) TEST_ERROR /* Get dataset object header address: DSET_EA */ - if(H5Oget_info2(did, &oinfo, H5O_INFO_BASIC) < 0) + if(H5Oget_info3(did, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR /* Cork the dataset: DSET_EA */ @@ -567,7 +567,7 @@ verify_dset_cork(hbool_t swmr, hbool_t new_format) TEST_ERROR /* Verify cork status */ - if(H5C__verify_cork_tag_test(fid, oinfo.addr, TRUE) < 0) + if(H5C__verify_cork_tag_test(fid, oinfo.token, TRUE) < 0) TEST_ERROR /* Create chunked dataset with fixed array indexing: DSET_FA */ @@ -577,7 +577,7 @@ verify_dset_cork(hbool_t swmr, hbool_t new_format) TEST_ERROR /* Get dataset object header address: DSET_FA */ - if(H5Oget_info2(did2, &oinfo2, H5O_INFO_BASIC) < 0) + if(H5Oget_info3(did2, &oinfo2, H5O_INFO_BASIC) < 0) TEST_ERROR /* Cork the dataset: DSET_FA */ @@ -589,11 +589,11 @@ verify_dset_cork(hbool_t swmr, hbool_t new_format) TEST_ERROR /* Verify the cork status for DSET_FA */ - if(H5C__verify_cork_tag_test(fid, oinfo2.addr, TRUE) < 0) + if(H5C__verify_cork_tag_test(fid, oinfo2.token, TRUE) < 0) TEST_ERROR /* Verify the cork status for DSET_EA */ - if(H5C__verify_cork_tag_test(fid, oinfo.addr, FALSE) < 0) + if(H5C__verify_cork_tag_test(fid, oinfo.token, FALSE) < 0) TEST_ERROR /* Create chunked dataset with v2-Btree indexing */ @@ -604,7 +604,7 @@ verify_dset_cork(hbool_t swmr, hbool_t new_format) TEST_ERROR /* Get dataset object header address: DSET_BT2 */ - if(H5Oget_info2(did3, &oinfo3, H5O_INFO_BASIC) < 0) + if(H5Oget_info3(did3, &oinfo3, H5O_INFO_BASIC) < 0) TEST_ERROR /* Cork the dataset: DSET_BT2 */ @@ -612,7 +612,7 @@ verify_dset_cork(hbool_t swmr, hbool_t new_format) TEST_ERROR /* Verify the cork status for DSET_BT2 */ - if(H5C__verify_cork_tag_test(fid, oinfo3.addr, TRUE) < 0) + if(H5C__verify_cork_tag_test(fid, oinfo3.token, TRUE) < 0) TEST_ERROR /* Closing */ @@ -663,7 +663,7 @@ verify_dset_cork(hbool_t swmr, hbool_t new_format) TEST_ERROR /* Verify the cork status for DSET_EA */ - if(H5C__verify_cork_tag_test(fid, oinfo.addr, FALSE) < 0) + if(H5C__verify_cork_tag_test(fid, oinfo.token, FALSE) < 0) TEST_ERROR /* Open and write to the dataset: DSET_FA */ @@ -677,7 +677,7 @@ verify_dset_cork(hbool_t swmr, hbool_t new_format) TEST_ERROR /* Verify the cork status for DSET_FA */ - if(H5C__verify_cork_tag_test(fid, oinfo2.addr, TRUE) < 0) + if(H5C__verify_cork_tag_test(fid, oinfo2.token, TRUE) < 0) TEST_ERROR /* Open and write to the dataset: DSET_BT2 */ @@ -687,7 +687,7 @@ verify_dset_cork(hbool_t swmr, hbool_t new_format) TEST_ERROR /* Verify the cork status for DSET_BT2 */ - if(H5C__verify_cork_tag_test(fid, oinfo3.addr, FALSE) < 0) + if(H5C__verify_cork_tag_test(fid, oinfo3.token, FALSE) < 0) TEST_ERROR /* Cork the dataset: DSET_BT2 */ @@ -695,7 +695,7 @@ verify_dset_cork(hbool_t swmr, hbool_t new_format) TEST_ERROR /* Verify the cork status for DSET_BT2 */ - if(H5C__verify_cork_tag_test(fid, oinfo3.addr, TRUE) < 0) + if(H5C__verify_cork_tag_test(fid, oinfo3.token, TRUE) < 0) TEST_ERROR /* Closing */ @@ -757,11 +757,11 @@ verify_group_cork(hbool_t swmr) hid_t fid = -1; /* File ID */ hid_t fapl = -1; /* File access property list */ hid_t gid = -1, gid2 = -1, gid3 = -1; /* Group IDs */ - H5O_info_t oinfo, oinfo2, oinfo3; /* Object metadata information */ - hid_t aid; /* Attribute ID */ - hid_t sid; /* Dataspace ID */ + H5O_info2_t oinfo, oinfo2, oinfo3; /* Object metadata information */ + hid_t aid; /* Attribute ID */ + hid_t sid; /* Dataspace ID */ char attrname[500]; /* Name of attribute */ - unsigned flags; /* File access flags */ + unsigned flags; /* File access flags */ int i = 0; /* Local index variable */ /* Testing Macro */ @@ -798,19 +798,19 @@ verify_group_cork(hbool_t swmr) TEST_ERROR /* Get group object header addresses */ - if(H5Oget_info2(gid, &oinfo, H5O_INFO_BASIC) < 0) + if(H5Oget_info3(gid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR - if(H5Oget_info2(gid2, &oinfo2, H5O_INFO_BASIC) < 0) + if(H5Oget_info3(gid2, &oinfo2, H5O_INFO_BASIC) < 0) TEST_ERROR - if(H5Oget_info2(gid3, &oinfo3, H5O_INFO_BASIC) < 0) + if(H5Oget_info3(gid3, &oinfo3, H5O_INFO_BASIC) < 0) TEST_ERROR /* Verify cork status of the groups */ - if(H5C__verify_cork_tag_test(fid, oinfo.addr, FALSE) < 0) + if(H5C__verify_cork_tag_test(fid, oinfo.token, FALSE) < 0) TEST_ERROR - if(H5C__verify_cork_tag_test(fid, oinfo2.addr, TRUE) < 0) + if(H5C__verify_cork_tag_test(fid, oinfo2.token, TRUE) < 0) TEST_ERROR - if(H5C__verify_cork_tag_test(fid, oinfo3.addr, FALSE) < 0) + if(H5C__verify_cork_tag_test(fid, oinfo3.token, FALSE) < 0) TEST_ERROR /* Close the second group: GRP2 */ @@ -822,7 +822,7 @@ verify_group_cork(hbool_t swmr) FAIL_STACK_ERROR /* Verify cork status of the second group: GRP2 */ - if(H5C__verify_cork_tag_test(fid, oinfo2.addr, FALSE) < 0) + if(H5C__verify_cork_tag_test(fid, oinfo2.token, FALSE) < 0) TEST_ERROR /* Closing */ @@ -863,7 +863,7 @@ verify_group_cork(hbool_t swmr) if(i == 3) { if(H5Odisable_mdc_flushes(gid3) < 0) TEST_ERROR - if(H5C__verify_cork_tag_test(fid, oinfo3.addr, TRUE) < 0) + if(H5C__verify_cork_tag_test(fid, oinfo3.token, TRUE) < 0) TEST_ERROR } if(H5Aclose(aid) < 0) @@ -871,7 +871,7 @@ verify_group_cork(hbool_t swmr) } /* end for */ /* Verify cork status of the third group: GRP3 */ - if(H5C__verify_cork_tag_test(fid, oinfo3.addr, TRUE) < 0) + if(H5C__verify_cork_tag_test(fid, oinfo3.token, TRUE) < 0) TEST_ERROR /* Closing */ @@ -925,12 +925,12 @@ verify_named_cork(hbool_t swmr) hid_t fapl = -1; /* File access property list */ hid_t tid = -1, tid2 = -1, tid3 = -1; /* Datatype IDs */ hid_t gid = -1, gid2 = -1; /* Group IDs */ - H5O_info_t oinfo, oinfo2, oinfo3, oinfo4; /* Object metadata information */ - hid_t aid = -1; /* Attribute ID */ - hid_t sid; /* Dataspace ID */ - hid_t did; /* Dataset ID */ + H5O_info2_t oinfo, oinfo2, oinfo3, oinfo4; /* Object metadata information */ + hid_t aid = -1; /* Attribute ID */ + hid_t sid; /* Dataspace ID */ + hid_t did; /* Dataset ID */ char attrname[500]; /* Name of attribute */ - unsigned flags; /* File access flags */ + unsigned flags; /* File access flags */ int i = 0; /* Local index variable */ /* Testing Macro */ @@ -987,19 +987,19 @@ verify_named_cork(hbool_t swmr) TEST_ERROR /* Get named datatype object header addresses */ - if(H5Oget_info2(tid, &oinfo, H5O_INFO_BASIC) < 0) + if(H5Oget_info3(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR - if(H5Oget_info2(tid2, &oinfo2, H5O_INFO_BASIC) < 0) + if(H5Oget_info3(tid2, &oinfo2, H5O_INFO_BASIC) < 0) TEST_ERROR - if(H5Oget_info2(tid3, &oinfo3, H5O_INFO_BASIC) < 0) + if(H5Oget_info3(tid3, &oinfo3, H5O_INFO_BASIC) < 0) TEST_ERROR /* Verify cork status of the named datatypes */ - if(H5C__verify_cork_tag_test(fid, oinfo.addr, TRUE) < 0) + if(H5C__verify_cork_tag_test(fid, oinfo.token, TRUE) < 0) TEST_ERROR - if(H5C__verify_cork_tag_test(fid, oinfo2.addr, FALSE) < 0) + if(H5C__verify_cork_tag_test(fid, oinfo2.token, FALSE) < 0) TEST_ERROR - if(H5C__verify_cork_tag_test(fid, oinfo3.addr, TRUE) < 0) + if(H5C__verify_cork_tag_test(fid, oinfo3.token, TRUE) < 0) TEST_ERROR /* Close the datatypes */ @@ -1019,11 +1019,11 @@ verify_named_cork(hbool_t swmr) FAIL_STACK_ERROR /* Verify cork status of the named datatypes */ - if(H5C__verify_cork_tag_test(fid, oinfo.addr, FALSE) < 0) + if(H5C__verify_cork_tag_test(fid, oinfo.token, FALSE) < 0) TEST_ERROR - if(H5C__verify_cork_tag_test(fid, oinfo2.addr, FALSE) < 0) + if(H5C__verify_cork_tag_test(fid, oinfo2.token, FALSE) < 0) TEST_ERROR - if(H5C__verify_cork_tag_test(fid, oinfo3.addr, FALSE) < 0) + if(H5C__verify_cork_tag_test(fid, oinfo3.token, FALSE) < 0) TEST_ERROR /* Closing */ @@ -1079,7 +1079,7 @@ verify_named_cork(hbool_t swmr) if(i == 3) { if(H5Odisable_mdc_flushes(tid3) < 0) TEST_ERROR - if(H5C__verify_cork_tag_test(fid, oinfo3.addr, TRUE) < 0) + if(H5C__verify_cork_tag_test(fid, oinfo3.token, TRUE) < 0) TEST_ERROR } if(H5Aclose(aid) < 0) @@ -1091,7 +1091,7 @@ verify_named_cork(hbool_t swmr) FAIL_STACK_ERROR /* Get dataset object header address */ - if(H5Oget_info2(did, &oinfo4, H5O_INFO_BASIC) < 0) + if(H5Oget_info3(did, &oinfo4, H5O_INFO_BASIC) < 0) TEST_ERROR /* Cork the dataset: DSET */ @@ -1099,20 +1099,20 @@ verify_named_cork(hbool_t swmr) TEST_ERROR /* Verify cork status of the datatype: DT */ - if(H5C__verify_cork_tag_test(fid, oinfo.addr, FALSE) < 0) + if(H5C__verify_cork_tag_test(fid, oinfo.token, FALSE) < 0) TEST_ERROR /* Verify cork status of the datatype: DT2 */ - if(H5C__verify_cork_tag_test(fid, oinfo2.addr, TRUE) < 0) + if(H5C__verify_cork_tag_test(fid, oinfo2.token, TRUE) < 0) TEST_ERROR /* Verify cork status of the datatype: DT3 */ - if(H5C__verify_cork_tag_test(fid, oinfo3.addr, TRUE) < 0) + if(H5C__verify_cork_tag_test(fid, oinfo3.token, TRUE) < 0) TEST_ERROR /* Un-cork the datatype: DT3 */ if(H5Oenable_mdc_flushes(tid3) < 0) TEST_ERROR /* Verify cork status of the datatype: DT3 */ - if(H5C__verify_cork_tag_test(fid, oinfo3.addr, FALSE) < 0) + if(H5C__verify_cork_tag_test(fid, oinfo3.token, FALSE) < 0) TEST_ERROR /* Cork the datatype: DT */ @@ -1120,14 +1120,14 @@ verify_named_cork(hbool_t swmr) TEST_ERROR /* Verify cork status of the datatype: DT */ - if(H5C__verify_cork_tag_test(fid, oinfo.addr, TRUE) < 0) + if(H5C__verify_cork_tag_test(fid, oinfo.token, TRUE) < 0) TEST_ERROR /* Verify cork status of the datatype: DT2 */ - if(H5C__verify_cork_tag_test(fid, oinfo2.addr, TRUE) < 0) + if(H5C__verify_cork_tag_test(fid, oinfo2.token, TRUE) < 0) TEST_ERROR /* Verify cork status of the dataset: DSET */ - if(H5C__verify_cork_tag_test(fid, oinfo4.addr, TRUE) < 0) + if(H5C__verify_cork_tag_test(fid, oinfo4.token, TRUE) < 0) TEST_ERROR /* Close the dataset */ @@ -1135,11 +1135,11 @@ verify_named_cork(hbool_t swmr) TEST_ERROR /* Verify cork status of the datatype: DT */ - if(H5C__verify_cork_tag_test(fid, oinfo.addr, TRUE) < 0) + if(H5C__verify_cork_tag_test(fid, oinfo.token, TRUE) < 0) TEST_ERROR /* Verify cork status of the dataset: DSET */ - if(H5C__verify_cork_tag_test(fid, oinfo4.addr, FALSE) < 0) + if(H5C__verify_cork_tag_test(fid, oinfo4.token, FALSE) < 0) TEST_ERROR /* Closing */ @@ -1206,10 +1206,10 @@ verify_multiple_cork(hbool_t swmr) hid_t aidd1 = -1, aidd2 = -1; /* Attribute ID */ hid_t aidt1 = -1, aidt2 = -1; /* Attribute ID */ hid_t sid = -1; /* Dataspace ID */ - H5O_info_t oinfo1, oinfo2, oinfo3; /* Object metadata information */ - hsize_t dim[1] = {5}; /* Dimension sizes */ - unsigned flags; /* File access flags */ - hbool_t corked; /* Cork status */ + H5O_info2_t oinfo1, oinfo2, oinfo3; /* Object metadata information */ + hsize_t dim[1] = {5}; /* Dimension sizes */ + unsigned flags; /* File access flags */ + hbool_t corked; /* Cork status */ herr_t ret; /* Return value */ /* Testing Macro */ @@ -1305,9 +1305,9 @@ verify_multiple_cork(hbool_t swmr) TEST_ERROR /* Verify cork status of the group: gid2 */ - if(H5Oget_info2(gid2, &oinfo1, H5O_INFO_BASIC) < 0) + if(H5Oget_info3(gid2, &oinfo1, H5O_INFO_BASIC) < 0) TEST_ERROR - if(H5C__verify_cork_tag_test(fid2, oinfo1.addr, TRUE) < 0) + if(H5C__verify_cork_tag_test(fid2, oinfo1.token, TRUE) < 0) TEST_ERROR /* Check cork status of the group: gid1 */ @@ -1333,9 +1333,9 @@ verify_multiple_cork(hbool_t swmr) TEST_ERROR /* Verify cork status of the dataset: did1 */ - if(H5Oget_info2(did1, &oinfo2, H5O_INFO_BASIC) < 0) + if(H5Oget_info3(did1, &oinfo2, H5O_INFO_BASIC) < 0) TEST_ERROR - if(H5C__verify_cork_tag_test(fid1, oinfo2.addr, TRUE) < 0) + if(H5C__verify_cork_tag_test(fid1, oinfo2.token, TRUE) < 0) TEST_ERROR /* Check cork status of the dataset: did2 */ @@ -1361,9 +1361,9 @@ verify_multiple_cork(hbool_t swmr) TEST_ERROR /* Verify cork status of the datatype: tid2 */ - if(H5Oget_info2(tid2, &oinfo3, H5O_INFO_BASIC) < 0) + if(H5Oget_info3(tid2, &oinfo3, H5O_INFO_BASIC) < 0) TEST_ERROR - if(H5C__verify_cork_tag_test(fid2, oinfo3.addr, TRUE) < 0) + if(H5C__verify_cork_tag_test(fid2, oinfo3.token, TRUE) < 0) TEST_ERROR /* Check cork status of the datatype: tid1 */ @@ -1377,9 +1377,9 @@ verify_multiple_cork(hbool_t swmr) TEST_ERROR /* Verify cork status of the group: gid1 */ - if(H5Oget_info2(gid1, &oinfo1, H5O_INFO_BASIC) < 0) + if(H5Oget_info3(gid1, &oinfo1, H5O_INFO_BASIC) < 0) TEST_ERROR - if(H5C__verify_cork_tag_test(fid1, oinfo1.addr, FALSE) < 0) + if(H5C__verify_cork_tag_test(fid1, oinfo1.token, FALSE) < 0) TEST_ERROR /* Check cork status of the group: gid2 */ @@ -1399,7 +1399,7 @@ verify_multiple_cork(hbool_t swmr) TEST_ERROR /* Verify cork status of the group: gid1 */ - if(H5C__verify_cork_tag_test(fid1, oinfo1.addr, FALSE) < 0) + if(H5C__verify_cork_tag_test(fid1, oinfo1.token, FALSE) < 0) TEST_ERROR /* Close the group: gid1 */ @@ -1411,9 +1411,9 @@ verify_multiple_cork(hbool_t swmr) TEST_ERROR /* Verify cork status of the dataset: did2 */ - if(H5Oget_info2(did2, &oinfo2, H5O_INFO_BASIC) < 0) + if(H5Oget_info3(did2, &oinfo2, H5O_INFO_BASIC) < 0) TEST_ERROR - if(H5C__verify_cork_tag_test(fid2, oinfo2.addr, FALSE) < 0) + if(H5C__verify_cork_tag_test(fid2, oinfo2.token, FALSE) < 0) TEST_ERROR /* Check cork status of the dataset: did1 */ @@ -1433,7 +1433,7 @@ verify_multiple_cork(hbool_t swmr) TEST_ERROR /* Verify cork status of the dataset: did1 */ - if(H5C__verify_cork_tag_test(fid1, oinfo2.addr, FALSE) < 0) + if(H5C__verify_cork_tag_test(fid1, oinfo2.token, FALSE) < 0) TEST_ERROR /* Close the dataset: did1 */ diff --git a/test/direct_chunk.c b/test/direct_chunk.c index 7b17043..6cf27c8 100644 --- a/test/direct_chunk.c +++ b/test/direct_chunk.c @@ -661,20 +661,20 @@ filter_bogus1(unsigned int flags, size_t H5_ATTR_UNUSED cd_nelmts, size_t *buf_size, void **buf) { int *int_ptr=(int *)*buf; /* Pointer to the data values */ - ssize_t buf_left=(ssize_t)*buf_size; /* Amount of data buffer left to process */ + size_t buf_left=*buf_size; /* Amount of data buffer left to process */ if(flags & H5Z_FLAG_REVERSE) { /* read */ /* Substract the "add on" value to all the data values */ while(buf_left>0) { *int_ptr++ -= (int)ADD_ON; - buf_left -= (ssize_t)sizeof(int); + buf_left -= sizeof(int); } /* end while */ } /* end if */ else { /* write */ /* Add the "add on" value to all the data values */ while(buf_left>0) { *int_ptr++ += (int)ADD_ON; - buf_left -= (ssize_t)sizeof(int); + buf_left -= sizeof(int); } /* end while */ } /* end else */ @@ -698,20 +698,20 @@ filter_bogus2(unsigned int flags, size_t H5_ATTR_UNUSED cd_nelmts, size_t *buf_size, void **buf) { int *int_ptr=(int *)*buf; /* Pointer to the data values */ - ssize_t buf_left=(ssize_t)*buf_size; /* Amount of data buffer left to process */ + size_t buf_left=*buf_size; /* Amount of data buffer left to process */ if(flags & H5Z_FLAG_REVERSE) { /* read */ /* Substract the "add on" value to all the data values */ while(buf_left>0) { *int_ptr++ /= (int)FACTOR; - buf_left -= (ssize_t)sizeof(int); + buf_left -= sizeof(int); } /* end while */ } /* end if */ else { /* write */ /* Add the "add on" value to all the data values */ while(buf_left>0) { *int_ptr++ *= (int)FACTOR; - buf_left -= (ssize_t)sizeof(int); + buf_left -= sizeof(int); } /* end while */ } /* end else */ diff --git a/test/dsets.c b/test/dsets.c index a394210..82766bf 100644 --- a/test/dsets.c +++ b/test/dsets.c @@ -147,10 +147,12 @@ const char *FILENAME[] = { #define DSET_COPY_DCPL_NAME_1 "copy_dcpl_1" #define DSET_COPY_DCPL_NAME_2 "copy_dcpl_2" #define COPY_DCPL_EXTFILE_NAME "ext_file" +#ifndef H5_NO_DEPRECATED_SYMBOLS #define DSET_DEPREC_NAME "deprecated" #define DSET_DEPREC_NAME_CHUNKED "deprecated_chunked" #define DSET_DEPREC_NAME_COMPACT "deprecated_compact" #define DSET_DEPREC_NAME_FILTER "deprecated_filter" +#endif /* H5_NO_DEPRECATED_SYMBOLS */ /* Dataset names for testing Fixed Array Indexing */ #define DSET_FIXED_MAX "DSET_FIXED_MAX" @@ -176,7 +178,9 @@ const char *FILENAME[] = { #define H5Z_FILTER_CORRUPT 306 #define H5Z_FILTER_CAN_APPLY_TEST 307 #define H5Z_FILTER_SET_LOCAL_TEST 308 +#ifndef H5_NO_DEPRECATED_SYMBOLS #define H5Z_FILTER_DEPREC 309 +#endif /* H5_NO_DEPRECATED_SYMBOLS */ #define H5Z_FILTER_EXPAND 310 #define H5Z_FILTER_CAN_APPLY_TEST2 311 #define H5Z_FILTER_COUNT 312 @@ -7161,8 +7165,8 @@ test_random_chunks_real(const char *testname, hbool_t early_alloc, hid_t fapl) /* Generate random point coordinates. Only one point is selected per chunk */ for(i=0; i= 0) FAIL_STACK_ERROR @@ -7325,7 +7325,7 @@ test_utf_ascii_conv(void) ************************************************/ /* Test conversion in memory */ H5E_BEGIN_TRY { - status = H5Tconvert(ascii_vtid, utf8_vtid, 1, (void *)ascii_w, NULL, H5P_DEFAULT); + status = H5Tconvert(ascii_vtid, utf8_vtid, 1, &ascii_w, NULL, H5P_DEFAULT); } H5E_END_TRY if(status >= 0) FAIL_STACK_ERROR diff --git a/test/efc.c b/test/efc.c index b427884..e62f6cc 100644 --- a/test/efc.c +++ b/test/efc.c @@ -33,7 +33,7 @@ const char *FILENAME[] = { }; /* Global patched filename buffer */ -static char filename[6][1024]; +static char filename[6][128]; /* Global property lists - just copies of the defaults (necessary to use * internal functions */ diff --git a/test/fillval.c b/test/fillval.c index 47cd53a..b3e2e88 100644 --- a/test/fillval.c +++ b/test/fillval.c @@ -758,7 +758,7 @@ test_rdwr_cases(hid_t file, hid_t dcpl, const char *dname, void *_fillval, int fillval=(-1), val_rd, should_be; int i, j, *buf=NULL, odd; unsigned u; - comp_datatype rd_c, fill_c, should_be_c; + comp_datatype rd_c, fill_c, should_be_c; comp_datatype *buf_c=NULL; H5D_space_status_t allocation; @@ -822,7 +822,7 @@ test_rdwr_cases(hid_t file, hid_t dcpl, const char *dname, void *_fillval, hs_offset[0], hs_offset[1], hs_offset[2], hs_offset[3], hs_offset[4], (double)rd_c.a, rd_c.x, rd_c.y, rd_c.z, - (double)fill_c.a, fill_c.x, fill_c.y, fill_c.z); + (double)fill_c.a, fill_c.x, fill_c.y, fill_c.z); goto error; } } diff --git a/test/flushrefresh.c b/test/flushrefresh.c index 92c9f87..20a4ba4 100644 --- a/test/flushrefresh.c +++ b/test/flushrefresh.c @@ -843,13 +843,13 @@ herr_t flush_verification(const char * obj_pathname, const char * expected) /* Variables */ hid_t oid = -1, fid = -1; herr_t status = 0; - H5O_info_t oinfo; + H5O_info2_t oinfo; /* Try to open the testfile and then obj_pathname within the file */ H5E_BEGIN_TRY { fid = H5Fopen(FILENAME, H5F_ACC_SWMR_READ, H5P_DEFAULT); oid = H5Oopen(fid, obj_pathname, H5P_DEFAULT); - status = H5Oget_info2(oid, &oinfo, H5O_INFO_BASIC); + status = H5Oget_info3(oid, &oinfo, H5O_INFO_BASIC); } H5E_END_TRY; /* Compare to expected result */ @@ -978,9 +978,12 @@ herr_t refresh_verification(const char * obj_pathname) { /* Variables */ hid_t oid,fid,status = 0; - H5O_info_t flushed_oinfo; - H5O_info_t refreshed_oinfo; + H5O_info2_t flushed_oinfo; + H5O_info2_t refreshed_oinfo; + H5O_native_info_t flushed_ninfo; + H5O_native_info_t refreshed_ninfo; int tries = 800, sleep_tries = 400; + int token_cmp; hbool_t ok = FALSE; HDremove(SIGNAL_BETWEEN_PROCESSES_2); @@ -990,8 +993,9 @@ herr_t refresh_verification(const char * obj_pathname) if((oid = H5Oopen(fid, obj_pathname, H5P_DEFAULT)) < 0) PROCESS_ERROR; /* Get Object info */ - if((status = H5Oget_info2(oid, &flushed_oinfo, H5O_INFO_BASIC|H5O_INFO_NUM_ATTRS|H5O_INFO_HDR)) < 0) PROCESS_ERROR; - + if((status = H5Oget_info3(oid, &flushed_oinfo, H5O_INFO_BASIC|H5O_INFO_NUM_ATTRS)) < 0) PROCESS_ERROR; + if((status = H5Oget_native_info(oid, &flushed_ninfo, H5O_NATIVE_INFO_HDR)) < 0) PROCESS_ERROR; + /* Make sure there are no attributes on the object. This is just a sanity check to ensure we didn't erroneously flush the attribute before starting the verification. */ @@ -1009,18 +1013,20 @@ herr_t refresh_verification(const char * obj_pathname) /* Get object info again. This will NOT reflect what's on disk, only what's in the cache. Thus, all values will be unchanged from above, despite newer information being on disk. */ - if((status = H5Oget_info2(oid, &refreshed_oinfo, H5O_INFO_BASIC|H5O_INFO_NUM_ATTRS|H5O_INFO_HDR)) < 0) PROCESS_ERROR; + if((status = H5Oget_info3(oid, &refreshed_oinfo, H5O_INFO_BASIC|H5O_INFO_NUM_ATTRS)) < 0) PROCESS_ERROR; + if((status = H5Oget_native_info(oid, &refreshed_ninfo, H5O_NATIVE_INFO_HDR)) < 0) PROCESS_ERROR; /* Verify that before doing a refresh, getting the object info returns stale information. (i.e., unchanged from above, despite new info on disk). */ - if(flushed_oinfo.addr != refreshed_oinfo.addr) PROCESS_ERROR; - if(flushed_oinfo.type != refreshed_oinfo.type) PROCESS_ERROR; - if(flushed_oinfo.hdr.version != refreshed_oinfo.hdr.version) PROCESS_ERROR; - if(flushed_oinfo.hdr.flags != refreshed_oinfo.hdr.flags) PROCESS_ERROR; - if(flushed_oinfo.num_attrs != refreshed_oinfo.num_attrs) PROCESS_ERROR; - if(flushed_oinfo.hdr.nmesgs != refreshed_oinfo.hdr.nmesgs) PROCESS_ERROR; - if(flushed_oinfo.hdr.nchunks != refreshed_oinfo.hdr.nchunks) PROCESS_ERROR; - if(flushed_oinfo.hdr.space.total != refreshed_oinfo.hdr.space.total) PROCESS_ERROR; + if(H5Otoken_cmp(oid, &flushed_oinfo.token, &refreshed_oinfo.token, &token_cmp) < 0) PROCESS_ERROR; + if(token_cmp) PROCESS_ERROR; + if(flushed_oinfo.type != refreshed_oinfo.type) PROCESS_ERROR; + if(flushed_oinfo.num_attrs != refreshed_oinfo.num_attrs) PROCESS_ERROR; + if(flushed_ninfo.hdr.version != refreshed_ninfo.hdr.version) PROCESS_ERROR; + if(flushed_ninfo.hdr.flags != refreshed_ninfo.hdr.flags) PROCESS_ERROR; + if(flushed_ninfo.hdr.nmesgs != refreshed_ninfo.hdr.nmesgs) PROCESS_ERROR; + if(flushed_ninfo.hdr.nchunks != refreshed_ninfo.hdr.nchunks) PROCESS_ERROR; + if(flushed_ninfo.hdr.space.total != refreshed_ninfo.hdr.space.total) PROCESS_ERROR; /* Refresh object */ /* The H5*refresh function called depends on which object we are trying @@ -1047,19 +1053,20 @@ herr_t refresh_verification(const char * obj_pathname) } /* end else */ /* Get object info. This should now accurately reflect the refreshed object on disk. */ - if((status = H5Oget_info2(oid, &refreshed_oinfo, H5O_INFO_BASIC|H5O_INFO_NUM_ATTRS|H5O_INFO_HDR)) < 0) - PROCESS_ERROR; + if((status = H5Oget_info3(oid, &refreshed_oinfo, H5O_INFO_BASIC|H5O_INFO_NUM_ATTRS)) < 0) PROCESS_ERROR; + if((status = H5Oget_native_info(oid, &refreshed_ninfo, H5O_NATIVE_INFO_HDR)) < 0) PROCESS_ERROR; + if(H5Otoken_cmp(oid, &flushed_oinfo.token, &refreshed_oinfo.token, &token_cmp) < 0) PROCESS_ERROR; /* Confirm following (first 4) attributes are the same: */ /* Confirm following (last 4) attributes are different */ - if( (flushed_oinfo.addr == refreshed_oinfo.addr) && - (flushed_oinfo.type == refreshed_oinfo.type) && - (flushed_oinfo.hdr.version == refreshed_oinfo.hdr.version) && - (flushed_oinfo.hdr.flags == refreshed_oinfo.hdr.flags) && - (flushed_oinfo.num_attrs != refreshed_oinfo.num_attrs) && - (flushed_oinfo.hdr.nmesgs != refreshed_oinfo.hdr.nmesgs) && - (flushed_oinfo.hdr.nchunks != refreshed_oinfo.hdr.nchunks) && - (flushed_oinfo.hdr.space.total != refreshed_oinfo.hdr.space.total) ) { + if( (!token_cmp) && + (flushed_oinfo.type == refreshed_oinfo.type) && + (flushed_oinfo.num_attrs != refreshed_oinfo.num_attrs) && + (flushed_ninfo.hdr.version == refreshed_ninfo.hdr.version) && + (flushed_ninfo.hdr.flags == refreshed_ninfo.hdr.flags) && + (flushed_ninfo.hdr.nmesgs != refreshed_ninfo.hdr.nmesgs) && + (flushed_ninfo.hdr.nchunks != refreshed_ninfo.hdr.nchunks) && + (flushed_ninfo.hdr.space.total != refreshed_ninfo.hdr.space.total) ) { ok = TRUE; break; } @@ -1071,11 +1078,11 @@ herr_t refresh_verification(const char * obj_pathname) if(!ok) { HDprintf("FLUSHED: num_attrs=%d, nmesgs=%d, nchunks=%d, total=%d\n", - (int)flushed_oinfo.num_attrs, (int)flushed_oinfo.hdr.nmesgs, - (int)flushed_oinfo.hdr.nchunks, (int)flushed_oinfo.hdr.space.total); + (int)flushed_oinfo.num_attrs, (int)flushed_ninfo.hdr.nmesgs, + (int)flushed_ninfo.hdr.nchunks, (int)flushed_ninfo.hdr.space.total); HDprintf("REFRESHED: num_attrs=%d, nmesgs=%d, nchunks=%d, total=%d\n", - (int)refreshed_oinfo.num_attrs, (int)refreshed_oinfo.hdr.nmesgs, - (int)refreshed_oinfo.hdr.nchunks, (int)refreshed_oinfo.hdr.space.total); + (int)refreshed_oinfo.num_attrs, (int)refreshed_ninfo.hdr.nmesgs, + (int)refreshed_ninfo.hdr.nchunks, (int)refreshed_ninfo.hdr.space.total); PROCESS_ERROR; } diff --git a/test/genall5.c b/test/genall5.c index 849d97c..3f55930 100644 --- a/test/genall5.c +++ b/test/genall5.c @@ -479,7 +479,7 @@ vrfy_ns_grp_c(hid_t fid, const char *group_name, unsigned nlinks) { u = 0; while ((pass) && (u < nlinks)) { - H5L_info_t lnk_info; + H5L_info2_t lnk_info; char linkname[16]; htri_t link_exists; @@ -493,7 +493,7 @@ vrfy_ns_grp_c(hid_t fid, const char *group_name, unsigned nlinks) { HDassert(link_exists >= 0); HDmemset(&lnk_info, 0, sizeof(grp_info)); - ret = H5Lget_info(gid, linkname, &lnk_info, H5P_DEFAULT); + ret = H5Lget_info2(gid, linkname, &lnk_info, H5P_DEFAULT); if (ret < 0) { pass = FALSE; @@ -554,7 +554,8 @@ vrfy_ns_grp_c(hid_t fid, const char *group_name, unsigned nlinks) { HDfree(slinkval); } /* end if */ else if (1 == (u % 3)) { - H5O_info_t root_oinfo; + H5O_info2_t root_oinfo; + int token_cmp = 0; if (H5L_TYPE_HARD != lnk_info.type) { pass = FALSE; @@ -563,18 +564,25 @@ vrfy_ns_grp_c(hid_t fid, const char *group_name, unsigned nlinks) { HDassert(H5L_TYPE_HARD == lnk_info.type); HDmemset(&root_oinfo, 0, sizeof(root_oinfo)); - ret = H5Oget_info2(fid, &root_oinfo, H5O_INFO_BASIC); + ret = H5Oget_info3(fid, &root_oinfo, H5O_INFO_BASIC); if (ret < 0) { pass = FALSE; failure_mssg = "vrfy_ns_grp_c: H5Oget_info() failed."; } - else if (root_oinfo.addr != lnk_info.u.address) { - pass = FALSE; - failure_mssg = "vrfy_ns_grp_c: root_oinfo.addr != lnk_info.u.address"; + else { + if(H5Otoken_cmp(fid, &root_oinfo.token, &lnk_info.u.token, &token_cmp) < 0) { + pass = FALSE; + failure_mssg = "vrfy_ns_grp_c: H5Otoken_cmp() failed."; + } + + if (token_cmp) { + pass = FALSE; + failure_mssg = "vrfy_ns_grp_c: root_oinfo.token != lnk_info.u.token"; + } } HDassert(ret >= 0); - HDassert(root_oinfo.addr == lnk_info.u.address); + HDassert(!token_cmp); } /* end else-if */ else { void *elinkval; @@ -888,7 +896,7 @@ vrfy_ns_grp_d(hid_t fid, const char *group_name, unsigned nlinks) { u = 0; while ((pass) && (u < nlinks)) { - H5L_info_t lnk_info; + H5L_info2_t lnk_info; char linkname[16]; htri_t link_exists; @@ -902,7 +910,7 @@ vrfy_ns_grp_d(hid_t fid, const char *group_name, unsigned nlinks) { HDassert(link_exists >= 0); HDmemset(&lnk_info, 0, sizeof(grp_info)); - ret = H5Lget_info(gid, linkname, &lnk_info, H5P_DEFAULT); + ret = H5Lget_info2(gid, linkname, &lnk_info, H5P_DEFAULT); if (ret < 0) { pass = FALSE; @@ -963,7 +971,8 @@ vrfy_ns_grp_d(hid_t fid, const char *group_name, unsigned nlinks) { HDfree(slinkval); } /* end if */ else if (1 == (u % 3)) { - H5O_info_t root_oinfo; + H5O_info2_t root_oinfo; + int token_cmp = 0; if (H5L_TYPE_HARD != lnk_info.type) { pass = FALSE; @@ -972,17 +981,24 @@ vrfy_ns_grp_d(hid_t fid, const char *group_name, unsigned nlinks) { HDassert(H5L_TYPE_HARD == lnk_info.type); HDmemset(&root_oinfo, 0, sizeof(root_oinfo)); - ret = H5Oget_info2(fid, &root_oinfo, H5O_INFO_BASIC); + ret = H5Oget_info3(fid, &root_oinfo, H5O_INFO_BASIC); if (ret < 0) { pass = FALSE; failure_mssg = "vrfy_ns_grp_d: H5Oget_info() failed."; } - else if (root_oinfo.addr != lnk_info.u.address) { - pass = FALSE; - failure_mssg = "vrfy_ns_grp_d: root_oinfo.addr != lnk_info.u.address"; + else { + if(H5Otoken_cmp(fid, &root_oinfo.token, &lnk_info.u.token, &token_cmp) < 0) { + pass = FALSE; + failure_mssg = "vrfy_ns_grp_d: H5Otoken_cmp() failed."; + } + + if (token_cmp) { + pass = FALSE; + failure_mssg = "vrfy_ns_grp_d: root_oinfo.token != lnk_info.u.token"; + } } HDassert(ret >= 0); - HDassert(root_oinfo.addr == lnk_info.u.address); + HDassert(!token_cmp); } /* end else-if */ else { void *elinkval; @@ -1486,7 +1502,7 @@ vrfy_os_grp_n(hid_t fid, const char *group_name, int proc_num, u = 0; while ((pass) && (u < nlinks)) { - H5L_info_t lnk_info; + H5L_info2_t lnk_info; char linkname[32]; htri_t link_exists; @@ -1500,7 +1516,7 @@ vrfy_os_grp_n(hid_t fid, const char *group_name, int proc_num, HDassert(link_exists >= 0); HDmemset(&lnk_info, 0, sizeof(grp_info)); - ret = H5Lget_info(gid, linkname, &lnk_info, H5P_DEFAULT); + ret = H5Lget_info2(gid, linkname, &lnk_info, H5P_DEFAULT); if (ret < 0) { pass = FALSE; @@ -1557,7 +1573,8 @@ vrfy_os_grp_n(hid_t fid, const char *group_name, int proc_num, HDfree(slinkval); } /* end if */ else { - H5O_info_t root_oinfo; + H5O_info2_t root_oinfo; + int token_cmp = 0; HDassert(1 == (u % 2)); @@ -1568,18 +1585,25 @@ vrfy_os_grp_n(hid_t fid, const char *group_name, int proc_num, HDassert(H5L_TYPE_HARD == lnk_info.type); HDmemset(&root_oinfo, 0, sizeof(root_oinfo)); - ret = H5Oget_info2(fid, &root_oinfo, H5O_INFO_BASIC); + ret = H5Oget_info3(fid, &root_oinfo, H5O_INFO_BASIC); if (ret < 0) { pass = FALSE; failure_mssg = "vrfy_os_grp_n: H5Oget_info() failed."; } - else if (root_oinfo.addr != lnk_info.u.address) { - pass = FALSE; - failure_mssg = "vrfy_os_grp_n: root_oinfo.addr != lnk_info.u.address"; + else { + if(H5Otoken_cmp(fid, &root_oinfo.token, &lnk_info.u.token, &token_cmp) < 0) { + pass = FALSE; + failure_mssg = "vrfy_os_grp_n: H5Otoken_cmp() failed."; + } + + if (token_cmp) { + pass = FALSE; + failure_mssg = "vrfy_os_grp_n: root_oinfo.token != lnk_info.u.token"; + } } HDassert(ret >= 0); - HDassert(root_oinfo.addr == lnk_info.u.address); + HDassert(!token_cmp); } /* end else */ u++; diff --git a/test/getname.c b/test/getname.c index 399f364..f677d78 100644 --- a/test/getname.c +++ b/test/getname.c @@ -101,8 +101,8 @@ test_main(hid_t file_id, hid_t fapl) hid_t space_id; hid_t type_id, type2_id; hsize_t dims[1] = { 5 }; - size_t name_len; /* Name length */ - H5O_info_t oinfo; /* Object info structs */ + size_t name_len; /* Name length */ + H5O_info2_t oinfo; /* Object info structs */ hid_t dtype; /* Object identifier for testing */ hid_t dtype_anon; /* Object identifier for testing anonymous */ ssize_t size; /* Size returned by H5Iget_name */ @@ -2390,7 +2390,7 @@ test_main(hid_t file_id, hid_t fapl) if((size = H5Iget_name(dtype_anon, NULL,0)) != 0) TEST_ERROR /* Store the address of the datatype for later use */ - if(H5Oget_info2(dtype_anon, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR + if(H5Oget_info3(dtype_anon, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR /* Update the reference count to dtype_anon to preserve the datatype */ if(H5Oincr_refcount(dtype_anon) < 0) TEST_ERROR @@ -2400,10 +2400,10 @@ test_main(hid_t file_id, hid_t fapl) if(H5Fclose(file2_id) < 0) TEST_ERROR /* Re-open the file and check that the anonymous datatypes persist */ - if( (file2_id = H5Fopen(filename2, H5F_ACC_RDONLY, fapl)) < 0) TEST_ERROR + if((file2_id = H5Fopen(filename2, H5F_ACC_RDONLY, fapl)) < 0) TEST_ERROR /* Check the H5Iget_name does not return an error for anon committed datatypes */ - if((dtype_anon = H5Oopen_by_addr(file2_id, oinfo.addr)) < 0) TEST_ERROR + if((dtype_anon = H5Oopen_by_token(file2_id, oinfo.token)) < 0) TEST_ERROR if((size = H5Iget_name(dtype_anon, NULL, 0)) != 0) TEST_ERROR diff --git a/test/h5test.c b/test/h5test.c index 6a3a5cb..ab859a5 100644 --- a/test/h5test.c +++ b/test/h5test.c @@ -1697,7 +1697,7 @@ error: */ static herr_t h5_verify_cached_stabs_cb(hid_t oid, const char H5_ATTR_UNUSED *name, - const H5O_info_t *oinfo, void H5_ATTR_UNUSED *udata) + const H5O_info2_t *oinfo, void H5_ATTR_UNUSED *udata) { if(oinfo->type == H5O_TYPE_GROUP) return H5G__verify_cached_stabs_test(oid); @@ -1745,7 +1745,7 @@ h5_verify_cached_stabs(const char *base_name[], hid_t fapl) continue; } /* end if */ - if(H5Ovisit2(file, H5_INDEX_NAME, H5_ITER_NATIVE, + if(H5Ovisit3(file, H5_INDEX_NAME, H5_ITER_NATIVE, h5_verify_cached_stabs_cb, NULL, H5O_INFO_BASIC) < 0) goto error; diff --git a/test/links.c b/test/links.c index 4dff1cf..60d3152 100644 --- a/test/links.c +++ b/test/links.c @@ -35,6 +35,7 @@ #include "H5Gpkg.h" /* Groups */ #include "H5Iprivate.h" /* IDs */ #include "H5Lprivate.h" /* Links */ +#include "H5VLnative_private.h" /* Native VOL connector */ /* File for external link test. Created with gen_udlinks.c */ #define LINKED_FILE "be_extlink2.h5" @@ -314,7 +315,119 @@ typedef struct { static hid_t dcpl_g; /* for [un]minimized dataset object headers */ +static herr_t +UD_hard_create(const char *link_name, hid_t loc_group, const void *udata, + size_t udata_size, hid_t lcpl_id); +static hid_t +UD_hard_traverse(const char *link_name, hid_t cur_group, + const void *udata, size_t udata_size, hid_t lapl_id, + hid_t dxpl_id); +static herr_t +UD_hard_delete(const char *link_name, hid_t file, const void *udata, + size_t udata_size); + +/* User-defined link class */ +const H5L_class_t UD_hard_class[1] = {{ + H5L_LINK_CLASS_T_VERS, /* H5L_class_t version */ + (H5L_type_t)UD_HARD_TYPE, /* Link type id number */ + "UD_hard_link", /* Link class name for debugging */ + UD_hard_create, /* Creation callback */ + NULL, /* Move/rename callback */ + NULL, /* Copy callback */ + UD_hard_traverse, /* The actual traversal function */ + UD_hard_delete, /* Deletion callback */ + NULL /* Query callback */ +}}; + +#ifndef H5_NO_DEPRECATED_SYMBOLS +static herr_t +UD_hard_create_deprec(const char *link_name, hid_t loc_group, const void *udata, + size_t udata_size, hid_t lcpl_id); +static hid_t +UD_hard_traverse_deprec(const char *link_name, hid_t cur_group, + const void *udata, size_t udata_size, hid_t lapl_id, + hid_t dxpl_id); +static herr_t +UD_hard_delete_deprec(const char *link_name, hid_t file, const void *udata, + size_t udata_size); + +/* User-defined link class */ +const H5L_class_t UD_hard_class_deprec[1] = {{ + H5L_LINK_CLASS_T_VERS, /* H5L_class_t version */ + (H5L_type_t)UD_HARD_TYPE, /* Link type id number */ + "UD_hard_link_deprec", /* Link class name for debugging */ + UD_hard_create_deprec, /* Creation callback */ + NULL, /* Move/rename callback */ + NULL, /* Copy callback */ + UD_hard_traverse_deprec, /* The actual traversal function */ + UD_hard_delete_deprec, /* Deletion callback */ + NULL /* Query callback */ +}}; +#endif + +static hid_t +UD_rereg_traverse(const char *link_name, hid_t cur_group, + const void *udata, size_t udata_size, hid_t lapl_id, + hid_t dxpl_id); + +/* This link class has the same ID number as the UD hard links but + * has a very different traversal function */ +const H5L_class_t UD_rereg_class[1] = {{ + H5L_LINK_CLASS_T_VERS, /* H5L_class_t version */ + (H5L_type_t)UD_HARD_TYPE, /* Link type id number */ + "UD_reregistered_type", /* Link class name for debugging */ + NULL, /* Creation callback */ + NULL, /* Move/rename callback */ + NULL, /* Copy callback */ + UD_rereg_traverse, /* The actual traversal function */ + NULL, /* Deletion callback */ + NULL /* Query callback */ +}}; + +static herr_t +UD_cb_create(const char * link_name, hid_t loc_group, const void *udata, + size_t udata_size, hid_t lcpl_id); +static herr_t +UD_cb_move(const char *new_name, hid_t new_loc, const void *udata, + size_t udata_size); +static hid_t +UD_cb_traverse(const char * link_name, hid_t cur_group, const void *udata, + size_t udata_size, hid_t lapl_id, hid_t dxpl_id); +static herr_t +UD_cb_delete(const char *link_name, hid_t file, const void *udata, + size_t udata_size); +static ssize_t +UD_cb_query(const char * link_name, const void *udata, size_t udata_size, + void *buf, size_t buf_size); + +const H5L_class_t UD_cb_class[1] = {{ + H5L_LINK_CLASS_T_VERS, /* H5L_class_t version */ + (H5L_type_t)UD_CB_TYPE, /* Link type id number */ + NULL, /* NULL name (to make sure this doesn't break anything */ + UD_cb_create, /* Creation callback */ + UD_cb_move, /* Move/rename callback */ + UD_cb_move, /* Copy callback */ + UD_cb_traverse, /* The actual traversal function */ + UD_cb_delete, /* Deletion callback */ + UD_cb_query /* Query callback */ +}}; + +static hid_t +UD_plist_traverse(const char *link_name, hid_t cur_group, + const void *udata, size_t udata_size, hid_t lapl_id, + hid_t dxpl_id); +const H5L_class_t UD_plist_class[1] = {{ + H5L_LINK_CLASS_T_VERS, /* H5L_class_t version */ + (H5L_type_t)UD_PLIST_TYPE, /* Link type id number */ + "UD_plist_link", /* Link class name for debugging */ + NULL, /* Creation callback */ + NULL, /* Move/rename callback */ + NULL, /* Copy callback */ + UD_plist_traverse, /* The actual traversal function */ + NULL, /* Deletion callback */ + NULL /* Query callback */ +}}; /*------------------------------------------------------------------------- * Function: fix_ext_filename @@ -499,10 +612,11 @@ static int cklinks(hid_t fapl, hbool_t new_format) { hid_t file; - H5O_info_t oinfo1, oinfo2; - H5L_info_t linfo2; + H5O_info2_t oinfo1, oinfo2; + H5L_info2_t linfo; char linkval[LINK_BUF_SIZE]; char filename[NAME_BUF_SIZE]; + int token_cmp; herr_t status; if(new_format) @@ -515,14 +629,15 @@ cklinks(hid_t fapl, hbool_t new_format) if((file = H5Fopen(filename, H5F_ACC_RDONLY, fapl)) < 0) FAIL_STACK_ERROR /* Hard link */ - if(H5Oget_info_by_name2(file, "d1", &oinfo1, H5O_INFO_BASIC, H5P_DEFAULT) < 0) FAIL_STACK_ERROR - if(H5Oget_info_by_name2(file, "grp1/hard", &oinfo2, H5O_INFO_BASIC, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + if(H5Oget_info_by_name3(file, "d1", &oinfo1, H5O_INFO_BASIC, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + if(H5Oget_info_by_name3(file, "grp1/hard", &oinfo2, H5O_INFO_BASIC, H5P_DEFAULT) < 0) FAIL_STACK_ERROR if(H5O_TYPE_DATASET != oinfo2.type) { H5_FAILED(); HDprintf(" %d: Unexpected object type should have been a dataset\n", __LINE__); TEST_ERROR } /* end if */ - if(H5F_addr_ne(oinfo1.addr, oinfo2.addr)) { + if(H5Otoken_cmp(file, &oinfo1.token, &oinfo2.token, &token_cmp) < 0) FAIL_STACK_ERROR + if(token_cmp) { H5_FAILED(); HDputs(" Hard link test failed. Link seems not to point to the "); HDputs(" expected file location."); @@ -551,13 +666,14 @@ cklinks(hid_t fapl, hbool_t new_format) } /* end if */ /* Symbolic link */ - if(H5Oget_info_by_name2(file, "grp1/soft", &oinfo2, H5O_INFO_BASIC, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + if(H5Oget_info_by_name3(file, "grp1/soft", &oinfo2, H5O_INFO_BASIC, H5P_DEFAULT) < 0) FAIL_STACK_ERROR if(H5O_TYPE_DATASET != oinfo2.type) { H5_FAILED(); HDprintf(" %d: Unexpected object type should have been a dataset\n", __LINE__); TEST_ERROR } /* end if */ - if(H5F_addr_ne(oinfo1.addr, oinfo2.addr)) { + if(H5Otoken_cmp(file, &oinfo1.token, &oinfo2.token, &token_cmp) < 0) FAIL_STACK_ERROR + if(token_cmp) { H5_FAILED(); HDputs(" Soft link test failed. Link seems not to point to the "); HDputs(" expected file location."); @@ -573,15 +689,15 @@ cklinks(hid_t fapl, hbool_t new_format) /* Dangling link */ H5E_BEGIN_TRY { - status = H5Oget_info_by_name2(file, "grp1/dangle", &oinfo2, H5O_INFO_BASIC, H5P_DEFAULT); + status = H5Oget_info_by_name3(file, "grp1/dangle", &oinfo2, H5O_INFO_BASIC, H5P_DEFAULT); } H5E_END_TRY; if(status >= 0) { H5_FAILED(); HDputs(" H5Oget_info_by_name() should have failed for a dangling link."); TEST_ERROR } /* end if */ - if(H5Lget_info(file, "grp1/dangle", &linfo2, H5P_DEFAULT) < 0) FAIL_STACK_ERROR - if(H5L_TYPE_SOFT != linfo2.type) { + if(H5Lget_info2(file, "grp1/dangle", &linfo, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + if(H5L_TYPE_SOFT != linfo.type) { H5_FAILED(); HDprintf(" %d: Unexpected object type should have been a symbolic link\n", __LINE__); TEST_ERROR @@ -600,15 +716,15 @@ cklinks(hid_t fapl, hbool_t new_format) /* Recursive link */ H5E_BEGIN_TRY { - status = H5Oget_info_by_name2(file, "grp1/recursive", &oinfo2, H5O_INFO_BASIC, H5P_DEFAULT); + status = H5Oget_info_by_name3(file, "grp1/recursive", &oinfo2, H5O_INFO_BASIC, H5P_DEFAULT); } H5E_END_TRY; if(status >= 0) { H5_FAILED(); HDputs(" H5Oget_info_by_name() should have failed for a recursive link."); TEST_ERROR } /* end if */ - if(H5Lget_info(file, "grp1/recursive", &linfo2, H5P_DEFAULT) < 0) FAIL_STACK_ERROR - if(H5L_TYPE_SOFT != linfo2.type) { + if(H5Lget_info2(file, "grp1/recursive", &linfo, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + if(H5L_TYPE_SOFT != linfo.type) { H5_FAILED(); HDprintf(" %d: Unexpected object type should have been a symbolic link\n", __LINE__); TEST_ERROR @@ -652,8 +768,9 @@ static int ck_new_links(hid_t fapl, hbool_t new_format) { hid_t file; - H5O_info_t oi_dset, oi_hard1, oi_hard2; + H5O_info2_t oi_dset, oi_hard1, oi_hard2; char filename[NAME_BUF_SIZE]; + int token_cmp1, token_cmp2; if(new_format) TESTING("new link queries (w/new group format)") @@ -665,9 +782,9 @@ ck_new_links(hid_t fapl, hbool_t new_format) if((file = H5Fopen(filename, H5F_ACC_RDONLY, fapl)) < 0) TEST_ERROR /* Get hard link info */ - if(H5Oget_info_by_name2(file, "/grp1/dataset2", &oi_dset, H5O_INFO_BASIC, H5P_DEFAULT) < 0) TEST_ERROR - if(H5Oget_info_by_name2(file, "/grp1/hard1", &oi_hard1, H5O_INFO_BASIC, H5P_DEFAULT) < 0) TEST_ERROR - if(H5Oget_info_by_name2(file, "/grp2/hard2", &oi_hard2, H5O_INFO_BASIC, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Oget_info_by_name3(file, "/grp1/dataset2", &oi_dset, H5O_INFO_BASIC, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Oget_info_by_name3(file, "/grp1/hard1", &oi_hard1, H5O_INFO_BASIC, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Oget_info_by_name3(file, "/grp2/hard2", &oi_hard2, H5O_INFO_BASIC, H5P_DEFAULT) < 0) TEST_ERROR /* Check hard links */ if(H5O_TYPE_DATASET != oi_hard1.type || H5O_TYPE_DATASET != oi_hard2.type) { @@ -675,7 +792,10 @@ ck_new_links(hid_t fapl, hbool_t new_format) HDprintf(" %d: Unexpected object type should have been a dataset\n", __LINE__); TEST_ERROR } - if(H5F_addr_ne(oi_dset.addr, oi_hard1.addr) || H5F_addr_ne(oi_dset.addr, oi_hard2.addr)) { + + if(H5Otoken_cmp(file, &oi_dset.token, &oi_hard1.token, &token_cmp1) < 0) TEST_ERROR + if(H5Otoken_cmp(file, &oi_dset.token, &oi_hard2.token, &token_cmp2) < 0) TEST_ERROR + if(token_cmp1 || token_cmp2) { H5_FAILED(); HDputs(" Hard link test failed. Link seems not to point to the "); HDputs(" expected file location."); @@ -920,7 +1040,7 @@ test_lcpl(hid_t fapl, hbool_t new_format) hid_t dset_id = -1; hid_t type_id = -1; hid_t lcpl_id = -1; - H5L_info_t linfo; + H5L_info2_t linfo; char filename[1024]; hsize_t dims[2]; @@ -942,7 +1062,7 @@ test_lcpl(hid_t fapl, hbool_t new_format) if(H5Gclose(group_id) < 0) TEST_ERROR /* Check that its character encoding is the default */ - if(H5Lget_info(file_id, "group", &linfo, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Lget_info2(file_id, "group", &linfo, H5P_DEFAULT) < 0) TEST_ERROR if(linfo.cset != H5F_DEFAULT_CSET) TEST_ERROR /* Create and commit a datatype with the default LCPL */ @@ -951,7 +1071,7 @@ test_lcpl(hid_t fapl, hbool_t new_format) if(H5Tclose(type_id) < 0) TEST_ERROR /* Check that its character encoding is the default */ - if(H5Lget_info(file_id, "type", &linfo, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Lget_info2(file_id, "type", &linfo, H5P_DEFAULT) < 0) TEST_ERROR if(linfo.cset != H5F_DEFAULT_CSET) TEST_ERROR /* Create a dataspace */ @@ -964,7 +1084,7 @@ test_lcpl(hid_t fapl, hbool_t new_format) if(H5Dclose(dset_id) < 0) TEST_ERROR /* Check that its character encoding is the default */ - if(H5Lget_info(file_id, "dataset", &linfo, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Lget_info2(file_id, "dataset", &linfo, H5P_DEFAULT) < 0) TEST_ERROR if(linfo.cset != H5F_DEFAULT_CSET) TEST_ERROR /* Create a link creation property list with the UTF-8 character encoding */ @@ -976,7 +1096,7 @@ test_lcpl(hid_t fapl, hbool_t new_format) if(H5Gclose(group_id) < 0) TEST_ERROR /* Check that its character encoding is UTF-8 */ - if(H5Lget_info(file_id, "group2", &linfo, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Lget_info2(file_id, "group2", &linfo, H5P_DEFAULT) < 0) TEST_ERROR if(linfo.cset != H5T_CSET_UTF8) TEST_ERROR /* Create and commit a datatype with the new LCPL */ @@ -985,7 +1105,7 @@ test_lcpl(hid_t fapl, hbool_t new_format) if(H5Tclose(type_id) < 0) TEST_ERROR /* Check that its character encoding is UTF-8 */ - if(H5Lget_info(file_id, "type2", &linfo, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Lget_info2(file_id, "type2", &linfo, H5P_DEFAULT) < 0) TEST_ERROR if(linfo.cset != H5T_CSET_UTF8) TEST_ERROR /* Create a dataset using the new LCPL */ @@ -993,7 +1113,7 @@ test_lcpl(hid_t fapl, hbool_t new_format) if(H5Dclose(dset_id) < 0) TEST_ERROR /* Check that its character encoding is UTF-8 */ - if(H5Lget_info(file_id, "dataset2", &linfo, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Lget_info2(file_id, "dataset2", &linfo, H5P_DEFAULT) < 0) TEST_ERROR if(linfo.cset != H5T_CSET_UTF8) TEST_ERROR /* Create a new link to the dataset with a different character encoding. */ @@ -1004,35 +1124,35 @@ test_lcpl(hid_t fapl, hbool_t new_format) if(H5Lcreate_hard(file_id, "/dataset2", file_id, "/dataset2_link", lcpl_id, H5P_DEFAULT) < 0) TEST_ERROR /* Check that its character encoding is ASCII */ - if(H5Lget_info(file_id, "/dataset2_link", &linfo, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Lget_info2(file_id, "/dataset2_link", &linfo, H5P_DEFAULT) < 0) TEST_ERROR if(linfo.cset != H5T_CSET_ASCII) TEST_ERROR /* Check that the first link's encoding hasn't changed */ - if(H5Lget_info(file_id, "/dataset2", &linfo, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Lget_info2(file_id, "/dataset2", &linfo, H5P_DEFAULT) < 0) TEST_ERROR if(linfo.cset != H5T_CSET_UTF8) TEST_ERROR /* Make sure that LCPLs work properly for other API calls: */ /* H5Lcreate_soft */ if(H5Pset_char_encoding(lcpl_id, H5T_CSET_UTF8) < 0) TEST_ERROR if(H5Lcreate_soft("dataset2", file_id, "slink_to_dset2", lcpl_id, H5P_DEFAULT) < 0) TEST_ERROR - if(H5Lget_info(file_id, "slink_to_dset2", &linfo, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Lget_info2(file_id, "slink_to_dset2", &linfo, H5P_DEFAULT) < 0) TEST_ERROR if(linfo.cset != H5T_CSET_UTF8) TEST_ERROR /* H5Lmove */ if(H5Pset_char_encoding(lcpl_id, H5T_CSET_ASCII) < 0) TEST_ERROR if(H5Lmove(file_id, "slink_to_dset2", file_id, "moved_slink", lcpl_id, H5P_DEFAULT) < 0) TEST_ERROR - if(H5Lget_info(file_id, "moved_slink", &linfo, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Lget_info2(file_id, "moved_slink", &linfo, H5P_DEFAULT) < 0) TEST_ERROR if(linfo.cset != H5T_CSET_ASCII) TEST_ERROR /* H5Lcopy */ if(H5Pset_char_encoding(lcpl_id, H5T_CSET_UTF8) < 0) TEST_ERROR if(H5Lcopy(file_id, "moved_slink", file_id, "copied_slink", lcpl_id, H5P_DEFAULT) < 0) TEST_ERROR - if(H5Lget_info(file_id, "copied_slink", &linfo, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Lget_info2(file_id, "copied_slink", &linfo, H5P_DEFAULT) < 0) TEST_ERROR if(linfo.cset != H5T_CSET_UTF8) TEST_ERROR /* H5Lcreate_external */ if(H5Lcreate_external("filename", "path", file_id, "extlink", lcpl_id, H5P_DEFAULT) < 0) TEST_ERROR - if(H5Lget_info(file_id, "extlink", &linfo, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Lget_info2(file_id, "extlink", &linfo, H5P_DEFAULT) < 0) TEST_ERROR if(linfo.cset != H5T_CSET_UTF8) TEST_ERROR /* Close open IDs */ @@ -1328,8 +1448,8 @@ test_move_preserves(hid_t fapl_id, hbool_t new_format) hid_t fcpl_id=-1; /* Group creation property list ID */ hid_t lcpl_id=-1; hid_t lcpl2_id=-1; - H5O_info_t oinfo; - H5L_info_t linfo; + H5O_info2_t oinfo; + H5L_info2_t linfo; H5T_cset_t old_cset; int64_t old_corder; /* Creation order value of link */ time_t old_modification_time; @@ -1366,8 +1486,8 @@ test_move_preserves(hid_t fapl_id, hbool_t new_format) if(H5Gclose(group_id) < 0) TEST_ERROR /* Get the group's link's information */ - if(H5Lget_info(file_id, "group", &linfo, H5P_DEFAULT) < 0) TEST_ERROR - if(H5Oget_info_by_name2(file_id, "group", &oinfo, H5O_INFO_TIME, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Lget_info2(file_id, "group", &linfo, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Oget_info_by_name3(file_id, "group", &oinfo, H5O_INFO_TIME, H5P_DEFAULT) < 0) TEST_ERROR old_cset = linfo.cset; if(old_cset != H5T_CSET_UTF8) TEST_ERROR if(linfo.corder_valid != TRUE) TEST_ERROR @@ -1385,8 +1505,8 @@ test_move_preserves(hid_t fapl_id, hbool_t new_format) if((file_id = H5Fopen(filename, H5F_ACC_RDWR, fapl_id)) < 0) TEST_ERROR /* Get the link's character set & modification time . They should be unchanged */ - if(H5Lget_info(file_id, "group", &linfo, H5P_DEFAULT) < 0) TEST_ERROR - if(H5Oget_info_by_name2(file_id, "group", &oinfo, H5O_INFO_TIME, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Lget_info2(file_id, "group", &linfo, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Oget_info_by_name3(file_id, "group", &oinfo, H5O_INFO_TIME, H5P_DEFAULT) < 0) TEST_ERROR if(old_modification_time != oinfo.mtime) TEST_ERROR if(old_cset != linfo.cset) TEST_ERROR if(linfo.corder_valid != TRUE) TEST_ERROR @@ -1394,9 +1514,9 @@ test_move_preserves(hid_t fapl_id, hbool_t new_format) /* Create a new link to the group. It should have a different creation order value but the same modification time */ if(H5Lcreate_hard(file_id, "group", file_id, "group2", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR - if(H5Oget_info_by_name2(file_id, "group2", &oinfo, H5O_INFO_TIME, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Oget_info_by_name3(file_id, "group2", &oinfo, H5O_INFO_TIME, H5P_DEFAULT) < 0) TEST_ERROR if(old_modification_time != oinfo.mtime) TEST_ERROR - if(H5Lget_info(file_id, "group2", &linfo, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Lget_info2(file_id, "group2", &linfo, H5P_DEFAULT) < 0) TEST_ERROR if(old_corder == linfo.corder) TEST_ERROR if(linfo.corder_valid != TRUE) TEST_ERROR if(linfo.corder != 1) TEST_ERROR @@ -1407,9 +1527,9 @@ test_move_preserves(hid_t fapl_id, hbool_t new_format) * should not change. */ if(H5Lcopy(file_id, "group", file_id, "group_copied", lcpl_id, H5P_DEFAULT) < 0) TEST_ERROR - if(H5Oget_info_by_name2(file_id, "group_copied", &oinfo, H5O_INFO_TIME, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Oget_info_by_name3(file_id, "group_copied", &oinfo, H5O_INFO_TIME, H5P_DEFAULT) < 0) TEST_ERROR if(old_modification_time != oinfo.mtime) TEST_ERROR - if(H5Lget_info(file_id, "group_copied", &linfo, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Lget_info2(file_id, "group_copied", &linfo, H5P_DEFAULT) < 0) TEST_ERROR if(linfo.corder_valid != TRUE) TEST_ERROR if(linfo.corder != 2) TEST_ERROR @@ -1418,9 +1538,9 @@ test_move_preserves(hid_t fapl_id, hbool_t new_format) /* Move the link with the default property list. */ if(H5Lmove(file_id, "group_copied", file_id, "group_copied2", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR - if(H5Oget_info_by_name2(file_id, "group_copied2", &oinfo, H5O_INFO_TIME, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Oget_info_by_name3(file_id, "group_copied2", &oinfo, H5O_INFO_TIME, H5P_DEFAULT) < 0) TEST_ERROR if(old_modification_time != oinfo.mtime) TEST_ERROR - if(H5Lget_info(file_id, "group_copied2", &linfo, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Lget_info2(file_id, "group_copied2", &linfo, H5P_DEFAULT) < 0) TEST_ERROR if(linfo.corder_valid != TRUE) TEST_ERROR if(linfo.corder != 3) TEST_ERROR @@ -1428,9 +1548,9 @@ test_move_preserves(hid_t fapl_id, hbool_t new_format) if(linfo.cset == H5T_CSET_UTF8) TEST_ERROR /* Check that the original link is unchanged */ - if(H5Oget_info_by_name2(file_id, "group", &oinfo, H5O_INFO_TIME, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Oget_info_by_name3(file_id, "group", &oinfo, H5O_INFO_TIME, H5P_DEFAULT) < 0) TEST_ERROR if(old_modification_time != oinfo.mtime) TEST_ERROR - if(H5Lget_info(file_id, "group", &linfo, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Lget_info2(file_id, "group", &linfo, H5P_DEFAULT) < 0) TEST_ERROR if(linfo.corder_valid != TRUE) TEST_ERROR if(old_corder != linfo.corder) TEST_ERROR if(linfo.cset != H5T_CSET_UTF8) TEST_ERROR @@ -1439,9 +1559,9 @@ test_move_preserves(hid_t fapl_id, hbool_t new_format) * Its creation order value will change, but modification time should not * change. */ if(H5Lmove(file_id, "group", file_id, "group_moved", lcpl_id, H5P_DEFAULT) < 0) TEST_ERROR - if(H5Oget_info_by_name2(file_id, "group_moved", &oinfo, H5O_INFO_TIME, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Oget_info_by_name3(file_id, "group_moved", &oinfo, H5O_INFO_TIME, H5P_DEFAULT) < 0) TEST_ERROR if(old_modification_time != oinfo.mtime) TEST_ERROR - if(H5Lget_info(file_id, "group_moved", &linfo, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Lget_info2(file_id, "group_moved", &linfo, H5P_DEFAULT) < 0) TEST_ERROR if(linfo.corder_valid != TRUE) TEST_ERROR if(linfo.corder != 4) TEST_ERROR @@ -1450,9 +1570,9 @@ test_move_preserves(hid_t fapl_id, hbool_t new_format) /* Move the link again using the default property list. */ if(H5Lmove(file_id, "group_moved", file_id, "group_moved_again", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR - if(H5Oget_info_by_name2(file_id, "group_moved_again", &oinfo, H5O_INFO_TIME, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Oget_info_by_name3(file_id, "group_moved_again", &oinfo, H5O_INFO_TIME, H5P_DEFAULT) < 0) TEST_ERROR if(old_modification_time != oinfo.mtime) TEST_ERROR - if(H5Lget_info(file_id, "group_moved_again", &linfo, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Lget_info2(file_id, "group_moved_again", &linfo, H5P_DEFAULT) < 0) TEST_ERROR if(linfo.corder_valid != TRUE) TEST_ERROR if(linfo.corder != 5) TEST_ERROR @@ -1464,167 +1584,4071 @@ test_move_preserves(hid_t fapl_id, hbool_t new_format) if(H5Pclose(lcpl_id) < 0) TEST_ERROR if(H5Fclose(file_id) < 0) TEST_ERROR - PASSED(); - return SUCCEED; + PASSED(); + return SUCCEED; + +error: + H5E_BEGIN_TRY { + H5Pclose(fcpl_id); + H5Pclose(lcpl_id); + H5Pclose(lcpl2_id); + H5Gclose(group_id); + H5Fclose(file_id); + } H5E_END_TRY; + return 1; +} /* end test_move_preserves() */ + + +/*------------------------------------------------------------------------- + * Function: test_deprec + * + * Purpose: Tests deprecated functions for backward compatibility. + * + * Return: Success: 0 + * Failure: number of errors + *------------------------------------------------------------------------- + */ +#ifndef H5_NO_DEPRECATED_SYMBOLS +static int +test_deprec(hid_t fapl, hbool_t new_format) +{ + hid_t file_id = -1; + hid_t group1_id = -1; + hid_t group2_id = -1; + H5G_stat_t sb_hard1, sb_hard2, sb_soft1, sb_soft2; + H5G_obj_t obj_type; /* Object type */ + hsize_t num_objs; /* Number of objects in a group */ + char filename[1024]; + char tmpstr[1024]; + + if(new_format) + TESTING("backwards compatibility (w/new group format)") + else + TESTING("backwards compatibility") + + /* Create file */ + h5_fixname(FILENAME[0], fapl, filename, sizeof filename); + + if((file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR + + /* Create two groups in the file */ + if((group1_id = H5Gcreate2(file_id, "group1", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR + if((group2_id = H5Gcreate2(file_id, "group2", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR + + /* Test H5Gset and get comment */ + if(H5Gset_comment(file_id, "group1", "comment") < 0) FAIL_STACK_ERROR + if(H5Gget_comment(file_id, "group1", sizeof(tmpstr), tmpstr) < 0) FAIL_STACK_ERROR + if(HDstrcmp(tmpstr, "comment")) TEST_ERROR + + /* Create links using H5Glink and H5Glink2 */ + if(H5Glink(file_id, H5G_LINK_HARD, "group2", "group1/link_to_group2") < 0) FAIL_STACK_ERROR + if(H5Glink2(file_id, "group1", H5G_LINK_HARD, group2_id, "link_to_group1") < 0) FAIL_STACK_ERROR + if(H5Glink2(file_id, "link_to_group1", H5G_LINK_SOFT, H5G_SAME_LOC, "group2/soft_link_to_group1") < 0) FAIL_STACK_ERROR + if(H5Glink2(file_id, "dangle", H5G_LINK_SOFT, H5G_SAME_LOC, "group2/dangle_soft_link") < 0) FAIL_STACK_ERROR + + /* Test getting the names for objects */ + if(H5Gget_objname_by_idx(group1_id, (hsize_t)0, tmpstr, sizeof(tmpstr)) < 0) FAIL_STACK_ERROR + if(HDstrcmp(tmpstr, "link_to_group2")) TEST_ERROR + H5E_BEGIN_TRY { + if(H5Gget_objname_by_idx(group1_id, (hsize_t)1, tmpstr, sizeof(tmpstr)) >= 0) TEST_ERROR + } H5E_END_TRY; + + /* Test getting the type for objects */ + if((obj_type = H5Gget_objtype_by_idx(group1_id, (hsize_t)0)) < 0) FAIL_STACK_ERROR + if(obj_type != H5G_GROUP) TEST_ERROR + H5E_BEGIN_TRY { + if(H5Gget_objtype_by_idx(group1_id, (hsize_t)1) >= 0) TEST_ERROR + } H5E_END_TRY; + + /* Test getting the number of objects in a group */ + if(H5Gget_num_objs(file_id, &num_objs) < 0) FAIL_STACK_ERROR + if(num_objs != 2) TEST_ERROR + if(H5Gget_num_objs(group1_id, &num_objs) < 0) FAIL_STACK_ERROR + if(num_objs != 1) TEST_ERROR + + /* Test that H5Glink created hard links properly */ + if(H5Gget_objinfo(file_id, "/group2", TRUE, &sb_hard1) < 0) FAIL_STACK_ERROR + if(H5Gget_objinfo(file_id, "/group1/link_to_group2", TRUE, &sb_hard2) < 0) FAIL_STACK_ERROR + + if(HDmemcmp(&sb_hard1.objno, sb_hard2.objno, sizeof(sb_hard1.objno))) { + H5_FAILED(); + HDputs(" Hard link test failed. Link seems not to point to the "); + HDputs(" expected file location."); + TEST_ERROR + } /* end if */ + + /* Test for the other hard link created */ + if(H5Gget_objinfo(file_id, "/group1", TRUE, &sb_hard1) < 0) FAIL_STACK_ERROR + if(H5Gget_objinfo(file_id, "/group2/link_to_group1", TRUE, &sb_hard2) < 0) FAIL_STACK_ERROR + + if(HDmemcmp(&sb_hard1.objno, sb_hard2.objno, sizeof(sb_hard1.objno))) { + H5_FAILED(); + HDputs(" Hard link test failed. Link seems not to point to the "); + HDputs(" expected file location."); + TEST_ERROR + } /* end if */ + + /* Test the soft link */ + if(H5Gget_objinfo(file_id, "/group2/soft_link_to_group1", FALSE, &sb_soft1) < 0) FAIL_STACK_ERROR + if(sb_soft1.type != H5G_LINK) TEST_ERROR + if(sb_soft1.linklen != HDstrlen("link_to_group1") + 1) TEST_ERROR + + if(H5Gget_linkval(group2_id, "soft_link_to_group1", sb_soft1.linklen, tmpstr) < 0) FAIL_STACK_ERROR + if(HDstrcmp("link_to_group1", tmpstr)) TEST_ERROR + + /* Test non-existing links with H5Gget_objinfo */ + H5E_BEGIN_TRY { + if(H5Gget_objinfo(file_id, "/group2/soft_link_no_exist", TRUE, NULL) >= 0) FAIL_STACK_ERROR + } H5E_END_TRY; + + /* Test the dangling soft link */ + if(H5Gget_objinfo(file_id, "/group2/dangle_soft_link", FALSE, &sb_soft2) < 0) FAIL_STACK_ERROR + if(sb_soft2.type != H5G_LINK) TEST_ERROR + if(sb_soft2.linklen != HDstrlen("dangle") + 1) TEST_ERROR + + if(H5Gget_linkval(group2_id, "dangle_soft_link", sb_soft2.linklen, tmpstr) < 0) FAIL_STACK_ERROR + if(HDstrcmp("dangle", tmpstr)) TEST_ERROR + + + /* Test H5Gmove and H5Gmove2 */ + if(H5Gmove(file_id, "group1", "moved_group1") < 0) FAIL_STACK_ERROR + if(H5Gmove2(file_id, "group2", group1_id, "moved_group2") < 0) FAIL_STACK_ERROR + + /* Ensure that both groups can be opened */ + if(H5Gclose(group2_id) < 0) FAIL_STACK_ERROR + if(H5Gclose(group1_id) < 0) FAIL_STACK_ERROR + + if((group1_id = H5Gopen2(file_id, "moved_group1", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR + if((group2_id = H5Gopen2(file_id, "moved_group1/moved_group2", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR + + /* Close open IDs */ + if(H5Gclose(group2_id) < 0) FAIL_STACK_ERROR + if(H5Gclose(group1_id) < 0) FAIL_STACK_ERROR + + /* Test H5Gunlink */ + if(H5Gunlink(file_id, "moved_group1/moved_group2") < 0) FAIL_STACK_ERROR + + H5E_BEGIN_TRY { + if(H5Gopen2(file_id, "moved_group1/moved_group2", H5P_DEFAULT) >=0) TEST_ERROR + } H5E_END_TRY; + + if(H5Fclose(file_id) < 0) FAIL_STACK_ERROR + + PASSED(); + return SUCCEED; + +error: + H5E_BEGIN_TRY { + H5Gclose(group2_id); + H5Gclose(group1_id); + H5Fclose(file_id); + } H5E_END_TRY; + return 1; +} /* end test_deprec() */ + +/*------------------------------------------------------------------------- + * Function: cklinks_deprec + * + * Purpose: Open the file created in the first step and check that the + * links look correct. + * + * Return: Success: 0 + * Failure: -1 + *------------------------------------------------------------------------- + */ +static int +cklinks_deprec(hid_t fapl, hbool_t new_format) +{ + hid_t file; + H5O_info1_t oinfo1, oinfo2; + H5L_info1_t linfo; + char linkval[LINK_BUF_SIZE]; + char filename[NAME_BUF_SIZE]; + herr_t status; + + if(new_format) + TESTING("link queries using deprecated routines (w/new group format)") + else + TESTING("link queries using deprecated routines") + + /* Open the file */ + h5_fixname(FILENAME[1], fapl, filename, sizeof filename); + if((file = H5Fopen(filename, H5F_ACC_RDONLY, fapl)) < 0) FAIL_STACK_ERROR + + /* Hard link */ + if(H5Oget_info_by_name2(file, "d1", &oinfo1, H5O_INFO_BASIC, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + if(H5Oget_info_by_name2(file, "grp1/hard", &oinfo2, H5O_INFO_BASIC, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + if(H5O_TYPE_DATASET != oinfo2.type) { + H5_FAILED(); + HDprintf(" %d: Unexpected object type should have been a dataset\n", __LINE__); + TEST_ERROR + } /* end if */ + if(H5F_addr_ne(oinfo1.addr, oinfo2.addr)) { + H5_FAILED(); + HDputs(" Hard link test failed. Link seems not to point to the "); + HDputs(" expected file location."); + TEST_ERROR + } /* end if */ + if(H5Lexists(file, "/", H5P_DEFAULT) != TRUE) FAIL_STACK_ERROR + if(H5Lexists(file, "d1", H5P_DEFAULT) != TRUE) FAIL_STACK_ERROR + if(H5Lexists(file, "grp1/hard", H5P_DEFAULT) != TRUE) FAIL_STACK_ERROR + if(H5Lexists(file, "/grp1", H5P_DEFAULT) != TRUE) FAIL_STACK_ERROR + if(H5Lexists(file, "/grp1/hard", H5P_DEFAULT) != TRUE) FAIL_STACK_ERROR + H5E_BEGIN_TRY { + status = H5Lexists(file, "no_grp1/hard", H5P_DEFAULT); + } H5E_END_TRY; + if(status >= 0) { + H5_FAILED(); + HDputs(" H5Lexists() should have failed for a path with missing components."); + TEST_ERROR + } /* end if */ + H5E_BEGIN_TRY { + status = H5Lexists(file, "/no_grp1/hard", H5P_DEFAULT); + } H5E_END_TRY; + if(status >= 0) { + H5_FAILED(); + HDputs(" H5Lexists() should have failed for a path with missing components."); + TEST_ERROR + } /* end if */ + + /* Symbolic link */ + if(H5Oget_info_by_name2(file, "grp1/soft", &oinfo2, H5O_INFO_BASIC, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + if(H5O_TYPE_DATASET != oinfo2.type) { + H5_FAILED(); + HDprintf(" %d: Unexpected object type should have been a dataset\n", __LINE__); + TEST_ERROR + } /* end if */ + if(H5F_addr_ne(oinfo1.addr, oinfo2.addr)) { + H5_FAILED(); + HDputs(" Soft link test failed. Link seems not to point to the "); + HDputs(" expected file location."); + TEST_ERROR + } /* end if */ + if(H5Lget_val(file, "grp1/soft", linkval, sizeof linkval, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + if(HDstrcmp(linkval, "/d1")) { + H5_FAILED(); + HDputs(" Soft link test failed. Wrong link value"); + TEST_ERROR + } /* end if */ + if(H5Lexists(file, "grp1/soft", H5P_DEFAULT) != TRUE) FAIL_STACK_ERROR + + /* Dangling link */ + H5E_BEGIN_TRY { + status = H5Oget_info_by_name2(file, "grp1/dangle", &oinfo2, H5O_INFO_BASIC, H5P_DEFAULT); + } H5E_END_TRY; + if(status >= 0) { + H5_FAILED(); + HDputs(" H5Oget_info_by_name() should have failed for a dangling link."); + TEST_ERROR + } /* end if */ + if(H5Lget_info1(file, "grp1/dangle", &linfo, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + if(H5L_TYPE_SOFT != linfo.type) { + H5_FAILED(); + HDprintf(" %d: Unexpected object type should have been a symbolic link\n", __LINE__); + TEST_ERROR + } /* end if */ + if(H5Lget_val(file, "grp1/dangle", linkval, sizeof linkval, H5P_DEFAULT) < 0) { + H5_FAILED(); + HDprintf(" %d: Can't retrieve link value\n", __LINE__); + TEST_ERROR + } /* end if */ + if(HDstrcmp(linkval, "foobar")) { + H5_FAILED(); + HDputs(" Dangling link test failed. Wrong link value"); + TEST_ERROR + } /* end if */ + if(H5Lexists(file, "grp1/dangle", H5P_DEFAULT) != TRUE) FAIL_STACK_ERROR + + /* Recursive link */ + H5E_BEGIN_TRY { + status = H5Oget_info_by_name2(file, "grp1/recursive", &oinfo2, H5O_INFO_BASIC, H5P_DEFAULT); + } H5E_END_TRY; + if(status >= 0) { + H5_FAILED(); + HDputs(" H5Oget_info_by_name() should have failed for a recursive link."); + TEST_ERROR + } /* end if */ + if(H5Lget_info1(file, "grp1/recursive", &linfo, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + if(H5L_TYPE_SOFT != linfo.type) { + H5_FAILED(); + HDprintf(" %d: Unexpected object type should have been a symbolic link\n", __LINE__); + TEST_ERROR + } /* end if */ + if(H5Lget_val(file, "grp1/recursive", linkval, sizeof linkval, H5P_DEFAULT) < 0) { + H5_FAILED(); + HDprintf(" %d: Can't retrieve link value\n", __LINE__); + TEST_ERROR + } /* end if */ + if(HDstrcmp(linkval, "/grp1/recursive")) { + H5_FAILED(); + HDputs(" Recursive link test failed. Wrong link value"); + TEST_ERROR + } /* end if */ + + /* Non-existent link */ + if(H5Lexists(file, "foobar", H5P_DEFAULT) == TRUE) FAIL_STACK_ERROR + + /* Cleanup */ + if(H5Fclose(file) < 0) FAIL_STACK_ERROR + + PASSED(); + return SUCCEED; + +error: + return FAIL; +} /* end chklinks_deprec() */ + +/*------------------------------------------------------------------------- + * Function: test_lcpl_deprec + * + * Purpose: Tests Link Creation Property Lists + * + * Return: Success: 0 + * Failure: number of errors + *------------------------------------------------------------------------- + */ +static int +test_lcpl_deprec(hid_t fapl, hbool_t new_format) +{ + hid_t file_id = -1; + hid_t group_id = -1; + hid_t space_id = -1; + hid_t dset_id = -1; + hid_t type_id = -1; + hid_t lcpl_id = -1; + H5L_info1_t linfo; + char filename[1024]; + hsize_t dims[2]; + + if(new_format) + TESTING("link creation property lists using deprecated routines (w/new group format)") + else + TESTING("link creation property lists using deprecated routines") + + /* Actually, intermediate group creation is tested elsewhere (tmisc). + * Here we only need to test the character encoding property */ + + /* Create file */ + h5_fixname(FILENAME[0], fapl, filename, sizeof filename); + + if((file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR + + /* Create and link a group with the default LCPL */ + if((group_id = H5Gcreate2(file_id, "/group", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR + if(H5Gclose(group_id) < 0) TEST_ERROR + + /* Check that its character encoding is the default */ + if(H5Lget_info1(file_id, "group", &linfo, H5P_DEFAULT) < 0) TEST_ERROR + if(linfo.cset != H5F_DEFAULT_CSET) TEST_ERROR + + /* Create and commit a datatype with the default LCPL */ + if((type_id = H5Tcopy(H5T_NATIVE_INT)) < 0) TEST_ERROR + if(H5Tcommit2(file_id, "/type", type_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Tclose(type_id) < 0) TEST_ERROR + + /* Check that its character encoding is the default */ + if(H5Lget_info1(file_id, "type", &linfo, H5P_DEFAULT) < 0) TEST_ERROR + if(linfo.cset != H5F_DEFAULT_CSET) TEST_ERROR + + /* Create a dataspace */ + dims[0] = H5L_DIM1; + dims[1] = H5L_DIM2; + if((space_id=H5Screate_simple(2 ,dims, NULL)) < 0) TEST_ERROR + + /* Create a dataset using the default LCPL */ + if((dset_id = H5Dcreate2(file_id, "/dataset", H5T_NATIVE_INT, space_id, H5P_DEFAULT, dcpl_g, H5P_DEFAULT)) < 0) TEST_ERROR + if(H5Dclose(dset_id) < 0) TEST_ERROR + + /* Check that its character encoding is the default */ + if(H5Lget_info1(file_id, "dataset", &linfo, H5P_DEFAULT) < 0) TEST_ERROR + if(linfo.cset != H5F_DEFAULT_CSET) TEST_ERROR + + /* Create a link creation property list with the UTF-8 character encoding */ + if((lcpl_id = H5Pcreate(H5P_LINK_CREATE)) < 0) TEST_ERROR + if(H5Pset_char_encoding(lcpl_id, H5T_CSET_UTF8) < 0) TEST_ERROR + + /* Create and link a group with the new LCPL */ + if((group_id = H5Gcreate2(file_id, "/group2", lcpl_id, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR + if(H5Gclose(group_id) < 0) TEST_ERROR + + /* Check that its character encoding is UTF-8 */ + if(H5Lget_info1(file_id, "group2", &linfo, H5P_DEFAULT) < 0) TEST_ERROR + if(linfo.cset != H5T_CSET_UTF8) TEST_ERROR + + /* Create and commit a datatype with the new LCPL */ + if((type_id = H5Tcopy(H5T_NATIVE_INT)) < 0) TEST_ERROR + if(H5Tcommit2(file_id, "/type2", type_id, lcpl_id, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Tclose(type_id) < 0) TEST_ERROR + + /* Check that its character encoding is UTF-8 */ + if(H5Lget_info1(file_id, "type2", &linfo, H5P_DEFAULT) < 0) TEST_ERROR + if(linfo.cset != H5T_CSET_UTF8) TEST_ERROR + + /* Create a dataset using the new LCPL */ + if((dset_id = H5Dcreate2(file_id, "/dataset2", H5T_NATIVE_INT, space_id, lcpl_id, dcpl_g, H5P_DEFAULT)) < 0) TEST_ERROR + if(H5Dclose(dset_id) < 0) TEST_ERROR + + /* Check that its character encoding is UTF-8 */ + if(H5Lget_info1(file_id, "dataset2", &linfo, H5P_DEFAULT) < 0) TEST_ERROR + if(linfo.cset != H5T_CSET_UTF8) TEST_ERROR + + /* Create a new link to the dataset with a different character encoding. */ + if(H5Pclose(lcpl_id) < 0) TEST_ERROR + if((lcpl_id = H5Pcreate(H5P_LINK_CREATE)) < 0) TEST_ERROR + if(H5Pset_char_encoding(lcpl_id, H5T_CSET_ASCII) < 0) TEST_ERROR + + if(H5Lcreate_hard(file_id, "/dataset2", file_id, "/dataset2_link", lcpl_id, H5P_DEFAULT) < 0) TEST_ERROR + + /* Check that its character encoding is ASCII */ + if(H5Lget_info1(file_id, "/dataset2_link", &linfo, H5P_DEFAULT) < 0) TEST_ERROR + if(linfo.cset != H5T_CSET_ASCII) TEST_ERROR + + /* Check that the first link's encoding hasn't changed */ + if(H5Lget_info1(file_id, "/dataset2", &linfo, H5P_DEFAULT) < 0) TEST_ERROR + if(linfo.cset != H5T_CSET_UTF8) TEST_ERROR + + /* Make sure that LCPLs work properly for other API calls: */ + /* H5Lcreate_soft */ + if(H5Pset_char_encoding(lcpl_id, H5T_CSET_UTF8) < 0) TEST_ERROR + if(H5Lcreate_soft("dataset2", file_id, "slink_to_dset2", lcpl_id, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Lget_info1(file_id, "slink_to_dset2", &linfo, H5P_DEFAULT) < 0) TEST_ERROR + if(linfo.cset != H5T_CSET_UTF8) TEST_ERROR + + /* H5Lmove */ + if(H5Pset_char_encoding(lcpl_id, H5T_CSET_ASCII) < 0) TEST_ERROR + if(H5Lmove(file_id, "slink_to_dset2", file_id, "moved_slink", lcpl_id, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Lget_info1(file_id, "moved_slink", &linfo, H5P_DEFAULT) < 0) TEST_ERROR + if(linfo.cset != H5T_CSET_ASCII) TEST_ERROR + + /* H5Lcopy */ + if(H5Pset_char_encoding(lcpl_id, H5T_CSET_UTF8) < 0) TEST_ERROR + if(H5Lcopy(file_id, "moved_slink", file_id, "copied_slink", lcpl_id, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Lget_info1(file_id, "copied_slink", &linfo, H5P_DEFAULT) < 0) TEST_ERROR + if(linfo.cset != H5T_CSET_UTF8) TEST_ERROR + + /* H5Lcreate_external */ + if(H5Lcreate_external("filename", "path", file_id, "extlink", lcpl_id, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Lget_info1(file_id, "extlink", &linfo, H5P_DEFAULT) < 0) TEST_ERROR + if(linfo.cset != H5T_CSET_UTF8) TEST_ERROR + + /* Close open IDs */ + if(H5Pclose(lcpl_id) < 0) TEST_ERROR + if(H5Sclose(space_id) < 0) TEST_ERROR + if(H5Fclose(file_id) < 0) TEST_ERROR + + PASSED(); + return SUCCEED; + +error: + H5E_BEGIN_TRY { + H5Gclose(group_id); + H5Dclose(dset_id); + H5Tclose(type_id); + H5Pclose(lcpl_id); + H5Sclose(space_id); + H5Fclose(file_id); + } H5E_END_TRY; + return 1; +} /* end test_lcpl_deprec() */ + +/*------------------------------------------------------------------------- + * Function: test_move_preserves_deprec + * + * Purpose: Tests that moving and renaming links preserves their + * properties. + * + * Return: Success: 0 + * Failure: number of errors + *------------------------------------------------------------------------- + */ +static int +test_move_preserves_deprec(hid_t fapl_id, hbool_t new_format) +{ + hid_t file_id=-1; + hid_t group_id=-1; + hid_t fcpl_id=-1; /* Group creation property list ID */ + hid_t lcpl_id=-1; + hid_t lcpl2_id=-1; + H5O_info1_t oinfo; + H5L_info1_t linfo; + H5T_cset_t old_cset; + int64_t old_corder; /* Creation order value of link */ + time_t old_modification_time; + time_t curr_time; + unsigned crt_order_flags; /* Status of creation order info for GCPL */ + char filename[1024]; + + if(new_format) + TESTING("moving and copying links using deprecated routines preserves their properties (w/new group format)") + else + TESTING("moving and copying links using deprecated routines preserves their properties") + + /* Create a file creation property list with creation order stored for links + * in the root group + */ + if((fcpl_id = H5Pcreate(H5P_FILE_CREATE)) < 0) TEST_ERROR + if(H5Pget_link_creation_order(fcpl_id, &crt_order_flags) < 0) TEST_ERROR + if(crt_order_flags != 0) TEST_ERROR + if(H5Pset_link_creation_order(fcpl_id, H5P_CRT_ORDER_TRACKED) < 0) TEST_ERROR + if(H5Pget_link_creation_order(fcpl_id, &crt_order_flags) < 0) TEST_ERROR + if(crt_order_flags != H5P_CRT_ORDER_TRACKED) TEST_ERROR + + /* Create file */ + /* (with creation order tracking for the root group) */ + h5_fixname(FILENAME[0], fapl_id, filename, sizeof filename); + if((file_id = H5Fcreate(filename, H5F_ACC_TRUNC, fcpl_id, fapl_id)) < 0) TEST_ERROR + + /* Create a link creation property list with the UTF-8 character encoding */ + if((lcpl_id = H5Pcreate(H5P_LINK_CREATE)) < 0) TEST_ERROR + if(H5Pset_char_encoding(lcpl_id, H5T_CSET_UTF8) < 0) TEST_ERROR + + /* Create a group with that lcpl */ + if((group_id = H5Gcreate2(file_id, "group", lcpl_id, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR + if(H5Gclose(group_id) < 0) TEST_ERROR + + /* Get the group's link's information */ + if(H5Lget_info1(file_id, "group", &linfo, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Oget_info_by_name2(file_id, "group", &oinfo, H5O_INFO_TIME, H5P_DEFAULT) < 0) TEST_ERROR + old_cset = linfo.cset; + if(old_cset != H5T_CSET_UTF8) TEST_ERROR + if(linfo.corder_valid != TRUE) TEST_ERROR + old_corder = linfo.corder; + if(old_corder != 0) TEST_ERROR + old_modification_time = oinfo.mtime; + + /* If this test happens too quickly, the times will all be the same. Make sure the time changes. */ + curr_time = HDtime(NULL); + while(HDtime(NULL) <= curr_time) + ; + + /* Close the file and reopen it */ + if(H5Fclose(file_id) < 0) TEST_ERROR + if((file_id = H5Fopen(filename, H5F_ACC_RDWR, fapl_id)) < 0) TEST_ERROR + + /* Get the link's character set & modification time . They should be unchanged */ + if(H5Lget_info1(file_id, "group", &linfo, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Oget_info_by_name2(file_id, "group", &oinfo, H5O_INFO_TIME, H5P_DEFAULT) < 0) TEST_ERROR + if(old_modification_time != oinfo.mtime) TEST_ERROR + if(old_cset != linfo.cset) TEST_ERROR + if(linfo.corder_valid != TRUE) TEST_ERROR + if(old_corder != linfo.corder) TEST_ERROR + + /* Create a new link to the group. It should have a different creation order value but the same modification time */ + if(H5Lcreate_hard(file_id, "group", file_id, "group2", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Oget_info_by_name2(file_id, "group2", &oinfo, H5O_INFO_TIME, H5P_DEFAULT) < 0) TEST_ERROR + if(old_modification_time != oinfo.mtime) TEST_ERROR + if(H5Lget_info1(file_id, "group2", &linfo, H5P_DEFAULT) < 0) TEST_ERROR + if(old_corder == linfo.corder) TEST_ERROR + if(linfo.corder_valid != TRUE) TEST_ERROR + if(linfo.corder != 1) TEST_ERROR + if(linfo.cset != H5T_CSET_ASCII) TEST_ERROR + + /* Copy the first link to a UTF-8 name. + * Its creation order value should be different, but modification time + * should not change. + */ + if(H5Lcopy(file_id, "group", file_id, "group_copied", lcpl_id, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Oget_info_by_name2(file_id, "group_copied", &oinfo, H5O_INFO_TIME, H5P_DEFAULT) < 0) TEST_ERROR + if(old_modification_time != oinfo.mtime) TEST_ERROR + if(H5Lget_info1(file_id, "group_copied", &linfo, H5P_DEFAULT) < 0) TEST_ERROR + if(linfo.corder_valid != TRUE) TEST_ERROR + if(linfo.corder != 2) TEST_ERROR + + /* Check that its character encoding is UTF-8 */ + if(linfo.cset != H5T_CSET_UTF8) TEST_ERROR + + /* Move the link with the default property list. */ + if(H5Lmove(file_id, "group_copied", file_id, "group_copied2", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Oget_info_by_name2(file_id, "group_copied2", &oinfo, H5O_INFO_TIME, H5P_DEFAULT) < 0) TEST_ERROR + if(old_modification_time != oinfo.mtime) TEST_ERROR + if(H5Lget_info1(file_id, "group_copied2", &linfo, H5P_DEFAULT) < 0) TEST_ERROR + if(linfo.corder_valid != TRUE) TEST_ERROR + if(linfo.corder != 3) TEST_ERROR + + /* Check that its character encoding is not UTF-8 */ + if(linfo.cset == H5T_CSET_UTF8) TEST_ERROR + + /* Check that the original link is unchanged */ + if(H5Oget_info_by_name2(file_id, "group", &oinfo, H5O_INFO_TIME, H5P_DEFAULT) < 0) TEST_ERROR + if(old_modification_time != oinfo.mtime) TEST_ERROR + if(H5Lget_info1(file_id, "group", &linfo, H5P_DEFAULT) < 0) TEST_ERROR + if(linfo.corder_valid != TRUE) TEST_ERROR + if(old_corder != linfo.corder) TEST_ERROR + if(linfo.cset != H5T_CSET_UTF8) TEST_ERROR + + /* Move the first link to a UTF-8 name. + * Its creation order value will change, but modification time should not + * change. */ + if(H5Lmove(file_id, "group", file_id, "group_moved", lcpl_id, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Oget_info_by_name2(file_id, "group_moved", &oinfo, H5O_INFO_TIME, H5P_DEFAULT) < 0) TEST_ERROR + if(old_modification_time != oinfo.mtime) TEST_ERROR + if(H5Lget_info1(file_id, "group_moved", &linfo, H5P_DEFAULT) < 0) TEST_ERROR + if(linfo.corder_valid != TRUE) TEST_ERROR + if(linfo.corder != 4) TEST_ERROR + + /* Check that its character encoding is UTF-8 */ + if(linfo.cset != H5T_CSET_UTF8) TEST_ERROR + + /* Move the link again using the default property list. */ + if(H5Lmove(file_id, "group_moved", file_id, "group_moved_again", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Oget_info_by_name2(file_id, "group_moved_again", &oinfo, H5O_INFO_TIME, H5P_DEFAULT) < 0) TEST_ERROR + if(old_modification_time != oinfo.mtime) TEST_ERROR + if(H5Lget_info1(file_id, "group_moved_again", &linfo, H5P_DEFAULT) < 0) TEST_ERROR + if(linfo.corder_valid != TRUE) TEST_ERROR + if(linfo.corder != 5) TEST_ERROR + + /* Check that its character encoding is not UTF-8 */ + if(linfo.cset == H5T_CSET_UTF8) TEST_ERROR + + /* Close open IDs */ + if(H5Pclose(fcpl_id) < 0) TEST_ERROR + if(H5Pclose(lcpl_id) < 0) TEST_ERROR + if(H5Fclose(file_id) < 0) TEST_ERROR + + PASSED(); + return SUCCEED; + +error: + H5E_BEGIN_TRY { + H5Pclose(fcpl_id); + H5Pclose(lcpl_id); + H5Pclose(lcpl2_id); + H5Gclose(group_id); + H5Fclose(file_id); + } H5E_END_TRY; + return 1; +} /* end test_move_preserves_deprec() */ + +/*------------------------------------------------------------------------- + * Function: external_link_root_deprec + * + * Purpose: Build a file with external link to root group in external file + * + * Return: Success: 0 + * Failure: -1 + *------------------------------------------------------------------------- + */ +static int +external_link_root_deprec(hid_t fapl, hbool_t new_format) +{ + hid_t fid = -1; /* File ID */ + hid_t gid = -1, gid2 = -1; /* Group IDs */ + H5L_info1_t linfo; /* Link information */ + char objname[NAME_BUF_SIZE]; /* Object name */ + char filename1[NAME_BUF_SIZE]; + char filename2[NAME_BUF_SIZE]; + const char *file; /* File from external link */ + const char *path; /* Path from external link */ + + if(new_format) + TESTING("external link to root using deprecated routines (w/new group format)") + else + TESTING("external link to root using deprecated routines") + + /* Set up filenames */ + h5_fixname(FILENAME[3], fapl, filename1, sizeof filename1); + h5_fixname(FILENAME[4], fapl, filename2, sizeof filename2); + + /* Create file to point to */ + if((fid = H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR + + /* Close file */ + if(H5Fclose(fid) < 0) TEST_ERROR + + /* Check that external links are registered with the library */ + if(H5Lis_registered(H5L_TYPE_EXTERNAL) != TRUE) TEST_ERROR + + /* Create file with link to first file */ + if((fid = H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR + + /* Create external link to object in first file */ + if(H5Lcreate_external(filename1, "/", fid, "ext_link", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR + + /* Check information for external link */ + if(H5Lget_info1(fid, "ext_link", &linfo, H5P_DEFAULT) < 0) goto error; + if(H5L_TYPE_EXTERNAL != linfo.type) { + H5_FAILED(); + HDputs(" Unexpected object type - should have been an external link"); + goto error; + } + if(H5Lget_val(fid, "ext_link", objname, sizeof(objname), H5P_DEFAULT) < 0) TEST_ERROR + if(H5Lunpack_elink_val(objname, linfo.u.val_size, NULL, &file, &path) < 0) TEST_ERROR + if(HDstrcmp(file, filename1)) { + H5_FAILED(); + HDputs(" External link file name incorrect"); + goto error; + } + if(HDstrcmp(path, "/")) { + H5_FAILED(); + HDputs(" External link path incorrect"); + goto error; + } + + /* Create external link to object in first file */ + /* (add a few extra '/'s to make certain library normalizes external link object names) */ + if(H5Lcreate_external(filename1, "///", fid, "ext_link2", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR + + /* Check information for external link */ + if(H5Lget_info1(fid, "ext_link", &linfo, H5P_DEFAULT) < 0) goto error; + if(H5L_TYPE_EXTERNAL != linfo.type) { + H5_FAILED(); + HDputs(" Unexpected object type - should have been an external link"); + goto error; + } + if(H5Lget_val(fid, "ext_link", objname, sizeof(objname), H5P_DEFAULT) < 0) TEST_ERROR + if(H5Lunpack_elink_val(objname, linfo.u.val_size, NULL, &file, &path) < 0) TEST_ERROR + if(HDstrcmp(file, filename1)) { + H5_FAILED(); + HDputs(" External link file name incorrect"); + goto error; + } + if(HDstrcmp(path, "/")) { + H5_FAILED(); + HDputs(" External link path incorrect"); + goto error; + } + + /* Close and re-open file to ensure that data is written to disk */ + if(H5Fclose(fid) < 0) TEST_ERROR + if((fid = H5Fopen(filename2, H5F_ACC_RDWR, fapl)) < 0) TEST_ERROR + + /* Open object through external link */ + if((gid = H5Gopen2(fid, "ext_link", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR + + /* Check name */ + if(H5Iget_name(gid, objname, (size_t)NAME_BUF_SIZE) < 0) TEST_ERROR + if(HDstrcmp(objname, "/")) TEST_ERROR + + /* Create object in external file */ + if((gid2 = H5Gcreate2(gid, "new_group", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR + + /* Close group in external file */ + if(H5Gclose(gid2) < 0) TEST_ERROR + + /* Close external object (lets first file close) */ + if(H5Gclose(gid) < 0) TEST_ERROR + + /* Create a new object using H5Gcreate2 through the external link + * directly + */ + if((gid = H5Gcreate2(fid, "ext_link/newer_group", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR + + /* Close file and group */ + if(H5Gclose(gid) < 0) TEST_ERROR + if(H5Fclose(fid) < 0) TEST_ERROR + + /* Check that all file IDs have been closed */ + if(H5I_nmembers(H5I_FILE) != 0) TEST_ERROR + H5F_sfile_assert_num(0); + + /* Open first file again with read-only access and check on objects created */ + if((fid = H5Fopen(filename1, H5F_ACC_RDONLY, fapl)) < 0) TEST_ERROR + + /* Open objects created through external link */ + if((gid = H5Gopen2(fid, "new_group", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR + if((gid2 = H5Gopen2(fid, "newer_group", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR + + /* Check names */ + if(H5Iget_name(gid, objname, (size_t)NAME_BUF_SIZE) < 0) TEST_ERROR + if(HDstrcmp(objname, "/new_group")) TEST_ERROR + if(H5Iget_name(gid2, objname, (size_t)NAME_BUF_SIZE) < 0) TEST_ERROR + if(HDstrcmp(objname, "/newer_group")) TEST_ERROR + + /* Close opened objects */ + if(H5Gclose(gid) < 0) TEST_ERROR + if(H5Gclose(gid2) < 0) TEST_ERROR + + /* Close first file */ + if(H5Fclose(fid) < 0) TEST_ERROR + + /* Check that all file IDs have been closed */ + if(H5I_nmembers(H5I_FILE) != 0) TEST_ERROR + H5F_sfile_assert_num(0); + + /* Verify that new objects can't be created through a read-only external + * link. + */ + if((fid = H5Fopen(filename2, H5F_ACC_RDONLY, fapl)) < 0) TEST_ERROR + + H5E_BEGIN_TRY { + gid = H5Gcreate2(fid, "ext_link/readonly_group", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + } H5E_END_TRY + if(gid >= 0) TEST_ERROR + + /* Close second file again */ + if(H5Fclose(fid) < 0) TEST_ERROR + + /* Check that all file IDs have been closed */ + if(H5I_nmembers(H5I_FILE) != 0) TEST_ERROR + H5F_sfile_assert_num(0); + + PASSED(); + return SUCCEED; + +error: + H5E_BEGIN_TRY { + H5Gclose (gid2); + H5Gclose (gid); + H5Fclose (fid); + } H5E_END_TRY; + return FAIL; +} /* end external_link_root_deprec() */ + +/*------------------------------------------------------------------------- + * Function: external_link_query_deprec + * + * Purpose: Query file & object names for external links, as well as + * information from H5Gget_obj_info + * + * Return: Success: 0 + * Failure: -1 + *------------------------------------------------------------------------- + */ +static int +external_link_query_deprec(hid_t fapl, hbool_t new_format) +{ + hid_t fid = -1; /* File ID */ + hid_t gid = -1; /* Group IDs */ + const char *file_name; /* Name of the file the external link points to */ + const char *object_name; /* Name of the object the external link points to */ + H5O_info1_t oi; /* Object information */ + H5L_info1_t li; /* Link information */ + char filename1[NAME_BUF_SIZE], + filename2[NAME_BUF_SIZE], /* Names of files to externally link across */ + query_buf[NAME_BUF_SIZE]; /* Buffer to hold query result */ + + if(new_format) + TESTING("query aspects of external link using deprecated routines (w/new group format)") + else + TESTING("query aspects of external link using deprecated routines") + + /* Set up filenames */ + h5_fixname(FILENAME[3], fapl, filename1, sizeof filename1); + h5_fixname(FILENAME[4], fapl, filename2, sizeof filename2); + + /* Create first file, with external link to object in second file */ + if((fid = H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR + + /* Create external link */ + /* (add a few extra '/'s to make certain library normalizes external link object names) */ + if(H5Lcreate_external(filename2, "///dst//", fid, "src", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR + + /* Get size of buffer for external link */ + if(H5Lget_info1(fid, "src", &li, H5P_DEFAULT) < 0) TEST_ERROR + if(li.u.val_size != (1 + (HDstrlen(filename2) + 1) + (HDstrlen("/dst") + 1))) TEST_ERROR + if (H5L_TYPE_EXTERNAL != li.type) { + H5_FAILED(); + HDputs(" Unexpected link class - should have been an external link"); + goto error; + } + + /* Close file */ + if(H5Fclose(fid) < 0) TEST_ERROR + + /* Create second file to point to */ + if((fid = H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR + + /* Create object to link to */ + if((gid = H5Gcreate2(fid, "dst", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR + if(H5Gclose(gid) < 0) TEST_ERROR + + /* Close file */ + if(H5Fclose(fid) < 0) TEST_ERROR + + /* Open first file */ + if((fid = H5Fopen(filename1, H5F_ACC_RDONLY, fapl)) < 0) TEST_ERROR + + /* Get size of buffer for external link */ + if(H5Lget_info1(fid, "src", &li, H5P_DEFAULT) < 0) TEST_ERROR + if(li.u.val_size != (1 + (HDstrlen(filename2) + 1) + (HDstrlen("/dst") + 1))) TEST_ERROR + if(H5L_TYPE_EXTERNAL != li.type) { + H5_FAILED(); + HDputs(" Unexpected link class - should have been an external link"); + goto error; + } + + /* Get information for external link. It should be two strings right after each other */ + if(H5Lget_val(fid, "src", query_buf, (size_t)NAME_BUF_SIZE, H5P_DEFAULT) < 0) TEST_ERROR + + /* Extract the file and object names from the buffer */ + if(H5Lunpack_elink_val(query_buf, li.u.val_size, NULL, &file_name, &object_name) < 0) TEST_ERROR + + /* Compare the file and object names */ + if(HDstrcmp(file_name, filename2)) TEST_ERROR + if(HDstrcmp(object_name, "/dst")) TEST_ERROR + + /* Query information about object that external link points to */ + if(H5Oget_info_by_name2(fid, "src", &oi, H5O_INFO_BASIC, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + if(H5O_TYPE_GROUP != oi.type) { + H5_FAILED(); + HDputs(" Unexpected object type - should have been a group"); + goto error; + } + + /* Close first file */ + if(H5Fclose(fid) < 0) TEST_ERROR + + /* Make sure that passing in NULLs to H5Lunpack_elink_val works */ + if(H5Lunpack_elink_val(query_buf, li.u.val_size, NULL, NULL, NULL) < 0) TEST_ERROR + + /* Make sure that bogus cases trigger errors in H5Lunpack_elink_val */ + H5E_BEGIN_TRY { + if(H5Lunpack_elink_val(query_buf, li.u.val_size - 1, NULL, NULL, NULL) >= 0) TEST_ERROR + } H5E_END_TRY + H5E_BEGIN_TRY { + if(H5Lunpack_elink_val(query_buf, (size_t)0, NULL, NULL, NULL) >= 0) TEST_ERROR + } H5E_END_TRY + H5E_BEGIN_TRY { + if(H5Lunpack_elink_val(NULL, (size_t)0, NULL, NULL, NULL) >= 0) TEST_ERROR + } H5E_END_TRY + H5E_BEGIN_TRY { + if(H5Lunpack_elink_val(NULL, (size_t)1000, NULL, NULL, NULL) >= 0) TEST_ERROR + } H5E_END_TRY + + PASSED(); + return SUCCEED; + +error: + H5E_BEGIN_TRY { + H5Gclose(gid); + H5Fclose(fid); + } H5E_END_TRY; + return FAIL; +} /* end external_link_query_deprec() */ + +/*------------------------------------------------------------------------- + * Function: external_link_closing_deprec + * + * Purpose: Test that files are closed correctly when traversing + * external links. + * + * Return: Success: 0 + * Failure: -1 + *------------------------------------------------------------------------- + */ +static int +external_link_closing_deprec(hid_t fapl, hbool_t new_format) +{ + hid_t fid1 = (-1), fid2 = (-1), fid3 = (-1), fid4=(-1); + hid_t gid=(-1), tid=(-1), tid2=(-1), sid=(-1), did=(-1); + hid_t lcpl_id=(-1); + hsize_t dims[2]; + char filename1[NAME_BUF_SIZE], + filename2[NAME_BUF_SIZE], + filename3[NAME_BUF_SIZE], + filename4[NAME_BUF_SIZE], /* Names of files to externally link across */ + buf[NAME_BUF_SIZE]; /* misc. buffer */ + H5L_info1_t li; + H5O_info1_t oi; + hobj_ref_t obj_ref; + + if(new_format) + TESTING("that external files are closed during traversal (w/new group format)") + else + TESTING("that external files are closed during traversal") + + /* In this test, external links will go from file1 to file2 and from + * file2 to file3. + * Test that all functions that can traverse external files close + * the files they open. + * Test that providing unusual paths containing external links can't + * make HDF5 forget to close a file it opened. + */ + + /* Set up filenames */ + h5_fixname(FILENAME[3], fapl, filename1, sizeof filename1); + h5_fixname(FILENAME[4], fapl, filename2, sizeof filename2); + h5_fixname(FILENAME[5], fapl, filename3, sizeof filename3); + h5_fixname(FILENAME[6], fapl, filename4, sizeof filename4); + + /* Create four files */ + if((fid1 = H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR + if((fid2 = H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR + if((fid3 = H5Fcreate(filename3, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR + if((fid4 = H5Fcreate(filename4, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR + + /* Create a dataspace and a datatype so we can create/commit a dataset/datatype in the files */ + dims[0] = 2; + dims[1] = 2; + if((sid = H5Screate_simple(2, dims, NULL)) < 0) TEST_ERROR + if((tid = H5Tcopy(H5T_NATIVE_INT)) < 0) TEST_ERROR + if((tid2 = H5Tcopy(H5T_NATIVE_INT)) < 0) TEST_ERROR + + /* Create external links from each file to the next */ + if(H5Lcreate_external(filename2, "/", fid1, "elink", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Lcreate_external(filename3, "/", fid2, "elink", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Lcreate_external(filename4, "/", fid3, "elink", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR + + /* Close all files but the first */ + if(H5Fclose(fid4) < 0) TEST_ERROR + if(H5Fclose(fid3) < 0) TEST_ERROR + if(H5Fclose(fid2) < 0) TEST_ERROR + + /* Test creating each kind of object */ + if((gid = H5Gcreate2(fid1, "elink/elink/elink/group1", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR + if(H5Tcommit2(fid1, "elink/elink/elink/type1", tid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR + if((did = H5Dcreate2(fid1, "elink/elink/elink/dataset1", tid2, sid, H5P_DEFAULT, dcpl_g, H5P_DEFAULT)) < 0) TEST_ERROR + + /* Close objects */ + if(H5Gclose(gid) < 0) TEST_ERROR + if(H5Tclose(tid) < 0) TEST_ERROR + if(H5Dclose(did) < 0) TEST_ERROR + + /* Test that getting info works */ + if(H5Lget_info1(fid1, "elink/elink/elink/type1", &li, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Lget_info1(fid1, "elink/elink/elink", &li, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Oget_info_by_name2(fid1, "elink/elink/elink/type1", &oi, H5O_INFO_BASIC, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Oget_info_by_name2(fid1, "elink/elink/elink", &oi, H5O_INFO_BASIC, H5P_DEFAULT) < 0) TEST_ERROR + + /* Test move */ + if(H5Lmove(fid1, "elink/elink/elink/group1", fid1, + "elink/elink/elink/group1_moved", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR + + /* Open file 4 so we can do some fancy things */ + if((fid4 = H5Fopen(filename4, H5F_ACC_RDWR, fapl)) < 0) FAIL_STACK_ERROR + if(H5Lmove(fid1, "elink/elink/elink/type1", fid4, + "type1_moved", H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + if(H5Lmove(fid4, "dataset1", fid1, + "elink/elink/elink/dataset1_moved", H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + + /* Close file 4 again */ + if(H5Fclose(fid4) < 0) FAIL_STACK_ERROR + + /* Test copy (as of this test, it uses the same code as move) */ + if(H5Lcopy(fid1, "elink/elink/elink", fid1, + "elink/elink/elink_copied", H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + if(H5Lcopy(fid1, "elink/elink/elink", fid1, + "elink/elink/elink/elink_copied2", H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + + /* Test H5Gset and get comment */ + if(H5Oset_comment_by_name(fid1, "elink/elink/elink/group1_moved", "comment", H5P_DEFAULT) < 0) FAIL_STACK_ERROR + if(H5Oget_comment_by_name(fid1, "elink/elink/elink/group1_moved", buf, sizeof(buf), H5P_DEFAULT) < 0) FAIL_STACK_ERROR + if(HDstrcmp(buf, "comment")) TEST_ERROR + + /* Test H5*open */ + if((gid = H5Gopen2(fid1, "elink/elink/elink/group1_moved", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR + if((tid = H5Topen2(fid1, "elink/elink/elink/type1_moved", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR + if((did = H5Dopen2(fid1, "elink/elink/elink/dataset1_moved", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR + /* Close objects */ + if(H5Gclose(gid) < 0) FAIL_STACK_ERROR + if(H5Tclose(tid) < 0) FAIL_STACK_ERROR + if(H5Dclose(did) < 0) FAIL_STACK_ERROR + + /* Test H5*open2 */ + if((gid = H5Gopen2(fid1, "elink/elink/elink/group1_moved", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR + if((tid = H5Topen2(fid1, "elink/elink/elink/type1_moved", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR + if((did = H5Dopen2(fid1, "elink/elink/elink/dataset1_moved", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR + /* Close objects */ + if(H5Gclose(gid) < 0) FAIL_STACK_ERROR + if(H5Tclose(tid) < 0) FAIL_STACK_ERROR + if(H5Dclose(did) < 0) FAIL_STACK_ERROR + + /* Test H5Oopen */ + if((did = H5Oopen(fid1, "elink/elink/elink/dataset1_moved", H5P_DEFAULT)) < 0) TEST_ERROR + if(H5Dclose(did) < 0) TEST_ERROR + + /* Test H5Fmount */ + if((gid = H5Gcreate2(fid1, "elink/elink/elink/mnt", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR + if(H5Gclose(gid) < 0) TEST_ERROR + H5E_BEGIN_TRY { + if(H5Fmount(fid1, "elink/elink/elink/mnt", fid1, H5P_DEFAULT) >= 0) TEST_ERROR + if(H5Funmount(fid1, "elink/elink/elink/mnt") >= 0) TEST_ERROR + } H5E_END_TRY + + /* Test H5Rcreate */ + if(H5Rcreate(&obj_ref, fid1, "elink/elink/elink/type1_moved", H5R_OBJECT, (hid_t)(-1)) < 0) TEST_ERROR + + /* Test unlink */ + if(H5Ldelete(fid1, "elink/elink/elink/group1_moved", H5P_DEFAULT) < 0) TEST_ERROR + if(H5Ldelete(fid1, "elink/elink/elink/type1_moved", H5P_DEFAULT) < 0) TEST_ERROR + if(H5Ldelete(fid1, "elink/elink/elink/dataset1_moved", H5P_DEFAULT) < 0) TEST_ERROR + if(H5Ldelete(fid1, "elink/elink/elink_copied", H5P_DEFAULT) < 0) TEST_ERROR + if(H5Ldelete(fid1, "elink/elink/elink/elink_copied2", H5P_DEFAULT) < 0) TEST_ERROR + + /* We've tested that the various functions above don't leave files open. + * Now test that we can't confuse HDF5 by giving unusual paths with external links + */ + /* Create an external link that points to another external link */ + if((fid2 = H5Fopen(filename2, H5F_ACC_RDWR, fapl)) < 0) TEST_ERROR + if(H5Lcreate_external(filename3, "/elink", fid2, "elink2", + H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Fclose(fid2) < 0) TEST_ERROR + + /* Do an external link traversal that recursively calls another external link. */ + if((gid = H5Gcreate2(fid1, "elink/elink2/group2", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR + if(H5Gclose(gid) < 0) TEST_ERROR + + /* Create two more groups so that the last three elements in the path are + * all within the same external file + */ + if((gid = H5Gcreate2(fid1, "elink/elink2/group2/group3", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR + if(H5Gclose(gid) < 0) TEST_ERROR + if((gid = H5Gcreate2(fid1, "elink/elink2/group2/group3/group4", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR + if(H5Gclose(gid) < 0) TEST_ERROR + if(H5Oget_info_by_name2(fid1, "elink/elink2/group2/group3/group4", &oi, H5O_INFO_BASIC, H5P_DEFAULT) < 0) TEST_ERROR + + /* Add a few regular groups and a soft link in file2 using intermediate group creation */ + if((lcpl_id = H5Pcreate(H5P_LINK_CREATE)) < 0) TEST_ERROR + if(H5Pset_create_intermediate_group(lcpl_id, TRUE) < 0) TEST_ERROR + if(H5Lcreate_soft("/elink2", fid1, "elink/file2group1/file2group2/slink", + lcpl_id, H5P_DEFAULT) < 0) TEST_ERROR + + /* Try to traverse this path. There are three soft traversals in a row; + * slink points to (file2)/elink2, which points to (file3)/elink, which + * points to file 4. + */ + if((gid = H5Gcreate2(fid1, "elink/file2group1/file2group2/slink/group3", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR + if(H5Gclose(gid) < 0) TEST_ERROR + if(H5Lget_info1(fid1, "elink/file2group1/file2group2/slink/group3", &li, H5P_DEFAULT) < 0) TEST_ERROR + + /* Some simpler tests */ + if((gid = H5Gcreate2(fid1, "elink/file2group3", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR + if(H5Gclose(gid) < 0) TEST_ERROR + if(H5Lget_info1(fid1, "elink/file2group3", &li, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Lget_info1(fid1, "elink/elink", &li, H5P_DEFAULT) < 0) TEST_ERROR + + + /* Close file1, the only file that should still be open */ + if(H5Fclose(fid1) < 0) TEST_ERROR + + /* Re-create each file. If they are hanging open, these creates will fail */ + if((fid1 = H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR + if((fid2 = H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR + if((fid3 = H5Fcreate(filename3, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR + if((fid4 = H5Fcreate(filename4, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR + + /* Cleanup */ + if(H5Sclose(sid) < 0) TEST_ERROR + if(H5Tclose(tid2) < 0) TEST_ERROR + if(H5Fclose(fid4) < 0) TEST_ERROR + if(H5Fclose(fid3) < 0) TEST_ERROR + if(H5Fclose(fid2) < 0) TEST_ERROR + if(H5Fclose(fid1) < 0) TEST_ERROR + + PASSED(); + + return SUCCEED; + +error: + H5E_BEGIN_TRY { + H5Gclose(gid); + H5Tclose(tid); + H5Dclose(did); + H5Sclose(sid); + H5Tclose(tid2); + H5Fclose(fid4); + H5Fclose(fid3); + H5Fclose(fid2); + H5Fclose(fid1); + } H5E_END_TRY; + return FAIL; +} /* external_link_closing_deprec() */ + +/* Callback functions for UD hard links. */ +/* UD_hard_create increments the object's reference count */ +static herr_t +UD_hard_create_deprec(const char H5_ATTR_UNUSED * link_name, hid_t loc_group, const void *udata, + size_t udata_size, hid_t H5_ATTR_UNUSED lcpl_id) +{ + haddr_t addr; + hid_t target_obj = -1; + herr_t ret_value = 0; + + if(udata_size != sizeof(haddr_t)) { + ret_value = -1; + goto done; + } /* end if */ + + addr = *((const haddr_t *)udata); + + /* Open the object this link points to */ + target_obj= H5Oopen_by_addr(loc_group, addr); + if(target_obj < 0) { + ret_value = -1; + goto done; + } /* end if */ + + /* Increment the reference count of the target object */ + if(H5Oincr_refcount(target_obj) < 0) { + ret_value = -1; + goto done; + } /* end if */ + +done: + /* Close the target object if we opened it */ + if(target_obj >= 0) { + switch(H5Iget_type(target_obj)) { + case H5I_GROUP: + if(H5Gclose(target_obj) < 0) + ret_value = -1; + break; + + case H5I_DATASET: + if(H5Dclose(target_obj) < 0) + ret_value = -1; + break; + + case H5I_DATATYPE: + if(H5Tclose(target_obj) < 0) + ret_value = -1; + break; + + case H5I_MAP: + /* TODO: Not supported in native file format yet */ + + case H5I_UNINIT: + case H5I_BADID: + case H5I_FILE: + case H5I_DATASPACE: + case H5I_ATTR: + case H5I_VFL: + case H5I_VOL: + case H5I_GENPROP_CLS: + case H5I_GENPROP_LST: + case H5I_ERROR_CLASS: + case H5I_ERROR_MSG: + case H5I_ERROR_STACK: + case H5I_SPACE_SEL_ITER: + case H5I_NTYPES: + default: + return FAIL; + } /* end switch */ + } /* end if */ + + return ret_value; +} /* end UD_hard_create() */ + +/* Traverse a hard link by opening the object */ +static hid_t +UD_hard_traverse_deprec(const char H5_ATTR_UNUSED *link_name, hid_t cur_group, + const void *udata, size_t udata_size, hid_t H5_ATTR_UNUSED lapl_id, + hid_t H5_ATTR_UNUSED dxpl_id) +{ + haddr_t addr; + hid_t ret_value = -1; + + if(udata_size != sizeof(haddr_t)) + return FAIL; + + addr = *((const haddr_t *) udata); + + ret_value = H5Oopen_by_addr(cur_group, addr); /* If this fails, our return value will be negative. */ + + return ret_value; +} /* end UD_hard_traverse() */ + +/* UD_hard_delete decrements the object's reference count */ +static herr_t +UD_hard_delete_deprec(const char H5_ATTR_UNUSED * link_name, hid_t file, const void *udata, + size_t udata_size) +{ + haddr_t addr; + hid_t target_obj = -1; + herr_t ret_value = 0; + + if(udata_size != sizeof(haddr_t)) { + ret_value = -1; + goto done; + } /* end if */ + + addr = *((const haddr_t *) udata); + + /* Open the object this link points to */ + target_obj= H5Oopen_by_addr(file, addr); + if(target_obj < 0) { + ret_value = -1; + goto done; + } /* end if */ + + /* Decrement the reference count of the target object */ + if(H5Odecr_refcount(target_obj) < 0) { + ret_value = -1; + goto done; + } /* end if */ + +done: + /* Close the target object if we opened it */ + if(target_obj >= 0) { + switch(H5Iget_type(target_obj)) { + case H5I_GROUP: + if(H5Gclose(target_obj) < 0) + ret_value = -1; + break; + + case H5I_DATASET: + if(H5Dclose(target_obj) < 0) + ret_value = -1; + break; + + case H5I_DATATYPE: + if(H5Tclose(target_obj) < 0) + ret_value = -1; + break; + + case H5I_MAP: + /* TODO: Not supported in native file format yet */ + + case H5I_UNINIT: + case H5I_BADID: + case H5I_FILE: + case H5I_DATASPACE: + case H5I_ATTR: + case H5I_VFL: + case H5I_VOL: + case H5I_GENPROP_CLS: + case H5I_GENPROP_LST: + case H5I_ERROR_CLASS: + case H5I_ERROR_MSG: + case H5I_ERROR_STACK: + case H5I_SPACE_SEL_ITER: + case H5I_NTYPES: + default: + return FAIL; + } /* end switch */ + } /* end if */ + + return ret_value; +} /* end UD_hard_delete() */ + +static int +ud_hard_links_deprec(hid_t fapl) +{ + hid_t fid = -1; /* File ID */ + hid_t gid = -1, gid2 = -1; /* Group IDs */ + H5L_info1_t li; /* Link information */ + char objname[NAME_BUF_SIZE]; /* Object name */ + h5_stat_size_t empty_size; /* Size of an empty file */ + char filename[NAME_BUF_SIZE]; + + TESTING("user-defined hard link using deprecated routines (w/new group format)") + + /* Set up filename and create file*/ + h5_fixname(FILENAME[0], fapl, filename, sizeof filename); + + if((fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR + + /* Get the size of the empty file for reference */ + if(H5Fclose(fid) < 0) TEST_ERROR + if((empty_size = h5_get_file_size(filename, fapl))<0) TEST_ERROR + + if((fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR + + /* Check that external links are registered and UD hard links are not */ + if(H5Lis_registered(H5L_TYPE_EXTERNAL) != TRUE) TEST_ERROR + if(H5Lis_registered((H5L_type_t)UD_HARD_TYPE) != FALSE) TEST_ERROR + + /* Register "user-defined hard links" with the library */ + if(H5Lregister(UD_hard_class_deprec) < 0) TEST_ERROR + + /* Check that UD hard links are now registered */ + if(H5Lis_registered(H5L_TYPE_EXTERNAL) != TRUE) TEST_ERROR + if(H5Lis_registered((H5L_type_t)UD_HARD_TYPE) != TRUE) TEST_ERROR + + /* Create a group for the UD hard link to point to */ + if((gid = H5Gcreate2(fid, "group", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR + + /* Get address for the group to give to the hard link */ + if(H5Lget_info1(fid, "group", &li, H5P_DEFAULT) < 0) TEST_ERROR + + if(H5Gclose(gid) < 0) TEST_ERROR + + /* Create a user-defined "hard link" to the group using the address we got + * from H5Lget_info1 */ + if(H5Lcreate_ud(fid, "ud_link", (H5L_type_t)UD_HARD_TYPE, &(li.u.address), (size_t)sizeof(haddr_t), H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR + + /* Close and re-open file to ensure that data is written to disk */ + if(H5Fclose(fid) < 0) TEST_ERROR + if((fid = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) TEST_ERROR + + /* Open group through UD link */ + if((gid = H5Gopen2(fid, "ud_link", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR + + /* Check name */ + if(H5Iget_name(gid, objname, (size_t)NAME_BUF_SIZE) < 0) TEST_ERROR + if(HDstrcmp(objname, "/group")) TEST_ERROR + + /* Create object in group */ + if((gid2 = H5Gcreate2(gid, "new_group", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR + + /* Close groups*/ + if(H5Gclose(gid2) < 0) TEST_ERROR + if(H5Gclose(gid) < 0) TEST_ERROR + + /* Re-open group without using ud link to check that it was created properly */ + if((gid = H5Gopen2(fid, "group/new_group", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR + + /* Check name */ + if(H5Iget_name(gid, objname, (size_t)NAME_BUF_SIZE) < 0) TEST_ERROR + if(HDstrcmp(objname, "/group/new_group")) TEST_ERROR + + /* Close opened object */ + if(H5Gclose(gid) < 0) FAIL_STACK_ERROR + + /* Check that H5Lget_objinfo works on the hard link */ + if(H5Lget_info1(fid, "ud_link", &li, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + /* UD hard links have no query function, thus return a "link length" of 0 */ + if(li.u.val_size != 0) TEST_ERROR + if(UD_HARD_TYPE != li.type) { + H5_FAILED(); + HDputs(" Unexpected link class - should have been a UD hard link"); + goto error; + } /* end if */ + + /* Unlink the group pointed to by the UD link. It shouldn't be + * deleted because of the UD link. */ + if(H5Ldelete(fid, "/group", H5P_DEFAULT) < 0) FAIL_STACK_ERROR + + /* Ensure we can open the group through the UD link */ + if((gid = H5Gopen2(fid, "ud_link", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR + + /* Unlink the group contained within it. */ + if(H5Ldelete(gid, "new_group", H5P_DEFAULT) < 0) FAIL_STACK_ERROR + if(H5Gclose(gid) < 0) FAIL_STACK_ERROR + + /* Now delete the UD link. This should cause the group to be + * deleted, too. */ + if(H5Ldelete(fid, "ud_link", H5P_DEFAULT) < 0) FAIL_STACK_ERROR + + /* Close file */ + if(H5Fclose(fid) < 0) FAIL_STACK_ERROR + + /* The file should be empty again. */ + if(empty_size != h5_get_file_size(filename, fapl)) TEST_ERROR + + if(H5Lunregister((H5L_type_t)UD_HARD_TYPE) < 0) FAIL_STACK_ERROR + + PASSED(); + return SUCCEED; + +error: + H5E_BEGIN_TRY { + H5Gclose(gid2); + H5Gclose(gid); + H5Fclose(fid); + } H5E_END_TRY; + return FAIL; +} /* end ud_hard_links_deprec() */ + +static int +ud_link_reregister_deprec(hid_t fapl) +{ + hid_t fid = -1; /* File ID */ + hid_t gid = -1, gid2 = -1; /* Group IDs */ + H5L_info1_t li; /* Link information */ + char objname[NAME_BUF_SIZE]; /* Object name */ + char filename[NAME_BUF_SIZE]; + h5_stat_size_t empty_size; /* Size of an empty file */ + + TESTING("registering a new class for existing UD links using deprecated routines (w/new group format)") + + /* Set up filename and create file*/ + h5_fixname(FILENAME[0], fapl, filename, sizeof filename); + + if((fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR + + /* Get the size of the empty file for reference */ + if(H5Fclose(fid) < 0) TEST_ERROR + if((empty_size = h5_get_file_size(filename, fapl))<0) TEST_ERROR + + if((fid=H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR + + /* Check that UD hard links are not registered */ + if(H5Lis_registered((H5L_type_t)UD_HARD_TYPE) != FALSE) TEST_ERROR + + /* Register "user-defined hard links" with the library */ + if(H5Lregister(UD_hard_class_deprec) < 0) TEST_ERROR + + /* Check that UD hard links are registered */ + if(H5Lis_registered((H5L_type_t)UD_HARD_TYPE) != TRUE) TEST_ERROR + + /* Point a UD defined hard link to a group in the same way as the previous test */ + if((gid = H5Gcreate2(fid, "group", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR + if(H5Lget_info1(fid, "group", &li, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Gclose(gid) < 0) TEST_ERROR + + if(H5Lcreate_ud(fid, "ud_link", (H5L_type_t)UD_HARD_TYPE, &(li.u.address), + sizeof(li.u.address), H5P_DEFAULT, H5P_DEFAULT) < 0) + TEST_ERROR + + /* Create a group named REREG_TARGET_NAME in the same group as the ud link */ + if((gid = H5Gcreate2(fid, REREG_TARGET_NAME, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR + if(H5Gclose(gid) < 0) TEST_ERROR + + /* Now unregister UD hard links */ + if(H5Lunregister((H5L_type_t)UD_HARD_TYPE) < 0) TEST_ERROR + + /* Check that UD hard links are no longer registered */ + if(H5Lis_registered((H5L_type_t)UD_HARD_TYPE) != FALSE) TEST_ERROR + + /* Verify that we can't traverse the ud link anymore */ + H5E_BEGIN_TRY { + if((gid = H5Gopen2(fid, "ud_link", H5P_DEFAULT)) >= 0) TEST_ERROR + } H5E_END_TRY + + /* Verify that we can't create any new links of this type */ + H5E_BEGIN_TRY { + if(H5Lcreate_ud(fid, "ud_link2", (H5L_type_t)UD_HARD_TYPE, &(li.u.address), + sizeof(li.u.address), H5P_DEFAULT, H5P_DEFAULT) >= 0) + TEST_ERROR + } H5E_END_TRY + + /* Register a new kind of link with the same ID number */ + if(H5Lregister(UD_rereg_class) < 0) TEST_ERROR + + /* Check that UD hard links are registered again */ + if(H5Lis_registered((H5L_type_t)UD_HARD_TYPE) != TRUE) TEST_ERROR + + /* Open a group through the ud link (now a different class of link). + * It should be a different group + * than the UD hard link pointed to */ + if((gid = H5Gopen2(fid, "ud_link", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR + + /* Check name */ + if(H5Iget_name(gid, objname, (size_t)NAME_BUF_SIZE) < 0) TEST_ERROR + if(HDstrcmp(objname, "/" REREG_TARGET_NAME)) TEST_ERROR + + /* Create object in group */ + if((gid2 = H5Gcreate2(gid, "new_group", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR + + /* Close groups*/ + if(H5Gclose(gid2) < 0) TEST_ERROR + if(H5Gclose(gid) < 0) TEST_ERROR + + /* Re-open group without using ud link to check that it was created properly */ + if((gid = H5Gopen2(fid, "rereg_target/new_group", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR + + /* Check name */ + if(H5Iget_name(gid, objname, (size_t)NAME_BUF_SIZE) < 0) TEST_ERROR + if(HDstrcmp(objname, "/rereg_target/new_group")) TEST_ERROR + + /* Close opened object */ + if(H5Gclose(gid) < 0) FAIL_STACK_ERROR + + /* Unlink the group pointed to by the UD hard link. It shouldn't be + * deleted because the UD link incremented its reference count. */ + if(H5Ldelete(fid, "/group", H5P_DEFAULT) < 0) FAIL_STACK_ERROR + + /* What a mess! Re-register user-defined links to clean up the + * reference counts. We shouldn't actually need to unregister the + * other link type */ + if(H5Lregister(UD_hard_class_deprec) < 0) FAIL_STACK_ERROR + if(H5Lis_registered((H5L_type_t)UD_HARD_TYPE) != TRUE) FAIL_STACK_ERROR + + /* Ensure we can open the group through the UD link (now that UD hard + * links have been registered) */ + if((gid = H5Gopen2(fid, "ud_link", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR + if(H5Gclose(gid) < 0) FAIL_STACK_ERROR + + /* Delete the UD hard link. This should cause the group to be + * deleted, too. */ + if(H5Ldelete(fid, "ud_link", H5P_DEFAULT) < 0) FAIL_STACK_ERROR + + /* Unlink the other two groups so that we can make sure the file is empty */ + if(H5Ldelete(fid, "/rereg_target/new_group", H5P_DEFAULT) < 0) FAIL_STACK_ERROR + if(H5Ldelete(fid, REREG_TARGET_NAME, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + + /* Close file */ + if(H5Fclose(fid) < 0) FAIL_STACK_ERROR + + /* The file should be empty again. */ + if(empty_size != h5_get_file_size(filename, fapl)) TEST_ERROR + + if(H5Lunregister((H5L_type_t)UD_HARD_TYPE) < 0) FAIL_STACK_ERROR + if(H5Lis_registered((H5L_type_t)UD_HARD_TYPE) != FALSE) FAIL_STACK_ERROR + + PASSED(); + return SUCCEED; + +error: + H5E_BEGIN_TRY { + H5Gclose(gid2); + H5Gclose(gid); + H5Fclose(fid); + } H5E_END_TRY; + return FAIL; +} /* end ud_link_reregister_deprec() */ + +static int +ud_callbacks_deprec(hid_t fapl, hbool_t new_format) +{ + hid_t fid = -1; /* File ID */ + hid_t gid = -1; /* Group ID */ + hid_t lcpl = -1; /* Link Creation PL */ + H5L_info1_t li; /* Link information */ + char ud_target_name[] = UD_CB_TARGET; /* Link target name */ + char filename[NAME_BUF_SIZE]; + char query_buf[NAME_BUF_SIZE]; + + if(new_format) + TESTING("user-defined link callbacks using deprecated routines (w/new group format)") + else + TESTING("user-defined link callbacks using deprecated routines") + + /* Set up filename and create file*/ + h5_fixname(FILENAME[0], fapl, filename, sizeof filename); + + if((fid=H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR + + /* Check that registered link classes are, and unregistered ones aren't */ + if(H5Lis_registered(H5L_TYPE_EXTERNAL) != TRUE) TEST_ERROR + if(H5Lis_registered((H5L_type_t)UD_HARD_TYPE) != FALSE) TEST_ERROR + if(H5Lis_registered((H5L_type_t)UD_CB_TYPE) != FALSE) TEST_ERROR + + /* Hit two birds with one stone: register UD hard links from previous + * test to check that having two UD links registered at once presents + * no problems. */ + if(H5Lregister(UD_hard_class_deprec) < 0) TEST_ERROR + + /* Register user-defined link class. This is the one we'll actually be using. */ + if(H5Lregister(UD_cb_class) < 0) TEST_ERROR + + /* Check that registered link classes are, and unregistered ones aren't */ + if(H5Lis_registered(H5L_TYPE_EXTERNAL) != TRUE) TEST_ERROR + if(H5Lis_registered((H5L_type_t)UD_HARD_TYPE) != TRUE) TEST_ERROR + if(H5Lis_registered((H5L_type_t)UD_CB_TYPE) != TRUE) TEST_ERROR + + /* Create a group for the UD link to point to */ + if((gid = H5Gcreate2(fid, UD_CB_TARGET, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR + + /* Create a user-defined link to the group. These UD links behave like soft links. */ + if(H5Lcreate_ud(fid, UD_CB_LINK_NAME, (H5L_type_t)UD_CB_TYPE, ud_target_name, (size_t)UD_CB_TARGET_LEN, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Gclose(gid) < 0) TEST_ERROR + + /* Try opening group through UD link */ + if((gid = H5Gopen2(fid, UD_CB_LINK_NAME, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR + if(H5Gclose(gid) < 0) TEST_ERROR + + /* Query the link to test its query callback */ + if(H5Lget_info1(fid, UD_CB_LINK_NAME, &li, H5P_DEFAULT) < 0) TEST_ERROR + if(li.u.val_size != 16) TEST_ERROR + if (UD_CB_TYPE != li.type) { + H5_FAILED(); + HDputs(" Unexpected link class - should have been a UD hard link"); + goto error; + } + + /* Fill the query buffer */ + if(H5Lget_val(fid, UD_CB_LINK_NAME, query_buf, (size_t)NAME_BUF_SIZE, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + if(HDstrcmp(query_buf, "query succeeded") != 0) TEST_ERROR + + /* Move the link */ + if(H5Lmove(fid, UD_CB_LINK_NAME, H5L_SAME_LOC, NEW_UD_CB_LINK_NAME, H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + + /* Re-open group to ensure that move worked */ + if((gid = H5Gopen2(fid, NEW_UD_CB_LINK_NAME, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR + if(H5Gclose(gid) < 0) FAIL_STACK_ERROR + + /* Remove UD link */ + if(H5Ldelete(fid, NEW_UD_CB_LINK_NAME, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + + /* Test that the callbacks don't work if the link class is not registered */ + + /* Create a new link. Just for fun, give it a non-default character + * encoding (to test that LAPLs work) */ + if((lcpl = H5Pcreate(H5P_LINK_CREATE)) < 0) FAIL_STACK_ERROR + if(H5Pset_char_encoding(lcpl, H5T_CSET_UTF8) < 0) FAIL_STACK_ERROR + if(H5Lcreate_ud(fid, UD_CB_LINK_NAME, (H5L_type_t)UD_CB_TYPE, ud_target_name, (size_t)UD_CB_TARGET_LEN, lcpl, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + if(H5Pclose(lcpl) < 0) FAIL_STACK_ERROR + + /* Check its character encoding */ + if(H5Lget_info1(fid, UD_CB_LINK_NAME, &li, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + if(li.cset != H5T_CSET_UTF8) TEST_ERROR + + /* Unregister the link class so the library forgets what its callbacks do */ + if(H5Lunregister((H5L_type_t)UD_CB_TYPE) < 0) FAIL_STACK_ERROR + + /* Now test that each of the callbacks fails */ + H5E_BEGIN_TRY { + if(H5Lcreate_ud(fid, NEW_UD_CB_LINK_NAME, (H5L_type_t)UD_CB_TYPE, ud_target_name, (size_t)UD_CB_TARGET_LEN, H5P_DEFAULT, H5P_DEFAULT) >= 0) FAIL_STACK_ERROR + if(H5Lmove(fid, UD_CB_LINK_NAME, H5L_SAME_LOC, NEW_UD_CB_LINK_NAME, H5P_DEFAULT, H5P_DEFAULT) >= 0) FAIL_STACK_ERROR + if(H5Ldelete(fid, UD_CB_LINK_NAME, H5P_DEFAULT) >= 0) FAIL_STACK_ERROR + if((gid = H5Gopen2(gid, UD_CB_LINK_NAME, H5P_DEFAULT)) >= 0) FAIL_STACK_ERROR + if(H5Ldelete(fid, UD_CB_LINK_NAME, H5P_DEFAULT) >= 0) FAIL_STACK_ERROR + } H5E_END_TRY + + /* The query callback should NOT fail, but should be unable to give a linklen */ + if(H5Lget_info1(fid, UD_CB_LINK_NAME, &li, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + if(li.u.val_size != 0) TEST_ERROR + if(li.type != UD_CB_TYPE) TEST_ERROR + + /* Unregister the UD hard links */ + if(H5Lunregister((H5L_type_t)UD_HARD_TYPE) < 0) FAIL_STACK_ERROR + + /* Close file */ + if(H5Fclose(fid) < 0) FAIL_STACK_ERROR + + PASSED(); + return SUCCEED; + +error: + H5E_BEGIN_TRY { + H5Pclose (lcpl); + H5Gclose (gid); + H5Fclose (fid); + } H5E_END_TRY; + return FAIL; +} /* end ud_callbacks_deprec() */ + +/*------------------------------------------------------------------------- + * Function: lapl_nlinks_deprec + * + * Purpose: Check that the maximum number of soft links can be adjusted + * by the user using the Link Access Property List. + * + * Return: Success: 0 + * Failure: -1 + *------------------------------------------------------------------------- + */ +static int +lapl_nlinks_deprec(hid_t fapl, hbool_t new_format) +{ + hid_t fid = -1; /* File ID */ + hid_t gid = -1, gid2 = -1; /* Group IDs */ + hid_t plist = -1; /* lapl ID */ + hid_t tid = -1, sid = -1, did = -1; /* Other IDs */ + hid_t gapl = -1, dapl = -1, tapl = -1; /* Other property lists */ + char objname[NAME_BUF_SIZE]; /* Object name */ + char filename[NAME_BUF_SIZE]; + size_t nlinks; /* nlinks for H5Pset_nlinks */ + hsize_t dims[2]; + + if(new_format) + TESTING("adjusting nlinks with LAPL using deprecated routines (w/new group format)") + else + TESTING("adjusting nlinks with LAPL using deprecated routines") + + /* Make certain test is valid */ + /* XXX: should probably make a "generic" test that creates the proper + * # of links based on this value - QAK + */ + HDassert(H5L_NUM_LINKS == 16); + + /* Create file */ + h5_fixname(FILENAME[1], fapl, filename, sizeof filename); + if((fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR + + /* Create group with short name in file (used as target for links) */ + if((gid = H5Gcreate2(fid, "final", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR + + /* Create chain of soft links to existing object (limited) */ + if(H5Lcreate_soft("final", fid, "soft1", H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + if(H5Lcreate_soft("soft1", fid, "soft2", H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + if(H5Lcreate_soft("soft2", fid, "soft3", H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + if(H5Lcreate_soft("soft3", fid, "soft4", H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + if(H5Lcreate_soft("soft4", fid, "soft5", H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + if(H5Lcreate_soft("soft5", fid, "soft6", H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + if(H5Lcreate_soft("soft6", fid, "soft7", H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + if(H5Lcreate_soft("soft7", fid, "soft8", H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + if(H5Lcreate_soft("soft8", fid, "soft9", H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + if(H5Lcreate_soft("soft9", fid, "soft10", H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + if(H5Lcreate_soft("soft10", fid, "soft11", H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + if(H5Lcreate_soft("soft11", fid, "soft12", H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + if(H5Lcreate_soft("soft12", fid, "soft13", H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + if(H5Lcreate_soft("soft13", fid, "soft14", H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + if(H5Lcreate_soft("soft14", fid, "soft15", H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + if(H5Lcreate_soft("soft15", fid, "soft16", H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + if(H5Lcreate_soft("soft16", fid, "soft17", H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + + /* Close objects */ + if(H5Gclose(gid) < 0) TEST_ERROR + if(H5Fclose(fid) < 0) TEST_ERROR + + /* Open file */ + if((fid = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) TEST_ERROR + + /* Create LAPL with higher-than-usual nlinks value */ + /* Create a non-default lapl with udata set to point to the first group */ + if((plist = H5Pcreate(H5P_LINK_ACCESS)) < 0) TEST_ERROR + nlinks = 20; + if(H5Pset_nlinks(plist, nlinks) < 0) TEST_ERROR + + /* Ensure that nlinks was set successfully */ + nlinks = 0; + if(H5Pget_nlinks(plist, &nlinks) < 0) TEST_ERROR + if(nlinks != 20) TEST_ERROR + + /* Open object through what is normally too many soft links using + * new property list */ + if((gid = H5Oopen(fid, "soft17", plist)) < 0) TEST_ERROR + + /* Check name */ + if(H5Iget_name(gid, objname, (size_t)NAME_BUF_SIZE) < 0) TEST_ERROR + if(HDstrcmp(objname, "/soft17")) TEST_ERROR + + /* Create group using soft link */ + if((gid2 = H5Gcreate2(gid, "new_soft", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR + + /* Close groups */ + if(H5Gclose(gid2) < 0) TEST_ERROR + if(H5Gclose(gid) < 0) TEST_ERROR + + /* Set nlinks to a smaller number */ + nlinks = 4; + if(H5Pset_nlinks(plist, nlinks) < 0) TEST_ERROR + + /* Ensure that nlinks was set successfully */ + nlinks = 0; + if(H5Pget_nlinks(plist, &nlinks) < 0) TEST_ERROR + if(nlinks != 4) TEST_ERROR + + /* Try opening through what is now too many soft links */ + H5E_BEGIN_TRY { + gid = H5Oopen(fid, "soft5", plist); + } H5E_END_TRY; + if (gid >= 0) { + H5_FAILED(); + HDputs(" Should have failed for sequence of too many nested links."); + goto error; + } + + /* Open object through lesser soft link */ + if((gid = H5Oopen(fid, "soft4", plist)) < 0) TEST_ERROR + + /* Check name */ + if(H5Iget_name(gid, objname, (size_t)NAME_BUF_SIZE) < 0) TEST_ERROR + if(HDstrcmp(objname, "/soft4")) TEST_ERROR + + /* Test other functions that should use a LAPL */ + nlinks = 20; + if(H5Pset_nlinks(plist, nlinks) < 0) TEST_ERROR + + /* Try copying and moving when both src and dst contain many soft links + * using a non-default LAPL + */ + if(H5Lcopy(fid, "soft17", fid, "soft17/newer_soft", H5P_DEFAULT, plist) < 0) TEST_ERROR + if(H5Lmove(fid, "soft17/newer_soft", fid, "soft17/newest_soft", H5P_DEFAULT, plist) < 0) TEST_ERROR + + /* H5Olink */ + if(H5Olink(gid, fid, "soft17/link_to_group", H5P_DEFAULT, plist) < 0) TEST_ERROR + + /* H5Lcreate_hard and H5Lcreate_soft */ + if(H5Lcreate_hard(fid, "soft17", fid, "soft17/link2_to_group", H5P_DEFAULT, plist) < 0) TEST_ERROR + if(H5Lcreate_soft("/soft4", fid, "soft17/soft_link", H5P_DEFAULT, plist) < 0) TEST_ERROR + + /* H5Ldelete */ + if(H5Ldelete(fid, "soft17/soft_link", plist) < 0) TEST_ERROR + + /* H5Lget_val and H5Lget_info1 */ + if(H5Lget_val(fid, "soft17", NULL, (size_t)0, plist) < 0) TEST_ERROR + if(H5Lget_info1(fid, "soft17", NULL, plist) < 0) TEST_ERROR + + /* H5Lcreate_external and H5Lcreate_ud */ + if(H5Lcreate_external("filename", "path", fid, "soft17/extlink", H5P_DEFAULT, plist) < 0) TEST_ERROR + if(H5Lregister(UD_rereg_class) < 0) TEST_ERROR + if(H5Lcreate_ud(fid, "soft17/udlink", (H5L_type_t)UD_HARD_TYPE, NULL, (size_t)0, H5P_DEFAULT, plist) < 0) TEST_ERROR + + /* Close plist */ + if(H5Pclose(plist) < 0) TEST_ERROR + + /* Create a datatype and dataset as targets inside the group */ + if((tid = H5Tcopy(H5T_NATIVE_INT)) < 0) TEST_ERROR + if(H5Tcommit2(gid, "datatype", tid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Tclose(tid) < 0) TEST_ERROR + + dims[0] = 2; + dims[1] = 2; + if((sid = H5Screate_simple(2, dims, NULL)) < 0) TEST_ERROR + if((did = H5Dcreate2(gid, "dataset", H5T_NATIVE_INT, sid, H5P_DEFAULT, dcpl_g, H5P_DEFAULT)) < 0) TEST_ERROR + if(H5Dclose(did) < 0) TEST_ERROR + + /* Close group */ + if(H5Gclose(gid) < 0) TEST_ERROR + + /* Try to open the objects using too many symlinks with default *APLs */ + H5E_BEGIN_TRY { + if((gid = H5Gopen2(fid, "soft17", H5P_DEFAULT)) >= 0) + FAIL_PUTS_ERROR(" Should have failed for too many nested links.") + if((tid = H5Topen2(fid, "soft17/datatype", H5P_DEFAULT)) >= 0) + FAIL_PUTS_ERROR(" Should have failed for too many nested links.") + if((did = H5Dopen2(fid, "soft17/dataset", H5P_DEFAULT)) >= 0) + FAIL_PUTS_ERROR(" Should have failed for too many nested links.") + } H5E_END_TRY + + /* Create property lists with nlinks set */ + if((gapl = H5Pcreate(H5P_GROUP_ACCESS)) < 0) TEST_ERROR + if((tapl = H5Pcreate(H5P_DATATYPE_ACCESS)) < 0) TEST_ERROR + if((dapl = H5Pcreate(H5P_DATASET_ACCESS)) < 0) TEST_ERROR + + nlinks = 20; + if(H5Pset_nlinks(gapl, nlinks) < 0) TEST_ERROR + if(H5Pset_nlinks(tapl, nlinks) < 0) TEST_ERROR + if(H5Pset_nlinks(dapl, nlinks) < 0) TEST_ERROR + + /* We should now be able to use these property lists to open each kind + * of object. + */ + if((gid = H5Gopen2(fid, "soft17", gapl)) < 0) FAIL_STACK_ERROR + if((tid = H5Topen2(fid, "soft17/datatype", tapl)) < 0) TEST_ERROR + if((did = H5Dopen2(fid, "soft17/dataset", dapl)) < 0) TEST_ERROR + + /* Close objects */ + if(H5Gclose(gid) < 0) TEST_ERROR + if(H5Tclose(tid) < 0) TEST_ERROR + if(H5Dclose(did) < 0) TEST_ERROR + + /* Close plists */ + if(H5Pclose(gapl) < 0) TEST_ERROR + if(H5Pclose(tapl) < 0) TEST_ERROR + if(H5Pclose(dapl) < 0) TEST_ERROR + + /* Unregister UD hard link class */ + if(H5Lunregister((H5L_type_t)UD_HARD_TYPE) < 0) TEST_ERROR + + /* Close file */ + if(H5Fclose(fid) < 0) TEST_ERROR + + PASSED(); + return SUCCEED; + +error: + H5E_BEGIN_TRY { + H5Pclose(gapl); + H5Pclose(dapl); + H5Pclose(tapl); + H5Dclose(did); + H5Sclose(sid); + H5Tclose(tid); + H5Gclose(gid2); + H5Gclose(gid); + H5Pclose(plist); + H5Fclose(fid); + } H5E_END_TRY; + return FAIL; +} /* end lapl_nlinks_deprec() */ + +/*------------------------------------------------------------------------- + * Function: linkinfo_deprec + * + * Purpose: Check that the link class is returned correctly when queried. + * + * Return: Success: 0 + * Failure: -1 + *------------------------------------------------------------------------- + */ +static int +linkinfo_deprec(hid_t fapl, hbool_t new_format) +{ + hid_t fid = -1; /* File ID */ + hid_t gid = -1; /* Group ID */ + hid_t tid = -1; /* Type ID */ + hid_t sid = -1, did = -1; /* Dataspace and dataset IDs */ + H5L_info1_t li; /* Link information */ + char filename[NAME_BUF_SIZE]; + + if(new_format) + TESTING("link type field in H5Lget_info using deprecated routines (w/new group format)") + else + TESTING("link type field in H5Lget_info using deprecated routines") + + /* Set up filename and create file*/ + h5_fixname(FILENAME[0], fapl, filename, sizeof filename); + + if((fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR + + /* Register a couple of user-defined link classes with the library */ + if(H5Lregister(UD_plist_class) < 0) TEST_ERROR + + /* Create an object of each type */ + if((tid = H5Tcopy(H5T_NATIVE_INT)) < 0) TEST_ERROR + if(H5Tcommit2(fid, "datatype", tid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR + if((gid = H5Gcreate2(fid, "group", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR + if(H5Lcreate_soft("group", fid, "softlink", H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + + if((sid = H5Screate(H5S_SCALAR)) < 0) TEST_ERROR + if((did = H5Dcreate2(fid, "dataset", H5T_NATIVE_INT, sid, H5P_DEFAULT, dcpl_g, H5P_DEFAULT)) < 0) TEST_ERROR + + if(H5Lcreate_ud(fid, "ud_link", (H5L_type_t)UD_PLIST_TYPE, NULL, (size_t)0, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Lcreate_external("file_name", "obj_path", fid, "ext_link", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR + + /* Close all objects */ + if(H5Tclose(tid) < 0) TEST_ERROR + if(H5Gclose(gid) < 0) TEST_ERROR + if(H5Dclose(did) < 0) TEST_ERROR + + /* Make sure that link type is correct when objects are queried */ + if(H5Lget_info1(fid, "datatype", &li, H5P_DEFAULT) < 0) TEST_ERROR + if(li.type != H5L_TYPE_HARD) TEST_ERROR + if(H5Lget_info1(fid, "group", &li, H5P_DEFAULT) < 0) TEST_ERROR + if(li.type != H5L_TYPE_HARD) TEST_ERROR + if(H5Lget_info1(fid, "dataset", &li, H5P_DEFAULT) < 0) TEST_ERROR + if(li.type != H5L_TYPE_HARD) TEST_ERROR + + if(H5Lget_info1(fid, "ext_link", &li, H5P_DEFAULT) < 0) TEST_ERROR + if(li.type != H5L_TYPE_EXTERNAL) TEST_ERROR + if(H5Lget_info1(fid, "softlink", &li, H5P_DEFAULT) < 0) TEST_ERROR + if(li.type != H5L_TYPE_SOFT) TEST_ERROR + if(H5Lget_info1(fid, "ud_link", &li, H5P_DEFAULT) < 0) TEST_ERROR + if(li.type != UD_PLIST_TYPE) TEST_ERROR + + /* Ensure that passing a NULL pointer doesn't cause an error */ + if(H5Lget_info1(fid, "group", NULL, H5P_DEFAULT) < 0) TEST_ERROR + + if(H5Fclose(fid) < 0) TEST_ERROR + + PASSED(); + return SUCCEED; + +error: + H5E_BEGIN_TRY { + H5Tclose (tid); + H5Dclose (did); + H5Gclose (gid); + H5Fclose (fid); + } H5E_END_TRY; + return FAIL; +} /* end linkinfo_deprec() */ + +/*------------------------------------------------------------------------- + * Function: corder_create_compact_deprec + * + * Purpose: Create a group with creation order indices and insert links + * in it when in compact form + * + * Return: Success: 0 + * Failure: -1 + *------------------------------------------------------------------------- + */ +static int +corder_create_compact_deprec(hid_t fapl) +{ + hid_t file_id = -1; /* File ID */ + hid_t group_id = -1, group_id2 = -1; /* Group IDs */ + hid_t gcpl_id = -1; /* Group creation property list ID */ + unsigned max_compact; /* Maximum # of links to store in group compactly */ + unsigned min_dense; /* Minimum # of links to store in group "densely" */ + unsigned nlinks; /* Number of link messages in group's header */ + char objname[NAME_BUF_SIZE]; /* Object name */ + char filename[NAME_BUF_SIZE];/* File name */ + unsigned u; /* Local index variable */ + + TESTING("creating compact group with creation order indexing using deprecated routines") + + /* Create file */ + h5_fixname(FILENAME[0], fapl, filename, sizeof filename); + if((file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR + + /* Create group creation property list */ + if((gcpl_id = H5Pcreate(H5P_GROUP_CREATE)) < 0) TEST_ERROR + + /* Set creation order tracking & indexing on group */ + if(H5Pset_link_creation_order(gcpl_id, (H5P_CRT_ORDER_TRACKED | H5P_CRT_ORDER_INDEXED)) < 0) TEST_ERROR + + /* Create group with creation order indexing & tracking on */ + if((group_id = H5Gcreate2(file_id, CORDER_GROUP_NAME, H5P_DEFAULT, gcpl_id, H5P_DEFAULT)) < 0) TEST_ERROR + + /* Check on group's initial status */ + if(H5G__is_empty_test(group_id) != TRUE) TEST_ERROR + if(H5G__has_stab_test(group_id) == TRUE) TEST_ERROR + if(H5G__is_new_dense_test(group_id) == TRUE) TEST_ERROR + + /* Query the group creation properties */ + if(H5Pget_link_phase_change(gcpl_id, &max_compact, &min_dense) < 0) TEST_ERROR + + /* Create several links, but keep group in compact form */ + for(u = 0; u < max_compact; u++) { + HDsnprintf(objname, sizeof(objname), "filler %u", u); + if((group_id2 = H5Gcreate2(group_id, objname, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR + if(H5Gclose(group_id2) < 0) TEST_ERROR + + /* Verify state of group */ + if(H5G__has_links_test(group_id, &nlinks) != TRUE) TEST_ERROR + if(nlinks != (u + 1)) TEST_ERROR + if(H5G__has_stab_test(group_id) == TRUE) TEST_ERROR + if(H5G__is_new_dense_test(group_id) == TRUE) TEST_ERROR + } /* end for */ + + /* Close the group */ + if(H5Gclose(group_id) < 0) TEST_ERROR + + /* Close the group creation property list */ + if(H5Pclose(gcpl_id) < 0) TEST_ERROR + + /* Close the file */ + if(H5Fclose(file_id) < 0) TEST_ERROR + + /* Re-open the file */ + if((file_id = H5Fopen(filename, H5F_ACC_RDONLY, fapl)) < 0) TEST_ERROR + + /* Open group created */ + if((group_id = H5Gopen2(file_id, CORDER_GROUP_NAME, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR + + /* Verify state of group */ + if(H5G__has_links_test(group_id, &nlinks) != TRUE) TEST_ERROR + if(nlinks != max_compact) TEST_ERROR + if(H5G__has_stab_test(group_id) == TRUE) TEST_ERROR + if(H5G__is_new_dense_test(group_id) == TRUE) TEST_ERROR + + /* Loop through links, checking their creation order values */ + /* (the name index is used, but the creation order value is in the same order) */ + for(u = 0; u < max_compact; u++) { + H5L_info1_t linfo; /* Link information */ + + /* Retrieve information for link */ + HDsnprintf(objname, sizeof(objname), "filler %u", u); + if(H5Lget_info1(group_id, objname, &linfo, H5P_DEFAULT) < 0) TEST_ERROR + + /* Verify creation order of link */ + if(linfo.corder_valid != TRUE) TEST_ERROR + if(linfo.corder != u) TEST_ERROR + } /* end for */ + + /* Close the group */ + if(H5Gclose(group_id) < 0) TEST_ERROR + + /* Close the file */ + if(H5Fclose(file_id) < 0) TEST_ERROR + + PASSED(); + return SUCCEED; + +error: + H5E_BEGIN_TRY { + H5Pclose(gcpl_id); + H5Gclose(group_id); + H5Fclose(file_id); + } H5E_END_TRY; + return FAIL; +} /* end corder_create_compact_deprec() */ + +/*------------------------------------------------------------------------- + * Function: corder_create_dense_deprec + * + * Purpose: Create a group with creation order indices and insert links + * in it until it's in dense form + * + * Return: Success: 0 + * Failure: -1 + *------------------------------------------------------------------------- + */ +static int +corder_create_dense_deprec(hid_t fapl) +{ + hid_t file_id = -1; /* File ID */ + hid_t group_id = -1, group_id2 = -1; /* Group IDs */ + hid_t gcpl_id = -1; /* Group creation property list ID */ + unsigned max_compact; /* Maximum # of links to store in group compactly */ + unsigned min_dense; /* Minimum # of links to store in group "densely" */ + unsigned nlinks; /* Number of link messages in group's header */ + hsize_t name_count; /* # of records in name index */ + hsize_t corder_count; /* # of records in creation order index */ + char objname[NAME_BUF_SIZE]; /* Object name */ + char filename[NAME_BUF_SIZE];/* File name */ + unsigned u; /* Local index variable */ + + TESTING("creating dense group with creation order indexing using deprecated routines") + + /* Create file */ + h5_fixname(FILENAME[0], fapl, filename, sizeof filename); + if((file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR + + /* Create group creation property list */ + if((gcpl_id = H5Pcreate(H5P_GROUP_CREATE)) < 0) TEST_ERROR + + /* Set creation order tracking & indexing on group */ + if(H5Pset_link_creation_order(gcpl_id, (H5P_CRT_ORDER_TRACKED | H5P_CRT_ORDER_INDEXED)) < 0) TEST_ERROR + + /* Create group with creation order indexing & tracking on */ + if((group_id = H5Gcreate2(file_id, CORDER_GROUP_NAME, H5P_DEFAULT, gcpl_id, H5P_DEFAULT)) < 0) TEST_ERROR + + /* Check on group's initial status */ + if(H5G__is_empty_test(group_id) != TRUE) TEST_ERROR + if(H5G__has_stab_test(group_id) == TRUE) TEST_ERROR + if(H5G__is_new_dense_test(group_id) == TRUE) TEST_ERROR + + /* Query the group creation properties */ + if(H5Pget_link_phase_change(gcpl_id, &max_compact, &min_dense) < 0) TEST_ERROR + + /* Create several links, up to limit of compact form */ + for(u = 0; u < max_compact; u++) { + HDsnprintf(objname, sizeof(objname), "filler %u", u); + if((group_id2 = H5Gcreate2(group_id, objname, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR + if(H5Gclose(group_id2) < 0) TEST_ERROR + + /* Verify state of group */ + if(H5G__has_links_test(group_id, &nlinks) != TRUE) TEST_ERROR + if(nlinks != (u + 1)) TEST_ERROR + if(H5G__has_stab_test(group_id) == TRUE) TEST_ERROR + if(H5G__is_new_dense_test(group_id) == TRUE) TEST_ERROR + } /* end for */ + + /* Create another link, to push group into dense form */ + HDsnprintf(objname, sizeof(objname), "filler %u", max_compact); + if((group_id2 = H5Gcreate2(group_id, objname, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR + if(H5Gclose(group_id2) < 0) TEST_ERROR + + /* Verify state of group */ + if(H5G__has_links_test(group_id, NULL) == TRUE) TEST_ERROR + if(H5G__has_stab_test(group_id) == TRUE) TEST_ERROR + if(H5G__is_new_dense_test(group_id) != TRUE) TEST_ERROR + + /* Retrieve & verify # of records in the name & creation order indices */ + if(H5G__new_dense_info_test(group_id, &name_count, &corder_count) < 0) TEST_ERROR + if(name_count != corder_count) TEST_ERROR + + /* Close the group */ + if(H5Gclose(group_id) < 0) TEST_ERROR + + /* Close the group creation property list */ + if(H5Pclose(gcpl_id) < 0) TEST_ERROR + + /* Close the file */ + if(H5Fclose(file_id) < 0) TEST_ERROR + + /* Re-open the file */ + if((file_id = H5Fopen(filename, H5F_ACC_RDONLY, fapl)) < 0) TEST_ERROR + + /* Open group created */ + if((group_id = H5Gopen2(file_id, CORDER_GROUP_NAME, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR + + /* Verify state of group */ + if(H5G__has_links_test(group_id, NULL) == TRUE) TEST_ERROR + if(H5G__has_stab_test(group_id) == TRUE) TEST_ERROR + if(H5G__is_new_dense_test(group_id) != TRUE) TEST_ERROR + + /* Loop through links, checking their creation order values */ + /* (the name index is used, but the creation order value is in the same order) */ + for(u = 0; u < (max_compact + 1); u++) { + H5L_info1_t linfo; /* Link information */ + + /* Retrieve information for link */ + HDsnprintf(objname, sizeof(objname), "filler %u", u); + if(H5Lget_info1(group_id, objname, &linfo, H5P_DEFAULT) < 0) TEST_ERROR + + /* Verify creation order of link */ + if(linfo.corder_valid != TRUE) TEST_ERROR + if(linfo.corder != u) TEST_ERROR + } /* end for */ + + /* Close the group */ + if(H5Gclose(group_id) < 0) TEST_ERROR + + /* Close the file */ + if(H5Fclose(file_id) < 0) TEST_ERROR + + PASSED(); + return SUCCEED; + +error: + H5E_BEGIN_TRY { + H5Pclose(gcpl_id); + H5Gclose(group_id); + H5Fclose(file_id); + } H5E_END_TRY; + return FAIL; +} /* end corder_create_dense_deprec() */ + +/*------------------------------------------------------------------------- + * Function: link_info_by_idx_check_deprec + * + * Purpose: Support routine for link_info_by_idx, to verify the link + * info is correct for a link + * + * Note: This routine assumes that the links have been inserted in the + * group in alphabetical order. + * + * Return: Success: 0 + * Failure: -1 + *------------------------------------------------------------------------- + */ +static int +link_info_by_idx_check_deprec(hid_t group_id, const char *linkname, hsize_t n, + hbool_t hard_link, hbool_t use_index) +{ + char tmpname[NAME_BUF_SIZE]; /* Temporary link name */ + char valname[NAME_BUF_SIZE]; /* Link value name */ + char tmpval[NAME_BUF_SIZE]; /* Temporary link value */ + H5L_info1_t linfo; /* Link info struct */ + + /* Make link value for increasing/native order queries */ + HDsnprintf(valname, sizeof(valname), "value %02u", (unsigned)n); + + /* Verify the link information for first link, in increasing creation order */ + HDmemset(&linfo, 0, sizeof(linfo)); + if(H5Lget_info_by_idx1(group_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, (hsize_t)0, &linfo, H5P_DEFAULT) < 0) TEST_ERROR + if(linfo.corder != 0) TEST_ERROR + + /* Verify the link information for new link, in increasing creation order */ + HDmemset(&linfo, 0, sizeof(linfo)); + if(H5Lget_info_by_idx1(group_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, n, &linfo, H5P_DEFAULT) < 0) TEST_ERROR + if(linfo.corder != (int64_t)n) TEST_ERROR + + /* Verify value for new soft link, in increasing creation order */ + if(!hard_link) { + HDmemset(tmpval, 0, (size_t)NAME_BUF_SIZE); + if(H5Lget_val_by_idx(group_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, n, tmpval, (size_t)NAME_BUF_SIZE, H5P_DEFAULT) < 0) TEST_ERROR + if(HDstrcmp(valname, tmpval)) TEST_ERROR + } /* end if */ + + /* Verify the name for new link, in increasing creation order */ + HDmemset(tmpname, 0, (size_t)NAME_BUF_SIZE); + if(H5Lget_name_by_idx(group_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, n, tmpname, (size_t)NAME_BUF_SIZE, H5P_DEFAULT) < 0) TEST_ERROR + if(HDstrcmp(linkname, tmpname)) TEST_ERROR + + /* Don't test "native" order if there is no creation order index, since + * there's not a good way to easily predict the link's order in the name + * index. + */ + if(use_index) { + /* Verify the link information for first link, in native creation order (which is increasing) */ + HDmemset(&linfo, 0, sizeof(linfo)); + if(H5Lget_info_by_idx1(group_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_NATIVE, (hsize_t)0, &linfo, H5P_DEFAULT) < 0) TEST_ERROR + if(linfo.corder != 0) TEST_ERROR + + /* Verify the link information for new link, in native creation order (which is increasing) */ + HDmemset(&linfo, 0, sizeof(linfo)); + if(H5Lget_info_by_idx1(group_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_NATIVE, n, &linfo, H5P_DEFAULT) < 0) TEST_ERROR + if(linfo.corder != (int64_t)n) TEST_ERROR + + /* Verify value for new soft link, in native creation order (which is increasing) */ + if(!hard_link) { + HDmemset(tmpval, 0, (size_t)NAME_BUF_SIZE); + if(H5Lget_val_by_idx(group_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_NATIVE, n, tmpval, (size_t)NAME_BUF_SIZE, H5P_DEFAULT) < 0) TEST_ERROR + if(HDstrcmp(valname, tmpval)) TEST_ERROR + } /* end if */ + + /* Verify the name for new link, in native creation order (which is increasing) */ + HDmemset(tmpname, 0, (size_t)NAME_BUF_SIZE); + if(H5Lget_name_by_idx(group_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_NATIVE, n, tmpname, (size_t)NAME_BUF_SIZE, H5P_DEFAULT) < 0) TEST_ERROR + if(HDstrcmp(linkname, tmpname)) TEST_ERROR + } /* end if */ + + /* Verify the link information for first link, in decreasing creation order */ + HDmemset(&linfo, 0, sizeof(linfo)); + if(H5Lget_info_by_idx1(group_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_DEC, n, &linfo, H5P_DEFAULT) < 0) TEST_ERROR + if(linfo.corder != 0) TEST_ERROR + + /* Verify the link information for new link, in decreasing creation order */ + HDmemset(&linfo, 0, sizeof(linfo)); + if(H5Lget_info_by_idx1(group_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_DEC, (hsize_t)0, &linfo, H5P_DEFAULT) < 0) TEST_ERROR + if(linfo.corder != (int64_t)n) TEST_ERROR + + /* Verify value for new soft link, in decreasing creation order */ + if(!hard_link) { + HDmemset(tmpval, 0, (size_t)NAME_BUF_SIZE); + if(H5Lget_val_by_idx(group_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_DEC, (hsize_t)0, tmpval, (size_t)NAME_BUF_SIZE, H5P_DEFAULT) < 0) TEST_ERROR + if(HDstrcmp(valname, tmpval)) TEST_ERROR + } /* end if */ + + /* Verify the name for new link, in decreasing creation order */ + HDmemset(tmpname, 0, (size_t)NAME_BUF_SIZE); + if(H5Lget_name_by_idx(group_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_DEC, (hsize_t)0, tmpname, (size_t)NAME_BUF_SIZE, H5P_DEFAULT) < 0) TEST_ERROR + if(HDstrcmp(linkname, tmpname)) TEST_ERROR + + + /* Verify the link information for first link, in increasing link name order */ + HDmemset(&linfo, 0, sizeof(linfo)); + if(H5Lget_info_by_idx1(group_id, ".", H5_INDEX_NAME, H5_ITER_INC, (hsize_t)0, &linfo, H5P_DEFAULT) < 0) TEST_ERROR + if(linfo.corder != 0) TEST_ERROR + + /* Verify the link information for new link, in increasing link name order */ + HDmemset(&linfo, 0, sizeof(linfo)); + if(H5Lget_info_by_idx1(group_id, ".", H5_INDEX_NAME, H5_ITER_INC, n, &linfo, H5P_DEFAULT) < 0) TEST_ERROR + if(linfo.corder != (int64_t)n) TEST_ERROR + + /* Verify value for new soft link, in increasing link name order */ + if(!hard_link) { + HDmemset(tmpval, 0, (size_t)NAME_BUF_SIZE); + if(H5Lget_val_by_idx(group_id, ".", H5_INDEX_NAME, H5_ITER_INC, n, tmpval, (size_t)NAME_BUF_SIZE, H5P_DEFAULT) < 0) TEST_ERROR + if(HDstrcmp(valname, tmpval)) TEST_ERROR + } /* end if */ + + /* Verify the name for new link, in increasing link name order */ + HDmemset(tmpname, 0, (size_t)NAME_BUF_SIZE); + if(H5Lget_name_by_idx(group_id, ".", H5_INDEX_NAME, H5_ITER_INC, n, tmpname, (size_t)NAME_BUF_SIZE, H5P_DEFAULT) < 0) TEST_ERROR + if(HDstrcmp(linkname, tmpname)) TEST_ERROR + + /* Don't test "native" order queries on link name order, since there's not + * a good way to easily predict the order of the links in the name index. + */ + + /* Verify the link information for first link, in decreasing link name order */ + HDmemset(&linfo, 0, sizeof(linfo)); + if(H5Lget_info_by_idx1(group_id, ".", H5_INDEX_NAME, H5_ITER_DEC, n, &linfo, H5P_DEFAULT) < 0) TEST_ERROR + if(linfo.corder != 0) TEST_ERROR + + /* Verify the link information for new link, in decreasing link name order */ + HDmemset(&linfo, 0, sizeof(linfo)); + if(H5Lget_info_by_idx1(group_id, ".", H5_INDEX_NAME, H5_ITER_DEC, (hsize_t)0, &linfo, H5P_DEFAULT) < 0) TEST_ERROR + if(linfo.corder != (int64_t)n) TEST_ERROR + + /* Verify value for new soft link, in decreasing link name order */ + if(!hard_link) { + HDmemset(tmpval, 0, (size_t)NAME_BUF_SIZE); + if(H5Lget_val_by_idx(group_id, ".", H5_INDEX_NAME, H5_ITER_DEC, (hsize_t)0, tmpval, (size_t)NAME_BUF_SIZE, H5P_DEFAULT) < 0) TEST_ERROR + if(HDstrcmp(valname, tmpval)) TEST_ERROR + } /* end if */ + + /* Verify the name for new link, in decreasing link name order */ + HDmemset(tmpname, 0, (size_t)NAME_BUF_SIZE); + if(H5Lget_name_by_idx(group_id, ".", H5_INDEX_NAME, H5_ITER_DEC, (hsize_t)0, tmpname, (size_t)NAME_BUF_SIZE, H5P_DEFAULT) < 0) TEST_ERROR + if(HDstrcmp(linkname, tmpname)) TEST_ERROR + + /* Success */ + return(0); + +error: + /* Failure */ + return(-1); +} /* end link_info_by_idx_check_deprec() */ + +/*------------------------------------------------------------------------- + * Function: link_info_by_idx_deprec + * + * Purpose: Create a group with creation order indices and test querying + * info by index. + * + * Return: Success: 0 + * Failure: -1 + *------------------------------------------------------------------------- + */ +static int +link_info_by_idx_deprec(hid_t fapl) +{ + hid_t file_id = -1; /* File ID */ + hid_t group_id = -1; /* Group ID */ + hid_t gcpl_id = -1; /* Group creation property list ID */ + unsigned hard_link; /* Create hard or soft link? */ + unsigned use_index; /* Use index on creation order values */ + unsigned max_compact; /* Maximum # of links to store in group compactly */ + unsigned min_dense; /* Minimum # of links to store in group "densely" */ + H5L_info1_t linfo; /* Link info struct */ + char objname[NAME_BUF_SIZE]; /* Object name */ + char valname[NAME_BUF_SIZE]; /* Link value name */ + char filename[NAME_BUF_SIZE];/* File name */ + char tmpname[NAME_BUF_SIZE]; /* Temporary link name */ + unsigned u; /* Local index variable */ + ssize_t name_len; /* Length of name */ + herr_t ret; /* Generic return value */ + + /* Loop over creating hard or soft links */ + for(hard_link = FALSE; hard_link <= TRUE; hard_link++) { + /* Loop over using index for creation order value */ + for(use_index = FALSE; use_index <= TRUE; use_index++) { + if(hard_link) { + if(use_index) + TESTING("querying info by index w/creation order index, using hard links and deprecated routines") + else + TESTING("querying info by index w/o creation order index, using hard links and deprecated routines") + } /* end if */ + else { + if(use_index) + TESTING("querying info by index w/creation order index, using soft links and deprecated routines") + else + TESTING("querying info by index w/o creation order index, using soft links and deprecated routines") + } /* end else */ + + /* Create file */ + h5_fixname(FILENAME[0], fapl, filename, sizeof filename); + if((file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR + + /* Create group creation property list */ + if((gcpl_id = H5Pcreate(H5P_GROUP_CREATE)) < 0) TEST_ERROR + + /* Set creation order tracking & indexing on group */ + if(H5Pset_link_creation_order(gcpl_id, (H5P_CRT_ORDER_TRACKED | (use_index ? H5P_CRT_ORDER_INDEXED : (unsigned)0))) < 0) TEST_ERROR + + /* Create group with creation order indexing & tracking on */ + if((group_id = H5Gcreate2(file_id, CORDER_GROUP_NAME, H5P_DEFAULT, gcpl_id, H5P_DEFAULT)) < 0) TEST_ERROR + + /* Query the group creation properties */ + if(H5Pget_link_phase_change(gcpl_id, &max_compact, &min_dense) < 0) TEST_ERROR + + /* Check for query on empty group */ + H5E_BEGIN_TRY { + ret = H5Lget_info_by_idx1(group_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, (hsize_t)0, &linfo, H5P_DEFAULT); + } H5E_END_TRY; + if(ret >= 0) TEST_ERROR + H5E_BEGIN_TRY { + name_len = H5Lget_name_by_idx(group_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, (hsize_t)0, tmpname, (size_t)NAME_BUF_SIZE, H5P_DEFAULT); + } H5E_END_TRY; + if(name_len >= 0) TEST_ERROR + + /* Create several links, up to limit of compact form */ + for(u = 0; u < max_compact; u++) { + /* Make name for link */ + HDsnprintf(objname, sizeof(objname), "filler %02u", u); + + /* Check for creating hard or soft link */ + if(hard_link) { + hid_t group_id2; /* Group ID */ + + /* Create hard link, with group object */ + if((group_id2 = H5Gcreate2(group_id, objname, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR + if(H5Gclose(group_id2) < 0) TEST_ERROR + } /* end if */ + else { + /* Make value for link */ + HDsnprintf(valname, sizeof(valname), "value %02u", u); + + /* Create soft link */ + if(H5Lcreate_soft(valname, group_id, objname, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR + } /* end else */ + + /* Verify link information for new link */ + if(link_info_by_idx_check_deprec(group_id, objname, (hsize_t)u, hard_link, use_index) < 0) TEST_ERROR + } /* end for */ + + /* Verify state of group */ + if(H5G__has_links_test(group_id, NULL) != TRUE) TEST_ERROR + + /* Check for out of bound offset queries */ + H5E_BEGIN_TRY { + ret = H5Lget_info_by_idx1(group_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, (hsize_t)u, &linfo, H5P_DEFAULT); + } H5E_END_TRY; + if(ret >= 0) TEST_ERROR + H5E_BEGIN_TRY { + ret = H5Lget_info_by_idx1(group_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_DEC, (hsize_t)u, &linfo, H5P_DEFAULT); + } H5E_END_TRY; + if(ret >= 0) TEST_ERROR + H5E_BEGIN_TRY { + name_len = H5Lget_name_by_idx(group_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, (hsize_t)u, tmpname, (size_t)NAME_BUF_SIZE, H5P_DEFAULT); + } H5E_END_TRY; + if(name_len >= 0) TEST_ERROR + + /* Create more links, to push group into dense form */ + for(; u < (max_compact * 2); u++) { + /* Make name for link */ + HDsnprintf(objname, sizeof(objname), "filler %02u", u); + + /* Check for creating hard or soft link */ + if(hard_link) { + hid_t group_id2; /* Group ID */ + + /* Create hard link, with group object */ + if((group_id2 = H5Gcreate2(group_id, objname, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR + if(H5Gclose(group_id2) < 0) TEST_ERROR + } /* end if */ + else { + /* Make value for link */ + HDsnprintf(valname, sizeof(valname), "value %02u", u); + + /* Create soft link */ + if(H5Lcreate_soft(valname, group_id, objname, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR + } /* end else */ + + /* Verify state of group */ + if(H5G__is_new_dense_test(group_id) != TRUE) TEST_ERROR + + /* Verify link information for new link */ + if(link_info_by_idx_check_deprec(group_id, objname, (hsize_t)u, hard_link, use_index) < 0) TEST_ERROR + } /* end for */ + + /* Check for out of bound offset queries */ + H5E_BEGIN_TRY { + ret = H5Lget_info_by_idx1(group_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, (hsize_t)u, &linfo, H5P_DEFAULT); + } H5E_END_TRY; + if(ret >= 0) TEST_ERROR + H5E_BEGIN_TRY { + ret = H5Lget_info_by_idx1(group_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_DEC, (hsize_t)u, &linfo, H5P_DEFAULT); + } H5E_END_TRY; + if(ret >= 0) TEST_ERROR + H5E_BEGIN_TRY { + name_len = H5Lget_name_by_idx(group_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, (hsize_t)u, tmpname, (size_t)NAME_BUF_SIZE, H5P_DEFAULT); + } H5E_END_TRY; + if(name_len >= 0) TEST_ERROR + + /* Close the group */ + if(H5Gclose(group_id) < 0) TEST_ERROR + + /* Close the group creation property list */ + if(H5Pclose(gcpl_id) < 0) TEST_ERROR + + /* Close the file */ + if(H5Fclose(file_id) < 0) TEST_ERROR + + PASSED(); + } /* end for */ + } /* end for */ + + return SUCCEED; + +error: + H5E_BEGIN_TRY { + H5Pclose(gcpl_id); + H5Gclose(group_id); + H5Fclose(file_id); + } H5E_END_TRY; + return FAIL; +} /* end link_info_by_idx_deprec() */ + +/*------------------------------------------------------------------------- + * Function: link_info_by_idx_old_deprec + * + * Purpose: Create a old-format group and test querying + * info by index. + * + * Return: Success: 0 + * Failure: -1 + *------------------------------------------------------------------------- + */ +static int +link_info_by_idx_old_deprec(hid_t fapl) +{ + hid_t file_id = -1; /* File ID */ + hid_t group_id = -1, group_id2 = -1; /* Group IDs */ + unsigned hard_link; /* Create hard or soft link? */ + H5L_info1_t linfo; /* Link info struct */ + char objname[NAME_BUF_SIZE]; /* Object name */ + char valname[NAME_BUF_SIZE]; /* Link value name */ + char filename[NAME_BUF_SIZE];/* File name */ + haddr_t objno[CORDER_NLINKS]; /* Addresses of the objects created */ + char tmpname[NAME_BUF_SIZE]; /* Temporary link name */ + char tmpval[NAME_BUF_SIZE]; /* Temporary link value */ + unsigned u; /* Local index variable */ + ssize_t name_len; /* Length of name */ + herr_t ret; /* Generic return value */ + + /* Loop over creating hard or soft links */ + for(hard_link = FALSE; hard_link <= TRUE; hard_link++) { + if(hard_link) + TESTING("querying info by index in old-style group, using hard links and deprecated routines") + else + TESTING("querying info by index in old-style group, using soft links and deprecated routines") + + /* Create file */ + h5_fixname(FILENAME[0], fapl, filename, sizeof filename); + if((file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR + + /* Create group to operate on */ + if((group_id = H5Gcreate2(file_id, CORDER_GROUP_NAME, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR + + /* Create several links */ + for(u = 0; u < CORDER_NLINKS; u++) { + /* Make name for link */ + HDsnprintf(objname, sizeof(objname), "filler %02u", u); + + /* Check for creating hard or soft link */ + if(hard_link) { + H5O_info1_t oi; /* Buffer for querying object's info */ + + /* Create group */ + if((group_id2 = H5Gcreate2(group_id, objname, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR + + /* Retrieve group's address on disk */ + if(H5Oget_info2(group_id2, &oi, H5O_INFO_BASIC) < 0) TEST_ERROR + objno[u] = oi.addr; + + /* Close group */ + if(H5Gclose(group_id2) < 0) TEST_ERROR + } /* end if */ + else { + /* Make value for link */ + HDsnprintf(valname, sizeof(valname), "value %02u", u); + + /* Create soft link */ + if(H5Lcreate_soft(valname, group_id, objname, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR + } /* end else */ + } /* end for */ + + /* Verify link information for created links */ + for(u = 0; u < CORDER_NLINKS; u++) { + unsigned dec_u = CORDER_NLINKS - (u + 1); /* Decreasing mapped index */ + + /* Make link name for increasing/native order queries */ + HDsnprintf(objname, sizeof(objname), "filler %02u", u); + + /* Make link value for increasing/native order queries */ + HDsnprintf(valname, sizeof(valname), "value %02u", u); + + /* Verify link information (in increasing order) */ + if(hard_link) { + if(H5Lget_info_by_idx1(group_id, ".", H5_INDEX_NAME, H5_ITER_INC, (hsize_t)u, &linfo, H5P_DEFAULT) < 0) TEST_ERROR + if(H5F_addr_ne(linfo.u.address, objno[u])) TEST_ERROR + } /* end if */ + else { + if(H5Lget_val_by_idx(group_id, ".", H5_INDEX_NAME, H5_ITER_INC, (hsize_t)u, tmpval, (size_t)NAME_BUF_SIZE, H5P_DEFAULT) < 0) TEST_ERROR + if(HDstrcmp(valname, tmpval)) TEST_ERROR + } /* end else */ + + /* Verify link name (in increasing order) */ + if(H5Lget_name_by_idx(group_id, ".", H5_INDEX_NAME, H5_ITER_INC, (hsize_t)u, tmpname, (size_t)NAME_BUF_SIZE, H5P_DEFAULT) < 0) TEST_ERROR + if(HDstrcmp(objname, tmpname)) TEST_ERROR + + + /* Verify link information (in native order - native is increasing) */ + if(hard_link) { + if(H5Lget_info_by_idx1(group_id, ".", H5_INDEX_NAME, H5_ITER_NATIVE, (hsize_t)u, &linfo, H5P_DEFAULT) < 0) TEST_ERROR + if(H5F_addr_ne(linfo.u.address, objno[u])) TEST_ERROR + } /* end if */ + else { + if(H5Lget_val_by_idx(group_id, ".", H5_INDEX_NAME, H5_ITER_NATIVE, (hsize_t)u, tmpval, (size_t)NAME_BUF_SIZE, H5P_DEFAULT) < 0) TEST_ERROR + if(HDstrcmp(valname, tmpval)) TEST_ERROR + } /* end else */ + + /* Verify link name (in native order - native is increasing) */ + if(H5Lget_name_by_idx(group_id, ".", H5_INDEX_NAME, H5_ITER_NATIVE, (hsize_t)u, tmpname, (size_t)NAME_BUF_SIZE, H5P_DEFAULT) < 0) TEST_ERROR + if(HDstrcmp(objname, tmpname)) TEST_ERROR + + + /* Make link name for decreasing order queries */ + HDsnprintf(objname, sizeof(objname), "filler %02u", dec_u); + + /* Make link value for decreasing order queries */ + HDsnprintf(valname, sizeof(valname), "value %02u", dec_u); + + /* Verify link information (in decreasing order) */ + if(hard_link) { + if(H5Lget_info_by_idx1(group_id, ".", H5_INDEX_NAME, H5_ITER_DEC, (hsize_t)u, &linfo, H5P_DEFAULT) < 0) TEST_ERROR + if(H5F_addr_ne(linfo.u.address, objno[dec_u])) TEST_ERROR + } /* end if */ + else { + if(H5Lget_val_by_idx(group_id, ".", H5_INDEX_NAME, H5_ITER_DEC, (hsize_t)u, tmpval, (size_t)NAME_BUF_SIZE, H5P_DEFAULT) < 0) TEST_ERROR + if(HDstrcmp(valname, tmpval)) TEST_ERROR + } /* end else */ + + /* Verify link name (in decreasing order) */ + if(H5Lget_name_by_idx(group_id, ".", H5_INDEX_NAME, H5_ITER_DEC, (hsize_t)u, tmpname, (size_t)NAME_BUF_SIZE, H5P_DEFAULT) < 0) TEST_ERROR + if(HDstrcmp(objname, tmpname)) TEST_ERROR + } /* end for */ + + /* Check for creation order index queries */ + H5E_BEGIN_TRY { + ret = H5Lget_info_by_idx1(group_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, (hsize_t)u, &linfo, H5P_DEFAULT); + } H5E_END_TRY; + if(ret >= 0) TEST_ERROR + H5E_BEGIN_TRY { + name_len = H5Lget_name_by_idx(group_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, (hsize_t)u, tmpname, (size_t)NAME_BUF_SIZE, H5P_DEFAULT); + } H5E_END_TRY; + if(name_len >= 0) TEST_ERROR + + /* Verify state of group */ + if(H5G__has_stab_test(group_id) != TRUE) TEST_ERROR + + /* Close the group */ + if(H5Gclose(group_id) < 0) TEST_ERROR + + /* Close the file */ + if(H5Fclose(file_id) < 0) TEST_ERROR + + PASSED(); + } /* end for */ + + return SUCCEED; + +error: + H5E_BEGIN_TRY { + H5Gclose(group_id); + H5Fclose(file_id); + } H5E_END_TRY; + return FAIL; +} /* end link_info_by_idx_old_deprec() */ + +/*------------------------------------------------------------------------- + * Function: delete_by_idx_deprec + * + * Purpose: Create a group with creation order indices and test deleting + * links by index. + * + * Return: Success: 0 + * Failure: -1 + *------------------------------------------------------------------------- + */ +static int +delete_by_idx_deprec(hid_t fapl) +{ + hid_t file_id = -1; /* File ID */ + hid_t group_id = -1; /* Group ID */ + hid_t gcpl_id = -1; /* Group creation property list ID */ + H5_index_t idx_type; /* Type of index to operate on */ + H5_iter_order_t order; /* Order within in the index */ + unsigned use_index; /* Use index on creation order values */ + unsigned max_compact; /* Maximum # of links to store in group compactly */ + unsigned min_dense; /* Minimum # of links to store in group "densely" */ + H5L_info1_t linfo; /* Link info struct */ + char objname[NAME_BUF_SIZE]; /* Object name */ + char filename[NAME_BUF_SIZE];/* File name */ + char tmpname[NAME_BUF_SIZE]; /* Temporary link name */ + unsigned u; /* Local index variable */ + herr_t ret; /* Generic return value */ + + /* Loop over operating on different indices on link fields */ + for(idx_type = H5_INDEX_NAME; idx_type <= H5_INDEX_CRT_ORDER; idx_type++) { + /* Loop over operating in different orders */ + for(order = H5_ITER_INC; order <=H5_ITER_DEC; order++) { + /* Loop over using index for creation order value */ + for(use_index = FALSE; use_index <= TRUE; use_index++) { + /* Print appropriate test message */ + if(idx_type == H5_INDEX_CRT_ORDER) { + if(order == H5_ITER_INC) { + if(use_index) + TESTING("deleting links by creation order index in increasing order w/creation order index using deprecated routines") + else + TESTING("deleting links by creation order index in increasing order w/o creation order index using deprecated routines") + } /* end if */ + else { + if(use_index) + TESTING("deleting links by creation order index in decreasing order w/creation order index using deprecated routines") + else + TESTING("deleting links by creation order index in decreasing order w/o creation order index using deprecated routines") + } /* end else */ + } /* end if */ + else { + if(order == H5_ITER_INC) { + if(use_index) + TESTING("deleting links by name index in increasing order w/creation order index using deprecated routines") + else + TESTING("deleting links by name index in increasing order w/o creation order index using deprecated routines") + } /* end if */ + else { + if(use_index) + TESTING("deleting links by name index in decreasing order w/creation order index using deprecated routines") + else + TESTING("deleting links by name index in decreasing order w/o creation order index using deprecated routines") + } /* end else */ + } /* end else */ + + /* Create file */ + h5_fixname(FILENAME[0], fapl, filename, sizeof filename); + if((file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR + + /* Create group creation property list */ + if((gcpl_id = H5Pcreate(H5P_GROUP_CREATE)) < 0) TEST_ERROR + + /* Set creation order tracking & indexing on group */ + if(H5Pset_link_creation_order(gcpl_id, (H5P_CRT_ORDER_TRACKED | (use_index ? H5P_CRT_ORDER_INDEXED : (unsigned)0))) < 0) TEST_ERROR + + /* Create group with creation order tracking on */ + if((group_id = H5Gcreate2(file_id, CORDER_GROUP_NAME, H5P_DEFAULT, gcpl_id, H5P_DEFAULT)) < 0) TEST_ERROR + + /* Query the group creation properties */ + if(H5Pget_link_phase_change(gcpl_id, &max_compact, &min_dense) < 0) TEST_ERROR + + /* Delete links from one end */ + + /* Check for deletion on empty group */ + H5E_BEGIN_TRY { + ret = H5Ldelete_by_idx(group_id, ".", idx_type, order, (hsize_t)0, H5P_DEFAULT); + } H5E_END_TRY; + if(ret >= 0) TEST_ERROR + + /* Check for deletion on non-existing group */ + H5E_BEGIN_TRY { + ret = H5Ldelete_by_idx(group_id, "None", idx_type, order, (hsize_t)0, H5P_DEFAULT); + } H5E_END_TRY; + if(ret >= 0) TEST_ERROR + + /* Create several links, up to limit of compact form */ + for(u = 0; u < max_compact; u++) { + hid_t group_id2; /* Group ID */ + + /* Make name for link */ + HDsnprintf(objname, sizeof(objname), "filler %02u", u); + + /* Create hard link, with group object */ + if((group_id2 = H5Gcreate2(group_id, objname, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR + if(H5Gclose(group_id2) < 0) TEST_ERROR + + /* Verify link information for new link */ + if(link_info_by_idx_check_deprec(group_id, objname, (hsize_t)u, TRUE, use_index) < 0) TEST_ERROR + } /* end for */ + + /* Verify state of group (compact) */ + if(H5G__has_links_test(group_id, NULL) != TRUE) TEST_ERROR + + /* Check for out of bound deletion */ + H5E_BEGIN_TRY { + ret = H5Ldelete_by_idx(group_id, ".", idx_type, order, (hsize_t)u, H5P_DEFAULT); + } H5E_END_TRY; + if(ret >= 0) TEST_ERROR + + /* Delete links from compact group */ + for(u = 0; u < (max_compact - 1); u++) { + /* Delete first link in appropriate order */ + if(H5Ldelete_by_idx(group_id, ".", idx_type, order, (hsize_t)0, H5P_DEFAULT) < 0) TEST_ERROR + + /* Verify the link information for first link in appropriate order */ + HDmemset(&linfo, 0, sizeof(linfo)); + if(H5Lget_info_by_idx1(group_id, ".", idx_type, order, (hsize_t)0, &linfo, H5P_DEFAULT) < 0) TEST_ERROR + if(order == H5_ITER_INC) { + if(linfo.corder != (u + 1)) TEST_ERROR + } /* end if */ + else { + if(linfo.corder != (max_compact - (u + 2))) TEST_ERROR + } /* end else */ + + /* Verify the name for first link in appropriate order */ + HDmemset(tmpname, 0, (size_t)NAME_BUF_SIZE); + if(H5Lget_name_by_idx(group_id, ".", idx_type, order, (hsize_t)0, tmpname, (size_t)NAME_BUF_SIZE, H5P_DEFAULT) < 0) TEST_ERROR + if(order == H5_ITER_INC) + HDsnprintf(objname, sizeof(objname), "filler %02u", (u + 1)); + else + HDsnprintf(objname, sizeof(objname), "filler %02u", (max_compact - (u + 2))); + if(HDstrcmp(objname, tmpname)) TEST_ERROR + } /* end for */ + + /* Delete last link */ + if(H5Ldelete_by_idx(group_id, ".", idx_type, order, (hsize_t)0, H5P_DEFAULT) < 0) TEST_ERROR + + /* Verify state of group (empty) */ + if(H5G__has_links_test(group_id, NULL) == TRUE) TEST_ERROR + + /* Create more links, to push group into dense form */ + for(u = 0; u < (max_compact * 2); u++) { + hid_t group_id2; /* Group ID */ + + /* Make name for link */ + HDsnprintf(objname, sizeof(objname), "filler %02u", u); + + /* Create hard link, with group object */ + if((group_id2 = H5Gcreate2(group_id, objname, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR + if(H5Gclose(group_id2) < 0) TEST_ERROR + + /* Verify state of group (dense) */ + if(u >= max_compact) + if(H5G__is_new_dense_test(group_id) != TRUE) TEST_ERROR + + /* Verify link information for new link */ + if(link_info_by_idx_check_deprec(group_id, objname, (hsize_t)u, TRUE, use_index) < 0) TEST_ERROR + } /* end for */ + + /* Check for out of bound deletion again */ + H5E_BEGIN_TRY { + ret = H5Ldelete_by_idx(group_id, ".", idx_type, order, (hsize_t)u, H5P_DEFAULT); + } H5E_END_TRY; + if(ret >= 0) TEST_ERROR + + /* Delete links from dense group, in appropriate order */ + for(u = 0; u < ((max_compact * 2) - 1); u++) { + /* Delete first link in appropriate order */ + if(H5Ldelete_by_idx(group_id, ".", idx_type, order, (hsize_t)0, H5P_DEFAULT) < 0) TEST_ERROR + + /* Verify the link information for first link in appropriate order */ + HDmemset(&linfo, 0, sizeof(linfo)); + if(H5Lget_info_by_idx1(group_id, ".", idx_type, order, (hsize_t)0, &linfo, H5P_DEFAULT) < 0) TEST_ERROR + if(order == H5_ITER_INC) { + if(linfo.corder != (u + 1)) TEST_ERROR + } /* end if */ + else { + if(linfo.corder != ((max_compact * 2) - (u + 2))) TEST_ERROR + } /* end else */ + + /* Verify the name for first link in appropriate order */ + HDmemset(tmpname, 0, (size_t)NAME_BUF_SIZE); + if(H5Lget_name_by_idx(group_id, ".", idx_type, order, (hsize_t)0, tmpname, (size_t)NAME_BUF_SIZE, H5P_DEFAULT) < 0) TEST_ERROR + if(order == H5_ITER_INC) + HDsnprintf(objname, sizeof(objname), "filler %02u", (u + 1)); + else + HDsnprintf(objname, sizeof(objname), "filler %02u", ((max_compact * 2) - (u + 2))); + if(HDstrcmp(objname, tmpname)) TEST_ERROR + } /* end for */ + + /* Delete last link */ + if(H5Ldelete_by_idx(group_id, ".", idx_type, order, (hsize_t)0, H5P_DEFAULT) < 0) TEST_ERROR + + /* Verify state of group (empty) */ + if(H5G__has_links_test(group_id, NULL) == TRUE) TEST_ERROR + if(H5G__is_new_dense_test(group_id) == TRUE) TEST_ERROR + + /* Check for deletion on empty group again */ + H5E_BEGIN_TRY { + ret = H5Ldelete_by_idx(group_id, ".", idx_type, order, (hsize_t)0, H5P_DEFAULT); + } H5E_END_TRY; + if(ret >= 0) TEST_ERROR + + /* Delete links in middle */ + + /* Create more links, to push group into dense form */ + for(u = 0; u < (max_compact * 2); u++) { + hid_t group_id2; /* Group ID */ + + /* Make name for link */ + HDsnprintf(objname, sizeof(objname), "filler %02u", u); + + /* Create hard link, with group object */ + if((group_id2 = H5Gcreate2(group_id, objname, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR + if(H5Gclose(group_id2) < 0) TEST_ERROR + + /* Verify state of group (dense) */ + if(u >= max_compact) + if(H5G__is_new_dense_test(group_id) != TRUE) TEST_ERROR + + /* Verify link information for new link */ + if(link_info_by_idx_check_deprec(group_id, objname, (hsize_t)u, TRUE, use_index) < 0) TEST_ERROR + } /* end for */ + + /* Delete every other link from dense group, in appropriate order */ + for(u = 0; u < max_compact; u++) { + /* Delete link */ + if(H5Ldelete_by_idx(group_id, ".", idx_type, order, (hsize_t)u, H5P_DEFAULT) < 0) TEST_ERROR + + /* Verify the link information for current link in appropriate order */ + HDmemset(&linfo, 0, sizeof(linfo)); + if(H5Lget_info_by_idx1(group_id, ".", idx_type, order, (hsize_t)u, &linfo, H5P_DEFAULT) < 0) TEST_ERROR + if(order == H5_ITER_INC) { + if(linfo.corder != ((u * 2) + 1)) TEST_ERROR + } /* end if */ + else { + if(linfo.corder != ((max_compact * 2) - ((u * 2) + 2))) TEST_ERROR + } /* end else */ + + /* Verify the name for current link in appropriate order */ + HDmemset(tmpname, 0, (size_t)NAME_BUF_SIZE); + if(H5Lget_name_by_idx(group_id, ".", idx_type, order, (hsize_t)u, tmpname, (size_t)NAME_BUF_SIZE, H5P_DEFAULT) < 0) TEST_ERROR + if(order == H5_ITER_INC) + HDsnprintf(objname, sizeof(objname), "filler %02u", ((u * 2) + 1)); + else + HDsnprintf(objname, sizeof(objname), "filler %02u", ((max_compact * 2) - ((u * 2) + 2))); + if(HDstrcmp(objname, tmpname)) TEST_ERROR + } /* end for */ + + /* Delete remaining links from dense group, in appropriate order */ + for(u = 0; u < (max_compact - 1); u++) { + /* Delete link */ + if(H5Ldelete_by_idx(group_id, ".", idx_type, order, (hsize_t)0, H5P_DEFAULT) < 0) TEST_ERROR + + /* Verify the link information for first link in appropriate order */ + HDmemset(&linfo, 0, sizeof(linfo)); + if(H5Lget_info_by_idx1(group_id, ".", idx_type, order, (hsize_t)0, &linfo, H5P_DEFAULT) < 0) TEST_ERROR + if(order == H5_ITER_INC) { + if(linfo.corder != ((u * 2) + 3)) TEST_ERROR + } /* end if */ + else { + if(linfo.corder != ((max_compact * 2) - ((u * 2) + 4))) TEST_ERROR + } /* end else */ + + /* Verify the name for first link in appropriate order */ + HDmemset(tmpname, 0, (size_t)NAME_BUF_SIZE); + if(H5Lget_name_by_idx(group_id, ".", idx_type, order, (hsize_t)0, tmpname, (size_t)NAME_BUF_SIZE, H5P_DEFAULT) < 0) TEST_ERROR + if(order == H5_ITER_INC) + HDsnprintf(objname, sizeof(objname), "filler %02u", ((u * 2) + 3)); + else + HDsnprintf(objname, sizeof(objname), "filler %02u", ((max_compact * 2) - ((u * 2) + 4))); + if(HDstrcmp(objname, tmpname)) TEST_ERROR + } /* end for */ + + /* Delete last link */ + if(H5Ldelete_by_idx(group_id, ".", idx_type, order, (hsize_t)0, H5P_DEFAULT) < 0) TEST_ERROR + + /* Verify state of group (empty) */ + if(H5G__has_links_test(group_id, NULL) == TRUE) TEST_ERROR + if(H5G__is_new_dense_test(group_id) == TRUE) TEST_ERROR + + /* Close the group */ + if(H5Gclose(group_id) < 0) TEST_ERROR + + /* Close the group creation property list */ + if(H5Pclose(gcpl_id) < 0) TEST_ERROR + + /* Close the file */ + if(H5Fclose(file_id) < 0) TEST_ERROR + + PASSED(); + } /* end for */ + } /* end for */ + } /* end for */ + + return SUCCEED; + +error: + H5E_BEGIN_TRY { + H5Pclose(gcpl_id); + H5Gclose(group_id); + H5Fclose(file_id); + } H5E_END_TRY; + return FAIL; +} /* end delete_by_idx_deprec() */ + +/*------------------------------------------------------------------------- + * Function: delete_by_idx_old_deprec + * + * Purpose: Create a old-format group and test deleting + * links by index. + * + * Return: Success: 0 + * Failure: -1 + *------------------------------------------------------------------------- + */ +static int +delete_by_idx_old_deprec(hid_t fapl) +{ + hid_t file_id = -1; /* File ID */ + hid_t group_id = -1, group_id2 = -1; /* Group IDs */ + H5L_info1_t linfo; /* Link info struct */ + H5_iter_order_t order; /* Order within in the index */ + char objname[NAME_BUF_SIZE]; /* Object name */ + char filename[NAME_BUF_SIZE];/* File name */ + haddr_t objno[CORDER_NLINKS]; /* Addresses of the objects created */ + char tmpname[NAME_BUF_SIZE]; /* Temporary link name */ + unsigned u; /* Local index variable */ + herr_t ret; /* Generic return value */ + + /* Loop over operating in different orders */ + for(order = H5_ITER_INC; order <=H5_ITER_DEC; order++) { + /* Print test banner */ + if(order == H5_ITER_INC) + TESTING("deleting links by index in increasing order in old-style group using deprecated routines") + else + TESTING("deleting links by index in decreasing order in old-style group using deprecated routines") + + /* Create file */ + h5_fixname(FILENAME[0], fapl, filename, sizeof filename); + if((file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR + + /* Create group to operate on */ + if((group_id = H5Gcreate2(file_id, CORDER_GROUP_NAME, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR + + /* Delete links from one end */ + + /* Check for deletion in empty group */ + H5E_BEGIN_TRY { + ret = H5Ldelete_by_idx(group_id, ".", H5_INDEX_NAME, order, (hsize_t)0, H5P_DEFAULT); + } H5E_END_TRY; + if(ret >= 0) TEST_ERROR + + /* Create several links */ + for(u = 0; u < CORDER_NLINKS; u++) { + H5O_info1_t oi; /* Buffer for querying object's info */ + + /* Make name for link */ + HDsnprintf(objname, sizeof(objname), "filler %02u", u); + + /* Create group */ + if((group_id2 = H5Gcreate2(group_id, objname, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR + + /* Retrieve group's address on disk */ + if(H5Oget_info2(group_id2, &oi, H5O_INFO_BASIC) < 0) TEST_ERROR + objno[u] = oi.addr; + + /* Close group */ + if(H5Gclose(group_id2) < 0) TEST_ERROR + } /* end for */ + + /* Check for bad index type deletion */ + H5E_BEGIN_TRY { + ret = H5Ldelete_by_idx(group_id, ".", H5_INDEX_CRT_ORDER, order, (hsize_t)0, H5P_DEFAULT); + } H5E_END_TRY; + if(ret >= 0) TEST_ERROR + + /* Check for out of bounds deletion */ + H5E_BEGIN_TRY { + ret = H5Ldelete_by_idx(group_id, ".", H5_INDEX_NAME, order, (hsize_t)u, H5P_DEFAULT); + } H5E_END_TRY; + if(ret >= 0) TEST_ERROR + + /* Delete links, in appropriate order */ + for(u = 0; u < (CORDER_NLINKS - 1); u++) { + unsigned dec_u = CORDER_NLINKS - (u + 2); /* Decreasing mapped index */ + + /* Delete first link in appropriate order */ + if(H5Ldelete_by_idx(group_id, ".", H5_INDEX_NAME, order, (hsize_t)0, H5P_DEFAULT) < 0) TEST_ERROR + + /* Verify the link information for first link in appropriate order */ + HDmemset(&linfo, 0, sizeof(linfo)); + if(H5Lget_info_by_idx1(group_id, ".", H5_INDEX_NAME, order, (hsize_t)0, &linfo, H5P_DEFAULT) < 0) TEST_ERROR + if(order == H5_ITER_INC) { + if(H5F_addr_ne(linfo.u.address, objno[u + 1])) TEST_ERROR + } /* end if */ + else { + if(H5F_addr_ne(linfo.u.address, objno[dec_u])) TEST_ERROR + } /* end else */ + + /* Verify the name for first link in appropriate order */ + HDmemset(tmpname, 0, (size_t)NAME_BUF_SIZE); + if(H5Lget_name_by_idx(group_id, ".", H5_INDEX_NAME, order, (hsize_t)0, tmpname, (size_t)NAME_BUF_SIZE, H5P_DEFAULT) < 0) TEST_ERROR + if(order == H5_ITER_INC) + HDsnprintf(objname, sizeof(objname), "filler %02u", (u + 1)); + else + HDsnprintf(objname, sizeof(objname), "filler %02u", dec_u); + if(HDstrcmp(objname, tmpname)) TEST_ERROR + } /* end for */ + + /* Delete last link */ + if(H5Ldelete_by_idx(group_id, ".", H5_INDEX_NAME, order, (hsize_t)0, H5P_DEFAULT) < 0) TEST_ERROR + + /* Check for deletion in empty group (again) */ + H5E_BEGIN_TRY { + ret = H5Ldelete_by_idx(group_id, ".", H5_INDEX_NAME, order, (hsize_t)0, H5P_DEFAULT); + } H5E_END_TRY; + if(ret >= 0) TEST_ERROR + + /* Verify state of group */ + if(H5G__has_stab_test(group_id) != TRUE) TEST_ERROR + + /* Delete links in middle */ + + /* Create several links */ + for(u = 0; u < CORDER_NLINKS; u++) { + H5O_info1_t oi; /* Buffer for querying object's info */ + + /* Make name for link */ + HDsnprintf(objname, sizeof(objname), "filler %02u", u); + + /* Create group */ + if((group_id2 = H5Gcreate2(group_id, objname, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR + + /* Retrieve group's address on disk */ + if(H5Oget_info2(group_id2, &oi, H5O_INFO_BASIC) < 0) TEST_ERROR + objno[u] = oi.addr; + + /* Close group */ + if(H5Gclose(group_id2) < 0) TEST_ERROR + } /* end for */ + + /* Delete every other link from group, in appropriate order */ + for(u = 0; u < (CORDER_NLINKS / 2); u++) { + unsigned dec_u = CORDER_NLINKS - ((u * 2) + 2); /* Decreasing mapped index */ + + /* Delete link */ + if(H5Ldelete_by_idx(group_id, ".", H5_INDEX_NAME, order, (hsize_t)u, H5P_DEFAULT) < 0) TEST_ERROR + + /* Verify the link information for current link in appropriate order */ + HDmemset(&linfo, 0, sizeof(linfo)); + if(H5Lget_info_by_idx1(group_id, ".", H5_INDEX_NAME, order, (hsize_t)u, &linfo, H5P_DEFAULT) < 0) TEST_ERROR + if(order == H5_ITER_INC) { + if(H5F_addr_ne(linfo.u.address, objno[(u * 2) + 1])) TEST_ERROR + } /* end if */ + else { + if(H5F_addr_ne(linfo.u.address, objno[dec_u])) TEST_ERROR + } /* end else */ + + /* Verify the name for current link in appropriate order */ + HDmemset(tmpname, 0, (size_t)NAME_BUF_SIZE); + if(H5Lget_name_by_idx(group_id, ".", H5_INDEX_NAME, order, (hsize_t)u, tmpname, (size_t)NAME_BUF_SIZE, H5P_DEFAULT) < 0) TEST_ERROR + if(order == H5_ITER_INC) + HDsnprintf(objname, sizeof(objname), "filler %02u", ((u * 2) + 1)); + else + HDsnprintf(objname, sizeof(objname), "filler %02u", dec_u); + if(HDstrcmp(objname, tmpname)) TEST_ERROR + } /* end for */ + + /* Delete remaining links from group, in appropriate order */ + for(u = 0; u < ((CORDER_NLINKS / 2) - 1); u++) { + unsigned dec_u = CORDER_NLINKS - ((u * 2) + 4); /* Decreasing mapped index */ + + /* Delete link */ + if(H5Ldelete_by_idx(group_id, ".", H5_INDEX_NAME, order, (hsize_t)0, H5P_DEFAULT) < 0) TEST_ERROR + + /* Verify the link information for first link in appropriate order */ + HDmemset(&linfo, 0, sizeof(linfo)); + if(H5Lget_info_by_idx1(group_id, ".", H5_INDEX_NAME, order, (hsize_t)0, &linfo, H5P_DEFAULT) < 0) TEST_ERROR + if(order == H5_ITER_INC) { + if(H5F_addr_ne(linfo.u.address, objno[(u * 2) + 3])) TEST_ERROR + } /* end if */ + else { + if(H5F_addr_ne(linfo.u.address, objno[dec_u])) TEST_ERROR + } /* end else */ + + /* Verify the name for first link in appropriate order */ + HDmemset(tmpname, 0, (size_t)NAME_BUF_SIZE); + if(H5Lget_name_by_idx(group_id, ".", H5_INDEX_NAME, order, (hsize_t)0, tmpname, (size_t)NAME_BUF_SIZE, H5P_DEFAULT) < 0) TEST_ERROR + if(order == H5_ITER_INC) + HDsnprintf(objname, sizeof(objname), "filler %02u", ((u * 2) + 3)); + else + HDsnprintf(objname, sizeof(objname), "filler %02u", dec_u); + if(HDstrcmp(objname, tmpname)) TEST_ERROR + } /* end for */ + + /* Delete last link */ + if(H5Ldelete_by_idx(group_id, ".", H5_INDEX_NAME, order, (hsize_t)0, H5P_DEFAULT) < 0) TEST_ERROR + + /* Verify state of group */ + if(H5G__has_stab_test(group_id) != TRUE) TEST_ERROR + + /* Close the group */ + if(H5Gclose(group_id) < 0) TEST_ERROR + + /* Close the file */ + if(H5Fclose(file_id) < 0) TEST_ERROR + + PASSED(); + } /* end for */ + + return SUCCEED; + +error: + H5E_BEGIN_TRY { + H5Gclose(group_id); + H5Fclose(file_id); + } H5E_END_TRY; + + return FAIL; +} /* end delete_by_idx_old_deprec() */ + +/*------------------------------------------------------------------------- + * Function: link_iterate_deprec_cb + * + * Purpose: Callback routine for iterating over links in group + * + * Return: Success: 0 + * Failure: -1 + *------------------------------------------------------------------------- + */ +static int +link_iterate_deprec_cb(hid_t group_id, const char *link_name, const H5L_info1_t *info, + void *_op_data) +{ + link_iter_info_t *op_data = (link_iter_info_t *)_op_data; /* User data */ + char objname[NAME_BUF_SIZE]; /* Object name */ + H5L_info1_t my_info; /* Local link info */ + + /* Increment # of times the callback was called */ + op_data->ncalled++; + + /* Get the link information directly to compare */ + if(H5Lget_info1(group_id, link_name, &my_info, H5P_DEFAULT) < 0) + return H5_ITER_ERROR; + + /* Check more things for link iteration (vs. group iteration) */ + if(info) { + /* Check for correct order of iteration */ + /* (if we are operating in increasing or decreasing order) */ + if(op_data->order != H5_ITER_NATIVE) + if(info->corder != op_data->curr) + return H5_ITER_ERROR; + + /* Compare link info structs */ + if(info->type != my_info.type) + return H5_ITER_ERROR; + if(info->corder_valid != my_info.corder_valid) + return H5_ITER_ERROR; + if(info->corder != my_info.corder) + return H5_ITER_ERROR; + if(info->cset != my_info.cset) + return H5_ITER_ERROR; + if(H5F_addr_ne(info->u.address, my_info.u.address)) + return H5_ITER_ERROR; + } /* end if */ + + /* Verify name of link */ + HDsnprintf(objname, sizeof(objname), "filler %02u", (unsigned)my_info.corder); + if(HDstrcmp(link_name, objname)) + return H5_ITER_ERROR; + + /* Check if we've visited this link before */ + if((size_t)op_data->curr >= op_data->max_visit) + return H5_ITER_ERROR; + if(op_data->visited[op_data->curr]) + return H5_ITER_ERROR; + op_data->visited[op_data->curr] = TRUE; + + /* Advance to next value, in correct direction */ + if(op_data->order != H5_ITER_DEC) + op_data->curr++; + else + op_data->curr--; + + /* Check for stopping in the middle of iterating */ + if(op_data->stop > 0) + if(--op_data->stop == 0) + return CORDER_ITER_STOP; + + return H5_ITER_CONT; +} /* end link_iterate_deprec_cb() */ + +/*------------------------------------------------------------------------- + * Function: group_iterate_deprec_cb + * + * Purpose: Callback routine for iterating over links in group with + * H5Giterate() + * + * Return: Success: 0 + * Failure: -1 + *------------------------------------------------------------------------- + */ +static int +group_iterate_deprec_cb(hid_t group_id, const char *link_name, void *_op_data) +{ + return link_iterate_deprec_cb(group_id, link_name, NULL, _op_data); +} /* end group_iterate_deprec_cb() */ + +/*------------------------------------------------------------------------- + * Function: link_iterate_fail_deprec_cb + * + * Purpose: Callback routine for iterating over links in group that + * always returns failure + * + * Return: Success: 0 + * Failure: -1 + *------------------------------------------------------------------------- + */ +static int +link_iterate_fail_deprec_cb(hid_t H5_ATTR_UNUSED group_id, const char H5_ATTR_UNUSED *link_name, + const H5L_info1_t H5_ATTR_UNUSED *info, void H5_ATTR_UNUSED *_op_data) +{ + return H5_ITER_ERROR; +} /* end link_iterate_fail_deprec_cb() */ + +/*------------------------------------------------------------------------- + * Function: link_iterate_check_deprec + * + * Purpose: Check iteration over links in a group + * + * Return: Success: 0 + * Failure: -1 + *------------------------------------------------------------------------- + */ +static int +link_iterate_check_deprec(hid_t group_id, H5_index_t idx_type, H5_iter_order_t order, + unsigned max_links, link_iter_info_t *iter_info) +{ + unsigned v; /* Local index variable */ + hsize_t skip; /* # of links to skip in group */ + int gskip; /* # of links to skip in group, with H5Giterate */ + herr_t ret; /* Generic return value */ + + /* Iterate over links in group */ + iter_info->nskipped = (unsigned)(skip = 0); + iter_info->order = order; + iter_info->stop = -1; + iter_info->ncalled = 0; + iter_info->curr = order != H5_ITER_DEC ? 0 : (max_links - 1); + HDmemset(iter_info->visited, 0, sizeof(hbool_t) * iter_info->max_visit); + if(H5Literate1(group_id, idx_type, order, &skip, link_iterate_deprec_cb, iter_info) < 0) TEST_ERROR + + /* Verify that we visited all the links */ + if(skip != max_links) TEST_ERROR + for(v = 0; v < max_links; v++) + if(iter_info->visited[v] == FALSE) TEST_ERROR + + /* Iterate over links in group, with H5Giterate */ + iter_info->nskipped = (unsigned)(gskip = 0); + iter_info->order = order; + iter_info->stop = -1; + iter_info->ncalled = 0; + iter_info->curr = order != H5_ITER_DEC ? 0 : (max_links - 1); + HDmemset(iter_info->visited, 0, sizeof(hbool_t) * iter_info->max_visit); + if(H5Giterate(group_id, ".", &gskip, group_iterate_deprec_cb, iter_info) < 0) TEST_ERROR + + /* Verify that we visited all the links */ + if(gskip != (int)max_links) TEST_ERROR + for(v = 0; v < max_links; v++) + if(iter_info->visited[v] == FALSE) TEST_ERROR + + /* Skip over some links in group */ + iter_info->nskipped = (unsigned)(skip = max_links / 2); + iter_info->order = order; + iter_info->stop = -1; + iter_info->ncalled = 0; + iter_info->curr = (int64_t)(order != H5_ITER_DEC ? skip : ((max_links - 1) - skip)); + HDmemset(iter_info->visited, 0, sizeof(hbool_t) * iter_info->max_visit); + if(H5Literate1(group_id, idx_type, order, &skip, link_iterate_deprec_cb, iter_info) < 0) TEST_ERROR + + /* Verify that we visited all the links */ + if(skip != max_links) TEST_ERROR + if(order == H5_ITER_INC) { + for(v = 0; v < (max_links / 2); v++) + if(iter_info->visited[v + (max_links / 2)] == FALSE) TEST_ERROR + } /* end if */ + else if(order == H5_ITER_DEC) { + for(v = 0; v < (max_links / 2); v++) + if(iter_info->visited[v] == FALSE) TEST_ERROR + } /* end if */ + else { + unsigned nvisit = 0; /* # of links visited */ + + HDassert(order == H5_ITER_NATIVE); + for(v = 0; v < max_links; v++) + if(iter_info->visited[v] == TRUE) + nvisit++; + + if(nvisit != (max_links / 2)) TEST_ERROR + } /* end else */ + + /* Skip over some links in group, with H5Giterate */ + iter_info->nskipped = (unsigned)(gskip = (int)(max_links / 2)); + iter_info->order = order; + iter_info->stop = -1; + iter_info->ncalled = 0; + iter_info->curr = order != H5_ITER_DEC ? (unsigned)gskip : ((max_links - 1) - (unsigned)gskip); + HDmemset(iter_info->visited, 0, sizeof(hbool_t) * iter_info->max_visit); + if(H5Giterate(group_id, ".", &gskip, group_iterate_deprec_cb, iter_info) < 0) TEST_ERROR + + /* Verify that we visited all the links */ + if(gskip != (int)max_links) TEST_ERROR + if(order == H5_ITER_INC) { + for(v = 0; v < (max_links / 2); v++) + if(iter_info->visited[v + (max_links / 2)] == FALSE) TEST_ERROR + } /* end if */ + else if(order == H5_ITER_DEC) { + for(v = 0; v < (max_links / 2); v++) + if(iter_info->visited[v] == FALSE) TEST_ERROR + } /* end if */ + else { + unsigned nvisit = 0; /* # of links visited */ + + HDassert(order == H5_ITER_NATIVE); + for(v = 0; v < max_links; v++) + if(iter_info->visited[v] == TRUE) + nvisit++; + + if(nvisit != (max_links / 2)) TEST_ERROR + } /* end else */ + + /* Iterate over links in group, stopping in the middle */ + iter_info->nskipped = (unsigned)(skip = 0); + iter_info->order = order; + iter_info->stop = 3; + iter_info->ncalled = 0; + iter_info->curr = order != H5_ITER_DEC ? 0 : (max_links - 1); + HDmemset(iter_info->visited, 0, sizeof(hbool_t) * iter_info->max_visit); + if((ret = H5Literate1(group_id, idx_type, order, &skip, link_iterate_deprec_cb, iter_info)) < 0) TEST_ERROR + if(ret != CORDER_ITER_STOP) TEST_ERROR + if(iter_info->ncalled != 3) TEST_ERROR + + /* Iterate over links in group, stopping in the middle, with H5Giterate() */ + iter_info->nskipped = (unsigned)(gskip = 0); + iter_info->order = order; + iter_info->stop = 3; + iter_info->ncalled = 0; + iter_info->curr = order != H5_ITER_DEC ? 0 : (max_links - 1); + HDmemset(iter_info->visited, 0, sizeof(hbool_t) * iter_info->max_visit); + if((ret = H5Giterate(group_id, ".", &gskip, group_iterate_deprec_cb, iter_info)) < 0) TEST_ERROR + if(ret != CORDER_ITER_STOP) TEST_ERROR + if(iter_info->ncalled != 3) TEST_ERROR + + /* Check for iteration routine indicating failure */ + skip = 0; + H5E_BEGIN_TRY { + ret = H5Literate1(group_id, idx_type, order, &skip, link_iterate_fail_deprec_cb, NULL); + } H5E_END_TRY; + if(ret >= 0) TEST_ERROR + + /* Success */ + return SUCCEED; + +error: + return FAIL; +} /* end link_iterate_check_deprec() */ + +/*------------------------------------------------------------------------- + * Function: link_iterate_deprec + * + * Purpose: Create a group with creation order indices and test iterating over + * links by index. + * + * Return: Success: 0 + * Failure: -1 + * + * Programmer: Quincey Koziol + * Tuesday, November 14, 2006 + * + *------------------------------------------------------------------------- + */ +static int +link_iterate_deprec(hid_t fapl) +{ + hid_t file_id = (-1); /* File ID */ + hid_t group_id = (-1); /* Group ID */ + hid_t gcpl_id = (-1); /* Group creation property list ID */ + H5_index_t idx_type; /* Type of index to operate on */ + H5_iter_order_t order; /* Order within in the index */ + unsigned use_index; /* Use index on creation order values */ + unsigned max_compact; /* Maximum # of links to store in group compactly */ + unsigned min_dense; /* Minimum # of links to store in group "densely" */ + char objname[NAME_BUF_SIZE]; /* Object name */ + char filename[NAME_BUF_SIZE];/* File name */ + link_iter_info_t iter_info; /* Iterator info */ + hbool_t *visited = NULL; /* Array of flags for visiting links */ + hsize_t skip; /* # of links to skip in group */ + unsigned u; /* Local index variable */ + herr_t ret; /* Generic return value */ + + /* Create group creation property list */ + if((gcpl_id = H5Pcreate(H5P_GROUP_CREATE)) < 0) TEST_ERROR + + /* Query the group creation properties */ + if(H5Pget_link_phase_change(gcpl_id, &max_compact, &min_dense) < 0) TEST_ERROR + + /* Allocate the "visited link" array */ + iter_info.max_visit = max_compact * 2; + if(NULL == (visited = (hbool_t *)HDmalloc(sizeof(hbool_t) * iter_info.max_visit))) TEST_ERROR + iter_info.visited = visited; + + /* Loop over operating on different indices on link fields */ + for(idx_type = H5_INDEX_NAME; idx_type <= H5_INDEX_CRT_ORDER; idx_type++) { + /* Loop over operating in different orders */ + for(order = H5_ITER_INC; order <=H5_ITER_NATIVE; order++) { + /* Loop over using index for creation order value */ + for(use_index = FALSE; use_index <= TRUE; use_index++) { + /* Print appropriate test message */ + if(idx_type == H5_INDEX_CRT_ORDER) { + if(order == H5_ITER_INC) { + if(use_index) + TESTING("iterating over links by creation order index in increasing order w/creation order index using deprecated routines") + else + TESTING("iterating over links by creation order index in increasing order w/o creation order index using deprecated routines") + } /* end if */ + else if(order == H5_ITER_DEC) { + if(use_index) + TESTING("iterating over links by creation order index in decreasing order w/creation order index using deprecated routines") + else + TESTING("iterating over links by creation order index in decreasing order w/o creation order index using deprecated routines") + } /* end else */ + else { + HDassert(order == H5_ITER_NATIVE); + if(use_index) + TESTING("iterating over links by creation order index in native order w/creation order index using deprecated routines") + else + TESTING("iterating over links by creation order index in native order w/o creation order index using deprecated routines") + } /* end else */ + } /* end if */ + else { + if(order == H5_ITER_INC) { + if(use_index) + TESTING("iterating over links by name index in increasing order w/creation order index using deprecated routines") + else + TESTING("iterating over links by name index in increasing order w/o creation order index using deprecated routines") + } /* end if */ + else if(order == H5_ITER_DEC) { + if(use_index) + TESTING("iterating over links by name index in decreasing order w/creation order index using deprecated routines") + else + TESTING("iterating over links by name index in decreasing order w/o creation order index using deprecated routines") + } /* end else */ + else { + HDassert(order == H5_ITER_NATIVE); + if(use_index) + TESTING("iterating over links by name index in native order w/creation order index using deprecated routines") + else + TESTING("iterating over links by name index in native order w/o creation order index using deprecated routines") + } /* end else */ + } /* end else */ + + /* Create file */ + h5_fixname(FILENAME[0], fapl, filename, sizeof filename); + if((file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR + + /* Set creation order tracking & indexing on group */ + if(H5Pset_link_creation_order(gcpl_id, (H5P_CRT_ORDER_TRACKED | (use_index ? H5P_CRT_ORDER_INDEXED : (unsigned)0))) < 0) TEST_ERROR + + /* Create group with creation order tracking on */ + if((group_id = H5Gcreate2(file_id, CORDER_GROUP_NAME, H5P_DEFAULT, gcpl_id, H5P_DEFAULT)) < 0) TEST_ERROR + + /* Check for iteration on empty group */ + /* (should be OK) */ + if(H5Literate1(group_id, idx_type, order, NULL, link_iterate_deprec_cb, NULL) < 0) TEST_ERROR + + /* Create several links, up to limit of compact form */ + for(u = 0; u < max_compact; u++) { + hid_t group_id2; /* Group ID */ + + /* Make name for link */ + HDsnprintf(objname, sizeof(objname), "filler %02u", u); + + /* Create hard link, with group object */ + if((group_id2 = H5Gcreate2(group_id, objname, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR + if(H5Gclose(group_id2) < 0) TEST_ERROR + } /* end for */ + + /* Verify state of group (compact) */ + if(H5G__has_links_test(group_id, NULL) != TRUE) TEST_ERROR + + /* Check for out of bound iteration on compact group */ + skip = (hsize_t)u; + H5E_BEGIN_TRY { + ret = H5Literate1(group_id, idx_type, order, &skip, link_iterate_deprec_cb, NULL); + } H5E_END_TRY; + if(ret >= 0) TEST_ERROR + + /* Test iteration over links in compact group */ + if(link_iterate_check_deprec(group_id, idx_type, order, u, &iter_info) < 0) TEST_ERROR + + /* Create more links, to push group into dense form */ + for(; u < (max_compact * 2); u++) { + hid_t group_id2; /* Group ID */ + + /* Make name for link */ + HDsnprintf(objname, sizeof(objname), "filler %02u", u); + + /* Create hard link, with group object */ + if((group_id2 = H5Gcreate2(group_id, objname, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR + if(H5Gclose(group_id2) < 0) TEST_ERROR + } /* end for */ + + /* Verify state of group (dense) */ + if(H5G__is_new_dense_test(group_id) != TRUE) TEST_ERROR + + /* Check for out of bound iteration on dense group */ + skip = (hsize_t)u; + H5E_BEGIN_TRY { + ret = H5Literate1(group_id, idx_type, order, &skip, link_iterate_deprec_cb, NULL); + } H5E_END_TRY; + if(ret >= 0) TEST_ERROR + + /* Test iteration over links in dense group */ + if(link_iterate_check_deprec(group_id, idx_type, order, u, &iter_info) < 0) TEST_ERROR + + + /* Close the group */ + if(H5Gclose(group_id) < 0) TEST_ERROR + + /* Close the file */ + if(H5Fclose(file_id) < 0) TEST_ERROR + + PASSED(); + } /* end for */ + } /* end for */ + } /* end for */ + + /* Close the group creation property list */ + if(H5Pclose(gcpl_id) < 0) TEST_ERROR + + /* Free resources */ + if(visited) + HDfree(visited); + + return SUCCEED; + +error: + /* Free resources */ + H5E_BEGIN_TRY { + H5Pclose(gcpl_id); + H5Gclose(group_id); + H5Fclose(file_id); + } H5E_END_TRY; + + if(visited) + HDfree(visited); + + return FAIL; +} /* end link_iterate_deprec() */ + +/*------------------------------------------------------------------------- + * Function: link_iterate_old_deprec_cb + * + * Purpose: Callback routine for iterating over [old] links in group + * + * Return: Success: 0 + * Failure: -1 + *------------------------------------------------------------------------- + */ +static int +link_iterate_old_deprec_cb(hid_t group_id, const char *link_name, const H5L_info1_t *info, void *_op_data) +{ + link_iter_info_t *op_data = (link_iter_info_t *)_op_data; /* User data */ + char objname[NAME_BUF_SIZE]; /* Object name */ + H5L_info1_t my_info; /* Local link info */ + + /* Increment # of times the callback was called */ + op_data->ncalled++; + + /* Get the link information directly to compare */ + if(H5Lget_info1(group_id, link_name, &my_info, H5P_DEFAULT) < 0) + return H5_ITER_ERROR; + + /* Check more things for link iteration (vs. group iteration) */ + if(info) { + /* Compare link info structs */ + if(info->type != my_info.type) + return H5_ITER_ERROR; + if(info->corder_valid != my_info.corder_valid) + return H5_ITER_ERROR; + if(info->corder != my_info.corder) + return H5_ITER_ERROR; + if(info->cset != my_info.cset) + return H5_ITER_ERROR; + if(H5F_addr_ne(info->u.address, my_info.u.address)) + return H5_ITER_ERROR; + } /* end if */ + + /* Verify name of link */ + HDsnprintf(objname, sizeof(objname), "filler %02u", (info ? (unsigned)op_data->curr : (unsigned)((op_data->ncalled - 1) + op_data->nskipped))); + if(HDstrcmp(link_name, objname)) + return H5_ITER_ERROR; + + /* Check if we've visited this link before */ + if((size_t)op_data->curr >= op_data->max_visit) + return H5_ITER_ERROR; + if(op_data->visited[op_data->curr]) + return H5_ITER_ERROR; + op_data->visited[op_data->curr] = TRUE; + + /* Advance to next value, in correct direction */ + if(op_data->order != H5_ITER_DEC) + op_data->curr++; + else + op_data->curr--; + + /* Check for stopping in the middle of iterating */ + if(op_data->stop > 0) + if(--op_data->stop == 0) + return CORDER_ITER_STOP; + + return H5_ITER_CONT; +} /* end link_iterate_old_deprec_cb() */ + +/*------------------------------------------------------------------------- + * Function: group_iterate_old_deprec_cb + * + * Purpose: Callback routine for iterating over links in group with + * H5Giterate() + * + * Return: Success: 0 + * Failure: -1 + *------------------------------------------------------------------------- + */ +static int +group_iterate_old_deprec_cb(hid_t group_id, const char *link_name, void *_op_data) +{ + return link_iterate_old_deprec_cb(group_id, link_name, NULL, _op_data); +} /* end group_iterate_old_deprec_cb() */ + +/*------------------------------------------------------------------------- + * Function: link_iterate_old_check_deprec + * + * Purpose: Check iteration over [old] links in a group + * + * Return: Success: 0 + * Failure: -1 + *------------------------------------------------------------------------- + */ +static int +link_iterate_old_check_deprec(hid_t group_id, H5_iter_order_t order, unsigned max_links, link_iter_info_t *iter_info) +{ + unsigned v; /* Local index variable */ + hsize_t skip; /* # of links to skip in group */ + int gskip; /* # of links to skip in group, with H5Giterate */ + herr_t ret; /* Generic return value */ + + /* Iterate over links in group */ + iter_info->nskipped = (unsigned)(skip = 0); + iter_info->order = order; + iter_info->stop = -1; + iter_info->ncalled = 0; + iter_info->curr = order != H5_ITER_DEC ? 0 : (max_links - 1); + HDmemset(iter_info->visited, 0, sizeof(hbool_t) * iter_info->max_visit); + if(H5Literate1(group_id, H5_INDEX_NAME, order, &skip, link_iterate_old_deprec_cb, iter_info) < 0) TEST_ERROR + + /* Verify that we visited all the links */ + if(skip != max_links) TEST_ERROR + for(v = 0; v < max_links; v++) + if(iter_info->visited[v] == FALSE) TEST_ERROR + + /* Iterate over links in group, with H5Giterate */ + iter_info->nskipped = (unsigned)(gskip = 0); + iter_info->order = order; + iter_info->stop = -1; + iter_info->ncalled = 0; + iter_info->curr = order != H5_ITER_DEC ? 0 : (max_links - 1); + HDmemset(iter_info->visited, 0, sizeof(hbool_t) * iter_info->max_visit); + if(H5Giterate(group_id, ".", &gskip, group_iterate_old_deprec_cb, iter_info) < 0) TEST_ERROR + + /* Verify that we visited all the links */ + if(gskip != (int)max_links) TEST_ERROR + for(v = 0; v < max_links; v++) + if(iter_info->visited[v] == FALSE) TEST_ERROR + + /* Skip over some links in group */ + iter_info->nskipped = (unsigned)(skip = max_links / 2); + iter_info->order = order; + iter_info->stop = -1; + iter_info->ncalled = 0; + iter_info->curr = (int64_t)(order != H5_ITER_DEC ? skip : ((max_links - 1) - skip)); + HDmemset(iter_info->visited, 0, sizeof(hbool_t) * iter_info->max_visit); + if(H5Literate1(group_id, H5_INDEX_NAME, order, &skip, link_iterate_old_deprec_cb, iter_info) < 0) TEST_ERROR + + /* Verify that we visited all the links */ + if(skip != max_links) TEST_ERROR + if(order == H5_ITER_INC) { + for(v = 0; v < (max_links / 2); v++) + if(iter_info->visited[v + (max_links / 2)] == FALSE) TEST_ERROR + } /* end if */ + else if(order == H5_ITER_DEC) { + for(v = 0; v < (max_links / 2); v++) + if(iter_info->visited[v] == FALSE) TEST_ERROR + } /* end if */ + else { + unsigned nvisit = 0; /* # of links visited */ + + HDassert(order == H5_ITER_NATIVE); + for(v = 0; v < max_links; v++) + if(iter_info->visited[v] == TRUE) + nvisit++; + + if(nvisit != (max_links / 2)) TEST_ERROR + } /* end else */ + + /* Skip over some links in group, with H5Giterate */ + iter_info->nskipped = (unsigned)(gskip = (int)(max_links / 2)); + iter_info->order = order; + iter_info->stop = -1; + iter_info->ncalled = 0; + iter_info->curr = order != H5_ITER_DEC ? (unsigned)gskip : ((max_links - 1) - (unsigned)gskip); + HDmemset(iter_info->visited, 0, sizeof(hbool_t) * iter_info->max_visit); + if(H5Giterate(group_id, ".", &gskip, group_iterate_old_deprec_cb, iter_info) < 0) TEST_ERROR + + /* Verify that we visited all the links */ + if(gskip != (int)max_links) TEST_ERROR + if(order == H5_ITER_INC) { + for(v = 0; v < (max_links / 2); v++) + if(iter_info->visited[v + (max_links / 2)] == FALSE) TEST_ERROR + } /* end if */ + else if(order == H5_ITER_DEC) { + for(v = 0; v < (max_links / 2); v++) + if(iter_info->visited[v] == FALSE) TEST_ERROR + } /* end if */ + else { + unsigned nvisit = 0; /* # of links visited */ + + HDassert(order == H5_ITER_NATIVE); + for(v = 0; v < max_links; v++) + if(iter_info->visited[v] == TRUE) + nvisit++; + + if(nvisit != (max_links / 2)) TEST_ERROR + } /* end else */ + + /* Iterate over links in group, stopping in the middle */ + iter_info->nskipped = (unsigned)(skip = 0); + iter_info->order = order; + iter_info->stop = 3; + iter_info->ncalled = 0; + iter_info->curr = order != H5_ITER_DEC ? 0 : (max_links - 1); + HDmemset(iter_info->visited, 0, sizeof(hbool_t) * iter_info->max_visit); + if((ret = H5Literate1(group_id, H5_INDEX_NAME, order, &skip, link_iterate_old_deprec_cb, iter_info)) < 0) TEST_ERROR + if(ret != CORDER_ITER_STOP) TEST_ERROR + if(iter_info->ncalled != 3) TEST_ERROR + + /* Iterate over links in group, stopping in the middle, with H5Giterate() */ + iter_info->nskipped = (unsigned)(gskip = 0); + iter_info->order = order; + iter_info->stop = 3; + iter_info->ncalled = 0; + iter_info->curr = order != H5_ITER_DEC ? 0 : (max_links - 1); + HDmemset(iter_info->visited, 0, sizeof(hbool_t) * iter_info->max_visit); + if((ret = H5Giterate(group_id, ".", &gskip, group_iterate_old_deprec_cb, iter_info)) < 0) TEST_ERROR + if(ret != CORDER_ITER_STOP) TEST_ERROR + if(iter_info->ncalled != 3) TEST_ERROR + + /* Check for iteration routine indicating failure */ + skip = 0; + H5E_BEGIN_TRY { + ret = H5Literate1(group_id, H5_INDEX_NAME, order, &skip, link_iterate_fail_deprec_cb, NULL); + } H5E_END_TRY; + if(ret >= 0) TEST_ERROR + + /* Check for iteration w/bad location ID */ + skip = 0; + H5E_BEGIN_TRY { + ret = H5Literate1((hid_t)(-1), H5_INDEX_NAME, order, &skip, link_iterate_fail_deprec_cb, NULL); + } H5E_END_TRY; + if(ret >= 0) TEST_ERROR -error: H5E_BEGIN_TRY { - H5Pclose(fcpl_id); - H5Pclose(lcpl_id); - H5Pclose(lcpl2_id); - H5Gclose(group_id); - H5Fclose(file_id); + ret = H5Giterate((hid_t)(-1), ".", &gskip, group_iterate_old_deprec_cb, iter_info); } H5E_END_TRY; - return 1; -} /* end test_move_preserves() */ + if(ret >= 0) TEST_ERROR + + /* Success */ + return SUCCEED; +error: + return FAIL; +} /* end link_iterate_old_check_deprec() */ /*------------------------------------------------------------------------- - * Function: test_deprec + * Function: link_iterate_old_deprec * - * Purpose: Tests deprecated functions for backward compatibility. + * Purpose: Create a "old-style" group and test iterating over links by index. * * Return: Success: 0 - * Failure: number of errors + * Failure: -1 *------------------------------------------------------------------------- */ -#ifndef H5_NO_DEPRECATED_SYMBOLS static int -test_deprec(hid_t fapl, hbool_t new_format) +link_iterate_old_deprec(hid_t fapl) { - hid_t file_id = -1; - hid_t group1_id = -1; - hid_t group2_id = -1; - H5G_stat_t sb_hard1, sb_hard2, sb_soft1, sb_soft2; - H5G_obj_t obj_type; /* Object type */ - hsize_t num_objs; /* Number of objects in a group */ - char filename[1024]; - char tmpstr[1024]; - - if(new_format) - TESTING("backwards compatibility (w/new group format)") - else - TESTING("backwards compatibility") - - /* Create file */ - h5_fixname(FILENAME[0], fapl, filename, sizeof filename); - - if((file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR - - /* Create two groups in the file */ - if((group1_id = H5Gcreate2(file_id, "group1", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR - if((group2_id = H5Gcreate2(file_id, "group2", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR - - /* Test H5Gset and get comment */ - if(H5Gset_comment(file_id, "group1", "comment") < 0) FAIL_STACK_ERROR - if(H5Gget_comment(file_id, "group1", sizeof(tmpstr), tmpstr) < 0) FAIL_STACK_ERROR - if(HDstrcmp(tmpstr, "comment")) TEST_ERROR - - /* Create links using H5Glink and H5Glink2 */ - if(H5Glink(file_id, H5G_LINK_HARD, "group2", "group1/link_to_group2") < 0) FAIL_STACK_ERROR - if(H5Glink2(file_id, "group1", H5G_LINK_HARD, group2_id, "link_to_group1") < 0) FAIL_STACK_ERROR - if(H5Glink2(file_id, "link_to_group1", H5G_LINK_SOFT, H5G_SAME_LOC, "group2/soft_link_to_group1") < 0) FAIL_STACK_ERROR - if(H5Glink2(file_id, "dangle", H5G_LINK_SOFT, H5G_SAME_LOC, "group2/dangle_soft_link") < 0) FAIL_STACK_ERROR - - /* Test getting the names for objects */ - if(H5Gget_objname_by_idx(group1_id, (hsize_t)0, tmpstr, sizeof(tmpstr)) < 0) FAIL_STACK_ERROR - if(HDstrcmp(tmpstr, "link_to_group2")) TEST_ERROR - H5E_BEGIN_TRY { - if(H5Gget_objname_by_idx(group1_id, (hsize_t)1, tmpstr, sizeof(tmpstr)) >= 0) TEST_ERROR - } H5E_END_TRY; - - /* Test getting the type for objects */ - if((obj_type = H5Gget_objtype_by_idx(group1_id, (hsize_t)0)) < 0) FAIL_STACK_ERROR - if(obj_type != H5G_GROUP) TEST_ERROR - H5E_BEGIN_TRY { - if(H5Gget_objtype_by_idx(group1_id, (hsize_t)1) >= 0) TEST_ERROR - } H5E_END_TRY; - - /* Test getting the number of objects in a group */ - if(H5Gget_num_objs(file_id, &num_objs) < 0) FAIL_STACK_ERROR - if(num_objs != 2) TEST_ERROR - if(H5Gget_num_objs(group1_id, &num_objs) < 0) FAIL_STACK_ERROR - if(num_objs != 1) TEST_ERROR - - /* Test that H5Glink created hard links properly */ - if(H5Gget_objinfo(file_id, "/group2", TRUE, &sb_hard1) < 0) FAIL_STACK_ERROR - if(H5Gget_objinfo(file_id, "/group1/link_to_group2", TRUE, &sb_hard2) < 0) FAIL_STACK_ERROR + hid_t file_id = -1; /* File ID */ + hid_t group_id = -1; /* Group ID */ + H5_iter_order_t order; /* Order within in the index */ + char objname[NAME_BUF_SIZE]; /* Object name */ + char filename[NAME_BUF_SIZE];/* File name */ + link_iter_info_t iter_info; /* Iterator info */ + hbool_t *visited = NULL; /* Array of flags for visiting links */ + hsize_t skip; /* # of links to skip in group */ + unsigned u; /* Local index variable */ + herr_t ret; /* Generic return value */ - if(HDmemcmp(&sb_hard1.objno, sb_hard2.objno, sizeof(sb_hard1.objno))) { - H5_FAILED(); - HDputs(" Hard link test failed. Link seems not to point to the "); - HDputs(" expected file location."); - TEST_ERROR - } /* end if */ + /* Allocate the "visited link" array */ + iter_info.max_visit = CORDER_NLINKS; + if(NULL == (visited = (hbool_t *)HDmalloc(sizeof(hbool_t) * iter_info.max_visit))) TEST_ERROR + iter_info.visited = visited; - /* Test for the other hard link created */ - if(H5Gget_objinfo(file_id, "/group1", TRUE, &sb_hard1) < 0) FAIL_STACK_ERROR - if(H5Gget_objinfo(file_id, "/group2/link_to_group1", TRUE, &sb_hard2) < 0) FAIL_STACK_ERROR + /* Loop over operating in different orders */ + for(order = H5_ITER_INC; order <=H5_ITER_NATIVE; order++) { + /* Print appropriate test message */ + if(order == H5_ITER_INC) { + TESTING("iterating over links by name index in increasing order in old-style group using deprecated routines") + } /* end if */ + else if(order == H5_ITER_DEC) { + TESTING("iterating over links by name index in decreasing order in old-style group using deprecated routines") + } /* end else */ + else { + HDassert(order == H5_ITER_NATIVE); + TESTING("iterating over links by name index in native order in old-style group using deprecated routines") + } /* end else */ - if(HDmemcmp(&sb_hard1.objno, sb_hard2.objno, sizeof(sb_hard1.objno))) { - H5_FAILED(); - HDputs(" Hard link test failed. Link seems not to point to the "); - HDputs(" expected file location."); - TEST_ERROR - } /* end if */ + /* Create file */ + h5_fixname(FILENAME[0], fapl, filename, sizeof filename); + if((file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR - /* Test the soft link */ - if(H5Gget_objinfo(file_id, "/group2/soft_link_to_group1", FALSE, &sb_soft1) < 0) FAIL_STACK_ERROR - if(sb_soft1.type != H5G_LINK) TEST_ERROR - if(sb_soft1.linklen != HDstrlen("link_to_group1") + 1) TEST_ERROR + /* Create group with creation order tracking on */ + if((group_id = H5Gcreate2(file_id, CORDER_GROUP_NAME, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR - if(H5Gget_linkval(group2_id, "soft_link_to_group1", sb_soft1.linklen, tmpstr) < 0) FAIL_STACK_ERROR - if(HDstrcmp("link_to_group1", tmpstr)) TEST_ERROR + /* Check for iteration on empty group */ + /* (should be OK) */ + if(H5Literate1(group_id, H5_INDEX_NAME, order, NULL, link_iterate_old_deprec_cb, NULL) < 0) TEST_ERROR - /* Test non-existing links with H5Gget_objinfo */ - H5E_BEGIN_TRY { - if(H5Gget_objinfo(file_id, "/group2/soft_link_no_exist", TRUE, NULL) >= 0) FAIL_STACK_ERROR - } H5E_END_TRY; + /* Create several links */ + for(u = 0; u < CORDER_NLINKS; u++) { + hid_t group_id2; /* Group ID */ - /* Test the dangling soft link */ - if(H5Gget_objinfo(file_id, "/group2/dangle_soft_link", FALSE, &sb_soft2) < 0) FAIL_STACK_ERROR - if(sb_soft2.type != H5G_LINK) TEST_ERROR - if(sb_soft2.linklen != HDstrlen("dangle") + 1) TEST_ERROR + /* Make name for link */ + HDsnprintf(objname, sizeof(objname), "filler %02u", u); - if(H5Gget_linkval(group2_id, "dangle_soft_link", sb_soft2.linklen, tmpstr) < 0) FAIL_STACK_ERROR - if(HDstrcmp("dangle", tmpstr)) TEST_ERROR + /* Create hard link, with group object */ + if((group_id2 = H5Gcreate2(group_id, objname, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR + if(H5Gclose(group_id2) < 0) TEST_ERROR + } /* end for */ + /* Verify state of group (symbol table) */ + if(H5G__has_stab_test(group_id) != TRUE) TEST_ERROR - /* Test H5Gmove and H5Gmove2 */ - if(H5Gmove(file_id, "group1", "moved_group1") < 0) FAIL_STACK_ERROR - if(H5Gmove2(file_id, "group2", group1_id, "moved_group2") < 0) FAIL_STACK_ERROR + /* Check for out of bound iteration on old-style group */ + skip = (hsize_t)u; + H5E_BEGIN_TRY { + ret = H5Literate1(group_id, H5_INDEX_NAME, order, &skip, link_iterate_old_deprec_cb, NULL); + } H5E_END_TRY; + if(ret >= 0) TEST_ERROR - /* Ensure that both groups can be opened */ - if(H5Gclose(group2_id) < 0) FAIL_STACK_ERROR - if(H5Gclose(group1_id) < 0) FAIL_STACK_ERROR + /* Check for iteration on creation order */ + /* (should fail) */ + skip = (hsize_t)0; + H5E_BEGIN_TRY { + ret = H5Literate1(group_id, H5_INDEX_CRT_ORDER, order, &skip, link_iterate_old_deprec_cb, NULL); + } H5E_END_TRY; + if(ret >= 0) TEST_ERROR - if((group1_id = H5Gopen2(file_id, "moved_group1", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR - if((group2_id = H5Gopen2(file_id, "moved_group1/moved_group2", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR + /* Test iteration over links in group */ + if(link_iterate_old_check_deprec(group_id, order, u, &iter_info) < 0) TEST_ERROR - /* Close open IDs */ - if(H5Gclose(group2_id) < 0) FAIL_STACK_ERROR - if(H5Gclose(group1_id) < 0) FAIL_STACK_ERROR + /* Close the group */ + if(H5Gclose(group_id) < 0) TEST_ERROR - /* Test H5Gunlink */ - if(H5Gunlink(file_id, "moved_group1/moved_group2") < 0) FAIL_STACK_ERROR + /* Close the file */ + if(H5Fclose(file_id) < 0) TEST_ERROR - H5E_BEGIN_TRY { - if(H5Gopen2(file_id, "moved_group1/moved_group2", H5P_DEFAULT) >=0) TEST_ERROR - } H5E_END_TRY; + PASSED(); + } /* end for */ - if(H5Fclose(file_id) < 0) FAIL_STACK_ERROR + /* Free resources */ + if(visited) + HDfree(visited); - PASSED(); return SUCCEED; error: + /* Free resources */ H5E_BEGIN_TRY { - H5Gclose(group2_id); - H5Gclose(group1_id); + H5Gclose(group_id); H5Fclose(file_id); } H5E_END_TRY; - return 1; -} /* end test_deprec() */ + + if(visited) + HDfree(visited); + + return FAIL; +} /* end link_iterate_old_deprec() */ #endif /* H5_NO_DEPRECATED_SYMBOLS */ @@ -1642,7 +5666,7 @@ external_link_root(hid_t fapl, hbool_t new_format) { hid_t fid = -1; /* File ID */ hid_t gid = -1, gid2 = -1; /* Group IDs */ - H5L_info_t linfo; /* Link information */ + H5L_info2_t linfo; /* Link information */ char objname[NAME_BUF_SIZE]; /* Object name */ char filename1[NAME_BUF_SIZE]; char filename2[NAME_BUF_SIZE]; @@ -1674,7 +5698,7 @@ external_link_root(hid_t fapl, hbool_t new_format) if(H5Lcreate_external(filename1, "/", fid, "ext_link", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR /* Check information for external link */ - if(H5Lget_info(fid, "ext_link", &linfo, H5P_DEFAULT) < 0) goto error; + if(H5Lget_info2(fid, "ext_link", &linfo, H5P_DEFAULT) < 0) goto error; if(H5L_TYPE_EXTERNAL != linfo.type) { H5_FAILED(); HDputs(" Unexpected object type - should have been an external link"); @@ -1698,7 +5722,7 @@ external_link_root(hid_t fapl, hbool_t new_format) if(H5Lcreate_external(filename1, "///", fid, "ext_link2", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR /* Check information for external link */ - if(H5Lget_info(fid, "ext_link", &linfo, H5P_DEFAULT) < 0) goto error; + if(H5Lget_info2(fid, "ext_link", &linfo, H5P_DEFAULT) < 0) goto error; if(H5L_TYPE_EXTERNAL != linfo.type) { H5_FAILED(); HDputs(" Unexpected object type - should have been an external link"); @@ -5013,15 +9037,15 @@ error: static int external_link_query(hid_t fapl, hbool_t new_format) { - hid_t fid = -1; /* File ID */ - hid_t gid = -1; /* Group IDs */ - const char *file_name; /* Name of the file the external link points to */ - const char *object_name; /* Name of the object the external link points to */ - H5O_info_t oi; /* Object information */ - H5L_info_t li; /* Link information */ - char filename1[NAME_BUF_SIZE], - filename2[NAME_BUF_SIZE], /* Names of files to externally link across */ - query_buf[NAME_BUF_SIZE]; /* Buffer to hold query result */ + hid_t fid = -1; /* File ID */ + hid_t gid = -1; /* Group IDs */ + const char *file_name; /* Name of the file the external link points to */ + const char *object_name; /* Name of the object the external link points to */ + H5O_info2_t oi; /* Object information */ + H5L_info2_t li; /* Link information */ + char filename1[NAME_BUF_SIZE], + filename2[NAME_BUF_SIZE], /* Names of files to externally link across */ + query_buf[NAME_BUF_SIZE]; /* Buffer to hold query result */ if(new_format) TESTING("query aspects of external link (w/new group format)") @@ -5040,7 +9064,7 @@ external_link_query(hid_t fapl, hbool_t new_format) if(H5Lcreate_external(filename2, "///dst//", fid, "src", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR /* Get size of buffer for external link */ - if(H5Lget_info(fid, "src", &li, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Lget_info2(fid, "src", &li, H5P_DEFAULT) < 0) TEST_ERROR if(li.u.val_size != (1 + (HDstrlen(filename2) + 1) + (HDstrlen("/dst") + 1))) TEST_ERROR if (H5L_TYPE_EXTERNAL != li.type) { H5_FAILED(); @@ -5065,7 +9089,7 @@ external_link_query(hid_t fapl, hbool_t new_format) if((fid = H5Fopen(filename1, H5F_ACC_RDONLY, fapl)) < 0) TEST_ERROR /* Get size of buffer for external link */ - if(H5Lget_info(fid, "src", &li, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Lget_info2(fid, "src", &li, H5P_DEFAULT) < 0) TEST_ERROR if(li.u.val_size != (1 + (HDstrlen(filename2) + 1) + (HDstrlen("/dst") + 1))) TEST_ERROR if(H5L_TYPE_EXTERNAL != li.type) { H5_FAILED(); @@ -5084,7 +9108,7 @@ external_link_query(hid_t fapl, hbool_t new_format) if(HDstrcmp(object_name, "/dst")) TEST_ERROR /* Query information about object that external link points to */ - if(H5Oget_info_by_name2(fid, "src", &oi, H5O_INFO_BASIC, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + if(H5Oget_info_by_name3(fid, "src", &oi, H5O_INFO_BASIC, H5P_DEFAULT) < 0) FAIL_STACK_ERROR if(H5O_TYPE_GROUP != oi.type) { H5_FAILED(); HDputs(" Unexpected object type - should have been a group"); @@ -5729,8 +9753,8 @@ external_link_closing(hid_t fapl, hbool_t new_format) filename3[NAME_BUF_SIZE], filename4[NAME_BUF_SIZE], /* Names of files to externally link across */ buf[NAME_BUF_SIZE]; /* misc. buffer */ - H5L_info_t li; - H5O_info_t oi; + H5L_info2_t li; + H5O_info2_t oi; hobj_ref_t obj_ref; if(new_format) @@ -5786,10 +9810,10 @@ external_link_closing(hid_t fapl, hbool_t new_format) if(H5Dclose(did) < 0) TEST_ERROR /* Test that getting info works */ - if(H5Lget_info(fid1, "elink/elink/elink/type1", &li, H5P_DEFAULT) < 0) TEST_ERROR - if(H5Lget_info(fid1, "elink/elink/elink", &li, H5P_DEFAULT) < 0) TEST_ERROR - if(H5Oget_info_by_name2(fid1, "elink/elink/elink/type1", &oi, H5O_INFO_BASIC, H5P_DEFAULT) < 0) TEST_ERROR - if(H5Oget_info_by_name2(fid1, "elink/elink/elink", &oi, H5O_INFO_BASIC, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Lget_info2(fid1, "elink/elink/elink/type1", &li, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Lget_info2(fid1, "elink/elink/elink", &li, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Oget_info_by_name3(fid1, "elink/elink/elink/type1", &oi, H5O_INFO_BASIC, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Oget_info_by_name3(fid1, "elink/elink/elink", &oi, H5O_INFO_BASIC, H5P_DEFAULT) < 0) TEST_ERROR /* Test move */ if(H5Lmove(fid1, "elink/elink/elink/group1", fid1, @@ -5876,7 +9900,7 @@ external_link_closing(hid_t fapl, hbool_t new_format) if(H5Gclose(gid) < 0) TEST_ERROR if((gid = H5Gcreate2(fid1, "elink/elink2/group2/group3/group4", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR if(H5Gclose(gid) < 0) TEST_ERROR - if(H5Oget_info_by_name2(fid1, "elink/elink2/group2/group3/group4", &oi, H5O_INFO_BASIC, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Oget_info_by_name3(fid1, "elink/elink2/group2/group3/group4", &oi, H5O_INFO_BASIC, H5P_DEFAULT) < 0) TEST_ERROR /* Add a few regular groups and a soft link in file2 using intermediate group creation */ if((lcpl_id = H5Pcreate(H5P_LINK_CREATE)) < 0) TEST_ERROR @@ -5890,13 +9914,13 @@ external_link_closing(hid_t fapl, hbool_t new_format) */ if((gid = H5Gcreate2(fid1, "elink/file2group1/file2group2/slink/group3", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR if(H5Gclose(gid) < 0) TEST_ERROR - if(H5Lget_info(fid1, "elink/file2group1/file2group2/slink/group3", &li, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Lget_info2(fid1, "elink/file2group1/file2group2/slink/group3", &li, H5P_DEFAULT) < 0) TEST_ERROR /* Some simpler tests */ if((gid = H5Gcreate2(fid1, "elink/file2group3", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR if(H5Gclose(gid) < 0) TEST_ERROR - if(H5Lget_info(fid1, "elink/file2group3", &li, H5P_DEFAULT) < 0) TEST_ERROR - if(H5Lget_info(fid1, "elink/elink", &li, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Lget_info2(fid1, "elink/file2group3", &li, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Lget_info2(fid1, "elink/elink", &li, H5P_DEFAULT) < 0) TEST_ERROR /* Close file1, the only file that should still be open */ @@ -7168,19 +11192,19 @@ static herr_t UD_hard_create(const char H5_ATTR_UNUSED * link_name, hid_t loc_group, const void *udata, size_t udata_size, hid_t H5_ATTR_UNUSED lcpl_id) { - haddr_t addr; + H5O_token_t token; hid_t target_obj = -1; herr_t ret_value = 0; - if(udata_size != sizeof(haddr_t)) { + if(udata_size != sizeof(H5O_token_t)) { ret_value = -1; goto done; } /* end if */ - addr = *((const haddr_t *)udata); + token = *(const H5O_token_t *)udata; /* Open the object this link points to */ - target_obj = H5Oopen_by_addr(loc_group, addr); + target_obj = H5Oopen_by_token(loc_group, token); if(target_obj < 0) { ret_value = -1; goto done; @@ -7242,15 +11266,16 @@ UD_hard_traverse(const char H5_ATTR_UNUSED *link_name, hid_t cur_group, const void *udata, size_t udata_size, hid_t H5_ATTR_UNUSED lapl_id, hid_t H5_ATTR_UNUSED dxpl_id) { - haddr_t addr; + H5O_token_t token; hid_t ret_value = -1; - if(udata_size != sizeof(haddr_t)) + if(udata_size != sizeof(H5O_token_t)) return FAIL; - addr = *((const haddr_t *) udata); + token = *(const H5O_token_t *)udata; - ret_value = H5Oopen_by_addr(cur_group, addr); /* If this fails, our return value will be negative. */ + /* If this fails, our return value will be negative. */ + ret_value = H5Oopen_by_token(cur_group, token); return ret_value; } /* end UD_hard_traverse() */ @@ -7260,19 +11285,19 @@ static herr_t UD_hard_delete(const char H5_ATTR_UNUSED * link_name, hid_t file, const void *udata, size_t udata_size) { - haddr_t addr; + H5O_token_t token; hid_t target_obj = -1; herr_t ret_value = 0; - if(udata_size != sizeof(haddr_t)) { + if(udata_size != sizeof(H5O_token_t)) { ret_value = -1; goto done; } /* end if */ - addr = *((const haddr_t *) udata); + token = *(const H5O_token_t *)udata; /* Open the object this link points to */ - target_obj = H5Oopen_by_addr(file, addr); + target_obj = H5Oopen_by_token(file, token); if(target_obj < 0) { ret_value = -1; goto done; @@ -7328,24 +11353,12 @@ done: return ret_value; } /* end UD_hard_delete() */ -const H5L_class_t UD_hard_class[1] = {{ - H5L_LINK_CLASS_T_VERS, /* H5L_class_t version */ - (H5L_type_t)UD_HARD_TYPE, /* Link type id number */ - "UD_hard_link", /* Link class name for debugging */ - UD_hard_create, /* Creation callback */ - NULL, /* Move/rename callback */ - NULL, /* Copy callback */ - UD_hard_traverse, /* The actual traversal function */ - UD_hard_delete, /* Deletion callback */ - NULL /* Query callback */ -}}; - static int ud_hard_links(hid_t fapl) { hid_t fid = -1; /* File ID */ hid_t gid = -1, gid2 = -1; /* Group IDs */ - H5L_info_t li; /* Link information */ + H5L_info2_t li; /* Link information */ char objname[NAME_BUF_SIZE]; /* Object name */ h5_stat_size_t empty_size; /* Size of an empty file */ char filename[NAME_BUF_SIZE]; @@ -7378,13 +11391,13 @@ ud_hard_links(hid_t fapl) if((gid = H5Gcreate2(fid, "group", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR /* Get address for the group to give to the hard link */ - if(H5Lget_info(fid, "group", &li, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Lget_info2(fid, "group", &li, H5P_DEFAULT) < 0) TEST_ERROR if(H5Gclose(gid) < 0) TEST_ERROR /* Create a user-defined "hard link" to the group using the address we got - * from H5Lget_info */ - if(H5Lcreate_ud(fid, "ud_link", (H5L_type_t)UD_HARD_TYPE, &(li.u.address), (size_t)sizeof(haddr_t), H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR + * from H5Lget_info2 */ + if(H5Lcreate_ud(fid, "ud_link", (H5L_type_t)UD_HARD_TYPE, &(li.u.token), sizeof(H5O_token_t), H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR /* Close and re-open file to ensure that data is written to disk */ if(H5Fclose(fid) < 0) TEST_ERROR @@ -7415,7 +11428,7 @@ ud_hard_links(hid_t fapl) if(H5Gclose(gid) < 0) FAIL_STACK_ERROR /* Check that H5Lget_objinfo works on the hard link */ - if(H5Lget_info(fid, "ud_link", &li, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + if(H5Lget_info2(fid, "ud_link", &li, H5P_DEFAULT) < 0) FAIL_STACK_ERROR /* UD hard links have no query function, thus return a "link length" of 0 */ if(li.u.val_size != 0) TEST_ERROR if(UD_HARD_TYPE != li.type) { @@ -7484,30 +11497,16 @@ UD_rereg_traverse(const char H5_ATTR_UNUSED * link_name, hid_t cur_group, return ret_value; -error: - return FAIL; -} /* end UD_rereg_traverse() */ - -/* This link class has the same ID number as the UD hard links but - * has a very different traversal function */ -const H5L_class_t UD_rereg_class[1] = {{ - H5L_LINK_CLASS_T_VERS, /* H5L_class_t version */ - (H5L_type_t)UD_HARD_TYPE, /* Link type id number */ - "UD_reregistered_type", /* Link class name for debugging */ - NULL, /* Creation callback */ - NULL, /* Move/rename callback */ - NULL, /* Copy callback */ - UD_rereg_traverse, /* The actual traversal function */ - NULL, /* Deletion callback */ - NULL /* Query callback */ -}}; +error: + return FAIL; +} /* end UD_rereg_traverse() */ static int ud_link_reregister(hid_t fapl) { hid_t fid = -1; /* File ID */ hid_t gid = -1, gid2 = -1; /* Group IDs */ - H5L_info_t li; /* Link information */ + H5L_info2_t li; /* Link information */ char objname[NAME_BUF_SIZE]; /* Object name */ char filename[NAME_BUF_SIZE]; h5_stat_size_t empty_size; /* Size of an empty file */ @@ -7536,11 +11535,11 @@ ud_link_reregister(hid_t fapl) /* Point a UD defined hard link to a group in the same way as the previous test */ if((gid = H5Gcreate2(fid, "group", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR - if (H5Lget_info(fid, "group", &li, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Lget_info2(fid, "group", &li, H5P_DEFAULT) < 0) TEST_ERROR if(H5Gclose(gid) < 0) TEST_ERROR - if(H5Lcreate_ud(fid, "ud_link", (H5L_type_t)UD_HARD_TYPE, &(li.u.address), - sizeof(li.u.address), H5P_DEFAULT, H5P_DEFAULT) < 0) + if(H5Lcreate_ud(fid, "ud_link", (H5L_type_t)UD_HARD_TYPE, &(li.u.token), + sizeof(H5O_token_t), H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR /* Create a group named REREG_TARGET_NAME in the same group as the ud link */ @@ -7560,8 +11559,8 @@ ud_link_reregister(hid_t fapl) /* Verify that we can't create any new links of this type */ H5E_BEGIN_TRY { - if(H5Lcreate_ud(fid, "ud_link2", (H5L_type_t)UD_HARD_TYPE, &(li.u.address), - sizeof(li.u.address), H5P_DEFAULT, H5P_DEFAULT) >= 0) + if(H5Lcreate_ud(fid, "ud_link2", (H5L_type_t)UD_HARD_TYPE, &(li.u.token), + sizeof(H5O_token_t), H5P_DEFAULT, H5P_DEFAULT) >= 0) TEST_ERROR } H5E_END_TRY @@ -7643,7 +11642,7 @@ error: /*------------------------------------------------------------------------- - * Function: ud_callbacks + * Function: UD_cb_create * * Purpose: Check that all callbacks are called and are given the correct * information. @@ -7759,25 +11758,13 @@ error: return FAIL; } /* end UD_cb_query() */ -const H5L_class_t UD_cb_class[1] = {{ - H5L_LINK_CLASS_T_VERS, /* H5L_class_t version */ - (H5L_type_t)UD_CB_TYPE, /* Link type id number */ - NULL, /* NULL name (to make sure this doesn't break anything */ - UD_cb_create, /* Creation callback */ - UD_cb_move, /* Move/rename callback */ - UD_cb_move, /* Copy callback */ - UD_cb_traverse, /* The actual traversal function */ - UD_cb_delete, /* Deletion callback */ - UD_cb_query /* Query callback */ -}}; - static int ud_callbacks(hid_t fapl, hbool_t new_format) { hid_t fid = -1; /* File ID */ hid_t gid = -1; /* Group ID */ hid_t lcpl = -1; /* Link Creation PL */ - H5L_info_t li; /* Link information */ + H5L_info2_t li; /* Link information */ char ud_target_name[] = UD_CB_TARGET; /* Link target name */ char filename[NAME_BUF_SIZE]; char query_buf[NAME_BUF_SIZE]; @@ -7822,7 +11809,7 @@ ud_callbacks(hid_t fapl, hbool_t new_format) if(H5Gclose(gid) < 0) TEST_ERROR /* Query the link to test its query callback */ - if(H5Lget_info(fid, UD_CB_LINK_NAME, &li, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Lget_info2(fid, UD_CB_LINK_NAME, &li, H5P_DEFAULT) < 0) TEST_ERROR if(li.u.val_size != 16) TEST_ERROR if (UD_CB_TYPE != li.type) { H5_FAILED(); @@ -7854,7 +11841,7 @@ ud_callbacks(hid_t fapl, hbool_t new_format) if(H5Pclose(lcpl) < 0) FAIL_STACK_ERROR /* Check its character encoding */ - if(H5Lget_info(fid, UD_CB_LINK_NAME, &li, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + if(H5Lget_info2(fid, UD_CB_LINK_NAME, &li, H5P_DEFAULT) < 0) FAIL_STACK_ERROR if(li.cset != H5T_CSET_UTF8) TEST_ERROR /* Unregister the link class so the library forgets what its callbacks do */ @@ -7870,7 +11857,7 @@ ud_callbacks(hid_t fapl, hbool_t new_format) } H5E_END_TRY /* The query callback should NOT fail, but should be unable to give a linklen */ - if(H5Lget_info(fid, UD_CB_LINK_NAME, &li, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + if(H5Lget_info2(fid, UD_CB_LINK_NAME, &li, H5P_DEFAULT) < 0) FAIL_STACK_ERROR if(li.u.val_size != 0) TEST_ERROR if(li.type != UD_CB_TYPE) TEST_ERROR @@ -7924,18 +11911,6 @@ error: return FAIL; } /* end UD_plist_traverse() */ -const H5L_class_t UD_plist_class[1] = {{ - H5L_LINK_CLASS_T_VERS, /* H5L_class_t version */ - (H5L_type_t)UD_PLIST_TYPE, /* Link type id number */ - "UD_plist_link", /* Link class name for debugging */ - NULL, /* Creation callback */ - NULL, /* Move/rename callback */ - NULL, /* Copy callback */ - UD_plist_traverse, /* The actual traversal function */ - NULL, /* Deletion callback */ - NULL /* Query callback */ -}}; - static int lapl_udata(hid_t fapl, hbool_t new_format) { @@ -8231,12 +12206,12 @@ const H5L_class_t UD_error4_class[1] = {{ static int ud_link_errors(hid_t fapl, hbool_t new_format) { - hid_t fid = -1; /* File ID */ - hid_t gid = -1; /* Group IDs */ - char group_name[NAME_BUF_SIZE]; - char filename[NAME_BUF_SIZE]; - char query_buf[NAME_BUF_SIZE]; - H5L_info_t li; /* Link information */ + hid_t fid = -1; /* File ID */ + hid_t gid = -1; /* Group IDs */ + char group_name[NAME_BUF_SIZE]; + char filename[NAME_BUF_SIZE]; + char query_buf[NAME_BUF_SIZE]; + H5L_info2_t li; /* Link information */ if(new_format) TESTING("user-defined link error conditions (w/new group format)") @@ -8301,7 +12276,7 @@ ud_link_errors(hid_t fapl, hbool_t new_format) if(H5Ldelete(fid, "ud_link", H5P_DEFAULT) >= 0) TEST_ERROR /* The query callback will fail */ - if(H5Lget_info(fid, "ud_link", &li, H5P_DEFAULT) >=0) TEST_ERROR + if(H5Lget_info2(fid, "ud_link", &li, H5P_DEFAULT) >=0) TEST_ERROR } H5E_END_TRY /* Now use a class with different callback functions */ @@ -8314,7 +12289,7 @@ ud_link_errors(hid_t fapl, hbool_t new_format) if(H5Lcopy(fid, "ud_link", fid, "copy_succ", H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR /* The query callback will succeed when we only want to get the size of the buffer... */ - if(H5Lget_info(fid, "ud_link", &li, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + if(H5Lget_info2(fid, "ud_link", &li, H5P_DEFAULT) < 0) FAIL_STACK_ERROR if(li.u.val_size != 0) TEST_ERROR /* ...but fail when we try to write data to the buffer itself*/ H5E_BEGIN_TRY { @@ -8325,7 +12300,7 @@ ud_link_errors(hid_t fapl, hbool_t new_format) if(H5Lregister(UD_cbfail_class3) < 0) FAIL_STACK_ERROR /* Now querying should succeed */ - if(H5Lget_info(fid, "ud_link", &li, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + if(H5Lget_info2(fid, "ud_link", &li, H5P_DEFAULT) < 0) FAIL_STACK_ERROR if(li.u.val_size != 8) TEST_ERROR if(H5Lget_val(fid, "ud_link", query_buf, (size_t)NAME_BUF_SIZE, H5P_DEFAULT) < 0) FAIL_STACK_ERROR if(HDstrcmp(query_buf, "succeed") != 0) TEST_ERROR @@ -8491,9 +12466,9 @@ lapl_nlinks(hid_t fapl, hbool_t new_format) /* H5Ldelete */ if(H5Ldelete(fid, "soft17/soft_link", plist) < 0) TEST_ERROR - /* H5Lget_val and H5Lget_info */ + /* H5Lget_val and H5Lget_info2 */ if(H5Lget_val(fid, "soft17", NULL, (size_t)0, plist) < 0) TEST_ERROR - if(H5Lget_info(fid, "soft17", NULL, plist) < 0) TEST_ERROR + if(H5Lget_info2(fid, "soft17", NULL, plist) < 0) TEST_ERROR /* H5Lcreate_external and H5Lcreate_ud */ if(H5Lcreate_external("filename", "path", fid, "soft17/extlink", H5P_DEFAULT, plist) < 0) TEST_ERROR @@ -8592,12 +12567,12 @@ error: static int linkinfo(hid_t fapl, hbool_t new_format) { - hid_t fid = -1; /* File ID */ - hid_t gid = -1; /* Group ID */ - hid_t tid = -1; /* Type ID */ - hid_t sid = -1, did = -1; /* Dataspace and dataset IDs */ - H5L_info_t li; /* Link information */ - char filename[NAME_BUF_SIZE]; + hid_t fid = -1; /* File ID */ + hid_t gid = -1; /* Group ID */ + hid_t tid = -1; /* Type ID */ + hid_t sid = -1, did = -1; /* Dataspace and dataset IDs */ + H5L_info2_t li; /* Link information */ + char filename[NAME_BUF_SIZE]; if(new_format) TESTING("link type field in H5Lget_info (w/new group format)") @@ -8630,22 +12605,22 @@ linkinfo(hid_t fapl, hbool_t new_format) if(H5Dclose(did) < 0) TEST_ERROR /* Make sure that link type is correct when objects are queried */ - if(H5Lget_info(fid, "datatype", &li, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Lget_info2(fid, "datatype", &li, H5P_DEFAULT) < 0) TEST_ERROR if(li.type != H5L_TYPE_HARD) TEST_ERROR - if(H5Lget_info(fid, "group", &li, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Lget_info2(fid, "group", &li, H5P_DEFAULT) < 0) TEST_ERROR if(li.type != H5L_TYPE_HARD) TEST_ERROR - if(H5Lget_info(fid, "dataset", &li, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Lget_info2(fid, "dataset", &li, H5P_DEFAULT) < 0) TEST_ERROR if(li.type != H5L_TYPE_HARD) TEST_ERROR - if(H5Lget_info(fid, "ext_link", &li, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Lget_info2(fid, "ext_link", &li, H5P_DEFAULT) < 0) TEST_ERROR if(li.type != H5L_TYPE_EXTERNAL) TEST_ERROR - if(H5Lget_info(fid, "softlink", &li, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Lget_info2(fid, "softlink", &li, H5P_DEFAULT) < 0) TEST_ERROR if(li.type != H5L_TYPE_SOFT) TEST_ERROR - if(H5Lget_info(fid, "ud_link", &li, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Lget_info2(fid, "ud_link", &li, H5P_DEFAULT) < 0) TEST_ERROR if(li.type != UD_PLIST_TYPE) TEST_ERROR /* Ensure that passing a NULL pointer doesn't cause an error */ - if(H5Lget_info(fid, "group", NULL, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Lget_info2(fid, "group", NULL, H5P_DEFAULT) < 0) TEST_ERROR if(H5Fclose(fid) < 0) TEST_ERROR @@ -8815,7 +12790,7 @@ error: *------------------------------------------------------------------------- */ static int -visit_link_cb(hid_t H5_ATTR_UNUSED group_id, const char *name, const H5L_info_t *linfo, void *_op_data) +visit_link_cb(hid_t H5_ATTR_UNUSED group_id, const char *name, const H5L_info2_t *linfo, void *_op_data) { lvisit_ud_t *op_data = (lvisit_ud_t *)_op_data; @@ -8857,26 +12832,26 @@ link_visit(hid_t fapl, hbool_t new_format) /* Visit all the links reachable from the root group (with file ID) */ udata.idx = 0; udata.info = lvisit0; - if(H5Lvisit(fid, H5_INDEX_NAME, H5_ITER_INC, visit_link_cb, &udata) < 0) FAIL_STACK_ERROR + if(H5Lvisit2(fid, H5_INDEX_NAME, H5_ITER_INC, visit_link_cb, &udata) < 0) FAIL_STACK_ERROR /* Visit all the links reachable from the root group (with group ID) */ if((gid = H5Gopen2(fid, "/", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR udata.idx = 0; udata.info = lvisit0; - if(H5Lvisit(gid, H5_INDEX_NAME, H5_ITER_INC, visit_link_cb, &udata) < 0) FAIL_STACK_ERROR + if(H5Lvisit2(gid, H5_INDEX_NAME, H5_ITER_INC, visit_link_cb, &udata) < 0) FAIL_STACK_ERROR if(H5Gclose(gid) < 0) FAIL_STACK_ERROR /* Visit all the links reachable from each internal group */ if((gid = H5Gopen2(fid, "/Group1", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR udata.idx = 0; udata.info = lvisit1; - if(H5Lvisit(gid, H5_INDEX_NAME, H5_ITER_INC, visit_link_cb, &udata) < 0) FAIL_STACK_ERROR + if(H5Lvisit2(gid, H5_INDEX_NAME, H5_ITER_INC, visit_link_cb, &udata) < 0) FAIL_STACK_ERROR if(H5Gclose(gid) < 0) FAIL_STACK_ERROR if((gid = H5Gopen2(fid, "/Group1/Group2", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR udata.idx = 0; udata.info = lvisit2; - if(H5Lvisit(gid, H5_INDEX_NAME, H5_ITER_INC, visit_link_cb, &udata) < 0) FAIL_STACK_ERROR + if(H5Lvisit2(gid, H5_INDEX_NAME, H5_ITER_INC, visit_link_cb, &udata) < 0) FAIL_STACK_ERROR if(H5Gclose(gid) < 0) FAIL_STACK_ERROR /* Close file created */ @@ -8921,34 +12896,34 @@ link_visit_by_name(hid_t fapl, hbool_t new_format) /* Visit all the links reachable from the root group (with file ID) */ udata.idx = 0; udata.info = lvisit0; - if(H5Lvisit_by_name(fid, "/", H5_INDEX_NAME, H5_ITER_INC, visit_link_cb, &udata, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + if(H5Lvisit_by_name2(fid, "/", H5_INDEX_NAME, H5_ITER_INC, visit_link_cb, &udata, H5P_DEFAULT) < 0) FAIL_STACK_ERROR /* Visit all the links reachable from the root group (with group ID) */ if((gid = H5Gopen2(fid, "/", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR udata.idx = 0; udata.info = lvisit0; - if(H5Lvisit_by_name(gid, ".", H5_INDEX_NAME, H5_ITER_INC, visit_link_cb, &udata, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + if(H5Lvisit_by_name2(gid, ".", H5_INDEX_NAME, H5_ITER_INC, visit_link_cb, &udata, H5P_DEFAULT) < 0) FAIL_STACK_ERROR if(H5Gclose(gid) < 0) FAIL_STACK_ERROR /* Visit all the links reachable from each internal group */ udata.idx = 0; udata.info = lvisit1; - if(H5Lvisit_by_name(fid, "/Group1", H5_INDEX_NAME, H5_ITER_INC, visit_link_cb, &udata, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + if(H5Lvisit_by_name2(fid, "/Group1", H5_INDEX_NAME, H5_ITER_INC, visit_link_cb, &udata, H5P_DEFAULT) < 0) FAIL_STACK_ERROR if((gid = H5Gopen2(fid, "/Group1", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR udata.idx = 0; udata.info = lvisit1; - if(H5Lvisit_by_name(gid, ".", H5_INDEX_NAME, H5_ITER_INC, visit_link_cb, &udata, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + if(H5Lvisit_by_name2(gid, ".", H5_INDEX_NAME, H5_ITER_INC, visit_link_cb, &udata, H5P_DEFAULT) < 0) FAIL_STACK_ERROR if(H5Gclose(gid) < 0) FAIL_STACK_ERROR udata.idx = 0; udata.info = lvisit2; - if(H5Lvisit_by_name(fid, "/Group1/Group2", H5_INDEX_NAME, H5_ITER_INC, visit_link_cb, &udata, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + if(H5Lvisit_by_name2(fid, "/Group1/Group2", H5_INDEX_NAME, H5_ITER_INC, visit_link_cb, &udata, H5P_DEFAULT) < 0) FAIL_STACK_ERROR if((gid = H5Gopen2(fid, "/Group1/Group2", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR udata.idx = 0; udata.info = lvisit2; - if(H5Lvisit_by_name(gid, ".", H5_INDEX_NAME, H5_ITER_INC, visit_link_cb, &udata, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + if(H5Lvisit_by_name2(gid, ".", H5_INDEX_NAME, H5_ITER_INC, visit_link_cb, &udata, H5P_DEFAULT) < 0) FAIL_STACK_ERROR if(H5Gclose(gid) < 0) FAIL_STACK_ERROR /* Close file created */ @@ -8976,7 +12951,7 @@ error: *------------------------------------------------------------------------- */ static int -visit_obj_cb(hid_t H5_ATTR_UNUSED group_id, const char *name, const H5O_info_t *oinfo, void *_op_data) +visit_obj_cb(hid_t H5_ATTR_UNUSED group_id, const char *name, const H5O_info2_t *oinfo, void *_op_data) { ovisit_ud_t *op_data = (ovisit_ud_t *)_op_data; @@ -9018,26 +12993,26 @@ obj_visit(hid_t fapl, hbool_t new_format) /* Visit all the objects reachable from the root group (with file ID) */ udata.idx = 0; udata.info = new_format ? ovisit0_new : ovisit0_old; - if(H5Ovisit2(fid, H5_INDEX_NAME, H5_ITER_INC, visit_obj_cb, &udata, H5O_INFO_BASIC) < 0) FAIL_STACK_ERROR + if(H5Ovisit3(fid, H5_INDEX_NAME, H5_ITER_INC, visit_obj_cb, &udata, H5O_INFO_BASIC) < 0) FAIL_STACK_ERROR /* Visit all the objects reachable from the root group (with group ID) */ if((gid = H5Gopen2(fid, "/", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR udata.idx = 0; udata.info = new_format ? ovisit0_new : ovisit0_old; - if(H5Ovisit2(gid, H5_INDEX_NAME, H5_ITER_INC, visit_obj_cb, &udata, H5O_INFO_BASIC) < 0) FAIL_STACK_ERROR + if(H5Ovisit3(gid, H5_INDEX_NAME, H5_ITER_INC, visit_obj_cb, &udata, H5O_INFO_BASIC) < 0) FAIL_STACK_ERROR if(H5Gclose(gid) < 0) FAIL_STACK_ERROR /* Visit all the objects reachable from each internal group */ if((gid = H5Gopen2(fid, "/Group1", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR udata.idx = 0; udata.info = new_format ? ovisit1_new : ovisit1_old; - if(H5Ovisit2(gid, H5_INDEX_NAME, H5_ITER_INC, visit_obj_cb, &udata, H5O_INFO_BASIC) < 0) FAIL_STACK_ERROR + if(H5Ovisit3(gid, H5_INDEX_NAME, H5_ITER_INC, visit_obj_cb, &udata, H5O_INFO_BASIC) < 0) FAIL_STACK_ERROR if(H5Gclose(gid) < 0) FAIL_STACK_ERROR if((gid = H5Gopen2(fid, "/Group1/Group2", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR udata.idx = 0; udata.info = new_format ? ovisit2_new : ovisit2_old; - if(H5Ovisit2(gid, H5_INDEX_NAME, H5_ITER_INC, visit_obj_cb, &udata, H5O_INFO_BASIC) < 0) FAIL_STACK_ERROR + if(H5Ovisit3(gid, H5_INDEX_NAME, H5_ITER_INC, visit_obj_cb, &udata, H5O_INFO_BASIC) < 0) FAIL_STACK_ERROR if(H5Gclose(gid) < 0) FAIL_STACK_ERROR /* Close file created */ @@ -9082,34 +13057,34 @@ obj_visit_by_name(hid_t fapl, hbool_t new_format) /* Visit all the objects reachable from the root group (with file ID) */ udata.idx = 0; udata.info = new_format ? ovisit0_new : ovisit0_old; - if(H5Ovisit_by_name2(fid, "/", H5_INDEX_NAME, H5_ITER_INC, visit_obj_cb, &udata, H5O_INFO_BASIC, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + if(H5Ovisit_by_name3(fid, "/", H5_INDEX_NAME, H5_ITER_INC, visit_obj_cb, &udata, H5O_INFO_BASIC, H5P_DEFAULT) < 0) FAIL_STACK_ERROR /* Visit all the objects reachable from the root group (with group ID) */ if((gid = H5Gopen2(fid, "/", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR udata.idx = 0; udata.info = new_format ? ovisit0_new : ovisit0_old; - if(H5Ovisit_by_name2(gid, ".", H5_INDEX_NAME, H5_ITER_INC, visit_obj_cb, &udata, H5O_INFO_BASIC, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + if(H5Ovisit_by_name3(gid, ".", H5_INDEX_NAME, H5_ITER_INC, visit_obj_cb, &udata, H5O_INFO_BASIC, H5P_DEFAULT) < 0) FAIL_STACK_ERROR if(H5Gclose(gid) < 0) FAIL_STACK_ERROR /* Visit all the objects reachable from each internal group */ udata.idx = 0; udata.info = new_format ? ovisit1_new : ovisit1_old; - if(H5Ovisit_by_name2(fid, "/Group1", H5_INDEX_NAME, H5_ITER_INC, visit_obj_cb, &udata, H5O_INFO_BASIC, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + if(H5Ovisit_by_name3(fid, "/Group1", H5_INDEX_NAME, H5_ITER_INC, visit_obj_cb, &udata, H5O_INFO_BASIC, H5P_DEFAULT) < 0) FAIL_STACK_ERROR if((gid = H5Gopen2(fid, "/Group1", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR udata.idx = 0; udata.info = new_format ? ovisit1_new : ovisit1_old; - if(H5Ovisit_by_name2(gid, ".", H5_INDEX_NAME, H5_ITER_INC, visit_obj_cb, &udata, H5O_INFO_BASIC, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + if(H5Ovisit_by_name3(gid, ".", H5_INDEX_NAME, H5_ITER_INC, visit_obj_cb, &udata, H5O_INFO_BASIC, H5P_DEFAULT) < 0) FAIL_STACK_ERROR if(H5Gclose(gid) < 0) FAIL_STACK_ERROR udata.idx = 0; udata.info = new_format ? ovisit2_new : ovisit2_old; - if(H5Ovisit_by_name2(fid, "/Group1/Group2", H5_INDEX_NAME, H5_ITER_INC, visit_obj_cb, &udata, H5O_INFO_BASIC, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + if(H5Ovisit_by_name3(fid, "/Group1/Group2", H5_INDEX_NAME, H5_ITER_INC, visit_obj_cb, &udata, H5O_INFO_BASIC, H5P_DEFAULT) < 0) FAIL_STACK_ERROR if((gid = H5Gopen2(fid, "/Group1/Group2", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR udata.idx = 0; udata.info = new_format ? ovisit2_new : ovisit2_old; - if(H5Ovisit_by_name2(gid, ".", H5_INDEX_NAME, H5_ITER_INC, visit_obj_cb, &udata, H5O_INFO_BASIC, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + if(H5Ovisit_by_name3(gid, ".", H5_INDEX_NAME, H5_ITER_INC, visit_obj_cb, &udata, H5O_INFO_BASIC, H5P_DEFAULT) < 0) FAIL_STACK_ERROR if(H5Gclose(gid) < 0) FAIL_STACK_ERROR /* Close file created */ @@ -9136,7 +13111,7 @@ error: *------------------------------------------------------------------------- */ static int -visit_obj_stop_cb(hid_t H5_ATTR_UNUSED group_id, const char H5_ATTR_UNUSED *name, const H5O_info_t H5_ATTR_UNUSED *oinfo, void *_op_data) +visit_obj_stop_cb(hid_t H5_ATTR_UNUSED group_id, const char H5_ATTR_UNUSED *name, const H5O_info2_t H5_ATTR_UNUSED *oinfo, void *_op_data) { unsigned *op_data = (unsigned *)_op_data; @@ -9176,14 +13151,14 @@ obj_visit_stop(hid_t fapl, hbool_t new_format) * returns H5_ITER_STOP */ nvisited = 0; - if((ret = H5Ovisit2(fid, H5_INDEX_NAME, H5_ITER_INC, visit_obj_stop_cb, &nvisited, H5O_INFO_BASIC)) < 0) + if((ret = H5Ovisit3(fid, H5_INDEX_NAME, H5_ITER_INC, visit_obj_stop_cb, &nvisited, H5O_INFO_BASIC)) < 0) FAIL_STACK_ERROR if(ret != H5_ITER_STOP) TEST_ERROR if(nvisited != 1) TEST_ERROR /* Same test with H5Ovisit_by_name */ nvisited = 0; - if((ret = H5Ovisit_by_name2(fid, "/", H5_INDEX_NAME, H5_ITER_INC, visit_obj_stop_cb, + if((ret = H5Ovisit_by_name3(fid, "/", H5_INDEX_NAME, H5_ITER_INC, visit_obj_stop_cb, &nvisited, H5O_INFO_BASIC, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR if(ret != H5_ITER_STOP) TEST_ERROR if(nvisited != 1) TEST_ERROR @@ -9977,11 +13952,11 @@ corder_create_compact(hid_t fapl) /* Loop through links, checking their creation order values */ /* (the name index is used, but the creation order value is in the same order) */ for(u = 0; u < max_compact; u++) { - H5L_info_t linfo; /* Link information */ + H5L_info2_t linfo; /* Link information */ /* Retrieve information for link */ HDsnprintf(objname, sizeof(objname), "filler %u", u); - if(H5Lget_info(group_id, objname, &linfo, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Lget_info2(group_id, objname, &linfo, H5P_DEFAULT) < 0) TEST_ERROR /* Verify creation order of link */ if(linfo.corder_valid != TRUE) TEST_ERROR @@ -10105,11 +14080,11 @@ corder_create_dense(hid_t fapl) /* Loop through links, checking their creation order values */ /* (the name index is used, but the creation order value is in the same order) */ for(u = 0; u < (max_compact + 1); u++) { - H5L_info_t linfo; /* Link information */ + H5L_info2_t linfo; /* Link information */ /* Retrieve information for link */ HDsnprintf(objname, sizeof(objname), "filler %u", u); - if(H5Lget_info(group_id, objname, &linfo, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Lget_info2(group_id, objname, &linfo, H5P_DEFAULT) < 0) TEST_ERROR /* Verify creation order of link */ if(linfo.corder_valid != TRUE) TEST_ERROR @@ -10503,19 +14478,19 @@ link_info_by_idx_check(hid_t group_id, const char *linkname, hsize_t n, char tmpname[NAME_BUF_SIZE]; /* Temporary link name */ char valname[NAME_BUF_SIZE]; /* Link value name */ char tmpval[NAME_BUF_SIZE]; /* Temporary link value */ - H5L_info_t linfo; /* Link info struct */ + H5L_info2_t linfo; /* Link info struct */ /* Make link value for increasing/native order queries */ HDsnprintf(valname, sizeof(valname), "value %02u", (unsigned)n); /* Verify the link information for first link, in increasing creation order */ HDmemset(&linfo, 0, sizeof(linfo)); - if(H5Lget_info_by_idx(group_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, (hsize_t)0, &linfo, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Lget_info_by_idx2(group_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, (hsize_t)0, &linfo, H5P_DEFAULT) < 0) TEST_ERROR if(linfo.corder != 0) TEST_ERROR /* Verify the link information for new link, in increasing creation order */ HDmemset(&linfo, 0, sizeof(linfo)); - if(H5Lget_info_by_idx(group_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, n, &linfo, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Lget_info_by_idx2(group_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, n, &linfo, H5P_DEFAULT) < 0) TEST_ERROR if(linfo.corder != (int64_t)n) TEST_ERROR /* Verify value for new soft link, in increasing creation order */ @@ -10537,12 +14512,12 @@ link_info_by_idx_check(hid_t group_id, const char *linkname, hsize_t n, if(use_index) { /* Verify the link information for first link, in native creation order (which is increasing) */ HDmemset(&linfo, 0, sizeof(linfo)); - if(H5Lget_info_by_idx(group_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_NATIVE, (hsize_t)0, &linfo, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Lget_info_by_idx2(group_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_NATIVE, (hsize_t)0, &linfo, H5P_DEFAULT) < 0) TEST_ERROR if(linfo.corder != 0) TEST_ERROR /* Verify the link information for new link, in native creation order (which is increasing) */ HDmemset(&linfo, 0, sizeof(linfo)); - if(H5Lget_info_by_idx(group_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_NATIVE, n, &linfo, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Lget_info_by_idx2(group_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_NATIVE, n, &linfo, H5P_DEFAULT) < 0) TEST_ERROR if(linfo.corder != (int64_t)n) TEST_ERROR /* Verify value for new soft link, in native creation order (which is increasing) */ @@ -10560,12 +14535,12 @@ link_info_by_idx_check(hid_t group_id, const char *linkname, hsize_t n, /* Verify the link information for first link, in decreasing creation order */ HDmemset(&linfo, 0, sizeof(linfo)); - if(H5Lget_info_by_idx(group_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_DEC, n, &linfo, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Lget_info_by_idx2(group_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_DEC, n, &linfo, H5P_DEFAULT) < 0) TEST_ERROR if(linfo.corder != 0) TEST_ERROR /* Verify the link information for new link, in decreasing creation order */ HDmemset(&linfo, 0, sizeof(linfo)); - if(H5Lget_info_by_idx(group_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_DEC, (hsize_t)0, &linfo, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Lget_info_by_idx2(group_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_DEC, (hsize_t)0, &linfo, H5P_DEFAULT) < 0) TEST_ERROR if(linfo.corder != (int64_t)n) TEST_ERROR /* Verify value for new soft link, in decreasing creation order */ @@ -10583,12 +14558,12 @@ link_info_by_idx_check(hid_t group_id, const char *linkname, hsize_t n, /* Verify the link information for first link, in increasing link name order */ HDmemset(&linfo, 0, sizeof(linfo)); - if(H5Lget_info_by_idx(group_id, ".", H5_INDEX_NAME, H5_ITER_INC, (hsize_t)0, &linfo, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Lget_info_by_idx2(group_id, ".", H5_INDEX_NAME, H5_ITER_INC, (hsize_t)0, &linfo, H5P_DEFAULT) < 0) TEST_ERROR if(linfo.corder != 0) TEST_ERROR /* Verify the link information for new link, in increasing link name order */ HDmemset(&linfo, 0, sizeof(linfo)); - if(H5Lget_info_by_idx(group_id, ".", H5_INDEX_NAME, H5_ITER_INC, n, &linfo, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Lget_info_by_idx2(group_id, ".", H5_INDEX_NAME, H5_ITER_INC, n, &linfo, H5P_DEFAULT) < 0) TEST_ERROR if(linfo.corder != (int64_t)n) TEST_ERROR /* Verify value for new soft link, in increasing link name order */ @@ -10609,12 +14584,12 @@ link_info_by_idx_check(hid_t group_id, const char *linkname, hsize_t n, /* Verify the link information for first link, in decreasing link name order */ HDmemset(&linfo, 0, sizeof(linfo)); - if(H5Lget_info_by_idx(group_id, ".", H5_INDEX_NAME, H5_ITER_DEC, n, &linfo, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Lget_info_by_idx2(group_id, ".", H5_INDEX_NAME, H5_ITER_DEC, n, &linfo, H5P_DEFAULT) < 0) TEST_ERROR if(linfo.corder != 0) TEST_ERROR /* Verify the link information for new link, in decreasing link name order */ HDmemset(&linfo, 0, sizeof(linfo)); - if(H5Lget_info_by_idx(group_id, ".", H5_INDEX_NAME, H5_ITER_DEC, (hsize_t)0, &linfo, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Lget_info_by_idx2(group_id, ".", H5_INDEX_NAME, H5_ITER_DEC, (hsize_t)0, &linfo, H5P_DEFAULT) < 0) TEST_ERROR if(linfo.corder != (int64_t)n) TEST_ERROR /* Verify value for new soft link, in decreasing link name order */ @@ -10658,7 +14633,7 @@ link_info_by_idx(hid_t fapl) unsigned use_index; /* Use index on creation order values */ unsigned max_compact; /* Maximum # of links to store in group compactly */ unsigned min_dense; /* Minimum # of links to store in group "densely" */ - H5L_info_t linfo; /* Link info struct */ + H5L_info2_t linfo; /* Link info struct */ char objname[NAME_BUF_SIZE]; /* Object name */ char valname[NAME_BUF_SIZE]; /* Link value name */ char filename[NAME_BUF_SIZE];/* File name */ @@ -10702,7 +14677,7 @@ link_info_by_idx(hid_t fapl) /* Check for query on empty group */ H5E_BEGIN_TRY { - ret = H5Lget_info_by_idx(group_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, (hsize_t)0, &linfo, H5P_DEFAULT); + ret = H5Lget_info_by_idx2(group_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, (hsize_t)0, &linfo, H5P_DEFAULT); } H5E_END_TRY; if(ret >= 0) TEST_ERROR H5E_BEGIN_TRY { @@ -10740,11 +14715,11 @@ link_info_by_idx(hid_t fapl) /* Check for out of bound offset queries */ H5E_BEGIN_TRY { - ret = H5Lget_info_by_idx(group_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, (hsize_t)u, &linfo, H5P_DEFAULT); + ret = H5Lget_info_by_idx2(group_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, (hsize_t)u, &linfo, H5P_DEFAULT); } H5E_END_TRY; if(ret >= 0) TEST_ERROR H5E_BEGIN_TRY { - ret = H5Lget_info_by_idx(group_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_DEC, (hsize_t)u, &linfo, H5P_DEFAULT); + ret = H5Lget_info_by_idx2(group_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_DEC, (hsize_t)u, &linfo, H5P_DEFAULT); } H5E_END_TRY; if(ret >= 0) TEST_ERROR H5E_BEGIN_TRY { @@ -10782,11 +14757,11 @@ link_info_by_idx(hid_t fapl) /* Check for out of bound offset queries */ H5E_BEGIN_TRY { - ret = H5Lget_info_by_idx(group_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, (hsize_t)u, &linfo, H5P_DEFAULT); + ret = H5Lget_info_by_idx2(group_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, (hsize_t)u, &linfo, H5P_DEFAULT); } H5E_END_TRY; if(ret >= 0) TEST_ERROR H5E_BEGIN_TRY { - ret = H5Lget_info_by_idx(group_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_DEC, (hsize_t)u, &linfo, H5P_DEFAULT); + ret = H5Lget_info_by_idx2(group_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_DEC, (hsize_t)u, &linfo, H5P_DEFAULT); } H5E_END_TRY; if(ret >= 0) TEST_ERROR H5E_BEGIN_TRY { @@ -10832,19 +14807,22 @@ error: static int link_info_by_idx_old(hid_t fapl) { - hid_t file_id = -1; /* File ID */ - hid_t group_id = -1, group_id2 = -1; /* Group IDs */ - unsigned hard_link; /* Create hard or soft link? */ - H5L_info_t linfo; /* Link info struct */ - char objname[NAME_BUF_SIZE]; /* Object name */ - char valname[NAME_BUF_SIZE]; /* Link value name */ - char filename[NAME_BUF_SIZE];/* File name */ - haddr_t objno[CORDER_NLINKS]; /* Addresses of the objects created */ - char tmpname[NAME_BUF_SIZE]; /* Temporary link name */ - char tmpval[NAME_BUF_SIZE]; /* Temporary link value */ - unsigned u; /* Local index variable */ - ssize_t name_len; /* Length of name */ - herr_t ret; /* Generic return value */ + hid_t file_id = -1; /* File ID */ + hid_t group_id = -1, group_id2 = -1; /* Group IDs */ + H5F_t *f = NULL; + unsigned hard_link; /* Create hard or soft link? */ + H5L_info2_t linfo; /* Link info struct */ + char objname[NAME_BUF_SIZE]; /* Object name */ + char valname[NAME_BUF_SIZE]; /* Link value name */ + char filename[NAME_BUF_SIZE];/* File name */ + H5O_token_t objtoken[CORDER_NLINKS];/* Tokens (Addresses) of the objects created */ + void *vol_obj_file = NULL; /* Object of file_id */ + char tmpname[NAME_BUF_SIZE]; /* Temporary link name */ + char tmpval[NAME_BUF_SIZE]; /* Temporary link value */ + unsigned u; /* Local index variable */ + ssize_t name_len; /* Length of name */ + int token_cmp; + herr_t ret; /* Generic return value */ /* Loop over creating hard or soft links */ for(hard_link = FALSE; hard_link <= TRUE; hard_link++) { @@ -10857,6 +14835,12 @@ link_info_by_idx_old(hid_t fapl) h5_fixname(FILENAME[0], fapl, filename, sizeof filename); if((file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR + /* Need the file struct to address encoding */ + /* Retrieve VOL object */ + if(NULL == (vol_obj_file = H5VL_vol_object(file_id))) TEST_ERROR + /* Retrieve file from VOL object */ + if(NULL == (f = (H5F_t *)H5VL_object_data((const H5VL_object_t *)vol_obj_file))) TEST_ERROR + /* Create group to operate on */ if((group_id = H5Gcreate2(file_id, CORDER_GROUP_NAME, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR @@ -10867,14 +14851,15 @@ link_info_by_idx_old(hid_t fapl) /* Check for creating hard or soft link */ if(hard_link) { - H5O_info_t oi; /* Buffer for querying object's info */ + H5O_info2_t oi; /* Buffer for querying object's info */ /* Create group */ if((group_id2 = H5Gcreate2(group_id, objname, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR - /* Retrieve group's address on disk */ - if(H5Oget_info2(group_id2, &oi, H5O_INFO_BASIC) < 0) TEST_ERROR - objno[u] = oi.addr; + /* Retrieve group's object token */ + if(H5Oget_info3(group_id2, &oi, H5O_INFO_BASIC) < 0) TEST_ERROR + + HDmemcpy(&objtoken[u], &oi.token, sizeof(H5O_token_t)); /* Close group */ if(H5Gclose(group_id2) < 0) TEST_ERROR @@ -10900,8 +14885,9 @@ link_info_by_idx_old(hid_t fapl) /* Verify link information (in increasing order) */ if(hard_link) { - if(H5Lget_info_by_idx(group_id, ".", H5_INDEX_NAME, H5_ITER_INC, (hsize_t)u, &linfo, H5P_DEFAULT) < 0) TEST_ERROR - if(H5F_addr_ne(linfo.u.address, objno[u])) TEST_ERROR + if(H5Lget_info_by_idx2(group_id, ".", H5_INDEX_NAME, H5_ITER_INC, (hsize_t)u, &linfo, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Otoken_cmp(group_id, &linfo.u.token, &objtoken[u], &token_cmp) < 0) TEST_ERROR + if(token_cmp) TEST_ERROR } /* end if */ else { if(H5Lget_val_by_idx(group_id, ".", H5_INDEX_NAME, H5_ITER_INC, (hsize_t)u, tmpval, (size_t)NAME_BUF_SIZE, H5P_DEFAULT) < 0) TEST_ERROR @@ -10915,8 +14901,9 @@ link_info_by_idx_old(hid_t fapl) /* Verify link information (in native order - native is increasing) */ if(hard_link) { - if(H5Lget_info_by_idx(group_id, ".", H5_INDEX_NAME, H5_ITER_NATIVE, (hsize_t)u, &linfo, H5P_DEFAULT) < 0) TEST_ERROR - if(H5F_addr_ne(linfo.u.address, objno[u])) TEST_ERROR + if(H5Lget_info_by_idx2(group_id, ".", H5_INDEX_NAME, H5_ITER_NATIVE, (hsize_t)u, &linfo, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Otoken_cmp(group_id, &linfo.u.token, &objtoken[u], &token_cmp) < 0) TEST_ERROR + if(token_cmp) TEST_ERROR } /* end if */ else { if(H5Lget_val_by_idx(group_id, ".", H5_INDEX_NAME, H5_ITER_NATIVE, (hsize_t)u, tmpval, (size_t)NAME_BUF_SIZE, H5P_DEFAULT) < 0) TEST_ERROR @@ -10936,8 +14923,9 @@ link_info_by_idx_old(hid_t fapl) /* Verify link information (in decreasing order) */ if(hard_link) { - if(H5Lget_info_by_idx(group_id, ".", H5_INDEX_NAME, H5_ITER_DEC, (hsize_t)u, &linfo, H5P_DEFAULT) < 0) TEST_ERROR - if(H5F_addr_ne(linfo.u.address, objno[dec_u])) TEST_ERROR + if(H5Lget_info_by_idx2(group_id, ".", H5_INDEX_NAME, H5_ITER_DEC, (hsize_t)u, &linfo, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Otoken_cmp(group_id, &linfo.u.token, &objtoken[dec_u], &token_cmp) < 0) TEST_ERROR + if(token_cmp) TEST_ERROR } /* end if */ else { if(H5Lget_val_by_idx(group_id, ".", H5_INDEX_NAME, H5_ITER_DEC, (hsize_t)u, tmpval, (size_t)NAME_BUF_SIZE, H5P_DEFAULT) < 0) TEST_ERROR @@ -10951,7 +14939,7 @@ link_info_by_idx_old(hid_t fapl) /* Check for creation order index queries */ H5E_BEGIN_TRY { - ret = H5Lget_info_by_idx(group_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, (hsize_t)u, &linfo, H5P_DEFAULT); + ret = H5Lget_info_by_idx2(group_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, (hsize_t)u, &linfo, H5P_DEFAULT); } H5E_END_TRY; if(ret >= 0) TEST_ERROR H5E_BEGIN_TRY { @@ -11003,7 +14991,7 @@ delete_by_idx(hid_t fapl) unsigned use_index; /* Use index on creation order values */ unsigned max_compact; /* Maximum # of links to store in group compactly */ unsigned min_dense; /* Minimum # of links to store in group "densely" */ - H5L_info_t linfo; /* Link info struct */ + H5L_info2_t linfo; /* Link info struct */ char objname[NAME_BUF_SIZE]; /* Object name */ char filename[NAME_BUF_SIZE];/* File name */ char tmpname[NAME_BUF_SIZE]; /* Temporary link name */ @@ -11107,7 +15095,7 @@ delete_by_idx(hid_t fapl) /* Verify the link information for first link in appropriate order */ HDmemset(&linfo, 0, sizeof(linfo)); - if(H5Lget_info_by_idx(group_id, ".", idx_type, order, (hsize_t)0, &linfo, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Lget_info_by_idx2(group_id, ".", idx_type, order, (hsize_t)0, &linfo, H5P_DEFAULT) < 0) TEST_ERROR if(order == H5_ITER_INC) { if(linfo.corder != (u + 1)) TEST_ERROR } /* end if */ @@ -11163,7 +15151,7 @@ delete_by_idx(hid_t fapl) /* Verify the link information for first link in appropriate order */ HDmemset(&linfo, 0, sizeof(linfo)); - if(H5Lget_info_by_idx(group_id, ".", idx_type, order, (hsize_t)0, &linfo, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Lget_info_by_idx2(group_id, ".", idx_type, order, (hsize_t)0, &linfo, H5P_DEFAULT) < 0) TEST_ERROR if(order == H5_ITER_INC) { if(linfo.corder != (u + 1)) TEST_ERROR } /* end if */ @@ -11222,7 +15210,7 @@ delete_by_idx(hid_t fapl) /* Verify the link information for current link in appropriate order */ HDmemset(&linfo, 0, sizeof(linfo)); - if(H5Lget_info_by_idx(group_id, ".", idx_type, order, (hsize_t)u, &linfo, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Lget_info_by_idx2(group_id, ".", idx_type, order, (hsize_t)u, &linfo, H5P_DEFAULT) < 0) TEST_ERROR if(order == H5_ITER_INC) { if(linfo.corder != ((u * 2) + 1)) TEST_ERROR } /* end if */ @@ -11247,7 +15235,7 @@ delete_by_idx(hid_t fapl) /* Verify the link information for first link in appropriate order */ HDmemset(&linfo, 0, sizeof(linfo)); - if(H5Lget_info_by_idx(group_id, ".", idx_type, order, (hsize_t)0, &linfo, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Lget_info_by_idx2(group_id, ".", idx_type, order, (hsize_t)0, &linfo, H5P_DEFAULT) < 0) TEST_ERROR if(order == H5_ITER_INC) { if(linfo.corder != ((u * 2) + 3)) TEST_ERROR } /* end if */ @@ -11311,16 +15299,19 @@ error: static int delete_by_idx_old(hid_t fapl) { - hid_t file_id = -1; /* File ID */ - hid_t group_id = -1, group_id2 = -1; /* Group IDs */ - H5L_info_t linfo; /* Link info struct */ - H5_iter_order_t order; /* Order within in the index */ - char objname[NAME_BUF_SIZE]; /* Object name */ - char filename[NAME_BUF_SIZE];/* File name */ - haddr_t objno[CORDER_NLINKS]; /* Addresses of the objects created */ - char tmpname[NAME_BUF_SIZE]; /* Temporary link name */ - unsigned u; /* Local index variable */ - herr_t ret; /* Generic return value */ + hid_t file_id = -1; /* File ID */ + hid_t group_id = -1, group_id2 = -1; /* Group IDs */ + H5F_t *f = NULL; + H5L_info2_t linfo; /* Link info struct */ + H5_iter_order_t order; /* Order within in the index */ + void *vol_obj_file = NULL; /* Object of file_id */ + char objname[NAME_BUF_SIZE]; /* Object name */ + char filename[NAME_BUF_SIZE];/* File name */ + H5O_token_t objtoken[CORDER_NLINKS];/* Tokens (Addresses) of the objects created */ + char tmpname[NAME_BUF_SIZE]; /* Temporary link name */ + unsigned u; /* Local index variable */ + int token_cmp; + herr_t ret; /* Generic return value */ /* Loop over operating in different orders */ for(order = H5_ITER_INC; order <=H5_ITER_DEC; order++) { @@ -11334,6 +15325,12 @@ delete_by_idx_old(hid_t fapl) h5_fixname(FILENAME[0], fapl, filename, sizeof filename); if((file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR + /* Need the file struct to address encoding */ + /* Retrieve VOL object */ + if(NULL == (vol_obj_file = H5VL_vol_object(file_id))) TEST_ERROR + /* Retrieve file from VOL object */ + if(NULL == (f = (H5F_t *)H5VL_object_data((const H5VL_object_t *)vol_obj_file))) TEST_ERROR + /* Create group to operate on */ if((group_id = H5Gcreate2(file_id, CORDER_GROUP_NAME, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR @@ -11347,7 +15344,7 @@ delete_by_idx_old(hid_t fapl) /* Create several links */ for(u = 0; u < CORDER_NLINKS; u++) { - H5O_info_t oi; /* Buffer for querying object's info */ + H5O_info2_t oi; /* Buffer for querying object's info */ /* Make name for link */ HDsnprintf(objname, sizeof(objname), "filler %02u", u); @@ -11355,9 +15352,10 @@ delete_by_idx_old(hid_t fapl) /* Create group */ if((group_id2 = H5Gcreate2(group_id, objname, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR - /* Retrieve group's address on disk */ - if(H5Oget_info2(group_id2, &oi, H5O_INFO_BASIC) < 0) TEST_ERROR - objno[u] = oi.addr; + /* Retrieve group's object token */ + if(H5Oget_info3(group_id2, &oi, H5O_INFO_BASIC) < 0) TEST_ERROR + + HDmemcpy(&objtoken[u], &oi.token, sizeof(H5O_token_t)); /* Close group */ if(H5Gclose(group_id2) < 0) TEST_ERROR @@ -11384,12 +15382,14 @@ delete_by_idx_old(hid_t fapl) /* Verify the link information for first link in appropriate order */ HDmemset(&linfo, 0, sizeof(linfo)); - if(H5Lget_info_by_idx(group_id, ".", H5_INDEX_NAME, order, (hsize_t)0, &linfo, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Lget_info_by_idx2(group_id, ".", H5_INDEX_NAME, order, (hsize_t)0, &linfo, H5P_DEFAULT) < 0) TEST_ERROR if(order == H5_ITER_INC) { - if(H5F_addr_ne(linfo.u.address, objno[u + 1])) TEST_ERROR + if(H5Otoken_cmp(group_id, &linfo.u.token, &objtoken[u + 1], &token_cmp) < 0) TEST_ERROR + if(token_cmp) TEST_ERROR } /* end if */ else { - if(H5F_addr_ne(linfo.u.address, objno[dec_u])) TEST_ERROR + if(H5Otoken_cmp(group_id, &linfo.u.token, &objtoken[dec_u], &token_cmp) < 0) TEST_ERROR + if(token_cmp) TEST_ERROR } /* end else */ /* Verify the name for first link in appropriate order */ @@ -11418,7 +15418,7 @@ delete_by_idx_old(hid_t fapl) /* Create several links */ for(u = 0; u < CORDER_NLINKS; u++) { - H5O_info_t oi; /* Buffer for querying object's info */ + H5O_info2_t oi; /* Buffer for querying object's info */ /* Make name for link */ HDsnprintf(objname, sizeof(objname), "filler %02u", u); @@ -11426,9 +15426,10 @@ delete_by_idx_old(hid_t fapl) /* Create group */ if((group_id2 = H5Gcreate2(group_id, objname, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR - /* Retrieve group's address on disk */ - if(H5Oget_info2(group_id2, &oi, H5O_INFO_BASIC) < 0) TEST_ERROR - objno[u] = oi.addr; + /* Retrieve group's object token */ + if(H5Oget_info3(group_id2, &oi, H5O_INFO_BASIC) < 0) TEST_ERROR + + HDmemcpy(&objtoken[u], &oi.token, sizeof(H5O_token_t)); /* Close group */ if(H5Gclose(group_id2) < 0) TEST_ERROR @@ -11443,12 +15444,14 @@ delete_by_idx_old(hid_t fapl) /* Verify the link information for current link in appropriate order */ HDmemset(&linfo, 0, sizeof(linfo)); - if(H5Lget_info_by_idx(group_id, ".", H5_INDEX_NAME, order, (hsize_t)u, &linfo, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Lget_info_by_idx2(group_id, ".", H5_INDEX_NAME, order, (hsize_t)u, &linfo, H5P_DEFAULT) < 0) TEST_ERROR if(order == H5_ITER_INC) { - if(H5F_addr_ne(linfo.u.address, objno[(u * 2) + 1])) TEST_ERROR + if(H5Otoken_cmp(group_id, &linfo.u.token, &objtoken[(u * 2) + 1], &token_cmp) < 0) TEST_ERROR + if(token_cmp) TEST_ERROR } /* end if */ else { - if(H5F_addr_ne(linfo.u.address, objno[dec_u])) TEST_ERROR + if(H5Otoken_cmp(group_id, &linfo.u.token, &objtoken[dec_u], &token_cmp) < 0) TEST_ERROR + if(token_cmp) TEST_ERROR } /* end else */ /* Verify the name for current link in appropriate order */ @@ -11470,12 +15473,14 @@ delete_by_idx_old(hid_t fapl) /* Verify the link information for first link in appropriate order */ HDmemset(&linfo, 0, sizeof(linfo)); - if(H5Lget_info_by_idx(group_id, ".", H5_INDEX_NAME, order, (hsize_t)0, &linfo, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Lget_info_by_idx2(group_id, ".", H5_INDEX_NAME, order, (hsize_t)0, &linfo, H5P_DEFAULT) < 0) TEST_ERROR if(order == H5_ITER_INC) { - if(H5F_addr_ne(linfo.u.address, objno[(u * 2) + 3])) TEST_ERROR + if(H5Otoken_cmp(group_id, &linfo.u.token, &objtoken[(u * 2) + 3], &token_cmp) < 0) TEST_ERROR + if(token_cmp) TEST_ERROR } /* end if */ else { - if(H5F_addr_ne(linfo.u.address, objno[dec_u])) TEST_ERROR + if(H5Otoken_cmp(group_id, &linfo.u.token, &objtoken[dec_u], &token_cmp) < 0) TEST_ERROR + if(token_cmp) TEST_ERROR } /* end else */ /* Verify the name for first link in appropriate order */ @@ -11525,22 +15530,24 @@ error: *------------------------------------------------------------------------- */ static int -link_iterate_cb(hid_t group_id, const char *link_name, const H5L_info_t *info, +link_iterate_cb(hid_t group_id, const char *link_name, const H5L_info2_t *info, void *_op_data) { link_iter_info_t *op_data = (link_iter_info_t *)_op_data; /* User data */ char objname[NAME_BUF_SIZE]; /* Object name */ - H5L_info_t my_info; /* Local link info */ + H5L_info2_t my_info; /* Local link info */ /* Increment # of times the callback was called */ op_data->ncalled++; /* Get the link information directly to compare */ - if(H5Lget_info(group_id, link_name, &my_info, H5P_DEFAULT) < 0) + if(H5Lget_info2(group_id, link_name, &my_info, H5P_DEFAULT) < 0) return H5_ITER_ERROR; /* Check more things for link iteration (vs. group iteration) */ if(info) { + int token_cmp; + /* Check for correct order of iteration */ /* (if we are operating in increasing or decreasing order) */ if(op_data->order != H5_ITER_NATIVE) @@ -11556,7 +15563,9 @@ link_iterate_cb(hid_t group_id, const char *link_name, const H5L_info_t *info, return H5_ITER_ERROR; if(info->cset != my_info.cset) return H5_ITER_ERROR; - if(H5F_addr_ne(info->u.address, my_info.u.address)) + if(H5Otoken_cmp(group_id, &info->u.token, &my_info.u.token, &token_cmp) < 0) + return H5_ITER_ERROR; + if(token_cmp) return H5_ITER_ERROR; } /* end if */ @@ -11618,7 +15627,7 @@ group_iterate_cb(hid_t group_id, const char *link_name, void *_op_data) */ static int link_iterate_fail_cb(hid_t H5_ATTR_UNUSED group_id, const char H5_ATTR_UNUSED *link_name, - const H5L_info_t H5_ATTR_UNUSED *info, void H5_ATTR_UNUSED *_op_data) + const H5L_info2_t H5_ATTR_UNUSED *info, void H5_ATTR_UNUSED *_op_data) { return H5_ITER_ERROR; } /* end link_iterate_fail_cb() */ @@ -11651,7 +15660,7 @@ link_iterate_check(hid_t group_id, H5_index_t idx_type, H5_iter_order_t order, iter_info->ncalled = 0; iter_info->curr = order != H5_ITER_DEC ? 0 : (max_links - 1); HDmemset(iter_info->visited, 0, sizeof(hbool_t) * iter_info->max_visit); - if(H5Literate(group_id, idx_type, order, &skip, link_iterate_cb, iter_info) < 0) TEST_ERROR + if(H5Literate2(group_id, idx_type, order, &skip, link_iterate_cb, iter_info) < 0) TEST_ERROR /* Verify that we visited all the links */ if(skip != max_links) TEST_ERROR @@ -11681,7 +15690,7 @@ link_iterate_check(hid_t group_id, H5_index_t idx_type, H5_iter_order_t order, iter_info->ncalled = 0; iter_info->curr = (int64_t)(order != H5_ITER_DEC ? skip : ((max_links - 1) - skip)); HDmemset(iter_info->visited, 0, sizeof(hbool_t) * iter_info->max_visit); - if(H5Literate(group_id, idx_type, order, &skip, link_iterate_cb, iter_info) < 0) TEST_ERROR + if(H5Literate2(group_id, idx_type, order, &skip, link_iterate_cb, iter_info) < 0) TEST_ERROR /* Verify that we visited all the links */ if(skip != max_links) TEST_ERROR @@ -11743,7 +15752,7 @@ link_iterate_check(hid_t group_id, H5_index_t idx_type, H5_iter_order_t order, iter_info->ncalled = 0; iter_info->curr = order != H5_ITER_DEC ? 0 : (max_links - 1); HDmemset(iter_info->visited, 0, sizeof(hbool_t) * iter_info->max_visit); - if((ret = H5Literate(group_id, idx_type, order, &skip, link_iterate_cb, iter_info)) < 0) TEST_ERROR + if((ret = H5Literate2(group_id, idx_type, order, &skip, link_iterate_cb, iter_info)) < 0) TEST_ERROR if(ret != CORDER_ITER_STOP) TEST_ERROR if(iter_info->ncalled != 3) TEST_ERROR @@ -11763,7 +15772,7 @@ link_iterate_check(hid_t group_id, H5_index_t idx_type, H5_iter_order_t order, /* Check for iteration routine indicating failure */ skip = 0; H5E_BEGIN_TRY { - ret = H5Literate(group_id, idx_type, order, &skip, link_iterate_fail_cb, NULL); + ret = H5Literate2(group_id, idx_type, order, &skip, link_iterate_fail_cb, NULL); } H5E_END_TRY; if(ret >= 0) TEST_ERROR @@ -11881,7 +15890,7 @@ link_iterate(hid_t fapl) /* Check for iteration on empty group */ /* (should be OK) */ - if(H5Literate(group_id, idx_type, order, NULL, link_iterate_cb, NULL) < 0) TEST_ERROR + if(H5Literate2(group_id, idx_type, order, NULL, link_iterate_cb, NULL) < 0) TEST_ERROR /* Create several links, up to limit of compact form */ for(u = 0; u < max_compact; u++) { @@ -11901,7 +15910,7 @@ link_iterate(hid_t fapl) /* Check for out of bound iteration on compact group */ skip = (hsize_t)u; H5E_BEGIN_TRY { - ret = H5Literate(group_id, idx_type, order, &skip, link_iterate_cb, NULL); + ret = H5Literate2(group_id, idx_type, order, &skip, link_iterate_cb, NULL); } H5E_END_TRY; if(ret >= 0) TEST_ERROR @@ -11926,7 +15935,7 @@ link_iterate(hid_t fapl) /* Check for out of bound iteration on dense group */ skip = (hsize_t)u; H5E_BEGIN_TRY { - ret = H5Literate(group_id, idx_type, order, &skip, link_iterate_cb, NULL); + ret = H5Literate2(group_id, idx_type, order, &skip, link_iterate_cb, NULL); } H5E_END_TRY; if(ret >= 0) TEST_ERROR @@ -11979,21 +15988,23 @@ error: *------------------------------------------------------------------------- */ static int -link_iterate_old_cb(hid_t group_id, const char *link_name, const H5L_info_t *info, void *_op_data) +link_iterate_old_cb(hid_t group_id, const char *link_name, const H5L_info2_t *info, void *_op_data) { link_iter_info_t *op_data = (link_iter_info_t *)_op_data; /* User data */ char objname[NAME_BUF_SIZE]; /* Object name */ - H5L_info_t my_info; /* Local link info */ + H5L_info2_t my_info; /* Local link info */ /* Increment # of times the callback was called */ op_data->ncalled++; /* Get the link information directly to compare */ - if(H5Lget_info(group_id, link_name, &my_info, H5P_DEFAULT) < 0) + if(H5Lget_info2(group_id, link_name, &my_info, H5P_DEFAULT) < 0) return H5_ITER_ERROR; /* Check more things for link iteration (vs. group iteration) */ if(info) { + int token_cmp; + /* Compare link info structs */ if(info->type != my_info.type) return H5_ITER_ERROR; @@ -12003,7 +16014,9 @@ link_iterate_old_cb(hid_t group_id, const char *link_name, const H5L_info_t *inf return H5_ITER_ERROR; if(info->cset != my_info.cset) return H5_ITER_ERROR; - if(H5F_addr_ne(info->u.address, my_info.u.address)) + if(H5Otoken_cmp(group_id, &info->u.token, &my_info.u.token, &token_cmp) < 0) + return H5_ITER_ERROR; + if(token_cmp) return H5_ITER_ERROR; } /* end if */ @@ -12079,7 +16092,7 @@ link_iterate_old_check(hid_t group_id, H5_iter_order_t order, unsigned max_links iter_info->ncalled = 0; iter_info->curr = order != H5_ITER_DEC ? 0 : (max_links - 1); HDmemset(iter_info->visited, 0, sizeof(hbool_t) * iter_info->max_visit); - if(H5Literate(group_id, H5_INDEX_NAME, order, &skip, link_iterate_old_cb, iter_info) < 0) TEST_ERROR + if(H5Literate2(group_id, H5_INDEX_NAME, order, &skip, link_iterate_old_cb, iter_info) < 0) TEST_ERROR /* Verify that we visited all the links */ if(skip != max_links) TEST_ERROR @@ -12109,7 +16122,7 @@ link_iterate_old_check(hid_t group_id, H5_iter_order_t order, unsigned max_links iter_info->ncalled = 0; iter_info->curr = (int64_t)(order != H5_ITER_DEC ? skip : ((max_links - 1) - skip)); HDmemset(iter_info->visited, 0, sizeof(hbool_t) * iter_info->max_visit); - if(H5Literate(group_id, H5_INDEX_NAME, order, &skip, link_iterate_old_cb, iter_info) < 0) TEST_ERROR + if(H5Literate2(group_id, H5_INDEX_NAME, order, &skip, link_iterate_old_cb, iter_info) < 0) TEST_ERROR /* Verify that we visited all the links */ if(skip != max_links) TEST_ERROR @@ -12171,7 +16184,7 @@ link_iterate_old_check(hid_t group_id, H5_iter_order_t order, unsigned max_links iter_info->ncalled = 0; iter_info->curr = order != H5_ITER_DEC ? 0 : (max_links - 1); HDmemset(iter_info->visited, 0, sizeof(hbool_t) * iter_info->max_visit); - if((ret = H5Literate(group_id, H5_INDEX_NAME, order, &skip, link_iterate_old_cb, iter_info)) < 0) TEST_ERROR + if((ret = H5Literate2(group_id, H5_INDEX_NAME, order, &skip, link_iterate_old_cb, iter_info)) < 0) TEST_ERROR if(ret != CORDER_ITER_STOP) TEST_ERROR if(iter_info->ncalled != 3) TEST_ERROR @@ -12191,14 +16204,14 @@ link_iterate_old_check(hid_t group_id, H5_iter_order_t order, unsigned max_links /* Check for iteration routine indicating failure */ skip = 0; H5E_BEGIN_TRY { - ret = H5Literate(group_id, H5_INDEX_NAME, order, &skip, link_iterate_fail_cb, NULL); + ret = H5Literate2(group_id, H5_INDEX_NAME, order, &skip, link_iterate_fail_cb, NULL); } H5E_END_TRY; if(ret >= 0) TEST_ERROR /* Check for iteration w/bad location ID */ skip = 0; H5E_BEGIN_TRY { - ret = H5Literate((hid_t)(-1), H5_INDEX_NAME, order, &skip, link_iterate_fail_cb, NULL); + ret = H5Literate2((hid_t)(-1), H5_INDEX_NAME, order, &skip, link_iterate_fail_cb, NULL); } H5E_END_TRY; if(ret >= 0) TEST_ERROR @@ -12268,7 +16281,7 @@ link_iterate_old(hid_t fapl) /* Check for iteration on empty group */ /* (should be OK) */ - if(H5Literate(group_id, H5_INDEX_NAME, order, NULL, link_iterate_old_cb, NULL) < 0) TEST_ERROR + if(H5Literate2(group_id, H5_INDEX_NAME, order, NULL, link_iterate_old_cb, NULL) < 0) TEST_ERROR /* Create several links */ for(u = 0; u < CORDER_NLINKS; u++) { @@ -12288,7 +16301,7 @@ link_iterate_old(hid_t fapl) /* Check for out of bound iteration on old-style group */ skip = (hsize_t)u; H5E_BEGIN_TRY { - ret = H5Literate(group_id, H5_INDEX_NAME, order, &skip, link_iterate_old_cb, NULL); + ret = H5Literate2(group_id, H5_INDEX_NAME, order, &skip, link_iterate_old_cb, NULL); } H5E_END_TRY; if(ret >= 0) TEST_ERROR @@ -12296,7 +16309,7 @@ link_iterate_old(hid_t fapl) /* (should fail) */ skip = (hsize_t)0; H5E_BEGIN_TRY { - ret = H5Literate(group_id, H5_INDEX_CRT_ORDER, order, &skip, link_iterate_old_cb, NULL); + ret = H5Literate2(group_id, H5_INDEX_CRT_ORDER, order, &skip, link_iterate_old_cb, NULL); } H5E_END_TRY; if(ret >= 0) TEST_ERROR @@ -12343,15 +16356,16 @@ error: */ static int open_by_idx_check(hid_t main_group_id, hid_t soft_group_id, hid_t mount_file_id, - H5_index_t idx_type, H5_iter_order_t order, unsigned max_links, haddr_t *objno) + H5_index_t idx_type, H5_iter_order_t order, unsigned max_links, H5O_token_t *objno) { char mntname[NAME_BUF_SIZE]; /* Link value */ hid_t group_id = -1; /* ID of group to test */ - H5O_info_t oi; /* Buffer for querying object's info */ - haddr_t mnt_root_addr; /* Address of root group in file to mount */ + H5O_info2_t oi; /* Buffer for querying object's info */ + H5O_token_t mnt_root_token; /* Token (address) of root group in file to mount */ hid_t obj_id; /* ID of object opened */ unsigned mnt_idx; /* Index to mount group on */ unsigned u, v; /* Local index variables */ + int token_cmp; /* Work through main & soft link groups */ for(v = 0; v < 2; v++) { @@ -12367,16 +16381,18 @@ open_by_idx_check(hid_t main_group_id, hid_t soft_group_id, hid_t mount_file_id, if((obj_id = H5Oopen_by_idx(group_id, ".", idx_type, order, (hsize_t)u, H5P_DEFAULT)) < 0) TEST_ERROR /* Get the object's information */ - if(H5Oget_info2(obj_id, &oi, H5O_INFO_BASIC) < 0) TEST_ERROR + if(H5Oget_info3(obj_id, &oi, H5O_INFO_BASIC) < 0) TEST_ERROR /* Check that the object is the correct one */ if(order == H5_ITER_INC) { - if(H5F_addr_ne(oi.addr, objno[u])) TEST_ERROR + if(H5Otoken_cmp(obj_id, &oi.token, &objno[u], &token_cmp) < 0) TEST_ERROR + if(token_cmp) TEST_ERROR } /* end if */ else if(order == H5_ITER_DEC) { unsigned dec_u = max_links - (u + 1); /* Decreasing mapped index */ - if(H5F_addr_ne(oi.addr, objno[dec_u])) TEST_ERROR + if(H5Otoken_cmp(obj_id, &oi.token, &objno[dec_u], &token_cmp) < 0) TEST_ERROR + if(token_cmp) TEST_ERROR } /* end if */ else { /* XXX: What to do about native order? */ @@ -12390,8 +16406,9 @@ open_by_idx_check(hid_t main_group_id, hid_t soft_group_id, hid_t mount_file_id, /* Verify opening correct object by index when file mounting is present */ /* Get the address of the root group in the file to mount */ - if(H5Oget_info2(mount_file_id, &oi, H5O_INFO_BASIC) < 0) TEST_ERROR - mnt_root_addr = oi.addr; + if(H5Oget_info3(mount_file_id, &oi, H5O_INFO_BASIC) < 0) + TEST_ERROR + HDmemcpy(&mnt_root_token, &oi.token, sizeof(mnt_root_token)); /* Mount a file over a group in main group */ mnt_idx = 2; @@ -12402,11 +16419,13 @@ open_by_idx_check(hid_t main_group_id, hid_t soft_group_id, hid_t mount_file_id, if((obj_id = H5Oopen_by_idx(group_id, ".", H5_INDEX_NAME, H5_ITER_INC, (hsize_t)mnt_idx, H5P_DEFAULT)) < 0) TEST_ERROR /* Get the object's information */ - if(H5Oget_info2(obj_id, &oi, H5O_INFO_BASIC) < 0) TEST_ERROR + if(H5Oget_info3(obj_id, &oi, H5O_INFO_BASIC) < 0) TEST_ERROR /* Check that the object is the root of the mounted file and not in the previous file */ - if(H5F_addr_ne(oi.addr, mnt_root_addr)) TEST_ERROR - if(H5F_addr_eq(oi.addr, objno[mnt_idx])) TEST_ERROR + if(H5Otoken_cmp(obj_id, &oi.token, &mnt_root_token, &token_cmp) < 0) TEST_ERROR + if(token_cmp) TEST_ERROR + if(H5Otoken_cmp(obj_id, &oi.token, &objno[mnt_idx], &token_cmp) < 0) TEST_ERROR + if(!token_cmp) TEST_ERROR /* Close object */ if(H5Oclose(obj_id) < 0) TEST_ERROR @@ -12445,11 +16464,11 @@ open_by_idx(hid_t fapl) unsigned use_index; /* Use index on creation order values */ unsigned max_compact; /* Maximum # of links to store in group compactly */ unsigned min_dense; /* Minimum # of links to store in group "densely" */ - H5O_info_t oi; /* Buffer for querying object's info */ + H5O_info2_t oi; /* Buffer for querying object's info */ char filename[NAME_BUF_SIZE];/* File name */ char objname[NAME_BUF_SIZE]; /* Object name */ char valname[2 * NAME_BUF_SIZE]; /* Link value */ - haddr_t *objno = NULL; /* Addresses of the objects created */ + H5O_token_t *objno = NULL; /* Tokens (addresses) of the objects created */ unsigned u; /* Local index variable */ hid_t ret; /* Generic return value */ @@ -12459,8 +16478,8 @@ open_by_idx(hid_t fapl) /* Query the group creation properties */ if(H5Pget_link_phase_change(gcpl_id, &max_compact, &min_dense) < 0) TEST_ERROR - /* Allocate object address array */ - if(NULL == (objno = (haddr_t *)HDmalloc(sizeof(haddr_t) * (max_compact * 2)))) TEST_ERROR + /* Allocate object token array */ + if(NULL == (objno = (H5O_token_t *)HDmalloc(sizeof(H5O_token_t) * (max_compact * 2)))) TEST_ERROR /* Create file to mount */ h5_fixname(FILENAME[1], fapl, filename, sizeof filename); @@ -12546,8 +16565,8 @@ open_by_idx(hid_t fapl) if((group_id2 = H5Gcreate2(group_id, objname, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR /* Retrieve group's address on disk */ - if(H5Oget_info2(group_id2, &oi, H5O_INFO_BASIC) < 0) TEST_ERROR - objno[u] = oi.addr; + if(H5Oget_info3(group_id2, &oi, H5O_INFO_BASIC) < 0) TEST_ERROR + objno[u] = oi.token; /* Close group created */ if(H5Gclose(group_id2) < 0) TEST_ERROR @@ -12555,7 +16574,7 @@ open_by_idx(hid_t fapl) /* Create soft link in another group, to objects in main group */ HDsnprintf(valname, sizeof(valname), "/%s/%s", CORDER_GROUP_NAME, objname); if(H5Lcreate_soft(valname, soft_group_id, objname, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR - } /* end for */ + } /* Verify state of group (compact) */ if(H5G__has_links_test(group_id, NULL) != TRUE) TEST_ERROR @@ -12580,8 +16599,8 @@ open_by_idx(hid_t fapl) if((group_id2 = H5Gcreate2(group_id, objname, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR /* Retrieve group's address on disk */ - if(H5Oget_info2(group_id2, &oi, H5O_INFO_BASIC) < 0) TEST_ERROR - objno[u] = oi.addr; + if(H5Oget_info3(group_id2, &oi, H5O_INFO_BASIC) < 0) TEST_ERROR + objno[u] = oi.token; /* Close group created */ if(H5Gclose(group_id2) < 0) TEST_ERROR @@ -12645,6 +16664,100 @@ error: /*------------------------------------------------------------------------- + * Function: open_by_idx_check_old + * + * Purpose: Check opening by index in a group + * + * Return: Success: 0 + * Failure: -1 + *------------------------------------------------------------------------- + */ +static int +open_by_idx_check_old(hid_t main_group_id, hid_t soft_group_id, hid_t mount_file_id, + H5_index_t idx_type, H5_iter_order_t order, unsigned max_links, H5O_token_t *objno) +{ + char mntname[NAME_BUF_SIZE]; /* Link value */ + hid_t group_id = -1; /* ID of group to test */ + H5O_info2_t oi; /* Buffer for querying object's info */ + H5O_token_t mnt_root_token; /* Token of root group in file to mount */ + hid_t obj_id; /* ID of object opened */ + unsigned mnt_idx; /* Index to mount group on */ + unsigned u, v; /* Local index variables */ + int cmp_value; /* Token comparison value */ + + /* Work through main & soft link groups */ + for(v = 0; v < 2; v++) { + /* Choose appropriate group to open links within */ + if(0 == v) + group_id = main_group_id; + else + group_id = soft_group_id; + + /* Open each object in main group by index and check that it's the correct one */ + for(u = 0; u < max_links; u++) { + /* Open the object */ + if((obj_id = H5Oopen_by_idx(group_id, ".", idx_type, order, (hsize_t)u, H5P_DEFAULT)) < 0) TEST_ERROR + + /* Get the object's information */ + if(H5Oget_info3(obj_id, &oi, H5O_INFO_BASIC) < 0) TEST_ERROR + + /* Check that the object is the correct one */ + if(order == H5_ITER_INC) { + if(H5Otoken_cmp(group_id, &oi.token, &objno[u], &cmp_value) < 0) TEST_ERROR + if(0 != cmp_value) TEST_ERROR + } /* end if */ + else if(order == H5_ITER_DEC) { + unsigned dec_u = max_links - (u + 1); /* Decreasing mapped index */ + + if(H5Otoken_cmp(group_id, &oi.token, &objno[dec_u], &cmp_value) < 0) TEST_ERROR + if(0 != cmp_value) TEST_ERROR + } /* end if */ + else { + /* XXX: What to do about native order? */ + } /* end else */ + + /* Close object */ + if(H5Oclose(obj_id) < 0) TEST_ERROR + } /* end for */ + } /* end for */ + + /* Verify opening correct object by index when file mounting is present */ + + /* Get the address of the root group in the file to mount */ + if(H5Oget_info3(mount_file_id, &oi, H5O_INFO_BASIC) < 0) TEST_ERROR + mnt_root_token = oi.token; + + /* Mount a file over a group in main group */ + mnt_idx = 2; + HDsnprintf(mntname, sizeof(mntname), "/%s/filler %02u", CORDER_GROUP_NAME, mnt_idx); + if(H5Fmount(main_group_id, mntname, mount_file_id, H5P_DEFAULT) < 0) TEST_ERROR + + /* Open the object that the file is mounted on */ + if((obj_id = H5Oopen_by_idx(group_id, ".", H5_INDEX_NAME, H5_ITER_INC, (hsize_t)mnt_idx, H5P_DEFAULT)) < 0) TEST_ERROR + + /* Get the object's information */ + if(H5Oget_info3(obj_id, &oi, H5O_INFO_BASIC) < 0) TEST_ERROR + + /* Check that the object is the root of the mounted file and not in the previous file */ + if(H5Otoken_cmp(group_id, &oi.token, &mnt_root_token, &cmp_value) < 0) TEST_ERROR + if(0 != cmp_value) TEST_ERROR + if(H5Otoken_cmp(group_id, &oi.token, &objno[mnt_idx], &cmp_value) < 0) TEST_ERROR + if(0 == cmp_value) TEST_ERROR + + /* Close object */ + if(H5Oclose(obj_id) < 0) TEST_ERROR + + /* Unmount the file */ + if(H5Funmount(main_group_id, mntname) < 0) TEST_ERROR + + /* Success */ + return SUCCEED; + +error: + return FAIL; +} /* end open_by_idx_check_old() */ + +/*------------------------------------------------------------------------- * Function: open_by_idx_old * * Purpose: Create an old-style group and test opening @@ -12662,11 +16775,11 @@ open_by_idx_old(hid_t fapl) hid_t group_id = -1; /* Group ID */ hid_t soft_group_id = -1; /* Group ID for soft links */ H5_iter_order_t order; /* Order within in the index */ - H5O_info_t oi; /* Buffer for querying object's info */ + H5O_info2_t oi; /* Buffer for querying object's info */ char filename[NAME_BUF_SIZE];/* File name */ char objname[NAME_BUF_SIZE]; /* Object name */ char valname[2 * NAME_BUF_SIZE]; /* Link value */ - haddr_t objno[CORDER_NLINKS]; /* Addresses of the objects created */ + H5O_token_t objno[CORDER_NLINKS]; /* Tokens for the objects created */ unsigned u; /* Local index variable */ hid_t ret; /* Generic return value */ @@ -12716,8 +16829,8 @@ open_by_idx_old(hid_t fapl) if((group_id2 = H5Gcreate2(group_id, objname, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR /* Retrieve group's address on disk */ - if(H5Oget_info2(group_id2, &oi, H5O_INFO_BASIC) < 0) TEST_ERROR - objno[u] = oi.addr; + if(H5Oget_info3(group_id2, &oi, H5O_INFO_BASIC) < 0) TEST_ERROR + objno[u] = oi.token; /* Close group created */ if(H5Gclose(group_id2) < 0) TEST_ERROR @@ -12743,7 +16856,7 @@ open_by_idx_old(hid_t fapl) if(ret >= 0) TEST_ERROR /* Verify opening objects by index */ - if(open_by_idx_check(group_id, soft_group_id, mount_file_id, H5_INDEX_NAME, order, u, objno) < 0) TEST_ERROR + if(open_by_idx_check_old(group_id, soft_group_id, mount_file_id, H5_INDEX_NAME, order, u, objno) < 0) TEST_ERROR /* Close the groups */ if(H5Gclose(group_id) < 0) TEST_ERROR @@ -12784,12 +16897,13 @@ error: */ static int object_info_check(hid_t main_group_id, hid_t soft_group_id, H5_index_t idx_type, - H5_iter_order_t order, unsigned max_links, haddr_t *objno) + H5_iter_order_t order, unsigned max_links, H5O_token_t *objno) { char objname[NAME_BUF_SIZE]; /* Object name */ hid_t group_id = -1; /* ID of group to test */ - H5O_info_t oinfo; /* Buffer for querying object's info */ + H5O_info2_t oinfo; /* Buffer for querying object's info */ unsigned u, v; /* Local index variables */ + int token_cmp; /* Work through main & soft link groups */ for(v = 0; v < 2; v++) { @@ -12805,25 +16919,28 @@ object_info_check(hid_t main_group_id, hid_t soft_group_id, H5_index_t idx_type, HDsnprintf(objname, sizeof(objname), "filler %02u", u); /* Query the object's information, by name */ - if(H5Oget_info_by_name2(group_id, objname, &oinfo, H5O_INFO_BASIC|H5O_INFO_NUM_ATTRS, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Oget_info_by_name3(group_id, objname, &oinfo, H5O_INFO_BASIC|H5O_INFO_NUM_ATTRS, H5P_DEFAULT) < 0) TEST_ERROR /* Check that the object is the correct one */ - if(H5F_addr_ne(oinfo.addr, objno[u])) TEST_ERROR - if(H5F_addr_ne(oinfo.num_attrs, u)) TEST_ERROR + if(H5Otoken_cmp(group_id, &oinfo.token, &objno[u], &token_cmp) < 0) TEST_ERROR + if(token_cmp) TEST_ERROR + if(oinfo.num_attrs != u) TEST_ERROR /* Query the object's information, by index */ - if(H5Oget_info_by_idx2(group_id, ".", idx_type, order, (hsize_t)u, &oinfo, H5O_INFO_BASIC|H5O_INFO_NUM_ATTRS, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Oget_info_by_idx3(group_id, ".", idx_type, order, (hsize_t)u, &oinfo, H5O_INFO_BASIC|H5O_INFO_NUM_ATTRS, H5P_DEFAULT) < 0) TEST_ERROR /* Check that the object is the correct one */ if(order == H5_ITER_INC) { - if(H5F_addr_ne(oinfo.addr, objno[u])) TEST_ERROR - if(H5F_addr_ne(oinfo.num_attrs, u)) TEST_ERROR + if(H5Otoken_cmp(group_id, &oinfo.token, &objno[u], &token_cmp) < 0) TEST_ERROR + if(token_cmp) TEST_ERROR + if(oinfo.num_attrs != u) TEST_ERROR } /* end if */ else if(order == H5_ITER_DEC) { unsigned dec_u = max_links - (u + 1); /* Decreasing mapped index */ - if(H5F_addr_ne(oinfo.addr, objno[dec_u])) TEST_ERROR - if(H5F_addr_ne(oinfo.num_attrs, dec_u)) TEST_ERROR + if(H5Otoken_cmp(group_id, &oinfo.token, &objno[dec_u], &token_cmp) < 0) TEST_ERROR + if(token_cmp) TEST_ERROR + if(oinfo.num_attrs != dec_u) TEST_ERROR } /* end if */ else { /* XXX: What to do about native order? */ @@ -12863,12 +16980,12 @@ object_info(hid_t fapl) unsigned use_index; /* Use index on creation order values */ unsigned max_compact; /* Maximum # of links to store in group compactly */ unsigned min_dense; /* Minimum # of links to store in group "densely" */ - H5O_info_t oinfo; /* Buffer for querying object's info */ + H5O_info2_t oinfo; /* Buffer for querying object's info */ char filename[NAME_BUF_SIZE];/* File name */ char objname[NAME_BUF_SIZE]; /* Object name */ char valname[2 * NAME_BUF_SIZE]; /* Link value */ char attrname[NAME_BUF_SIZE]; /* Attribute name */ - haddr_t *objno = NULL; /* Addresses of the objects created */ + H5O_token_t *objno = NULL; /* Tokens (addresses) of the objects created */ herr_t ret; /* Generic return value */ unsigned u, v; /* Local index variables */ @@ -12878,8 +16995,8 @@ object_info(hid_t fapl) /* Query the group creation properties */ if(H5Pget_link_phase_change(gcpl_id, &max_compact, &min_dense) < 0) TEST_ERROR - /* Allocate object address array */ - if(NULL == (objno = (haddr_t *)HDmalloc(sizeof(haddr_t) * (max_compact * 2)))) TEST_ERROR + /* Allocate object token array */ + if(NULL == (objno = (H5O_token_t *)HDmalloc(sizeof(H5O_token_t) * (max_compact * 2)))) TEST_ERROR /* Create dataspace for attributes */ if((space_id = H5Screate(H5S_SCALAR)) < 0) TEST_ERROR @@ -12950,7 +17067,7 @@ object_info(hid_t fapl) /* Check for out of bound query by index on empty group */ H5E_BEGIN_TRY { - ret = H5Oget_info_by_idx2(group_id, ".", H5_INDEX_NAME, order, (hsize_t)0, &oinfo, H5O_INFO_BASIC, H5P_DEFAULT); + ret = H5Oget_info_by_idx3(group_id, ".", H5_INDEX_NAME, order, (hsize_t)0, &oinfo, H5O_INFO_BASIC, H5P_DEFAULT); } H5E_END_TRY; if(ret >= 0) TEST_ERROR @@ -12966,8 +17083,8 @@ object_info(hid_t fapl) if((group_id2 = H5Gcreate2(group_id, objname, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR /* Retrieve group's address on disk */ - if(H5Oget_info2(group_id2, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR - objno[u] = oinfo.addr; + if(H5Oget_info3(group_id2, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR + objno[u] = oinfo.token; /* Create attributes on new object */ for(v = 0; v < u; v++) { @@ -12994,7 +17111,7 @@ object_info(hid_t fapl) /* Check for out of bound query by index */ H5E_BEGIN_TRY { - ret = H5Oget_info_by_idx2(group_id, ".", H5_INDEX_NAME, order, (hsize_t)u, &oinfo, H5O_INFO_BASIC, H5P_DEFAULT); + ret = H5Oget_info_by_idx3(group_id, ".", H5_INDEX_NAME, order, (hsize_t)u, &oinfo, H5O_INFO_BASIC, H5P_DEFAULT); } H5E_END_TRY; if(ret >= 0) TEST_ERROR @@ -13014,8 +17131,8 @@ object_info(hid_t fapl) if((group_id2 = H5Gcreate2(group_id, objname, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR /* Retrieve group's address on disk */ - if(H5Oget_info2(group_id2, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR - objno[u] = oinfo.addr; + if(H5Oget_info3(group_id2, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR + objno[u] = oinfo.token; /* Create attributes on new object */ for(v = 0; v < u; v++) { @@ -13042,7 +17159,7 @@ object_info(hid_t fapl) /* Check for out of bound query by index */ H5E_BEGIN_TRY { - ret = H5Oget_info_by_idx2(group_id, ".", H5_INDEX_NAME, order, (hsize_t)u, &oinfo, H5O_INFO_BASIC, H5P_DEFAULT); + ret = H5Oget_info_by_idx3(group_id, ".", H5_INDEX_NAME, order, (hsize_t)u, &oinfo, H5O_INFO_BASIC, H5P_DEFAULT); } H5E_END_TRY; if(ret >= 0) TEST_ERROR @@ -13088,6 +17205,77 @@ error: /*------------------------------------------------------------------------- + * Function: object_info_check_old + * + * Purpose: Check querying object info in a group + * + * Return: Success: 0 + * Failure: -1 + *------------------------------------------------------------------------- + */ +static int +object_info_check_old(hid_t main_group_id, hid_t soft_group_id, H5_index_t idx_type, + H5_iter_order_t order, unsigned max_links, H5O_token_t *objno) +{ + char objname[NAME_BUF_SIZE]; /* Object name */ + hid_t group_id = -1; /* ID of group to test */ + H5O_info2_t oinfo; /* Buffer for querying object's info */ + unsigned u, v; /* Local index variables */ + + /* Work through main & soft link groups */ + for(v = 0; v < 2; v++) { + /* Choose appropriate group to open links within */ + if(0 == v) + group_id = main_group_id; + else + group_id = soft_group_id; + + /* Open each object in group by name and check that it's the correct one */ + for(u = 0; u < max_links; u++) { + int cmp_value; /* Token comparison value */ + + /* Make name for link */ + HDsnprintf(objname, sizeof(objname), "filler %02u", u); + + /* Query the object's information, by name */ + if(H5Oget_info_by_name3(group_id, objname, &oinfo, H5O_INFO_BASIC|H5O_INFO_NUM_ATTRS, H5P_DEFAULT) < 0) TEST_ERROR + + /* Check that the object is the correct one */ + if(H5Otoken_cmp(group_id, &oinfo.token, &objno[u], &cmp_value) < 0) TEST_ERROR + if(0 != cmp_value) TEST_ERROR + if(oinfo.num_attrs != u) TEST_ERROR + + /* Query the object's information, by index */ + if(H5Oget_info_by_idx3(group_id, ".", idx_type, order, (hsize_t)u, &oinfo, H5O_INFO_BASIC|H5O_INFO_NUM_ATTRS, H5P_DEFAULT) < 0) TEST_ERROR + + /* Check that the object is the correct one */ + if(order == H5_ITER_INC) { + if(H5Otoken_cmp(group_id, &oinfo.token, &objno[u], &cmp_value) < 0) TEST_ERROR + if(0 != cmp_value) TEST_ERROR + if(oinfo.num_attrs != u) TEST_ERROR + } + else if(order == H5_ITER_DEC) { + unsigned dec_u = max_links - (u + 1); /* Decreasing mapped index */ + + if(H5Otoken_cmp(group_id, &oinfo.token, &objno[dec_u], &cmp_value) < 0) TEST_ERROR + if(0 != cmp_value) TEST_ERROR + if(oinfo.num_attrs != dec_u) TEST_ERROR + } + else { + /* XXX: What to do about native order? */ + } + + } /* end for */ + } /* end for */ + + /* Success */ + return SUCCEED; + +error: + return FAIL; +} /* end object_info_check_old() */ + +/*------------------------------------------------------------------------- * Function: object_info_old * * Purpose: Create an old-style group test querying object info. @@ -13104,12 +17292,12 @@ object_info_old(hid_t fapl) hid_t soft_group_id = -1; /* Group ID for soft links */ hid_t space_id = -1; /* Dataspace ID (for attributes) */ H5_iter_order_t order; /* Order within in the index */ - H5O_info_t oinfo; /* Buffer for querying object's info */ + H5O_info2_t oinfo; /* Buffer for querying object's info */ char filename[NAME_BUF_SIZE];/* File name */ char objname[NAME_BUF_SIZE]; /* Object name */ char valname[2 * NAME_BUF_SIZE]; /* Link value */ char attrname[NAME_BUF_SIZE]; /* Attribute name */ - haddr_t objno[CORDER_NLINKS]; /* Addresses of the objects created */ + H5O_token_t objno[CORDER_NLINKS]; /* Tokens for the objects created */ herr_t ret; /* Generic return value */ unsigned u, v; /* Local index variables */ @@ -13143,7 +17331,7 @@ object_info_old(hid_t fapl) /* Check for out of bound query by index on empty group */ H5E_BEGIN_TRY { - ret = H5Oget_info_by_idx2(group_id, ".", H5_INDEX_NAME, order, (hsize_t)0, &oinfo, H5O_INFO_BASIC, H5P_DEFAULT); + ret = H5Oget_info_by_idx3(group_id, ".", H5_INDEX_NAME, order, (hsize_t)0, &oinfo, H5O_INFO_BASIC, H5P_DEFAULT); } H5E_END_TRY; if(ret >= 0) TEST_ERROR @@ -13159,8 +17347,8 @@ object_info_old(hid_t fapl) if((group_id2 = H5Gcreate2(group_id, objname, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR /* Retrieve group's address on disk */ - if(H5Oget_info2(group_id2, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR - objno[u] = oinfo.addr; + if(H5Oget_info3(group_id2, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR + objno[u] = oinfo.token; /* Create attributes on new object */ for(v = 0; v < u; v++) { @@ -13187,18 +17375,18 @@ object_info_old(hid_t fapl) /* Check for out of bound query by index */ H5E_BEGIN_TRY { - ret = H5Oget_info_by_idx2(group_id, ".", H5_INDEX_NAME, order, (hsize_t)u, &oinfo, H5O_INFO_BASIC, H5P_DEFAULT); + ret = H5Oget_info_by_idx3(group_id, ".", H5_INDEX_NAME, order, (hsize_t)u, &oinfo, H5O_INFO_BASIC, H5P_DEFAULT); } H5E_END_TRY; if(ret >= 0) TEST_ERROR /* Check for creation order index query */ H5E_BEGIN_TRY { - ret = H5Oget_info_by_idx2(group_id, ".", H5_INDEX_CRT_ORDER, order, (hsize_t)(u - 1), &oinfo, H5O_INFO_BASIC, H5P_DEFAULT); + ret = H5Oget_info_by_idx3(group_id, ".", H5_INDEX_CRT_ORDER, order, (hsize_t)(u - 1), &oinfo, H5O_INFO_BASIC, H5P_DEFAULT); } H5E_END_TRY; if(ret >= 0) TEST_ERROR /* Verify querying objects by name */ - if(object_info_check(group_id, soft_group_id, H5_INDEX_NAME, order, u, objno) < 0) TEST_ERROR + if(object_info_check_old(group_id, soft_group_id, H5_INDEX_NAME, order, u, objno) < 0) TEST_ERROR /* Close the groups */ if(H5Gclose(group_id) < 0) TEST_ERROR @@ -13867,7 +18055,8 @@ timestamps(hid_t fapl) hid_t group_id2 = -1; /* Group ID */ hid_t gcpl_id = -1; /* Group creation property list ID */ hid_t gcpl_id2 = -1; /* Group creation property list ID */ - H5O_info_t oinfo, oinfo2; /* Object info for groups created */ + H5O_info2_t oinfo, oinfo2; /* Object info for groups created */ + H5O_native_info_t ninfo, ninfo2; /* Native info for groups created */ char filename[NAME_BUF_SIZE];/* File name */ hbool_t track_times; /* The object timestamp setting */ @@ -13916,10 +18105,15 @@ timestamps(hid_t fapl) if(track_times != TRUE) TEST_ERROR /* Query the object information for each group */ - if(H5Oget_info2(group_id, &oinfo, H5O_INFO_TIME|H5O_INFO_HDR) < 0) TEST_ERROR - if(H5Oget_info2(group_id2, &oinfo2, H5O_INFO_TIME|H5O_INFO_HDR) < 0) TEST_ERROR + /* Generic info */ + if(H5Oget_info3(group_id, &oinfo, H5O_INFO_TIME) < 0) TEST_ERROR + if(H5Oget_info3(group_id2, &oinfo2, H5O_INFO_TIME) < 0) TEST_ERROR + /* Native file format info */ + if(H5Oget_native_info(group_id, &ninfo, H5O_NATIVE_INFO_HDR) < 0) TEST_ERROR + if(H5Oget_native_info(group_id2, &ninfo2, H5O_NATIVE_INFO_HDR) < 0) TEST_ERROR /* Sanity check object information for each group */ + /* Generic info */ if(oinfo.atime != 0) TEST_ERROR if(oinfo.mtime != 0) TEST_ERROR if(oinfo.ctime != 0) TEST_ERROR @@ -13928,10 +18122,11 @@ timestamps(hid_t fapl) if(oinfo.mtime == oinfo2.mtime) TEST_ERROR if(oinfo.ctime == oinfo2.ctime) TEST_ERROR if(oinfo.btime == oinfo2.btime) TEST_ERROR - if((oinfo.hdr.flags & H5O_HDR_STORE_TIMES) != 0) TEST_ERROR - if((oinfo2.hdr.flags & H5O_HDR_STORE_TIMES) == 0) TEST_ERROR - if(oinfo.hdr.space.total >= oinfo2.hdr.space.total) TEST_ERROR - if(oinfo.hdr.space.meta >= oinfo2.hdr.space.meta) TEST_ERROR + /* Native file format info */ + if((ninfo.hdr.flags & H5O_HDR_STORE_TIMES) != 0) TEST_ERROR + if((ninfo2.hdr.flags & H5O_HDR_STORE_TIMES) == 0) TEST_ERROR + if(ninfo.hdr.space.total >= ninfo2.hdr.space.total) TEST_ERROR + if(ninfo.hdr.space.meta >= ninfo2.hdr.space.meta) TEST_ERROR /* Close the property lists */ if(H5Pclose(gcpl_id) < 0) TEST_ERROR @@ -13962,10 +18157,14 @@ timestamps(hid_t fapl) if(track_times != TRUE) TEST_ERROR /* Query the object information for each group */ - if(H5Oget_info2(group_id, &oinfo, H5O_INFO_TIME|H5O_INFO_HDR) < 0) TEST_ERROR - if(H5Oget_info2(group_id2, &oinfo2, H5O_INFO_TIME|H5O_INFO_HDR) < 0) TEST_ERROR + if(H5Oget_info3(group_id, &oinfo, H5O_INFO_TIME) < 0) TEST_ERROR + if(H5Oget_info3(group_id2, &oinfo2, H5O_INFO_TIME) < 0) TEST_ERROR + /* Native file format info */ + if(H5Oget_native_info(group_id, &ninfo, H5O_NATIVE_INFO_HDR) < 0) TEST_ERROR + if(H5Oget_native_info(group_id2, &ninfo2, H5O_NATIVE_INFO_HDR) < 0) TEST_ERROR /* Sanity check object information for each group */ + /* Generic info */ if(oinfo.atime != 0) TEST_ERROR if(oinfo.mtime != 0) TEST_ERROR if(oinfo.ctime != 0) TEST_ERROR @@ -13974,10 +18173,11 @@ timestamps(hid_t fapl) if(oinfo.mtime == oinfo2.mtime) TEST_ERROR if(oinfo.ctime == oinfo2.ctime) TEST_ERROR if(oinfo.btime == oinfo2.btime) TEST_ERROR - if((oinfo.hdr.flags & H5O_HDR_STORE_TIMES) != 0) TEST_ERROR - if((oinfo2.hdr.flags & H5O_HDR_STORE_TIMES) == 0) TEST_ERROR - if(oinfo.hdr.space.total >= oinfo2.hdr.space.total) TEST_ERROR - if(oinfo.hdr.space.meta >= oinfo2.hdr.space.meta) TEST_ERROR + /* Native file format info */ + if((ninfo.hdr.flags & H5O_HDR_STORE_TIMES) != 0) TEST_ERROR + if((ninfo2.hdr.flags & H5O_HDR_STORE_TIMES) == 0) TEST_ERROR + if(ninfo.hdr.space.total >= ninfo2.hdr.space.total) TEST_ERROR + if(ninfo.hdr.space.meta >= ninfo2.hdr.space.meta) TEST_ERROR /* Close the property lists */ if(H5Pclose(gcpl_id) < 0) TEST_ERROR @@ -14065,6 +18265,9 @@ main(void) /* General tests... (on both old & new format groups */ nerrors += mklinks(my_fapl, new_format) < 0 ? 1 : 0; nerrors += cklinks(my_fapl, new_format) < 0 ? 1 : 0; +#ifndef H5_NO_DEPRECATED_SYMBOLS + nerrors += cklinks_deprec(my_fapl, new_format) < 0 ? 1 : 0; +#endif /* H5_NO_DEPRECATED_SYMBOLS */ nerrors += new_links(my_fapl, new_format) < 0 ? 1 : 0; nerrors += ck_new_links(my_fapl, new_format) < 0 ? 1 : 0; nerrors += long_links(my_fapl, new_format) < 0 ? 1 : 0; @@ -14072,13 +18275,18 @@ main(void) /* Test new H5L link creation routine */ nerrors += test_lcpl(my_fapl, new_format); +#ifndef H5_NO_DEPRECATED_SYMBOLS + nerrors += test_lcpl_deprec(my_fapl, new_format); +#endif /* H5_NO_DEPRECATED_SYMBOLS */ nerrors += test_move(my_fapl, new_format); nerrors += test_copy(my_fapl, new_format); nerrors += test_move_preserves(my_fapl, new_format); #ifndef H5_NO_DEPRECATED_SYMBOLS + nerrors += test_move_preserves_deprec(my_fapl, new_format); nerrors += test_deprec(my_fapl, new_format); #endif /* H5_NO_DEPRECATED_SYMBOLS */ + /* tests for external link */ /* Test external file cache first, so it sees the default efc setting on the fapl */ @@ -14106,6 +18314,9 @@ main(void) } /* end else */ nerrors += external_link_root(my_fapl, new_format) < 0 ? 1 : 0; +#ifndef H5_NO_DEPRECATED_SYMBOLS + nerrors += external_link_root_deprec(my_fapl, new_format) < 0 ? 1 : 0; +#endif /* H5_NO_DEPRECATED_SYMBOLS */ nerrors += external_link_path(my_fapl, new_format) < 0 ? 1 : 0; nerrors += external_link_self(my_fapl, new_format) < 0 ? 1 : 0; nerrors += external_link_pingpong(my_fapl, new_format) < 0 ? 1 : 0; @@ -14113,11 +18324,17 @@ main(void) nerrors += external_link_dangling(my_fapl, new_format) < 0 ? 1 : 0; nerrors += external_link_recursive(my_fapl, new_format) < 0 ? 1 : 0; nerrors += external_link_query(my_fapl, new_format) < 0 ? 1 : 0; +#ifndef H5_NO_DEPRECATED_SYMBOLS + nerrors += external_link_query_deprec(my_fapl, new_format) < 0 ? 1 : 0; +#endif /* H5_NO_DEPRECATED_SYMBOLS */ nerrors += external_link_unlink_compact(my_fapl, new_format) < 0 ? 1 : 0; nerrors += external_link_unlink_dense(my_fapl, new_format) < 0 ? 1 : 0; nerrors += external_link_move(my_fapl, new_format) < 0 ? 1 : 0; nerrors += external_link_ride(my_fapl, new_format) < 0 ? 1 : 0; nerrors += external_link_closing(my_fapl, new_format) < 0 ? 1 : 0; +#ifndef H5_NO_DEPRECATED_SYMBOLS + nerrors += external_link_closing_deprec(my_fapl, new_format) < 0 ? 1 : 0; +#endif /* H5_NO_DEPRECATED_SYMBOLS */ nerrors += external_link_endian(new_format) < 0 ? 1 : 0; nerrors += external_link_strong(my_fapl, new_format) < 0 ? 1 : 0; @@ -14156,14 +18373,29 @@ main(void) * above has already been tested for UD links. */ if(new_format == TRUE) { - nerrors += ud_hard_links(fapl2) < 0 ? 1 : 0; /* requires new format groups */ - nerrors += ud_link_reregister(fapl2) < 0 ? 1 : 0; /* requires new format groups */ + nerrors += ud_hard_links(fapl2) < 0 ? 1 : 0; /* requires new format groups */ +#ifndef H5_NO_DEPRECATED_SYMBOLS + nerrors += ud_hard_links_deprec(fapl2) < 0 ? 1 : 0; /* requires new format groups */ +#endif /* H5_NO_DEPRECATED_SYMBOLS */ + nerrors += ud_link_reregister(fapl2) < 0 ? 1 : 0; /* requires new format groups */ +#ifndef H5_NO_DEPRECATED_SYMBOLS + nerrors += ud_link_reregister_deprec(fapl2) < 0 ? 1 : 0; /* requires new format groups */ +#endif /* H5_NO_DEPRECATED_SYMBOLS */ } /* end if */ nerrors += ud_callbacks(my_fapl, new_format) < 0 ? 1 : 0; +#ifndef H5_NO_DEPRECATED_SYMBOLS + nerrors += ud_callbacks_deprec(my_fapl, new_format) < 0 ? 1 : 0; +#endif /* H5_NO_DEPRECATED_SYMBOLS */ nerrors += ud_link_errors(my_fapl, new_format) < 0 ? 1 : 0; nerrors += lapl_udata(my_fapl, new_format) < 0 ? 1 : 0; nerrors += lapl_nlinks(my_fapl, new_format) < 0 ? 1 : 0; +#ifndef H5_NO_DEPRECATED_SYMBOLS + nerrors += lapl_nlinks_deprec(my_fapl, new_format) < 0 ? 1 : 0; +#endif /* H5_NO_DEPRECATED_SYMBOLS */ nerrors += linkinfo(my_fapl, new_format) < 0 ? 1 : 0; +#ifndef H5_NO_DEPRECATED_SYMBOLS + nerrors += linkinfo_deprec(my_fapl, new_format) < 0 ? 1 : 0; +#endif /* H5_NO_DEPRECATED_SYMBOLS */ /* Misc. extra tests, useful for both new & old format files */ nerrors += link_visit(my_fapl, new_format) < 0 ? 1 : 0; @@ -14187,12 +18419,27 @@ main(void) * correct. */ nerrors += corder_create_compact(fapl2) < 0 ? 1 : 0; +#ifndef H5_NO_DEPRECATED_SYMBOLS + nerrors += corder_create_compact_deprec(fapl2) < 0 ? 1 : 0; +#endif /* H5_NO_DEPRECATED_SYMBOLS */ nerrors += corder_create_dense(fapl2) < 0 ? 1 : 0; +#ifndef H5_NO_DEPRECATED_SYMBOLS + nerrors += corder_create_dense_deprec(fapl2) < 0 ? 1 : 0; +#endif /* H5_NO_DEPRECATED_SYMBOLS */ nerrors += corder_transition(fapl2) < 0 ? 1 : 0; nerrors += corder_delete(fapl2) < 0 ? 1 : 0; nerrors += link_info_by_idx(fapl2) < 0 ? 1 : 0; +#ifndef H5_NO_DEPRECATED_SYMBOLS + nerrors += link_info_by_idx_deprec(fapl2) < 0 ? 1 : 0; +#endif /* H5_NO_DEPRECATED_SYMBOLS */ nerrors += delete_by_idx(fapl2) < 0 ? 1 : 0; +#ifndef H5_NO_DEPRECATED_SYMBOLS + nerrors += delete_by_idx_deprec(fapl2) < 0 ? 1 : 0; +#endif /* H5_NO_DEPRECATED_SYMBOLS */ nerrors += link_iterate(fapl2) < 0 ? 1 : 0; +#ifndef H5_NO_DEPRECATED_SYMBOLS + nerrors += link_iterate_deprec(fapl2) < 0 ? 1 : 0; +#endif /* H5_NO_DEPRECATED_SYMBOLS */ nerrors += open_by_idx(fapl2) < 0 ? 1 : 0; nerrors += object_info(fapl2) < 0 ? 1 : 0; nerrors += group_info(fapl2) < 0 ? 1 : 0; @@ -14200,8 +18447,17 @@ main(void) /* Test new API calls on old-style groups */ nerrors += link_info_by_idx_old(fapl) < 0 ? 1 : 0; +#ifndef H5_NO_DEPRECATED_SYMBOLS + nerrors += link_info_by_idx_old_deprec(fapl) < 0 ? 1 : 0; +#endif /* H5_NO_DEPRECATED_SYMBOLS */ nerrors += delete_by_idx_old(fapl) < 0 ? 1 : 0; +#ifndef H5_NO_DEPRECATED_SYMBOLS + nerrors += delete_by_idx_old_deprec(fapl) < 0 ? 1 : 0; +#endif /* H5_NO_DEPRECATED_SYMBOLS */ nerrors += link_iterate_old(fapl) < 0 ? 1 : 0; +#ifndef H5_NO_DEPRECATED_SYMBOLS + nerrors += link_iterate_old_deprec(fapl) < 0 ? 1 : 0; +#endif /* H5_NO_DEPRECATED_SYMBOLS */ nerrors += open_by_idx_old(fapl) < 0 ? 1 : 0; nerrors += object_info_old(fapl) < 0 ? 1 : 0; nerrors += group_info_old(fapl) < 0 ? 1 : 0; diff --git a/test/mount.c b/test/mount.c index 72973ad..3abe084 100644 --- a/test/mount.c +++ b/test/mount.c @@ -400,8 +400,9 @@ static int test_hide(hid_t fapl) { hid_t file1 = -1, file2 = -1, grp = -1; - H5O_info_t oi1, oi2; + H5O_info2_t oi1, oi2; char filename1[1024], filename2[1024]; + hbool_t same_obj; TESTING("name hiding under mount point"); h5_fixname(FILENAME[0], fapl, filename1, sizeof(filename1)); @@ -412,7 +413,7 @@ test_hide(hid_t fapl) FAIL_STACK_ERROR /* Get information about file1:/mnt1/file1 for later */ - if(H5Oget_info_by_name2(file1, "/mnt1/file1", &oi1, H5O_INFO_BASIC, H5P_DEFAULT) < 0) + if(H5Oget_info_by_name3(file1, "/mnt1/file1", &oi1, H5O_INFO_BASIC, H5P_DEFAULT) < 0) FAIL_STACK_ERROR /* Build the virtual file */ @@ -427,19 +428,32 @@ test_hide(hid_t fapl) H5_FAILED(); HDputs(" Name is still accessible under mount point."); TEST_ERROR - } /* end if */ + } /* * The original objects under file1:/mnt1 are still accessible by their * other names. This is a rather stupid test but demonstrates a point. */ - if(H5Oget_info_by_name2(file1, "/file1", &oi2, H5O_INFO_BASIC, H5P_DEFAULT) < 0) + if(H5Oget_info_by_name3(file1, "/file1", &oi2, H5O_INFO_BASIC, H5P_DEFAULT) < 0) FAIL_STACK_ERROR - if(oi1.fileno != oi2.fileno || H5F_addr_ne(oi1.addr, oi2.addr)) { + + same_obj = TRUE; + if(oi1.fileno == oi2.fileno) { + int token_cmp; + + if(H5Otoken_cmp(file1, &oi1.token, &oi2.token, &token_cmp) < 0) + FAIL_STACK_ERROR + if(token_cmp) + same_obj = FALSE; + } + else + same_obj = FALSE; + + if(!same_obj) { H5_FAILED(); HDputs(" Hard link failed for hidden object."); TEST_ERROR - } /* end if */ + } /* Unmount and close objects */ if(H5Funmount(file1, "/mnt1") < 0) FAIL_STACK_ERROR @@ -480,8 +494,9 @@ static int test_assoc(hid_t fapl) { hid_t file1 = -1, file2 = -1; - H5O_info_t oi1, oi2; + H5O_info2_t oi1, oi2; char filename1[1024], filename2[1024]; + hbool_t same_obj; TESTING("mount point open"); h5_fixname(FILENAME[0], fapl, filename1, sizeof filename1); @@ -493,7 +508,7 @@ test_assoc(hid_t fapl) FAIL_STACK_ERROR /* Get information about the root of file2 */ - if(H5Oget_info2(file2, &oi1, H5O_INFO_BASIC) < 0) + if(H5Oget_info3(file2, &oi1, H5O_INFO_BASIC) < 0) FAIL_STACK_ERROR /* Create the virtual file */ @@ -504,11 +519,23 @@ test_assoc(hid_t fapl) * Get info about the mount point -- should be the same as the root group * of file2. */ - if(H5Oget_info_by_name2(file1, "/mnt1", &oi2, H5O_INFO_BASIC, H5P_DEFAULT) < 0) + if(H5Oget_info_by_name3(file1, "/mnt1", &oi2, H5O_INFO_BASIC, H5P_DEFAULT) < 0) FAIL_STACK_ERROR - if(oi1.fileno != oi2.fileno || H5F_addr_ne(oi1.addr, oi2.addr)) { - H5_FAILED(); + same_obj = TRUE; + if(oi1.fileno == oi2.fileno) { + int token_cmp; + + if(H5Otoken_cmp(file1, &oi1.token, &oi2.token, &token_cmp) < 0) + FAIL_STACK_ERROR + if(token_cmp) + same_obj = FALSE; + } + else + same_obj = FALSE; + + if(!same_obj) { + H5_FAILED(); HDputs(" Association failed."); TEST_ERROR } /* end if */ @@ -676,7 +703,7 @@ static int test_preopen(hid_t fapl) { hid_t file1 = -1, file2 = -1, grp = -1; - H5O_info_t oinfo; + H5O_info2_t oinfo; char filename1[1024], filename2[1024]; TESTING("preopening objects under the mount point"); @@ -694,7 +721,7 @@ test_preopen(hid_t fapl) if(H5Fmount(file1, "/mnt1", file2, H5P_DEFAULT) < 0) FAIL_STACK_ERROR /* Now access the thing we previously opened */ - if(H5Oget_info2(grp, &oinfo, H5O_INFO_BASIC) < 0) FAIL_STACK_ERROR + if(H5Oget_info3(grp, &oinfo, H5O_INFO_BASIC) < 0) FAIL_STACK_ERROR /* Shut down */ if(H5Funmount(file1, "/mnt1") < 0) FAIL_STACK_ERROR @@ -738,7 +765,7 @@ test_postopen(hid_t fapl) { hid_t file1 = -1, file2 = -1, grp = -1; - H5O_info_t oinfo; + H5O_info2_t oinfo; char filename1[1024], filename2[1024]; TESTING("open object access after unmount"); @@ -758,10 +785,10 @@ test_postopen(hid_t fapl) if(H5Funmount(file1, "/mnt1") < 0) FAIL_STACK_ERROR /* Now access the thing we previously opened */ - if(H5Oget_info2(grp, &oinfo, H5O_INFO_BASIC) < 0) FAIL_STACK_ERROR + if(H5Oget_info3(grp, &oinfo, H5O_INFO_BASIC) < 0) FAIL_STACK_ERROR /* Try accessing it from the file */ - if(H5Oget_info_by_name2(file2, "/file2", &oinfo, H5O_INFO_BASIC, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + if(H5Oget_info_by_name3(file2, "/file2", &oinfo, H5O_INFO_BASIC, H5P_DEFAULT) < 0) FAIL_STACK_ERROR /* Shut down */ if(H5Gclose(grp) < 0) FAIL_STACK_ERROR @@ -803,7 +830,7 @@ static int test_unlink(hid_t fapl) { hid_t file1 = -1, file2 = -1, mnt = -1, root = -1; - H5O_info_t oinfo; + H5O_info2_t oinfo; char filename1[1024], filename2[1024]; herr_t status; @@ -831,12 +858,12 @@ test_unlink(hid_t fapl) * before the H5Fmount() and thus refers to the mount point itself rather * than the group mounted there. */ - if(H5Oget_info_by_name2(file1, "/mnt_unlink/file2", &oinfo, H5O_INFO_BASIC, H5P_DEFAULT) < 0) FAIL_STACK_ERROR - if(H5Oget_info_by_name2(mnt, "/mnt_unlink/file2", &oinfo, H5O_INFO_BASIC, H5P_DEFAULT) < 0) FAIL_STACK_ERROR - if(H5Oget_info_by_name2(root, "/mnt_unlink/file2", &oinfo, H5O_INFO_BASIC, H5P_DEFAULT) < 0) FAIL_STACK_ERROR - if(H5Oget_info_by_name2(root, "file2", &oinfo, H5O_INFO_BASIC, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + if(H5Oget_info_by_name3(file1, "/mnt_unlink/file2", &oinfo, H5O_INFO_BASIC, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + if(H5Oget_info_by_name3(mnt, "/mnt_unlink/file2", &oinfo, H5O_INFO_BASIC, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + if(H5Oget_info_by_name3(root, "/mnt_unlink/file2", &oinfo, H5O_INFO_BASIC, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + if(H5Oget_info_by_name3(root, "file2", &oinfo, H5O_INFO_BASIC, H5P_DEFAULT) < 0) FAIL_STACK_ERROR H5E_BEGIN_TRY { - status = H5Oget_info_by_name2(mnt, "file2", &oinfo, H5O_INFO_BASIC, H5P_DEFAULT); + status = H5Oget_info_by_name3(mnt, "file2", &oinfo, H5O_INFO_BASIC, H5P_DEFAULT); } H5E_END_TRY; if(status >= 0) { H5_FAILED(); @@ -851,9 +878,9 @@ test_unlink(hid_t fapl) * We should still be able to get to "/file2" of file2 by starting at * `root' which is still open, but not by name. */ - if(H5Oget_info_by_name2(root, "file2", &oinfo, H5O_INFO_BASIC, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + if(H5Oget_info_by_name3(root, "file2", &oinfo, H5O_INFO_BASIC, H5P_DEFAULT) < 0) FAIL_STACK_ERROR H5E_BEGIN_TRY { - status = H5Oget_info_by_name2(mnt, "file2", &oinfo, H5O_INFO_BASIC, H5P_DEFAULT); + status = H5Oget_info_by_name3(mnt, "file2", &oinfo, H5O_INFO_BASIC, H5P_DEFAULT); } H5E_END_TRY; if(status >= 0) { H5_FAILED(); @@ -861,7 +888,7 @@ test_unlink(hid_t fapl) TEST_ERROR } /* end if */ H5E_BEGIN_TRY { - status = H5Oget_info_by_name2(file2, "/mnt_unlink/file2", &oinfo, H5O_INFO_BASIC, H5P_DEFAULT); + status = H5Oget_info_by_name3(file2, "/mnt_unlink/file2", &oinfo, H5O_INFO_BASIC, H5P_DEFAULT); } H5E_END_TRY; if(status >= 0) { H5_FAILED(); @@ -932,7 +959,7 @@ static int test_mvmpt(hid_t fapl) { hid_t file1 = -1, file2 = -1; - H5O_info_t oinfo; + H5O_info2_t oinfo; char filename1[1024], filename2[1024]; TESTING("mount point renaming"); @@ -949,7 +976,7 @@ test_mvmpt(hid_t fapl) if(H5Lmove(file1, "/mnt_move_a", H5L_SAME_LOC, "/mnt_move_b", H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR /* Access something under the new name */ - if(H5Oget_info_by_name2(file1, "/mnt_move_b/file2", &oinfo, H5O_INFO_BASIC, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + if(H5Oget_info_by_name3(file1, "/mnt_move_b/file2", &oinfo, H5O_INFO_BASIC, H5P_DEFAULT) < 0) FAIL_STACK_ERROR /* Shut down */ if(H5Funmount(file1, "/mnt_move_b") < 0) FAIL_STACK_ERROR @@ -1094,7 +1121,7 @@ static int test_uniformity(hid_t fapl) { hid_t file1 = -1, file2 = -1; - H5O_info_t oinfo; + H5O_info2_t oinfo; char filename1[1024], filename2[1024]; TESTING("file handle uniformity"); @@ -1108,18 +1135,18 @@ test_uniformity(hid_t fapl) if(H5Fmount(file1, "/mnt1", file2, H5P_DEFAULT) < 0) FAIL_STACK_ERROR /* Access some things from the file1 handle */ - if(H5Oget_info_by_name2(file1, "/", &oinfo, H5O_INFO_BASIC, H5P_DEFAULT) < 0) FAIL_STACK_ERROR - if(H5Oget_info_by_name2(file1, "/mnt1", &oinfo, H5O_INFO_BASIC, H5P_DEFAULT) < 0) FAIL_STACK_ERROR - if(H5Oget_info_by_name2(file1, "mnt1", &oinfo, H5O_INFO_BASIC, H5P_DEFAULT) < 0) FAIL_STACK_ERROR - if(H5Oget_info_by_name2(file1, "/mnt1/file2", &oinfo, H5O_INFO_BASIC, H5P_DEFAULT) < 0) FAIL_STACK_ERROR - if(H5Oget_info_by_name2(file1, "mnt1/file2", &oinfo, H5O_INFO_BASIC, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + if(H5Oget_info_by_name3(file1, "/", &oinfo, H5O_INFO_BASIC, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + if(H5Oget_info_by_name3(file1, "/mnt1", &oinfo, H5O_INFO_BASIC, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + if(H5Oget_info_by_name3(file1, "mnt1", &oinfo, H5O_INFO_BASIC, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + if(H5Oget_info_by_name3(file1, "/mnt1/file2", &oinfo, H5O_INFO_BASIC, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + if(H5Oget_info_by_name3(file1, "mnt1/file2", &oinfo, H5O_INFO_BASIC, H5P_DEFAULT) < 0) FAIL_STACK_ERROR /* Access the same things from the file2 handle */ - if(H5Oget_info_by_name2(file2, "/", &oinfo, H5O_INFO_BASIC, H5P_DEFAULT) < 0) FAIL_STACK_ERROR - if(H5Oget_info_by_name2(file2, "/mnt1", &oinfo, H5O_INFO_BASIC, H5P_DEFAULT) < 0) FAIL_STACK_ERROR - if(H5Oget_info_by_name2(file2, "mnt1", &oinfo, H5O_INFO_BASIC, H5P_DEFAULT) < 0) FAIL_STACK_ERROR - if(H5Oget_info_by_name2(file2, "/mnt1/file2", &oinfo, H5O_INFO_BASIC, H5P_DEFAULT) < 0) FAIL_STACK_ERROR - if(H5Oget_info_by_name2(file2, "mnt1/file2", &oinfo, H5O_INFO_BASIC, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + if(H5Oget_info_by_name3(file2, "/", &oinfo, H5O_INFO_BASIC, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + if(H5Oget_info_by_name3(file2, "/mnt1", &oinfo, H5O_INFO_BASIC, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + if(H5Oget_info_by_name3(file2, "mnt1", &oinfo, H5O_INFO_BASIC, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + if(H5Oget_info_by_name3(file2, "/mnt1/file2", &oinfo, H5O_INFO_BASIC, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + if(H5Oget_info_by_name3(file2, "mnt1/file2", &oinfo, H5O_INFO_BASIC, H5P_DEFAULT) < 0) FAIL_STACK_ERROR /* Shut down */ if(H5Funmount(file1, "/mnt1") < 0) FAIL_STACK_ERROR @@ -1158,7 +1185,7 @@ static int test_close(hid_t fapl) { hid_t file1 = -1, file2 = -1; - H5O_info_t oinfo; + H5O_info2_t oinfo; char filename1[1024], filename2[1024]; TESTING("file handle close"); @@ -1176,7 +1203,7 @@ test_close(hid_t fapl) * still accessible through the file2 handle. */ if(H5Fclose(file1) < 0) FAIL_STACK_ERROR - if(H5Oget_info_by_name2(file2, "/mnt1", &oinfo, H5O_INFO_BASIC, H5P_DEFAULT) < 0) { + if(H5Oget_info_by_name3(file2, "/mnt1", &oinfo, H5O_INFO_BASIC, H5P_DEFAULT) < 0) { H5_FAILED(); HDputs(" File1 contents are not accessible!"); TEST_ERROR @@ -1197,7 +1224,7 @@ test_close(hid_t fapl) * Close file2. It is not actually closed because it's a child of file1. */ if(H5Fclose(file2) < 0) FAIL_STACK_ERROR - if(H5Oget_info_by_name2(file1, "/mnt1/file2", &oinfo, H5O_INFO_BASIC, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + if(H5Oget_info_by_name3(file1, "/mnt1/file2", &oinfo, H5O_INFO_BASIC, H5P_DEFAULT) < 0) FAIL_STACK_ERROR if(H5Fclose(file1) < 0) FAIL_STACK_ERROR /* Check that all file IDs have been closed */ @@ -2432,7 +2459,7 @@ test_fcdegree_strong(hid_t fapl) hid_t fid1 = -1, fid2 = -1; /* File IDs */ hid_t gidA = -1, gidM = -1, gidAM = -1; /* Group IDs */ hid_t fapl_id = -1; /* FAPL IDs */ - H5O_info_t oinfo; + H5O_info2_t oinfo; char filename1[1024], filename2[1024]; /* Name of files to mount */ herr_t ret; /* Generic return value */ @@ -2501,9 +2528,9 @@ test_fcdegree_strong(hid_t fapl) TEST_ERROR /* Check that objects are still open */ - if(H5Oget_info2(gidA, &oinfo, H5O_INFO_BASIC) < 0) + if(H5Oget_info3(gidA, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR - if(H5Oget_info2(gidAM, &oinfo, H5O_INFO_BASIC) < 0) + if(H5Oget_info3(gidAM, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR /* Close file #2 (should close open objects also) */ @@ -2512,12 +2539,12 @@ test_fcdegree_strong(hid_t fapl) /* Check that objects are closed */ H5E_BEGIN_TRY { - ret = H5Oget_info2(gidA, &oinfo, H5O_INFO_BASIC); + ret = H5Oget_info3(gidA, &oinfo, H5O_INFO_BASIC); } H5E_END_TRY; if(ret >= 0) TEST_ERROR H5E_BEGIN_TRY { - ret = H5Oget_info2(gidAM, &oinfo, H5O_INFO_BASIC); + ret = H5Oget_info3(gidAM, &oinfo, H5O_INFO_BASIC); } H5E_END_TRY; if(ret >= 0) TEST_ERROR diff --git a/test/mtime.c b/test/mtime.c index 06f576b..81a20db 100644 --- a/test/mtime.c +++ b/test/mtime.c @@ -60,9 +60,10 @@ main(void) hsize_t size[1] = {2}; time_t now; struct tm *tm; - H5O_info_t oi1, oi2; + H5O_info2_t oi1, oi2; signed char buf1[32], buf2[32]; char filename[1024]; + int token_cmp; h5_reset(); fapl = h5_fileaccess(); @@ -88,14 +89,15 @@ main(void) */ h5_fixname(FILENAME[0], fapl, filename, sizeof filename); if((file = H5Fopen(filename, H5F_ACC_RDONLY, fapl)) < 0) TEST_ERROR; - if(H5Oget_info_by_name2(file, "dset", &oi1, H5O_INFO_BASIC|H5O_INFO_TIME, H5P_DEFAULT) < 0) TEST_ERROR; + if(H5Oget_info_by_name3(file, "dset", &oi1, H5O_INFO_BASIC|H5O_INFO_TIME, H5P_DEFAULT) < 0) TEST_ERROR; if((dset = H5Dopen2(file, "dset", H5P_DEFAULT)) < 0) TEST_ERROR; - if(H5Oget_info2(dset, &oi2, H5O_INFO_BASIC|H5O_INFO_TIME) < 0) TEST_ERROR; + if(H5Oget_info3(dset, &oi2, H5O_INFO_BASIC|H5O_INFO_TIME) < 0) TEST_ERROR; + if(H5Otoken_cmp(file, &oi1.token, &oi2.token, &token_cmp) < 0)TEST_ERROR; if(H5Dclose(dset) < 0) TEST_ERROR; if(H5Fclose(file) < 0) TEST_ERROR; - /* Compare addresses & times from the two ways of calling H5Oget_info() */ - if(oi1.addr != oi2.addr || oi1.ctime != oi2.ctime) { + /* Compare object tokens & times from the two ways of calling H5Oget_info() */ + if(token_cmp || oi1.ctime != oi2.ctime) { H5_FAILED(); HDputs(" Calling H5Oget_info() with the dataset ID returned"); HDputs(" different values than calling it with a file and dataset"); @@ -132,7 +134,7 @@ main(void) file = H5Fopen(testfile, H5F_ACC_RDONLY, H5P_DEFAULT); if(file >= 0){ - if(H5Oget_info_by_name2(file, "/Dataset1", &oi1, H5O_INFO_TIME, H5P_DEFAULT) < 0) + if(H5Oget_info_by_name3(file, "/Dataset1", &oi1, H5O_INFO_TIME, H5P_DEFAULT) < 0) TEST_ERROR; if(oi1.ctime != MTIME1) { H5_FAILED(); @@ -162,7 +164,7 @@ main(void) file = H5Fopen(testfile, H5F_ACC_RDONLY, H5P_DEFAULT); if(file >= 0){ - if(H5Oget_info_by_name2(file, "/Dataset1", &oi2, H5O_INFO_TIME, H5P_DEFAULT) < 0) + if(H5Oget_info_by_name3(file, "/Dataset1", &oi2, H5O_INFO_TIME, H5P_DEFAULT) < 0) TEST_ERROR; if(oi2.ctime != MTIME2) { H5_FAILED(); diff --git a/test/null_vol_connector.c b/test/null_vol_connector.c index 985b576..ef76fe6 100644 --- a/test/null_vol_connector.c +++ b/test/null_vol_connector.c @@ -126,6 +126,11 @@ static const H5VL_class_t null_vol_g = { NULL, /* specific */ NULL /* optional */ }, + { /* token_cls */ + NULL, /* cmp */ + NULL, /* to_str */ + NULL /* from_str */ + }, NULL /* optional */ }; diff --git a/test/objcopy.c b/test/objcopy.c index cabdbfd..5174700 100644 --- a/test/objcopy.c +++ b/test/objcopy.c @@ -168,7 +168,7 @@ unsigned num_attributes_g; /* Number of attributes created */ static struct { size_t nalloc; /* number of slots allocated */ size_t nobjs; /* number of objects */ - haddr_t *obj; /* Addresses of objects seen */ + H5O_token_t *obj; /* Tokens of objects seen */ } idtab_g; /* Local function prototypes */ @@ -191,9 +191,9 @@ compare_attribute_compound_vlstr(hid_t loc, hid_t loc2); /*------------------------------------------------------------------------- - * Function: addr_insert + * Function: token_insert * - * Purpose: Add an address to the table. + * Purpose: Add a token to the table. * * Return: void * @@ -203,7 +203,7 @@ compare_attribute_compound_vlstr(hid_t loc, hid_t loc2); *------------------------------------------------------------------------- */ static void -addr_insert(H5O_info_t *oi) +token_insert(H5O_info2_t *oi) { size_t n; @@ -215,19 +215,19 @@ addr_insert(H5O_info_t *oi) /* Extend the table */ if(idtab_g.nobjs >= idtab_g.nalloc) { idtab_g.nalloc = MAX(256, 2*idtab_g.nalloc); - idtab_g.obj = (haddr_t *)HDrealloc(idtab_g.obj, idtab_g.nalloc * sizeof(idtab_g.obj[0])); + idtab_g.obj = (H5O_token_t *)HDrealloc(idtab_g.obj, idtab_g.nalloc * sizeof(idtab_g.obj[0])); } /* end if */ /* Insert the entry */ n = idtab_g.nobjs++; - idtab_g.obj[n] = oi->addr; -} /* end addr_insert() */ + idtab_g.obj[n] = oi->token; +} /* end token_insert() */ /*------------------------------------------------------------------------- - * Function: addr_lookup + * Function: token_lookup * - * Purpose: Check if address has already been encountered + * Purpose: Check if a token has already been encountered * * Return: Success: TRUE/FALSE * Failure: (can't fail) @@ -238,24 +238,28 @@ addr_insert(H5O_info_t *oi) *------------------------------------------------------------------------- */ static H5_ATTR_PURE hbool_t -addr_lookup(H5O_info_t *oi) +token_lookup(hid_t loc_id, H5O_info2_t *oi) { - size_t n; + size_t n; + int token_cmp; if(oi->rc < 2) return FALSE; /*only one link possible*/ - for(n = 0; n < idtab_g.nobjs; n++) - if(H5F_addr_eq(idtab_g.obj[n], oi->addr)) + for(n = 0; n < idtab_g.nobjs; n++) { + if(H5Otoken_cmp(loc_id, &idtab_g.obj[n], &oi->token, &token_cmp) < 0) + return FALSE; + if(!token_cmp) return TRUE; + } return FALSE; -} /* end addr_lookup() */ +} /* end token_lookup() */ /*------------------------------------------------------------------------- - * Function: addr_reset + * Function: token_reset * - * Purpose: Reset the address tracking data structures + * Purpose: Reset the token tracking data structures * * Return: void * @@ -265,13 +269,13 @@ addr_lookup(H5O_info_t *oi) *------------------------------------------------------------------------- */ static void -addr_reset(void) +token_reset(void) { if(idtab_g.obj) HDfree(idtab_g.obj); idtab_g.obj = NULL; idtab_g.nalloc = idtab_g.nobjs = 0; -} /* end addr_reset() */ +} /* end token_reset() */ /*------------------------------------------------------------------------- @@ -852,7 +856,7 @@ static int compare_std_attributes(hid_t oid, hid_t oid2, hid_t pid) { hid_t aid = -1, aid2 = -1; /* Attribute IDs */ - H5O_info_t oinfo1, oinfo2; /* Object info */ + H5O_info2_t oinfo1, oinfo2; /* Object info */ unsigned cpy_flags; /* Object copy flags */ /* Retrieve the object copy flags from the property list, if it's non-DEFAULT */ @@ -863,10 +867,10 @@ compare_std_attributes(hid_t oid, hid_t oid2, hid_t pid) cpy_flags = 0; /* Check the number of attributes on source dataset */ - if(H5Oget_info2(oid, &oinfo1, H5O_INFO_NUM_ATTRS) < 0) TEST_ERROR + if(H5Oget_info3(oid, &oinfo1, H5O_INFO_NUM_ATTRS) < 0) TEST_ERROR /* Check the number of attributes on destination dataset */ - if(H5Oget_info2(oid2, &oinfo2, H5O_INFO_NUM_ATTRS) < 0) TEST_ERROR + if(H5Oget_info3(oid2, &oinfo2, H5O_INFO_NUM_ATTRS) < 0) TEST_ERROR if(cpy_flags & H5O_COPY_WITHOUT_ATTR_FLAG) { /* Check that the destination has no attributes */ @@ -1055,11 +1059,13 @@ compare_data(hid_t parent1, hid_t parent2, hid_t pid, hid_t tid, size_t nelmts, /* break the infinite loop when the ref_object points to itself */ if(obj_owner > 0) { - H5O_info_t oinfo1, oinfo2; + H5O_info2_t oinfo1, oinfo2; + int token_cmp; - if(H5Oget_info2(obj_owner, &oinfo1, H5O_INFO_BASIC) < 0) TEST_ERROR - if(H5Oget_info2(obj1_id, &oinfo2, H5O_INFO_BASIC) < 0) TEST_ERROR - if(H5F_addr_eq(oinfo1.addr, oinfo2.addr)) { + if(H5Oget_info3(obj_owner, &oinfo1, H5O_INFO_BASIC) < 0) TEST_ERROR + if(H5Oget_info3(obj1_id, &oinfo2, H5O_INFO_BASIC) < 0) TEST_ERROR + if(H5Otoken_cmp(obj1_id, &oinfo1.token, &oinfo2.token, &token_cmp) < 0) TEST_ERROR + if(!token_cmp) { if(H5Oclose(obj1_id) < 0) TEST_ERROR if(H5Oclose(obj2_id) < 0) TEST_ERROR return TRUE; @@ -1116,11 +1122,13 @@ compare_data(hid_t parent1, hid_t parent2, hid_t pid, hid_t tid, size_t nelmts, /* break the infinite loop when the ref_object points to itself */ if(obj_owner > 0) { - H5O_info_t oinfo1, oinfo2; + H5O_info2_t oinfo1, oinfo2; + int token_cmp; - if(H5Oget_info2(obj_owner, &oinfo1, H5O_INFO_BASIC) < 0) TEST_ERROR - if(H5Oget_info2(obj1_id, &oinfo2, H5O_INFO_BASIC) < 0) TEST_ERROR - if(H5F_addr_eq(oinfo1.addr, oinfo2.addr)) { + if(H5Oget_info3(obj_owner, &oinfo1, H5O_INFO_BASIC) < 0) TEST_ERROR + if(H5Oget_info3(obj1_id, &oinfo2, H5O_INFO_BASIC) < 0) TEST_ERROR + if(H5Otoken_cmp(obj1_id, &oinfo1.token, &oinfo2.token, &token_cmp) < 0) TEST_ERROR + if(!token_cmp) { if(H5Oclose(obj1_id) < 0) TEST_ERROR if(H5Oclose(obj2_id) < 0) TEST_ERROR return TRUE; @@ -1273,7 +1281,7 @@ compare_datasets(hid_t did, hid_t did2, hid_t pid, const void *wbuf) /* Check that the space used is the same */ /* (Don't check if the dataset is filtered (i.e. compressed, etc.) and - * the datatype is VLEN, since the addresses for the vlen + * the datatype is VLEN, since the tokens for the vlen * data in each dataset will (probably) be different and the storage * size will thus vary) */ @@ -1394,8 +1402,8 @@ compare_groups(hid_t gid, hid_t gid2, hid_t pid, int depth, unsigned copy_flags) if(ginfo2.nlinks > 0) { char objname[NAME_BUF_SIZE]; /* Name of object in group */ char objname2[NAME_BUF_SIZE]; /* Name of object in group */ - H5L_info_t linfo; /* Link information */ - H5L_info_t linfo2; /* Link information */ + H5L_info2_t linfo; /* Link information */ + H5L_info2_t linfo2; /* Link information */ /* Loop over contents of groups */ for(idx = 0; idx < ginfo.nlinks; idx++) { @@ -1405,18 +1413,24 @@ compare_groups(hid_t gid, hid_t gid2, hid_t pid, int depth, unsigned copy_flags) if(HDstrcmp(objname, objname2)) TEST_ERROR /* Get link info */ - if(H5Lget_info(gid, objname, &linfo, H5P_DEFAULT) < 0) TEST_ERROR - if(H5Lget_info(gid2, objname2, &linfo2, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Lget_info2(gid, objname, &linfo, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Lget_info2(gid2, objname2, &linfo2, H5P_DEFAULT) < 0) TEST_ERROR if(linfo.type != linfo2.type) TEST_ERROR /* Extra checks for "real" objects */ if(linfo.type == H5L_TYPE_HARD) { - hid_t oid, oid2; /* IDs of objects within group */ - H5O_info_t oinfo, oinfo2; /* Object info */ + hid_t oid, oid2; /* IDs of objects within group */ + H5O_info2_t oinfo, oinfo2; /* Data model object info */ + H5O_native_info_t ninfo, ninfo2; /* Native file format object info */ /* Compare some pieces of the object info */ - if(H5Oget_info_by_name2(gid, objname, &oinfo, H5O_INFO_BASIC|H5O_INFO_HDR, H5P_DEFAULT) < 0) TEST_ERROR - if(H5Oget_info_by_name2(gid2, objname2, &oinfo2, H5O_INFO_BASIC|H5O_INFO_HDR, H5P_DEFAULT) < 0) TEST_ERROR + /* Get data model object info */ + if(H5Oget_info_by_name3(gid, objname, &oinfo, H5O_INFO_BASIC, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Oget_info_by_name3(gid2, objname2, &oinfo2, H5O_INFO_BASIC, H5P_DEFAULT) < 0) TEST_ERROR + + /* Get native object info */ + if(H5Oget_native_info_by_name(gid, objname, &ninfo, H5O_NATIVE_INFO_HDR, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Oget_native_info_by_name(gid2, objname2, &ninfo2, H5O_NATIVE_INFO_HDR, H5P_DEFAULT) < 0) TEST_ERROR if(oinfo.type != oinfo2.type) TEST_ERROR if(oinfo.rc != oinfo2.rc) TEST_ERROR @@ -1427,17 +1441,17 @@ compare_groups(hid_t gid, hid_t gid2, hid_t pid, int depth, unsigned copy_flags) * of messages hasn't increased. */ if(H5O_COPY_PRESERVE_NULL_FLAG & copy_flags) { - if(oinfo.hdr.nmesgs != oinfo2.hdr.nmesgs) + if(ninfo.hdr.nmesgs != ninfo2.hdr.nmesgs) ; else - if(oinfo.hdr.nmesgs < oinfo2.hdr.nmesgs) TEST_ERROR + if(ninfo.hdr.nmesgs < ninfo2.hdr.nmesgs) TEST_ERROR } /* Check for object already having been compared */ - if(addr_lookup(&oinfo)) + if(token_lookup(gid, &oinfo)) continue; else - addr_insert(&oinfo); + token_insert(&oinfo); /* Open objects */ if((oid = H5Oopen(gid, objname, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR @@ -1580,8 +1594,8 @@ test_copy_named_datatype(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, hid_t d h5_fixname(FILENAME[0], src_fapl, src_filename, sizeof src_filename); h5_fixname(FILENAME[1], dst_fapl, dst_filename, sizeof dst_filename); - /* Reset file address checking info */ - addr_reset(); + /* Reset file token checking info */ + token_reset(); /* create source file */ if((fid_src = H5Fcreate(src_filename, H5F_ACC_TRUNC, fcpl_src, src_fapl)) < 0) TEST_ERROR @@ -1605,7 +1619,7 @@ test_copy_named_datatype(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, hid_t d /* create destination file */ if((fid_dst = H5Fcreate(dst_filename, H5F_ACC_TRUNC, fcpl_dst, dst_fapl)) < 0) TEST_ERROR - /* Create an uncopied object in destination file so that addresses in source and destination files aren't the same */ + /* Create an uncopied object in destination file so that tokens in source and destination files aren't the same */ if(H5Gclose(H5Gcreate2(fid_dst, NAME_GROUP_UNCOPIED, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR /* copy the datatype from SRC to DST */ @@ -1673,8 +1687,8 @@ test_copy_named_datatype_vl(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, hid_ h5_fixname(FILENAME[0], src_fapl, src_filename, sizeof src_filename); h5_fixname(FILENAME[1], dst_fapl, dst_filename, sizeof dst_filename); - /* Reset file address checking info */ - addr_reset(); + /* Reset file token checking info */ + token_reset(); /* create source file */ if((fid_src = H5Fcreate(src_filename, H5F_ACC_TRUNC, fcpl_src, src_fapl)) < 0) TEST_ERROR @@ -1698,7 +1712,7 @@ test_copy_named_datatype_vl(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, hid_ /* create destination file */ if((fid_dst = H5Fcreate(dst_filename, H5F_ACC_TRUNC, fcpl_dst, dst_fapl)) < 0) TEST_ERROR - /* Create an uncopied object in destination file so that addresses in source and destination files aren't the same */ + /* Create an uncopied object in destination file so that tokens in source and destination files aren't the same */ if(H5Gclose(H5Gcreate2(fid_dst, NAME_GROUP_UNCOPIED, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR /* copy the datatype from SRC to DST */ @@ -1766,8 +1780,8 @@ test_copy_named_datatype_vl_vl(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, h h5_fixname(FILENAME[0], src_fapl, src_filename, sizeof src_filename); h5_fixname(FILENAME[1], dst_fapl, dst_filename, sizeof dst_filename); - /* Reset file address checking info */ - addr_reset(); + /* Reset file token checking info */ + token_reset(); /* create source file */ if((fid_src = H5Fcreate(src_filename, H5F_ACC_TRUNC, fcpl_src, src_fapl)) < 0) TEST_ERROR @@ -1797,7 +1811,7 @@ test_copy_named_datatype_vl_vl(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, h /* create destination file */ if((fid_dst = H5Fcreate(dst_filename, H5F_ACC_TRUNC, fcpl_dst, dst_fapl)) < 0) TEST_ERROR - /* Create an uncopied object in destination file so that addresses in source and destination files aren't the same */ + /* Create an uncopied object in destination file so that tokens in source and destination files aren't the same */ if(H5Gclose(H5Gcreate2(fid_dst, NAME_GROUP_UNCOPIED, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR /* copy the datatype from SRC to DST */ @@ -1861,10 +1875,11 @@ test_copy_named_datatype_attr_self(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fap hid_t aid = -1; /* Attribute ID */ hid_t sid = -1; /* Dataspace ID */ hsize_t dims[2] = {3, 4}; /* Dataspace dimensions */ - H5O_info_t oinfo, oinfo2; /* Object info */ + H5O_info2_t oinfo, oinfo2; /* Object info */ H5G_info_t ginfo; /* Group info */ - char src_filename[NAME_BUF_SIZE]; - char dst_filename[NAME_BUF_SIZE]; + hbool_t same_type; + char src_filename[NAME_BUF_SIZE]; + char dst_filename[NAME_BUF_SIZE]; TESTING("H5Ocopy(): named datatype with self-referential attribute"); @@ -1872,8 +1887,8 @@ test_copy_named_datatype_attr_self(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fap h5_fixname(FILENAME[0], src_fapl, src_filename, sizeof src_filename); h5_fixname(FILENAME[1], dst_fapl, dst_filename, sizeof dst_filename); - /* Reset file address checking info */ - addr_reset(); + /* Reset file token checking info */ + token_reset(); /* create source file */ if((fid_src = H5Fcreate(src_filename, H5F_ACC_TRUNC, fcpl_src, src_fapl)) < 0) TEST_ERROR @@ -1912,7 +1927,7 @@ test_copy_named_datatype_attr_self(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fap /* create destination file */ if((fid_dst = H5Fcreate(dst_filename, H5F_ACC_TRUNC, fcpl_dst, dst_fapl)) < 0) TEST_ERROR - /* Create an uncopied object in destination file so that addresses in source and destination files aren't the same */ + /* Create an uncopied object in destination file so that tokens in source and destination files aren't the same */ if(H5Gclose(H5Gcreate2(fid_dst, NAME_GROUP_UNCOPIED, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR /* copy the datatype from SRC to DST */ @@ -1939,10 +1954,20 @@ test_copy_named_datatype_attr_self(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fap /* verify that the attribute's datatype is committed */ if(H5Tcommitted(tid) != TRUE) TEST_ERROR - /* verify that the addresses of the datatypes are the same */ - if(H5Oget_info2(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR - if(H5Oget_info2(tid2, &oinfo2, H5O_INFO_BASIC) < 0) TEST_ERROR - if(oinfo.fileno != oinfo2.fileno || oinfo.addr != oinfo2.addr) + /* verify that the tokens of the datatypes are the same */ + if(H5Oget_info3(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR + if(H5Oget_info3(tid2, &oinfo2, H5O_INFO_BASIC) < 0) TEST_ERROR + + same_type = TRUE; + if(oinfo.fileno == oinfo2.fileno) { + int token_cmp; + if(H5Otoken_cmp(tid2, &oinfo.token, &oinfo2.token, &token_cmp) < 0) TEST_ERROR + if(token_cmp) same_type = FALSE; + } + else + same_type = FALSE; + + if(!same_type) FAIL_PUTS_ERROR("destination attribute does not use the same committed datatype") /* Verify that there are only 2 links int he destination root group */ @@ -2015,8 +2040,8 @@ test_copy_dataset_simple(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, hid_t d h5_fixname(FILENAME[0], src_fapl, src_filename, sizeof src_filename); h5_fixname(FILENAME[1], dst_fapl, dst_filename, sizeof dst_filename); - /* Reset file address checking info */ - addr_reset(); + /* Reset file token checking info */ + token_reset(); /* create source file */ if((fid_src = H5Fcreate(src_filename, H5F_ACC_TRUNC, fcpl_src, src_fapl)) < 0) TEST_ERROR @@ -2053,7 +2078,7 @@ test_copy_dataset_simple(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, hid_t d /* create destination file */ if((fid_dst = H5Fcreate(dst_filename, H5F_ACC_TRUNC, fcpl_dst, dst_fapl)) < 0) TEST_ERROR - /* Create an uncopied object in destination file so that addresses in source and destination files aren't the same */ + /* Create an uncopied object in destination file so that tokens in source and destination files aren't the same */ if(H5Gclose(H5Gcreate2(fid_dst, NAME_GROUP_UNCOPIED, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR /* copy the dataset from SRC to DST */ @@ -2144,8 +2169,8 @@ test_copy_dataset_versionbounds(hid_t fcpl_src, hid_t fapl_src) h5_fixname(FILENAME[4], fapl_src, src_fname, sizeof src_fname); h5_fixname(FILENAME[5], fapl_dst, dst_fname, sizeof dst_fname); - /* Reset file address checking info */ - addr_reset(); + /* Reset file token checking info */ + token_reset(); /* Create source file */ fid_src = H5Fcreate(src_fname, H5F_ACC_TRUNC, fcpl_src, fapl_src); @@ -2202,7 +2227,7 @@ test_copy_dataset_versionbounds(hid_t fcpl_src, hid_t fapl_src) fid_dst = H5Fcreate(dst_fname, H5F_ACC_TRUNC, H5P_DEFAULT, fapl_dst); if (fid_dst < 0) TEST_ERROR - /* Create an uncopied object in destination file so that addresses + /* Create an uncopied object in destination file so that tokens in source and destination files aren't the same */ if(H5Gclose(H5Gcreate2(fid_dst, NAME_GROUP_UNCOPIED, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR @@ -2306,8 +2331,8 @@ test_copy_dataset_simple_samefile(hid_t fcpl, hid_t fapl) /* Initialize the filenames */ h5_fixname(FILENAME[0], fapl, filename, sizeof filename); - /* Reset file address checking info */ - addr_reset(); + /* Reset file token checking info */ + token_reset(); /* create source file */ if((fid = H5Fcreate(filename, H5F_ACC_TRUNC, fcpl, fapl)) < 0) TEST_ERROR @@ -2413,8 +2438,8 @@ test_copy_dataset_simple_empty(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, h h5_fixname(FILENAME[0], src_fapl, src_filename, sizeof src_filename); h5_fixname(FILENAME[1], dst_fapl, dst_filename, sizeof dst_filename); - /* Reset file address checking info */ - addr_reset(); + /* Reset file token checking info */ + token_reset(); /* create source file */ if((fid_src = H5Fcreate(src_filename, H5F_ACC_TRUNC, fcpl_src, src_fapl)) < 0) TEST_ERROR @@ -2451,7 +2476,7 @@ test_copy_dataset_simple_empty(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, h /* create destination file */ if((fid_dst = H5Fcreate(dst_filename, H5F_ACC_TRUNC, fcpl_dst, dst_fapl)) < 0) TEST_ERROR - /* Create an uncopied object in destination file so that addresses in source and destination files aren't the same */ + /* Create an uncopied object in destination file so that tokens in source and destination files aren't the same */ if(H5Gclose(H5Gcreate2(fid_dst, NAME_GROUP_UNCOPIED, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR /* copy the dataset from SRC to DST */ @@ -2537,8 +2562,8 @@ test_copy_dataset_compound(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, hid_t h5_fixname(FILENAME[0], src_fapl, src_filename, sizeof src_filename); h5_fixname(FILENAME[1], dst_fapl, dst_filename, sizeof dst_filename); - /* Reset file address checking info */ - addr_reset(); + /* Reset file token checking info */ + token_reset(); /* create source file */ if((fid_src = H5Fcreate(src_filename, H5F_ACC_TRUNC, fcpl_src, src_fapl)) < 0) TEST_ERROR @@ -2582,7 +2607,7 @@ test_copy_dataset_compound(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, hid_t /* create destination file */ if((fid_dst = H5Fcreate(dst_filename, H5F_ACC_TRUNC, fcpl_dst, dst_fapl)) < 0) TEST_ERROR - /* Create an uncopied object in destination file so that addresses in source and destination files aren't the same */ + /* Create an uncopied object in destination file so that tokens in source and destination files aren't the same */ if(H5Gclose(H5Gcreate2(fid_dst, NAME_GROUP_UNCOPIED, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR /* copy the dataset from SRC to DST */ @@ -2669,8 +2694,8 @@ test_copy_dataset_chunked(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, hid_t h5_fixname(FILENAME[0], src_fapl, src_filename, sizeof src_filename); h5_fixname(FILENAME[1], dst_fapl, dst_filename, sizeof dst_filename); - /* Reset file address checking info */ - addr_reset(); + /* Reset file token checking info */ + token_reset(); /* create source file */ if((fid_src = H5Fcreate(src_filename, H5F_ACC_TRUNC, fcpl_src, src_fapl)) < 0) TEST_ERROR @@ -2867,7 +2892,7 @@ test_copy_dataset_chunked(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, hid_t /* create destination file */ if((fid_dst = H5Fcreate(dst_filename, H5F_ACC_TRUNC, fcpl_dst, dst_fapl)) < 0) TEST_ERROR - /* Create an uncopied object in destination file so that addresses in source and destination files aren't the same */ + /* Create an uncopied object in destination file so that tokens in source and destination files aren't the same */ if(H5Gclose(H5Gcreate2(fid_dst, NAME_GROUP_UNCOPIED, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR /* copy the datasets from SRC to DST */ @@ -3072,8 +3097,8 @@ test_copy_dataset_chunked_empty(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, h5_fixname(FILENAME[0], src_fapl, src_filename, sizeof src_filename); h5_fixname(FILENAME[1], dst_fapl, dst_filename, sizeof dst_filename); - /* Reset file address checking info */ - addr_reset(); + /* Reset file token checking info */ + token_reset(); /* create source file */ if((fid_src = H5Fcreate(src_filename, H5F_ACC_TRUNC, fcpl_src, src_fapl)) < 0) TEST_ERROR @@ -3265,7 +3290,7 @@ test_copy_dataset_chunked_empty(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, /* create destination file */ if((fid_dst = H5Fcreate(dst_filename, H5F_ACC_TRUNC, fcpl_dst, dst_fapl)) < 0) TEST_ERROR - /* Create an uncopied object in destination file so that addresses in source and destination files aren't the same */ + /* Create an uncopied object in destination file so that tokens in source and destination files aren't the same */ if(H5Gclose(H5Gcreate2(fid_dst, NAME_GROUP_UNCOPIED, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR /* copy the datasets from SRC to DST */ @@ -3482,8 +3507,8 @@ test_copy_dataset_chunked_sparse(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, h5_fixname(FILENAME[0], src_fapl, src_filename, sizeof src_filename); h5_fixname(FILENAME[1], dst_fapl, dst_filename, sizeof dst_filename); - /* Reset file address checking info */ - addr_reset(); + /* Reset file token checking info */ + token_reset(); /* create source file */ if((fid_src = H5Fcreate(src_filename, H5F_ACC_TRUNC, fcpl_src, src_fapl)) < 0) TEST_ERROR @@ -3640,7 +3665,7 @@ test_copy_dataset_chunked_sparse(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, /* create destination file */ if((fid_dst = H5Fcreate(dst_filename, H5F_ACC_TRUNC, fcpl_dst, dst_fapl)) < 0) TEST_ERROR - /* Create an uncopied object in destination file so that addresses in source and destination files aren't the same */ + /* Create an uncopied object in destination file so that tokens in source and destination files aren't the same */ if(H5Gclose(H5Gcreate2(fid_dst, NAME_GROUP_UNCOPIED, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR /* copy the datasets from SRC to DST */ @@ -3795,8 +3820,8 @@ test_copy_dataset_compressed(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, hid h5_fixname(FILENAME[0], src_fapl, src_filename, sizeof src_filename); h5_fixname(FILENAME[1], dst_fapl, dst_filename, sizeof dst_filename); - /* Reset file address checking info */ - addr_reset(); + /* Reset file token checking info */ + token_reset(); /* create source file */ if((fid_src = H5Fcreate(src_filename, H5F_ACC_TRUNC, fcpl_src, src_fapl)) < 0) TEST_ERROR @@ -3942,7 +3967,7 @@ test_copy_dataset_compressed(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, hid /* create destination file */ if((fid_dst = H5Fcreate(dst_filename, H5F_ACC_TRUNC, fcpl_dst, dst_fapl)) < 0) TEST_ERROR - /* Create an uncopied object in destination file so that addresses in source and destination files aren't the same */ + /* Create an uncopied object in destination file so that tokens in source and destination files aren't the same */ if(H5Gclose(H5Gcreate2(fid_dst, NAME_GROUP_UNCOPIED, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR /* copy the dataset from SRC to DST */ @@ -4129,8 +4154,8 @@ test_copy_dataset_no_edge_filt(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, h5_fixname(FILENAME[0], src_fapl, src_filename, sizeof src_filename); h5_fixname(FILENAME[1], dst_fapl, dst_filename, sizeof dst_filename); - /* Reset file address checking info */ - addr_reset(); + /* Reset file token checking info */ + token_reset(); /* create source file */ if((fid_src = H5Fcreate(src_filename, H5F_ACC_TRUNC, fcpl_src, src_fapl)) < 0) TEST_ERROR @@ -4180,7 +4205,7 @@ test_copy_dataset_no_edge_filt(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, /* create destination file */ if((fid_dst = H5Fcreate(dst_filename, H5F_ACC_TRUNC, fcpl_dst, dst_fapl)) < 0) TEST_ERROR - /* Create an uncopied object in destination file so that addresses in source and destination files aren't the same */ + /* Create an uncopied object in destination file so that tokens in source and destination files aren't the same */ if(H5Gclose(H5Gcreate2(fid_dst, NAME_GROUP_UNCOPIED, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR /* copy the dataset from SRC to DST */ @@ -4276,8 +4301,8 @@ test_copy_dataset_compact(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, hid_t h5_fixname(FILENAME[0], src_fapl, src_filename, sizeof src_filename); h5_fixname(FILENAME[1], dst_fapl, dst_filename, sizeof dst_filename); - /* Reset file address checking info */ - addr_reset(); + /* Reset file token checking info */ + token_reset(); /* create source file */ if((fid_src = H5Fcreate(src_filename, H5F_ACC_TRUNC, fcpl_src, src_fapl)) < 0) TEST_ERROR @@ -4323,7 +4348,7 @@ test_copy_dataset_compact(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, hid_t /* create destination file */ if((fid_dst = H5Fcreate(dst_filename, H5F_ACC_TRUNC, fcpl_dst, dst_fapl)) < 0) TEST_ERROR - /* Create an uncopied object in destination file so that addresses in source and destination files aren't the same */ + /* Create an uncopied object in destination file so that tokens in source and destination files aren't the same */ if(H5Gclose(H5Gcreate2(fid_dst, NAME_GROUP_UNCOPIED, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR /* copy the dataset from SRC to DST */ @@ -4408,8 +4433,8 @@ test_copy_dataset_external(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, hid_t h5_fixname(FILENAME[0], src_fapl, src_filename, sizeof src_filename); h5_fixname(FILENAME[1], dst_fapl, dst_filename, sizeof dst_filename); - /* Reset file address checking info */ - addr_reset(); + /* Reset file token checking info */ + token_reset(); /* create source file */ if((fid_src = H5Fcreate(src_filename, H5F_ACC_TRUNC, fcpl_src, src_fapl)) < 0) TEST_ERROR @@ -4450,7 +4475,7 @@ test_copy_dataset_external(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, hid_t /* create destination file */ if((fid_dst = H5Fcreate(dst_filename, H5F_ACC_TRUNC, fcpl_dst, dst_fapl)) < 0) TEST_ERROR - /* Create an uncopied object in destination file so that addresses in source and destination files aren't the same */ + /* Create an uncopied object in destination file so that tokens in source and destination files aren't the same */ if(H5Gclose(H5Gcreate2(fid_dst, NAME_GROUP_UNCOPIED, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR /* copy the dataset from SRC to DST */ @@ -4530,8 +4555,8 @@ test_copy_dataset_named_dtype(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, hi h5_fixname(FILENAME[0], src_fapl, src_filename, sizeof src_filename); h5_fixname(FILENAME[1], dst_fapl, dst_filename, sizeof dst_filename); - /* Reset file address checking info */ - addr_reset(); + /* Reset file token checking info */ + token_reset(); /* create source file */ if((fid_src = H5Fcreate(src_filename, H5F_ACC_TRUNC, fcpl_src, src_fapl)) < 0) TEST_ERROR @@ -4571,7 +4596,7 @@ test_copy_dataset_named_dtype(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, hi /* create destination file */ if((fid_dst = H5Fcreate(dst_filename, H5F_ACC_TRUNC, fcpl_dst, dst_fapl)) < 0) TEST_ERROR - /* Create an uncopied object in destination file so that addresses in source and destination files aren't the same */ + /* Create an uncopied object in destination file so that tokens in source and destination files aren't the same */ if(H5Gclose(H5Gcreate2(fid_dst, NAME_GROUP_UNCOPIED, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR /* copy the dataset from SRC to DST */ @@ -4652,8 +4677,8 @@ test_copy_dataset_named_dtype_hier(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fap h5_fixname(FILENAME[0], src_fapl, src_filename, sizeof src_filename); h5_fixname(FILENAME[1], dst_fapl, dst_filename, sizeof dst_filename); - /* Reset file address checking info */ - addr_reset(); + /* Reset file token checking info */ + token_reset(); /* create source file */ if((fid_src = H5Fcreate(src_filename, H5F_ACC_TRUNC, fcpl_src, src_fapl)) < 0) TEST_ERROR @@ -4708,7 +4733,7 @@ test_copy_dataset_named_dtype_hier(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fap /* create destination file */ if((fid_dst = H5Fcreate(dst_filename, H5F_ACC_TRUNC, fcpl_dst, dst_fapl)) < 0) TEST_ERROR - /* Create an uncopied object in destination file so that addresses in source and destination files aren't the same */ + /* Create an uncopied object in destination file so that tokens in source and destination files aren't the same */ if(H5Gclose(H5Gcreate2(fid_dst, NAME_GROUP_UNCOPIED, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR /* copy the dataset from SRC to DST */ @@ -4791,8 +4816,8 @@ test_copy_dataset_named_dtype_hier_outside(hid_t fcpl_src, hid_t fcpl_dst, hid_t h5_fixname(FILENAME[0], src_fapl, src_filename, sizeof src_filename); h5_fixname(FILENAME[1], dst_fapl, dst_filename, sizeof dst_filename); - /* Reset file address checking info */ - addr_reset(); + /* Reset file token checking info */ + token_reset(); /* create source file */ if((fid_src = H5Fcreate(src_filename, H5F_ACC_TRUNC, fcpl_src, src_fapl)) < 0) TEST_ERROR @@ -4847,7 +4872,7 @@ test_copy_dataset_named_dtype_hier_outside(hid_t fcpl_src, hid_t fcpl_dst, hid_t /* create destination file */ if((fid_dst = H5Fcreate(dst_filename, H5F_ACC_TRUNC, fcpl_dst, dst_fapl)) < 0) TEST_ERROR - /* Create an uncopied object in destination file so that addresses in source and destination files aren't the same */ + /* Create an uncopied object in destination file so that tokens in source and destination files aren't the same */ if(H5Gclose(H5Gcreate2(fid_dst, NAME_GROUP_UNCOPIED, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR /* copy the dataset from SRC to DST */ @@ -4936,8 +4961,8 @@ test_copy_dataset_multi_ohdr_chunks(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fa h5_fixname(FILENAME[0], src_fapl, src_filename, sizeof src_filename); h5_fixname(FILENAME[1], dst_fapl, dst_filename, sizeof dst_filename); - /* Reset file address checking info */ - addr_reset(); + /* Reset file token checking info */ + token_reset(); /* create source file */ if((fid_src = H5Fcreate(src_filename, H5F_ACC_TRUNC, fcpl_src, src_fapl)) < 0) TEST_ERROR @@ -4991,7 +5016,7 @@ test_copy_dataset_multi_ohdr_chunks(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fa /* create destination file */ if((fid_dst = H5Fcreate(dst_filename, H5F_ACC_TRUNC, fcpl_dst, dst_fapl)) < 0) TEST_ERROR - /* Create an uncopied object in destination file so that addresses in source and destination files aren't the same */ + /* Create an uncopied object in destination file so that tokens in source and destination files aren't the same */ if(H5Gclose(H5Gcreate2(fid_dst, NAME_GROUP_UNCOPIED, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR /* copy the dataset from SRC to DST */ @@ -5078,8 +5103,8 @@ test_copy_dataset_attr_named_dtype(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fap h5_fixname(FILENAME[0], src_fapl, src_filename, sizeof src_filename); h5_fixname(FILENAME[1], dst_fapl, dst_filename, sizeof dst_filename); - /* Reset file address checking info */ - addr_reset(); + /* Reset file token checking info */ + token_reset(); /* create source file */ if((fid_src = H5Fcreate(src_filename, H5F_ACC_TRUNC, fcpl_src, src_fapl)) < 0) TEST_ERROR @@ -5137,7 +5162,7 @@ test_copy_dataset_attr_named_dtype(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fap /* create destination file */ if((fid_dst = H5Fcreate(dst_filename, H5F_ACC_TRUNC, fcpl_dst, dst_fapl)) < 0) TEST_ERROR - /* Create an uncopied object in destination file so that addresses in source and destination files aren't the same */ + /* Create an uncopied object in destination file so that tokens in source and destination files aren't the same */ if(H5Gclose(H5Gcreate2(fid_dst, NAME_GROUP_UNCOPIED, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR /* copy the dataset from SRC to DST */ @@ -5224,8 +5249,8 @@ test_copy_dataset_contig_vl(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, hid_ h5_fixname(FILENAME[0], src_fapl, src_filename, sizeof src_filename); h5_fixname(FILENAME[1], dst_fapl, dst_filename, sizeof dst_filename); - /* Reset file address checking info */ - addr_reset(); + /* Reset file token checking info */ + token_reset(); /* create source file */ if((fid_src = H5Fcreate(src_filename, H5F_ACC_TRUNC, fcpl_src, src_fapl)) < 0) TEST_ERROR @@ -5258,7 +5283,7 @@ test_copy_dataset_contig_vl(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, hid_ /* create destination file */ if((fid_dst = H5Fcreate(dst_filename, H5F_ACC_TRUNC, fcpl_dst, dst_fapl)) < 0) TEST_ERROR - /* Create an uncopied object in destination file so that addresses in source and destination files aren't the same */ + /* Create an uncopied object in destination file so that tokens in source and destination files aren't the same */ if(H5Gclose(H5Gcreate2(fid_dst, NAME_GROUP_UNCOPIED, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR /* copy the dataset from SRC to DST */ @@ -5362,8 +5387,8 @@ test_copy_dataset_chunked_vl(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, hid h5_fixname(FILENAME[0], src_fapl, src_filename, sizeof src_filename); h5_fixname(FILENAME[1], dst_fapl, dst_filename, sizeof dst_filename); - /* Reset file address checking info */ - addr_reset(); + /* Reset file token checking info */ + token_reset(); /* create source file */ if((fid_src = H5Fcreate(src_filename, H5F_ACC_TRUNC, fcpl_src, src_fapl)) < 0) TEST_ERROR @@ -5417,7 +5442,7 @@ test_copy_dataset_chunked_vl(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, hid /* create destination file */ if((fid_dst = H5Fcreate(dst_filename, H5F_ACC_TRUNC, fcpl_dst, dst_fapl)) < 0) TEST_ERROR - /* Create an uncopied object in destination file so that addresses in source and destination files aren't the same */ + /* Create an uncopied object in destination file so that tokens in source and destination files aren't the same */ if(H5Gclose(H5Gcreate2(fid_dst, NAME_GROUP_UNCOPIED, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR /* copy the dataset from SRC to DST */ @@ -5545,8 +5570,8 @@ test_copy_dataset_compact_vl(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, hid h5_fixname(FILENAME[0], src_fapl, src_filename, sizeof src_filename); h5_fixname(FILENAME[1], dst_fapl, dst_filename, sizeof dst_filename); - /* Reset file address checking info */ - addr_reset(); + /* Reset file token checking info */ + token_reset(); /* create source file */ if((fid_src = H5Fcreate(src_filename, H5F_ACC_TRUNC, fcpl_src, src_fapl)) < 0) TEST_ERROR @@ -5586,7 +5611,7 @@ test_copy_dataset_compact_vl(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, hid /* create destination file */ if((fid_dst = H5Fcreate(dst_filename, H5F_ACC_TRUNC, fcpl_dst, dst_fapl)) < 0) TEST_ERROR - /* Create an uncopied object in destination file so that addresses in source and destination files aren't the same */ + /* Create an uncopied object in destination file so that tokens in source and destination files aren't the same */ if(H5Gclose(H5Gcreate2(fid_dst, NAME_GROUP_UNCOPIED, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR /* copy the dataset from SRC to DST */ @@ -5677,8 +5702,8 @@ test_copy_attribute_vl(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, hid_t dst h5_fixname(FILENAME[0], src_fapl, src_filename, sizeof src_filename); h5_fixname(FILENAME[1], dst_fapl, dst_filename, sizeof dst_filename); - /* Reset file address checking info */ - addr_reset(); + /* Reset file token checking info */ + token_reset(); /* create source file */ if((fid_src = H5Fcreate(src_filename, H5F_ACC_TRUNC, fcpl_src, src_fapl)) < 0) TEST_ERROR @@ -5712,7 +5737,7 @@ test_copy_attribute_vl(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, hid_t dst /* create destination file */ if((fid_dst = H5Fcreate(dst_filename, H5F_ACC_TRUNC, fcpl_dst, dst_fapl)) < 0) TEST_ERROR - /* Create an uncopied object in destination file so that addresses in source and destination files aren't the same */ + /* Create an uncopied object in destination file so that tokens in source and destination files aren't the same */ if(H5Gclose(H5Gcreate2(fid_dst, NAME_GROUP_UNCOPIED, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR /* copy the dataset from SRC to DST */ @@ -5970,8 +5995,8 @@ test_copy_attribute_compound_vlstr(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fap h5_fixname(FILENAME[0], src_fapl, src_filename, sizeof src_filename); h5_fixname(FILENAME[1], dst_fapl, dst_filename, sizeof dst_filename); - /* Reset file address checking info */ - addr_reset(); + /* Reset file token checking info */ + token_reset(); /* create source file */ if((fid_src = H5Fcreate(src_filename, H5F_ACC_TRUNC, fcpl_src, src_fapl)) < 0) @@ -6026,7 +6051,7 @@ test_copy_attribute_compound_vlstr(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fap if((fid_dst = H5Fcreate(dst_filename, H5F_ACC_TRUNC, fcpl_dst, dst_fapl)) < 0) FAIL_STACK_ERROR - /* Create an uncopied object in destination file so that addresses in source and destination files aren't the same */ + /* Create an uncopied object in destination file so that tokens in source and destination files aren't the same */ if(H5Gclose(H5Gcreate2(fid_dst, NAME_GROUP_UNCOPIED, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR @@ -6152,8 +6177,8 @@ test_copy_dataset_compressed_vl(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, h5_fixname(FILENAME[0], src_fapl, src_filename, sizeof src_filename); h5_fixname(FILENAME[1], dst_fapl, dst_filename, sizeof dst_filename); - /* Reset file address checking info */ - addr_reset(); + /* Reset file token checking info */ + token_reset(); /* create source file */ if((fid_src = H5Fcreate(src_filename, H5F_ACC_TRUNC, fcpl_src, src_fapl)) < 0) TEST_ERROR @@ -6195,7 +6220,7 @@ test_copy_dataset_compressed_vl(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, /* create destination file */ if((fid_dst = H5Fcreate(dst_filename, H5F_ACC_TRUNC, fcpl_dst, dst_fapl)) < 0) TEST_ERROR - /* Create an uncopied object in destination file so that addresses in source and destination files aren't the same */ + /* Create an uncopied object in destination file so that tokens in source and destination files aren't the same */ if(H5Gclose(H5Gcreate2(fid_dst, NAME_GROUP_UNCOPIED, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR /* copy the dataset from SRC to DST */ @@ -6285,8 +6310,8 @@ test_copy_group_empty(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, hid_t dst_ h5_fixname(FILENAME[0], src_fapl, src_filename, sizeof src_filename); h5_fixname(FILENAME[1], dst_fapl, dst_filename, sizeof dst_filename); - /* Reset file address checking info */ - addr_reset(); + /* Reset file token checking info */ + token_reset(); /* create source file */ if((fid_src = H5Fcreate(src_filename, H5F_ACC_TRUNC, fcpl_src, src_fapl)) < 0) TEST_ERROR @@ -6310,7 +6335,7 @@ test_copy_group_empty(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, hid_t dst_ /* create destination file */ if((fid_dst = H5Fcreate(dst_filename, H5F_ACC_TRUNC, fcpl_dst, dst_fapl)) < 0) TEST_ERROR - /* Create an uncopied object in destination file so that addresses in source and destination files aren't the same */ + /* Create an uncopied object in destination file so that tokens in source and destination files aren't the same */ if(H5Gclose(H5Gcreate2(fid_dst, NAME_GROUP_UNCOPIED, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR /* copy the group from SRC to DST */ @@ -6389,8 +6414,8 @@ test_copy_root_group(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, hid_t dst_f h5_fixname(FILENAME[0], src_fapl, src_filename, sizeof src_filename); h5_fixname(FILENAME[1], dst_fapl, dst_filename, sizeof dst_filename); - /* Reset file address checking info */ - addr_reset(); + /* Reset file token checking info */ + token_reset(); /* create source file */ if((fid_src = H5Fcreate(src_filename, H5F_ACC_TRUNC, fcpl_src, src_fapl)) < 0) TEST_ERROR @@ -6438,7 +6463,7 @@ test_copy_root_group(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, hid_t dst_f /* create destination file */ if((fid_dst = H5Fcreate(dst_filename, H5F_ACC_TRUNC, fcpl_dst, dst_fapl)) < 0) TEST_ERROR - /* Create an uncopied object in destination file so that addresses in source and destination files aren't the same */ + /* Create an uncopied object in destination file so that tokens in source and destination files aren't the same */ if(H5Gclose(H5Gcreate2(fid_dst, NAME_GROUP_UNCOPIED, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR /* copy the group from SRC to DST */ @@ -6520,8 +6545,8 @@ test_copy_group(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, hid_t dst_fapl) h5_fixname(FILENAME[0], src_fapl, src_filename, sizeof src_filename); h5_fixname(FILENAME[1], dst_fapl, dst_filename, sizeof dst_filename); - /* Reset file address checking info */ - addr_reset(); + /* Reset file token checking info */ + token_reset(); /* create source file */ if((fid_src = H5Fcreate(src_filename, H5F_ACC_TRUNC, fcpl_src, src_fapl)) < 0) TEST_ERROR @@ -6570,7 +6595,7 @@ test_copy_group(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, hid_t dst_fapl) /* create destination file */ if((fid_dst = H5Fcreate(dst_filename, H5F_ACC_TRUNC, fcpl_dst, dst_fapl)) < 0) TEST_ERROR - /* Create an uncopied object in destination file so that addresses in source and destination files aren't the same */ + /* Create an uncopied object in destination file so that tokens in source and destination files aren't the same */ if(H5Gclose(H5Gcreate2(fid_dst, NAME_GROUP_UNCOPIED, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR /* copy the group from SRC to DST */ @@ -6653,8 +6678,8 @@ test_copy_group_deep(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, hid_t dst_f h5_fixname(FILENAME[0], src_fapl, src_filename, sizeof src_filename); h5_fixname(FILENAME[1], dst_fapl, dst_filename, sizeof dst_filename); - /* Reset file address checking info */ - addr_reset(); + /* Reset file token checking info */ + token_reset(); /* create source file */ if((fid_src = H5Fcreate(src_filename, H5F_ACC_TRUNC, fcpl_src, src_fapl)) < 0) TEST_ERROR @@ -6712,7 +6737,7 @@ test_copy_group_deep(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, hid_t dst_f /* create destination file */ if((fid_dst = H5Fcreate(dst_filename, H5F_ACC_TRUNC, fcpl_dst, dst_fapl)) < 0) TEST_ERROR - /* Create an uncopied object in destination file so that addresses in source and destination files aren't the same */ + /* Create an uncopied object in destination file so that tokens in source and destination files aren't the same */ if(H5Gclose(H5Gcreate2(fid_dst, NAME_GROUP_UNCOPIED, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR /* copy the group from SRC to DST */ @@ -6784,8 +6809,8 @@ test_copy_group_loop(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, hid_t dst_f h5_fixname(FILENAME[0], src_fapl, src_filename, sizeof src_filename); h5_fixname(FILENAME[1], dst_fapl, dst_filename, sizeof dst_filename); - /* Reset file address checking info */ - addr_reset(); + /* Reset file token checking info */ + token_reset(); /* create source file */ if((fid_src = H5Fcreate(src_filename, H5F_ACC_TRUNC, fcpl_src, src_fapl)) < 0) TEST_ERROR @@ -6823,7 +6848,7 @@ test_copy_group_loop(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, hid_t dst_f /* create destination file */ if((fid_dst = H5Fcreate(dst_filename, H5F_ACC_TRUNC, fcpl_dst, dst_fapl)) < 0) TEST_ERROR - /* Create an uncopied object in destination file so that addresses in source and destination files aren't the same */ + /* Create an uncopied object in destination file so that tokens in source and destination files aren't the same */ if(H5Gclose(H5Gcreate2(fid_dst, NAME_GROUP_UNCOPIED, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR /* copy the group from SRC to DST */ @@ -6901,8 +6926,8 @@ test_copy_group_wide_loop(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, hid_t h5_fixname(FILENAME[0], src_fapl, src_filename, sizeof src_filename); h5_fixname(FILENAME[1], dst_fapl, dst_filename, sizeof dst_filename); - /* Reset file address checking info */ - addr_reset(); + /* Reset file token checking info */ + token_reset(); /* create source file */ if((fid_src = H5Fcreate(src_filename, H5F_ACC_TRUNC, fcpl_src, src_fapl)) < 0) TEST_ERROR @@ -6952,7 +6977,7 @@ test_copy_group_wide_loop(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, hid_t /* create destination file */ if((fid_dst = H5Fcreate(dst_filename, H5F_ACC_TRUNC, fcpl_dst, dst_fapl)) < 0) TEST_ERROR - /* Create an uncopied object in destination file so that addresses in source and destination files aren't the same */ + /* Create an uncopied object in destination file so that tokens in source and destination files aren't the same */ if(H5Gclose(H5Gcreate2(fid_dst, NAME_GROUP_UNCOPIED, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR /* copy the group from SRC to DST */ @@ -7018,7 +7043,7 @@ test_copy_group_links(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, hid_t dst_ hid_t plid = -1; /* Object copy plist ID */ hsize_t dim2d[2]; hsize_t dim1d[1]; - H5L_info_t linfo; + H5L_info2_t linfo; int buf[DIM_SIZE_1][DIM_SIZE_2]; int i, j; unsigned expand_soft; @@ -7040,8 +7065,8 @@ test_copy_group_links(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, hid_t dst_ h5_fixname(FILENAME[1], src_fapl, dst_filename, sizeof dst_filename); h5_fixname(FILENAME[2], dst_fapl, ext_filename, sizeof ext_filename); - /* Reset file address checking info */ - addr_reset(); + /* Reset file token checking info */ + token_reset(); /* create source file */ if((fid_src = H5Fcreate(src_filename, H5F_ACC_TRUNC, fcpl_src, src_fapl)) < 0) TEST_ERROR @@ -7135,7 +7160,7 @@ test_copy_group_links(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, hid_t dst_ /* create destination file */ if((fid_dst = H5Fcreate(dst_filename, H5F_ACC_TRUNC, fcpl_dst, dst_fapl)) < 0) TEST_ERROR - /* Create an uncopied object in destination file so that addresses in source and destination files aren't the same */ + /* Create an uncopied object in destination file so that tokens in source and destination files aren't the same */ if(H5Gclose(H5Gcreate2(fid_dst, NAME_GROUP_UNCOPIED, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR /* copy the group from SRC to DST */ @@ -7152,7 +7177,7 @@ test_copy_group_links(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, hid_t dst_ * re-add it as a soft link so compare_groups() works */ if(expand_soft) { /* Check link type */ - if(H5Lget_info(fid_dst, NAME_LINK_SOFT, &linfo, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Lget_info2(fid_dst, NAME_LINK_SOFT, &linfo, H5P_DEFAULT) < 0) TEST_ERROR if(linfo.type != H5L_TYPE_HARD) FAIL_PUTS_ERROR("Soft link was not expanded to a hard link") @@ -7175,7 +7200,7 @@ test_copy_group_links(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, hid_t dst_ * and re-add it as an external link so compare_groups() works */ if(expand_ext) { /* Check link type */ - if(H5Lget_info(fid_dst, NAME_LINK_EXTERN, &linfo, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Lget_info2(fid_dst, NAME_LINK_EXTERN, &linfo, H5P_DEFAULT) < 0) TEST_ERROR if(linfo.type != H5L_TYPE_HARD) FAIL_PUTS_ERROR("External link was not expanded to a hard link") @@ -7295,8 +7320,8 @@ test_copy_soft_link(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, hid_t dst_fa h5_fixname(FILENAME[0], src_fapl, src_filename, sizeof src_filename); h5_fixname(FILENAME[1], dst_fapl, dst_filename, sizeof dst_filename); - /* Reset file address checking info */ - addr_reset(); + /* Reset file token checking info */ + token_reset(); /* create source file */ if((fid_src = H5Fcreate(src_filename, H5F_ACC_TRUNC, fcpl_src, src_fapl)) < 0) TEST_ERROR @@ -7341,7 +7366,7 @@ test_copy_soft_link(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, hid_t dst_fa /* create destination file */ if((fid_dst = H5Fcreate(dst_filename, H5F_ACC_TRUNC, fcpl_dst, dst_fapl)) < 0) TEST_ERROR - /* Create an uncopied object in destination file so that addresses in source and destination files aren't the same */ + /* Create an uncopied object in destination file so that tokens in source and destination files aren't the same */ if(H5Gclose(H5Gcreate2(fid_dst, NAME_GROUP_UNCOPIED, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR /* copy the dataset from SRC to DST */ @@ -7425,8 +7450,8 @@ test_copy_ext_link(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, hid_t dst_fap h5_fixname(FILENAME[1], src_fapl, dst_filename, sizeof dst_filename); h5_fixname(FILENAME[2], dst_fapl, ext_filename, sizeof ext_filename); - /* Reset file address checking info */ - addr_reset(); + /* Reset file token checking info */ + token_reset(); /* create source file */ if((fid_src = H5Fcreate(src_filename, H5F_ACC_TRUNC, fcpl_src, src_fapl)) < 0) TEST_ERROR @@ -7474,7 +7499,7 @@ test_copy_ext_link(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, hid_t dst_fap /* create destination file */ if((fid_dst = H5Fcreate(dst_filename, H5F_ACC_TRUNC, fcpl_dst, dst_fapl)) < 0) TEST_ERROR - /* Create an uncopied object in destination file so that addresses in source and destination files aren't the same */ + /* Create an uncopied object in destination file so that tokens in source and destination files aren't the same */ if(H5Gclose(H5Gcreate2(fid_dst, NAME_GROUP_UNCOPIED, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR /* copy the dataset from SRC to DST */ @@ -7558,8 +7583,8 @@ test_copy_exist(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, hid_t dst_fapl) h5_fixname(FILENAME[0], src_fapl, src_filename, sizeof src_filename); h5_fixname(FILENAME[1], dst_fapl, dst_filename, sizeof dst_filename); - /* Reset file address checking info */ - addr_reset(); + /* Reset file token checking info */ + token_reset(); /* create source file */ if((fid_src = H5Fcreate(src_filename, H5F_ACC_TRUNC, fcpl_src, src_fapl)) < 0) TEST_ERROR @@ -7596,7 +7621,7 @@ test_copy_exist(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, hid_t dst_fapl) /* create destination file */ if((fid_dst = H5Fcreate(dst_filename, H5F_ACC_TRUNC, fcpl_dst, dst_fapl)) < 0) TEST_ERROR - /* Create an uncopied object in destination file so that addresses in source and destination files aren't the same */ + /* Create an uncopied object in destination file so that tokens in source and destination files aren't the same */ if(H5Gclose(H5Gcreate2(fid_dst, NAME_GROUP_UNCOPIED, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR /* copy the dataset from SRC to DST */ @@ -7667,8 +7692,8 @@ test_copy_path(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, hid_t dst_fapl) h5_fixname(FILENAME[0], src_fapl, src_filename, sizeof src_filename); h5_fixname(FILENAME[1], dst_fapl, dst_filename, sizeof dst_filename); - /* Reset file address checking info */ - addr_reset(); + /* Reset file token checking info */ + token_reset(); /* create source file */ if((fid_src = H5Fcreate(src_filename, H5F_ACC_TRUNC, fcpl_src, src_fapl)) < 0) TEST_ERROR @@ -7705,7 +7730,7 @@ test_copy_path(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, hid_t dst_fapl) /* create destination file */ if((fid_dst = H5Fcreate(dst_filename, H5F_ACC_TRUNC, fcpl_dst, dst_fapl)) < 0) TEST_ERROR - /* Create an uncopied object in destination file so that addresses in source and destination files aren't the same */ + /* Create an uncopied object in destination file so that tokens in source and destination files aren't the same */ if(H5Gclose(H5Gcreate2(fid_dst, NAME_GROUP_UNCOPIED, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR /* copy the dataset from SRC to DST (should fail - intermediate groups not there) */ @@ -7789,8 +7814,8 @@ test_copy_same_file_named_datatype(hid_t fcpl_src, hid_t fapl) /* Initialize the filenames */ h5_fixname(FILENAME[0], fapl, filename, sizeof filename); - /* Reset file address checking info */ - addr_reset(); + /* Reset file token checking info */ + token_reset(); /* create source file */ if((fid = H5Fcreate(filename, H5F_ACC_TRUNC, fcpl_src, fapl)) < 0) TEST_ERROR @@ -7868,8 +7893,8 @@ test_copy_old_layout(hid_t fcpl_dst, hid_t fapl, hbool_t test_open) /* Initialize the destination filename */ h5_fixname(FILENAME[1], fapl, dst_filename, sizeof dst_filename); - /* Reset file address checking info */ - addr_reset(); + /* Reset file token checking info */ + token_reset(); /* Setup */ if((src_fapl = h5_fileaccess_flags(H5_FILEACCESS_LIBVER)) < 0) TEST_ERROR @@ -7883,7 +7908,7 @@ test_copy_old_layout(hid_t fcpl_dst, hid_t fapl, hbool_t test_open) /* create destination file */ if((fid_dst = H5Fcreate(dst_filename, H5F_ACC_TRUNC, fcpl_dst, fapl)) < 0) TEST_ERROR - /* Create an uncopied object in destination file so that addresses in source and destination files aren't the same */ + /* Create an uncopied object in destination file so that tokens in source and destination files aren't the same */ if(H5Gclose(H5Gcreate2(fid_dst, NAME_GROUP_UNCOPIED, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR if(test_open) { @@ -7975,8 +8000,8 @@ test_copy_dataset_compact_named_vl(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fap h5_fixname(FILENAME[0], src_fapl, src_filename, sizeof src_filename); h5_fixname(FILENAME[1], dst_fapl, dst_filename, sizeof dst_filename); - /* Reset file address checking info */ - addr_reset(); + /* Reset file token checking info */ + token_reset(); /* create source file */ if((fid_src = H5Fcreate(src_filename, H5F_ACC_TRUNC, fcpl_src, src_fapl)) < 0) TEST_ERROR @@ -8025,7 +8050,7 @@ test_copy_dataset_compact_named_vl(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fap /* create destination file */ if((fid_dst = H5Fcreate(dst_filename, H5F_ACC_TRUNC, fcpl_dst, dst_fapl)) < 0) TEST_ERROR - /* Create an uncopied object in destination file so that addresses in source and destination files aren't the same */ + /* Create an uncopied object in destination file so that tokens in source and destination files aren't the same */ if(H5Gclose(H5Gcreate2(fid_dst, NAME_GROUP_UNCOPIED, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR /* copy the dataset from SRC to DST */ @@ -8129,8 +8154,8 @@ test_copy_dataset_contig_named_vl(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl h5_fixname(FILENAME[0], src_fapl, src_filename, sizeof src_filename); h5_fixname(FILENAME[1], dst_fapl, dst_filename, sizeof dst_filename); - /* Reset file address checking info */ - addr_reset(); + /* Reset file token checking info */ + token_reset(); /* create source file */ if((fid_src = H5Fcreate(src_filename, H5F_ACC_TRUNC, fcpl_src, src_fapl)) < 0) TEST_ERROR @@ -8172,7 +8197,7 @@ test_copy_dataset_contig_named_vl(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl /* create destination file */ if((fid_dst = H5Fcreate(dst_filename, H5F_ACC_TRUNC, fcpl_dst, dst_fapl)) < 0) TEST_ERROR - /* Create an uncopied object in destination file so that addresses in source and destination files aren't the same */ + /* Create an uncopied object in destination file so that tokens in source and destination files aren't the same */ if(H5Gclose(H5Gcreate2(fid_dst, NAME_GROUP_UNCOPIED, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR /* copy the dataset from SRC to DST */ @@ -8284,8 +8309,8 @@ test_copy_dataset_chunked_named_vl(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fap h5_fixname(FILENAME[0], src_fapl, src_filename, sizeof src_filename); h5_fixname(FILENAME[1], dst_fapl, dst_filename, sizeof dst_filename); - /* Reset file address checking info */ - addr_reset(); + /* Reset file token checking info */ + token_reset(); /* create source file */ if((fid_src = H5Fcreate(src_filename, H5F_ACC_TRUNC, fcpl_src, src_fapl)) < 0) TEST_ERROR @@ -8337,7 +8362,7 @@ test_copy_dataset_chunked_named_vl(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fap /* create destination file */ if((fid_dst = H5Fcreate(dst_filename, H5F_ACC_TRUNC, fcpl_dst, dst_fapl)) < 0) TEST_ERROR - /* Create an uncopied object in destination file so that addresses in source and destination files aren't the same */ + /* Create an uncopied object in destination file so that tokens in source and destination files aren't the same */ if(H5Gclose(H5Gcreate2(fid_dst, NAME_GROUP_UNCOPIED, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR /* copy the dataset from SRC to DST */ @@ -8445,8 +8470,8 @@ test_copy_dataset_compressed_named_vl(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_ h5_fixname(FILENAME[0], src_fapl, src_filename, sizeof src_filename); h5_fixname(FILENAME[1], dst_fapl, dst_filename, sizeof dst_filename); - /* Reset file address checking info */ - addr_reset(); + /* Reset file token checking info */ + token_reset(); /* create source file */ if((fid_src = H5Fcreate(src_filename, H5F_ACC_TRUNC, fcpl_src, src_fapl)) < 0) TEST_ERROR @@ -8496,7 +8521,7 @@ test_copy_dataset_compressed_named_vl(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_ /* create destination file */ if((fid_dst = H5Fcreate(dst_filename, H5F_ACC_TRUNC, fcpl_dst, dst_fapl)) < 0) TEST_ERROR - /* Create an uncopied object in destination file so that addresses in source and destination files aren't the same */ + /* Create an uncopied object in destination file so that tokens in source and destination files aren't the same */ if(H5Gclose(H5Gcreate2(fid_dst, NAME_GROUP_UNCOPIED, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR /* copy the dataset from SRC to DST */ @@ -8615,8 +8640,8 @@ test_copy_dataset_compact_vl_vl(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, h5_fixname(FILENAME[0], src_fapl, src_filename, sizeof src_filename); h5_fixname(FILENAME[1], dst_fapl, dst_filename, sizeof dst_filename); - /* Reset file address checking info */ - addr_reset(); + /* Reset file token checking info */ + token_reset(); /* create source file */ if((fid_src = H5Fcreate(src_filename, H5F_ACC_TRUNC, fcpl_src, src_fapl)) < 0) TEST_ERROR @@ -8659,7 +8684,7 @@ test_copy_dataset_compact_vl_vl(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, /* create destination file */ if((fid_dst = H5Fcreate(dst_filename, H5F_ACC_TRUNC, fcpl_dst, dst_fapl)) < 0) TEST_ERROR - /* Create an uncopied object in destination file so that addresses in source and destination files aren't the same */ + /* Create an uncopied object in destination file so that tokens in source and destination files aren't the same */ if(H5Gclose(H5Gcreate2(fid_dst, NAME_GROUP_UNCOPIED, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR /* copy the dataset from SRC to DST */ @@ -8785,8 +8810,8 @@ test_copy_dataset_contig_vl_vl(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, h h5_fixname(FILENAME[0], src_fapl, src_filename, sizeof src_filename); h5_fixname(FILENAME[1], dst_fapl, dst_filename, sizeof dst_filename); - /* Reset file address checking info */ - addr_reset(); + /* Reset file token checking info */ + token_reset(); /* create source file */ if((fid_src = H5Fcreate(src_filename, H5F_ACC_TRUNC, fcpl_src, src_fapl)) < 0) TEST_ERROR @@ -8830,7 +8855,7 @@ test_copy_dataset_contig_vl_vl(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, h /* create destination file */ if((fid_dst = H5Fcreate(dst_filename, H5F_ACC_TRUNC, fcpl_dst, dst_fapl)) < 0) TEST_ERROR - /* Create an uncopied object in destination file so that addresses in source and destination files aren't the same */ + /* Create an uncopied object in destination file so that tokens in source and destination files aren't the same */ if(H5Gclose(H5Gcreate2(fid_dst, NAME_GROUP_UNCOPIED, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR /* copy the dataset from SRC to DST */ @@ -8951,8 +8976,8 @@ test_copy_dataset_chunked_vl_vl(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, h5_fixname(FILENAME[0], src_fapl, src_filename, sizeof src_filename); h5_fixname(FILENAME[1], dst_fapl, dst_filename, sizeof dst_filename); - /* Reset file address checking info */ - addr_reset(); + /* Reset file token checking info */ + token_reset(); /* create source file */ if((fid_src = H5Fcreate(src_filename, H5F_ACC_TRUNC, fcpl_src, src_fapl)) < 0) TEST_ERROR @@ -9159,8 +9184,8 @@ test_copy_dataset_compressed_vl_vl(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fap h5_fixname(FILENAME[0], src_fapl, src_filename, sizeof src_filename); h5_fixname(FILENAME[1], dst_fapl, dst_filename, sizeof dst_filename); - /* Reset file address checking info */ - addr_reset(); + /* Reset file token checking info */ + token_reset(); /* create source file */ if((fid_src = H5Fcreate(src_filename, H5F_ACC_TRUNC, fcpl_src, src_fapl)) < 0) TEST_ERROR @@ -9326,8 +9351,8 @@ test_copy_dataset_contig_cmpd_vl(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, h5_fixname(FILENAME[0], src_fapl, src_filename, sizeof src_filename); h5_fixname(FILENAME[1], dst_fapl, dst_filename, sizeof dst_filename); - /* Reset file address checking info */ - addr_reset(); + /* Reset file token checking info */ + token_reset(); /* create source file */ if((fid_src = H5Fcreate(src_filename, H5F_ACC_TRUNC, fcpl_src, src_fapl)) < 0) TEST_ERROR @@ -9364,7 +9389,7 @@ test_copy_dataset_contig_cmpd_vl(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, /* create destination file */ if((fid_dst = H5Fcreate(dst_filename, H5F_ACC_TRUNC, fcpl_dst, dst_fapl)) < 0) TEST_ERROR - /* Create an uncopied object in destination file so that addresses in source and destination files aren't the same */ + /* Create an uncopied object in destination file so that tokens in source and destination files aren't the same */ if(H5Gclose(H5Gcreate2(fid_dst, NAME_GROUP_UNCOPIED, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR /* copy the dataset from SRC to DST */ @@ -9472,8 +9497,8 @@ test_copy_dataset_chunked_cmpd_vl(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl h5_fixname(FILENAME[0], src_fapl, src_filename, sizeof src_filename); h5_fixname(FILENAME[1], dst_fapl, dst_filename, sizeof dst_filename); - /* Reset file address checking info */ - addr_reset(); + /* Reset file token checking info */ + token_reset(); /* create source file */ if((fid_src = H5Fcreate(src_filename, H5F_ACC_TRUNC, fcpl_src, src_fapl)) < 0) TEST_ERROR @@ -9517,7 +9542,7 @@ test_copy_dataset_chunked_cmpd_vl(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl /* create destination file */ if((fid_dst = H5Fcreate(dst_filename, H5F_ACC_TRUNC, fcpl_dst, dst_fapl)) < 0) TEST_ERROR - /* Create an uncopied object in destination file so that addresses in source and destination files aren't the same */ + /* Create an uncopied object in destination file so that tokens in source and destination files aren't the same */ if(H5Gclose(H5Gcreate2(fid_dst, NAME_GROUP_UNCOPIED, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR /* copy the dataset from SRC to DST */ @@ -9625,8 +9650,8 @@ test_copy_dataset_compact_cmpd_vl(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl h5_fixname(FILENAME[0], src_fapl, src_filename, sizeof src_filename); h5_fixname(FILENAME[1], dst_fapl, dst_filename, sizeof dst_filename); - /* Reset file address checking info */ - addr_reset(); + /* Reset file token checking info */ + token_reset(); /* create source file */ if((fid_src = H5Fcreate(src_filename, H5F_ACC_TRUNC, fcpl_src, src_fapl)) < 0) TEST_ERROR @@ -9670,7 +9695,7 @@ test_copy_dataset_compact_cmpd_vl(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl /* create destination file */ if((fid_dst = H5Fcreate(dst_filename, H5F_ACC_TRUNC, fcpl_dst, dst_fapl)) < 0) TEST_ERROR - /* Create an uncopied object in destination file so that addresses in source and destination files aren't the same */ + /* Create an uncopied object in destination file so that tokens in source and destination files aren't the same */ if(H5Gclose(H5Gcreate2(fid_dst, NAME_GROUP_UNCOPIED, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR /* copy the dataset from SRC to DST */ @@ -9776,8 +9801,8 @@ test_copy_null_ref(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, hid_t dst_fap h5_fixname(FILENAME[1], src_fapl, mid_filename, sizeof mid_filename); h5_fixname(FILENAME[2], dst_fapl, dst_filename, sizeof dst_filename); - /* Reset file address checking info */ - addr_reset(); + /* Reset file token checking info */ + token_reset(); /* Create source file */ if((fid1 = H5Fcreate(src_filename, H5F_ACC_TRUNC, fcpl_src, src_fapl)) < 0) @@ -9945,8 +9970,8 @@ test_copy_null_ref_open(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, hid_t ds h5_fixname(FILENAME[1], src_fapl, mid_filename, sizeof mid_filename); h5_fixname(FILENAME[2], dst_fapl, dst_filename, sizeof dst_filename); - /* Reset file address checking info */ - addr_reset(); + /* Reset file token checking info */ + token_reset(); /* Create source file */ if((fid1 = H5Fcreate(src_filename, H5F_ACC_TRUNC, fcpl_src, src_fapl)) < 0) @@ -10107,8 +10132,8 @@ test_copy_attr_crt_order(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, hid_t d h5_fixname(FILENAME[0], src_fapl, src_filename, sizeof src_filename); h5_fixname(FILENAME[1], src_fapl, dst_filename, sizeof dst_filename); - /* Reset file address checking info */ - addr_reset(); + /* Reset file token checking info */ + token_reset(); /* Create source file */ if((fid1 = H5Fcreate(src_filename, H5F_ACC_TRUNC, fcpl_src, src_fapl)) < 0) @@ -10225,11 +10250,12 @@ test_copy_committed_datatype_merge(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fap unsigned int i; /* Local index variables */ hsize_t dim1d[1]; /* Dataset dimensions */ int buf[DIM_SIZE_1]; /* Buffer for writing data */ - H5O_info_t oinfo; /* Object info */ - haddr_t exp_addr; /* Expected object address */ + H5O_info2_t oinfo; /* Object info */ + H5O_token_t exp_token; /* Expected object token */ char src1_filename[NAME_BUF_SIZE]; char src2_filename[NAME_BUF_SIZE]; char dst_filename[NAME_BUF_SIZE]; + int token_cmp; if(reopen) { TESTING("H5Ocopy(): merging committed datatypes with reopen") @@ -10246,8 +10272,8 @@ test_copy_committed_datatype_merge(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fap h5_fixname(FILENAME[3], src_fapl, src2_filename, sizeof src2_filename); h5_fixname(FILENAME[1], dst_fapl, dst_filename, sizeof dst_filename); - /* Reset file address checking info */ - addr_reset(); + /* Reset file token checking info */ + token_reset(); /* create source files */ if((fid_src1 = H5Fcreate(src1_filename, H5F_ACC_TRUNC, fcpl_src, src_fapl)) < 0) TEST_ERROR @@ -10323,7 +10349,7 @@ test_copy_committed_datatype_merge(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fap /* create destination file */ if((fid_dst = H5Fcreate(dst_filename, H5F_ACC_TRUNC, fcpl_dst, dst_fapl)) < 0) TEST_ERROR - /* Create an uncopied object in destination file so that addresses in source and destination files aren't the same */ + /* Create an uncopied object in destination file so that tokens in source and destination files aren't the same */ if(H5Gclose(H5Gcreate2(fid_dst, NAME_GROUP_UNCOPIED, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR /* copy SRC1 to DST */ @@ -10338,31 +10364,34 @@ test_copy_committed_datatype_merge(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fap if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDONLY, dst_fapl)) < 0) TEST_ERROR } /* end if */ - /* Open SRC1 committed dtype, get address */ + /* Open SRC1 committed dtype, get token */ if((tid = H5Topen2(fid_dst, NAME_GROUP_TOP "/" NAME_DATATYPE_SIMPLE, H5P_DEFAULT)) < 0) TEST_ERROR - if(H5Oget_info2(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR - exp_addr = oinfo.addr; + if(H5Oget_info3(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR + HDmemcpy(&exp_token, &oinfo.token, sizeof(exp_token)); if(H5Tclose(tid) < 0) TEST_ERROR - /* Open SRC1 dset dtype, check address */ + /* Open SRC1 dset dtype, check token */ if((did = H5Dopen2(fid_dst, NAME_GROUP_TOP "/" NAME_DATASET_SIMPLE, H5P_DEFAULT)) < 0) TEST_ERROR if((tid = H5Dget_type(did)) < 0) TEST_ERROR - if(H5Oget_info2(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR - if(oinfo.addr != exp_addr) TEST_ERROR + if(H5Oget_info3(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR + if(H5Otoken_cmp(tid, &oinfo.token, &exp_token, &token_cmp) < 0) TEST_ERROR + if(token_cmp) TEST_ERROR if(H5Tclose(tid) < 0) TEST_ERROR if(H5Dclose(did) < 0) TEST_ERROR - /* Open SRC2 committed dtype, check address */ + /* Open SRC2 committed dtype, check token */ if((tid = H5Topen2(fid_dst, NAME_GROUP_TOP2 "/" NAME_DATATYPE_SIMPLE, H5P_DEFAULT)) < 0) TEST_ERROR - if(H5Oget_info2(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR - if(oinfo.addr != exp_addr) TEST_ERROR + if(H5Oget_info3(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR + if(H5Otoken_cmp(tid, &oinfo.token, &exp_token, &token_cmp) < 0) TEST_ERROR + if(token_cmp) TEST_ERROR if(H5Tclose(tid) < 0) TEST_ERROR - /* Open SRC2 dset dtype, check address */ + /* Open SRC2 dset dtype, check token */ if((did = H5Dopen2(fid_dst, NAME_GROUP_TOP2 "/" NAME_DATASET_SIMPLE, H5P_DEFAULT)) < 0) TEST_ERROR if((tid = H5Dget_type(did)) < 0) TEST_ERROR - if(H5Oget_info2(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR - if(oinfo.addr != exp_addr) TEST_ERROR + if(H5Oget_info3(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR + if(H5Otoken_cmp(tid, &oinfo.token, &exp_token, &token_cmp) < 0) TEST_ERROR + if(token_cmp) TEST_ERROR if(H5Tclose(tid) < 0) TEST_ERROR if(H5Dclose(did) < 0) TEST_ERROR @@ -10376,7 +10405,7 @@ test_copy_committed_datatype_merge(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fap /* recreate destination file */ if((fid_dst = H5Fcreate(dst_filename, H5F_ACC_TRUNC, fcpl_dst, dst_fapl)) < 0) TEST_ERROR - /* Create an uncopied object in destination file so that addresses in source and destination files aren't the same */ + /* Create an uncopied object in destination file so that tokens in source and destination files aren't the same */ if(H5Gclose(H5Gcreate2(fid_dst, NAME_GROUP_UNCOPIED, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR /* copy SRC1 to DST */ @@ -10391,19 +10420,20 @@ test_copy_committed_datatype_merge(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fap if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDONLY, dst_fapl)) < 0) TEST_ERROR } /* end if */ - /* Open SRC1 dset dtype, get address */ + /* Open SRC1 dset dtype, get token */ if((did = H5Dopen2(fid_dst, NAME_DATASET_SIMPLE, H5P_DEFAULT)) < 0) TEST_ERROR if((tid = H5Dget_type(did)) < 0) TEST_ERROR - if(H5Oget_info2(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR - exp_addr = oinfo.addr; + if(H5Oget_info3(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR + HDmemcpy(&exp_token, &oinfo.token, sizeof(exp_token)); if(H5Tclose(tid) < 0) TEST_ERROR if(H5Dclose(did) < 0) TEST_ERROR - /* Open SRC2 dset dtype, check address */ + /* Open SRC2 dset dtype, check token */ if((did = H5Dopen2(fid_dst, NAME_DATASET_SIMPLE2, H5P_DEFAULT)) < 0) TEST_ERROR if((tid = H5Dget_type(did)) < 0) TEST_ERROR - if(H5Oget_info2(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR - if(oinfo.addr != exp_addr) TEST_ERROR + if(H5Oget_info3(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR + if(H5Otoken_cmp(tid, &oinfo.token, &exp_token, &token_cmp) < 0) TEST_ERROR + if(token_cmp) TEST_ERROR if(H5Tclose(tid) < 0) TEST_ERROR if(H5Dclose(did) < 0) TEST_ERROR @@ -10463,9 +10493,10 @@ test_copy_committed_datatype_merge_same_file(hid_t fcpl, hid_t fapl, hbool_t reo unsigned int i; /* Local index variables */ hsize_t dim1d[1]; /* Dataset dimensions */ int buf[DIM_SIZE_1]; /* Buffer for writing data */ - H5O_info_t oinfo; /* Object info */ - haddr_t exp_addr; /* Expected object address */ + H5O_info2_t oinfo; /* Object info */ + H5O_token_t exp_token; /* Expected object token */ char filename[NAME_BUF_SIZE]; + int token_cmp; if(reopen) TESTING("H5Ocopy(): merging committed datatypes to the source file with reopen") @@ -10479,8 +10510,8 @@ test_copy_committed_datatype_merge_same_file(hid_t fcpl, hid_t fapl, hbool_t reo /* Initialize the filename */ h5_fixname(FILENAME[0], fapl, filename, sizeof filename); - /* Reset file address checking info */ - addr_reset(); + /* Reset file token checking info */ + token_reset(); /* create file */ if((fid = H5Fcreate(filename, H5F_ACC_TRUNC, fcpl, fapl)) < 0) TEST_ERROR @@ -10553,7 +10584,7 @@ test_copy_committed_datatype_merge_same_file(hid_t fcpl, hid_t fapl, hbool_t reo /* * First copy each group to the destination group 3 (each with their own * group), and verify the committed datatypes are merged as expected. All - * datatypes copied should reference (share an address with) the + * datatypes copied should reference (share a token with) the * corresponding source datatype. */ /* Create destination group */ @@ -10572,61 +10603,68 @@ test_copy_committed_datatype_merge_same_file(hid_t fcpl, hid_t fapl, hbool_t reo if((fid = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) TEST_ERROR } /* end if */ - /* Open group 1 source committed dtype, get address */ + /* Open group 1 source committed dtype, get token */ if((tid = H5Topen2(fid, NAME_GROUP_TOP "/" NAME_DATATYPE_SIMPLE, H5P_DEFAULT)) < 0) TEST_ERROR - if(H5Oget_info2(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR - exp_addr = oinfo.addr; + if(H5Oget_info3(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR + HDmemcpy(&exp_token, &oinfo.token, sizeof(exp_token)); if(H5Tclose(tid) < 0) TEST_ERROR - /* Open group 1 source dset dtype, check address */ + /* Open group 1 source dset dtype, check token */ if((did = H5Dopen2(fid, NAME_GROUP_TOP "/" NAME_DATASET_SIMPLE, H5P_DEFAULT)) < 0) TEST_ERROR if((tid = H5Dget_type(did)) < 0) TEST_ERROR - if(H5Oget_info2(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR - if(oinfo.addr != exp_addr) TEST_ERROR + if(H5Oget_info3(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR + if(H5Otoken_cmp(tid, &oinfo.token, &exp_token, &token_cmp) < 0) TEST_ERROR + if(token_cmp) TEST_ERROR if(H5Tclose(tid) < 0) TEST_ERROR if(H5Dclose(did) < 0) TEST_ERROR - /* Open group 1 committed dtype, check address */ + /* Open group 1 committed dtype, check token */ if((tid = H5Topen2(fid, NAME_GROUP_TOP3 "/" NAME_GROUP_TOP "/" NAME_DATATYPE_SIMPLE, H5P_DEFAULT)) < 0) TEST_ERROR - if(H5Oget_info2(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR - if(oinfo.addr != exp_addr) TEST_ERROR + if(H5Oget_info3(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR + if(H5Otoken_cmp(tid, &oinfo.token, &exp_token, &token_cmp) < 0) TEST_ERROR + if(token_cmp) TEST_ERROR if(H5Tclose(tid) < 0) TEST_ERROR - /* Open group 1 dset dtype, check address */ + /* Open group 1 dset dtype, check token */ if((did = H5Dopen2(fid, NAME_GROUP_TOP3 "/" NAME_GROUP_TOP "/" NAME_DATASET_SIMPLE, H5P_DEFAULT)) < 0) TEST_ERROR if((tid = H5Dget_type(did)) < 0) TEST_ERROR - if(H5Oget_info2(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR - if(oinfo.addr != exp_addr) TEST_ERROR + if(H5Oget_info3(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR + if(H5Otoken_cmp(tid, &oinfo.token, &exp_token, &token_cmp) < 0) TEST_ERROR + if(token_cmp) TEST_ERROR if(H5Tclose(tid) < 0) TEST_ERROR if(H5Dclose(did) < 0) TEST_ERROR - /* Open group 2 source committed dtype, get address and make sure it is + /* Open group 2 source committed dtype, get token and make sure it is * different from group 1 source committed dtype */ if((tid = H5Topen2(fid, NAME_GROUP_TOP2 "/" NAME_DATATYPE_SIMPLE, H5P_DEFAULT)) < 0) TEST_ERROR - if(H5Oget_info2(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR - if(oinfo.addr == exp_addr) TEST_ERROR - exp_addr = oinfo.addr; + if(H5Oget_info3(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR + if(H5Otoken_cmp(tid, &oinfo.token, &exp_token, &token_cmp) < 0) TEST_ERROR + if(!token_cmp) TEST_ERROR + HDmemcpy(&exp_token, &oinfo.token, sizeof(exp_token)); if(H5Tclose(tid) < 0) TEST_ERROR - /* Open group 2 source dset dtype, check address */ + /* Open group 2 source dset dtype, check token */ if((did = H5Dopen2(fid, NAME_GROUP_TOP2 "/" NAME_DATASET_SIMPLE, H5P_DEFAULT)) < 0) TEST_ERROR if((tid = H5Dget_type(did)) < 0) TEST_ERROR - if(H5Oget_info2(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR - if(oinfo.addr != exp_addr) TEST_ERROR + if(H5Oget_info3(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR + if(H5Otoken_cmp(tid, &oinfo.token, &exp_token, &token_cmp) < 0) TEST_ERROR + if(token_cmp) TEST_ERROR if(H5Tclose(tid) < 0) TEST_ERROR if(H5Dclose(did) < 0) TEST_ERROR - /* Open group 2 committed dtype, check address */ + /* Open group 2 committed dtype, check token */ if((tid = H5Topen2(fid, NAME_GROUP_TOP3 "/" NAME_GROUP_TOP2 "/" NAME_DATATYPE_SIMPLE, H5P_DEFAULT)) < 0) TEST_ERROR - if(H5Oget_info2(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR - if(oinfo.addr != exp_addr) TEST_ERROR + if(H5Oget_info3(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR + if(H5Otoken_cmp(tid, &oinfo.token, &exp_token, &token_cmp) < 0) TEST_ERROR + if(token_cmp) TEST_ERROR if(H5Tclose(tid) < 0) TEST_ERROR - /* Open group 2 dset dtype, check address */ + /* Open group 2 dset dtype, check token */ if((did = H5Dopen2(fid, NAME_GROUP_TOP3 "/" NAME_GROUP_TOP2 "/" NAME_DATASET_SIMPLE, H5P_DEFAULT)) < 0) TEST_ERROR if((tid = H5Dget_type(did)) < 0) TEST_ERROR - if(H5Oget_info2(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR - if(oinfo.addr != exp_addr) TEST_ERROR + if(H5Oget_info3(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR + if(H5Otoken_cmp(tid, &oinfo.token, &exp_token, &token_cmp) < 0) TEST_ERROR + if(token_cmp) TEST_ERROR if(H5Tclose(tid) < 0) TEST_ERROR if(H5Dclose(did) < 0) TEST_ERROR @@ -10650,37 +10688,40 @@ test_copy_committed_datatype_merge_same_file(hid_t fcpl, hid_t fapl, hbool_t reo if((fid = H5Fopen(filename, H5F_ACC_RDONLY, fapl)) < 0) TEST_ERROR } /* end if */ - /* Open group 1 source dset dtype, get address */ + /* Open group 1 source dset dtype, get token */ if((did = H5Dopen2(fid, NAME_GROUP_TOP "/" NAME_DATASET_SIMPLE, H5P_DEFAULT)) < 0) TEST_ERROR if((tid = H5Dget_type(did)) < 0) TEST_ERROR - if(H5Oget_info2(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR - exp_addr = oinfo.addr; + if(H5Oget_info3(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR + HDmemcpy(&exp_token, &oinfo.token, sizeof(exp_token)); if(H5Tclose(tid) < 0) TEST_ERROR if(H5Dclose(did) < 0) TEST_ERROR - /* Open group 1 dset dtype, check address */ + /* Open group 1 dset dtype, check token */ if((did = H5Dopen2(fid, NAME_GROUP_TOP4 "/" NAME_DATASET_SIMPLE, H5P_DEFAULT)) < 0) TEST_ERROR if((tid = H5Dget_type(did)) < 0) TEST_ERROR - if(H5Oget_info2(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR - if(oinfo.addr != exp_addr) TEST_ERROR + if(H5Oget_info3(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR + if(H5Otoken_cmp(tid, &oinfo.token, &exp_token, &token_cmp) < 0) TEST_ERROR + if(token_cmp) TEST_ERROR if(H5Tclose(tid) < 0) TEST_ERROR if(H5Dclose(did) < 0) TEST_ERROR - /* Open group 2 source dset dtype, get address and make sure it is + /* Open group 2 source dset dtype, get token and make sure it is * different from group 1 source dset dtype */ if((did = H5Dopen2(fid, NAME_GROUP_TOP2 "/" NAME_DATASET_SIMPLE, H5P_DEFAULT)) < 0) TEST_ERROR if((tid = H5Dget_type(did)) < 0) TEST_ERROR - if(H5Oget_info2(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR - if(oinfo.addr == exp_addr) TEST_ERROR - exp_addr = oinfo.addr; + if(H5Oget_info3(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR + if(H5Otoken_cmp(tid, &oinfo.token, &exp_token, &token_cmp) < 0) TEST_ERROR + if(!token_cmp) TEST_ERROR + HDmemcpy(&exp_token, &oinfo.token, sizeof(exp_token)); if(H5Tclose(tid) < 0) TEST_ERROR if(H5Dclose(did) < 0) TEST_ERROR - /* Open group 2 dset dtype, check address */ + /* Open group 2 dset dtype, check token */ if((did = H5Dopen2(fid, NAME_GROUP_TOP4 "/" NAME_DATASET_SIMPLE2, H5P_DEFAULT)) < 0) TEST_ERROR if((tid = H5Dget_type(did)) < 0) TEST_ERROR - if(H5Oget_info2(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR - if(oinfo.addr != exp_addr) TEST_ERROR + if(H5Oget_info3(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR + if(H5Otoken_cmp(tid, &oinfo.token, &exp_token, &token_cmp) < 0) TEST_ERROR + if(token_cmp) TEST_ERROR if(H5Tclose(tid) < 0) TEST_ERROR if(H5Dclose(did) < 0) TEST_ERROR @@ -10736,10 +10777,11 @@ test_copy_committed_dt_merge_sugg(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl unsigned int i; /* Local index variables */ hsize_t dim1d[1]; /* Dataset dimensions */ int buf[DIM_SIZE_1]; /* Buffer for writing data */ - H5O_info_t oinfo; /* Object info */ - haddr_t exp_addr; /* Expected object address */ + H5O_info2_t oinfo; /* Object info */ + H5O_token_t exp_token; /* Expected object token */ char src_filename[NAME_BUF_SIZE]; char dst_filename[NAME_BUF_SIZE]; + int token_cmp; if(reopen) TESTING("H5Ocopy(): merging committed datatypes with suggestions and reopen") @@ -10754,8 +10796,8 @@ test_copy_committed_dt_merge_sugg(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl h5_fixname(FILENAME[0], src_fapl, src_filename, sizeof src_filename); h5_fixname(FILENAME[1], dst_fapl, dst_filename, sizeof dst_filename); - /* Reset file address checking info */ - addr_reset(); + /* Reset file token checking info */ + token_reset(); /* create source file */ if((fid_src = H5Fcreate(src_filename, H5F_ACC_TRUNC, fcpl_src, src_fapl)) < 0) TEST_ERROR @@ -10844,17 +10886,18 @@ test_copy_committed_dt_merge_sugg(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDONLY, dst_fapl)) < 0) TEST_ERROR } /* end if */ - /* Open committed dtype "b", get address */ + /* Open committed dtype "b", get token */ if((tid = H5Topen2(fid_dst, "/b", H5P_DEFAULT)) < 0) TEST_ERROR - if(H5Oget_info2(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR - exp_addr = oinfo.addr; + if(H5Oget_info3(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR + HDmemcpy(&exp_token, &oinfo.token, sizeof(exp_token)); if(H5Tclose(tid) < 0) TEST_ERROR - /* Open dset dtype, check address */ + /* Open dset dtype, check token */ if((did = H5Dopen2(fid_dst, NAME_DATASET_SIMPLE, H5P_DEFAULT)) < 0) TEST_ERROR if((tid = H5Dget_type(did)) < 0) TEST_ERROR - if(H5Oget_info2(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR - if(oinfo.addr != exp_addr) TEST_ERROR + if(H5Oget_info3(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR + if(H5Otoken_cmp(tid, &oinfo.token, &exp_token, &token_cmp) < 0) TEST_ERROR + if(token_cmp) TEST_ERROR if(H5Tclose(tid) < 0) TEST_ERROR if(H5Dclose(did) < 0) TEST_ERROR @@ -10882,31 +10925,33 @@ test_copy_committed_dt_merge_sugg(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDONLY, dst_fapl)) < 0) TEST_ERROR } /* end if */ - /* Open committed dtype "a", get address */ + /* Open committed dtype "a", get token */ if((tid = H5Topen2(fid_dst, "/a", H5P_DEFAULT)) < 0) TEST_ERROR - if(H5Oget_info2(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR - exp_addr = oinfo.addr; + if(H5Oget_info3(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR + HDmemcpy(&exp_token, &oinfo.token, sizeof(exp_token)); if(H5Tclose(tid) < 0) TEST_ERROR - /* Open dset 2 dtype, check address */ + /* Open dset 2 dtype, check token */ if((did = H5Dopen2(fid_dst, NAME_DATASET_SIMPLE2, H5P_DEFAULT)) < 0) TEST_ERROR if((tid = H5Dget_type(did)) < 0) TEST_ERROR - if(H5Oget_info2(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR - if(oinfo.addr != exp_addr) TEST_ERROR + if(H5Oget_info3(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR + if(H5Otoken_cmp(tid, &oinfo.token, &exp_token, &token_cmp) < 0) TEST_ERROR + if(token_cmp) TEST_ERROR if(H5Tclose(tid) < 0) TEST_ERROR if(H5Dclose(did) < 0) TEST_ERROR - /* Open committed dtype "b", get address */ + /* Open committed dtype "b", get token */ if((tid = H5Topen2(fid_dst, "/b", H5P_DEFAULT)) < 0) TEST_ERROR - if(H5Oget_info2(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR - exp_addr = oinfo.addr; + if(H5Oget_info3(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR + HDmemcpy(&exp_token, &oinfo.token, sizeof(exp_token)); if(H5Tclose(tid) < 0) TEST_ERROR - /* Open dset dtype, check address */ + /* Open dset dtype, check token */ if((did = H5Dopen2(fid_dst, NAME_DATASET_SIMPLE, H5P_DEFAULT)) < 0) TEST_ERROR if((tid = H5Dget_type(did)) < 0) TEST_ERROR - if(H5Oget_info2(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR - if(oinfo.addr != exp_addr) TEST_ERROR + if(H5Oget_info3(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR + if(H5Otoken_cmp(tid, &oinfo.token, &exp_token, &token_cmp) < 0) TEST_ERROR + if(token_cmp) TEST_ERROR if(H5Tclose(tid) < 0) TEST_ERROR if(H5Dclose(did) < 0) TEST_ERROR @@ -10967,10 +11012,11 @@ test_copy_committed_dt_merge_attr(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl unsigned int i; /* Local index variables */ hsize_t dim1d[1]; /* Dataset dimensions */ int buf[DIM_SIZE_1]; /* Buffer for writing data */ - H5O_info_t oinfo; /* Object info */ - haddr_t exp_addr; /* Expected object address */ + H5O_info2_t oinfo; /* Object info */ + H5O_token_t exp_token; /* Expected object token */ char src_filename[NAME_BUF_SIZE]; char dst_filename[NAME_BUF_SIZE]; + int token_cmp; if(reopen) TESTING("H5Ocopy(): merging committed datatypes with attributes and reopen") @@ -10985,8 +11031,8 @@ test_copy_committed_dt_merge_attr(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl h5_fixname(FILENAME[0], src_fapl, src_filename, sizeof src_filename); h5_fixname(FILENAME[1], dst_fapl, dst_filename, sizeof dst_filename); - /* Reset file address checking info */ - addr_reset(); + /* Reset file token checking info */ + token_reset(); /* create source file */ if((fid_src = H5Fcreate(src_filename, H5F_ACC_TRUNC, fcpl_src, src_fapl)) < 0) TEST_ERROR @@ -11078,19 +11124,20 @@ test_copy_committed_dt_merge_attr(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDONLY, dst_fapl)) < 0) TEST_ERROR } /* end if */ - /* Open attribute dtype, get address */ + /* Open attribute dtype, get token */ if((aid = H5Aopen_by_name(fid_dst, NAME_GROUP_TOP, "attr", H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR if((tid = H5Aget_type(aid)) < 0) TEST_ERROR - if(H5Oget_info2(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR - exp_addr = oinfo.addr; + if(H5Oget_info3(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR + HDmemcpy(&exp_token, &oinfo.token, sizeof(exp_token)); if(H5Tclose(tid) < 0) TEST_ERROR if(H5Aclose(aid) < 0) TEST_ERROR - /* Open dset dtype, check address */ + /* Open dset dtype, check token */ if((did = H5Dopen2(fid_dst, NAME_DATASET_SIMPLE, H5P_DEFAULT)) < 0) TEST_ERROR if((tid = H5Dget_type(did)) < 0) TEST_ERROR - if(H5Oget_info2(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR - if(oinfo.addr != exp_addr) TEST_ERROR + if(H5Oget_info3(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR + if(H5Otoken_cmp(tid, &oinfo.token, &exp_token, &token_cmp) < 0) TEST_ERROR + if(token_cmp) TEST_ERROR if(H5Tclose(tid) < 0) TEST_ERROR if(H5Dclose(did) < 0) TEST_ERROR @@ -11198,10 +11245,11 @@ test_copy_cdt_hier_merge(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, hid_t d int i; /* Local index variable */ hsize_t dim1d[1]; /* dimension sizes */ int buf[DIM_SIZE_1]; /* Buffer for data */ - haddr_t exp_addr_int, exp_addr_short; /* Expected object addresses */ - H5O_info_t oinfo; /* Object info */ + H5O_token_t exp_token_int, exp_token_short; /* Expected object tokenes */ + H5O_info2_t oinfo; /* Object info */ char src_filename[NAME_BUF_SIZE]; /* Source file name */ char dst_filename[NAME_BUF_SIZE]; /* Destination file name */ + int token_cmp; if(reopen) TESTING("H5Ocopy(): hier. of committed datatypes and merging with reopen") @@ -11216,8 +11264,8 @@ test_copy_cdt_hier_merge(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, hid_t d h5_fixname(FILENAME[0], src_fapl, src_filename, sizeof src_filename); h5_fixname(FILENAME[1], dst_fapl, dst_filename, sizeof dst_filename); - /* Reset file address checking info */ - addr_reset(); + /* Reset file token checking info */ + token_reset(); /* * Populate source file @@ -11338,16 +11386,16 @@ test_copy_cdt_hier_merge(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, hid_t d */ if(H5Ocopy(fid_src, "/", fid_dst, SRC_ROOT_GROUP, ocpypl_id, H5P_DEFAULT) < 0) TEST_ERROR - /* get address of committed datatype at root group */ + /* get token of committed datatype at root group */ if((tid = H5Topen2(fid_dst, SRC_ROOT_GROUP "/" ROOT_NDT_INT, H5P_DEFAULT)) < 0) TEST_ERROR - if(H5Oget_info2(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR - exp_addr_int = oinfo.addr; + if(H5Oget_info3(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR + HDmemcpy(&exp_token_int, &oinfo.token, sizeof(exp_token_int)); if(H5Tclose(tid) < 0) TEST_ERROR - /* get address of committed datatype at /g0 */ + /* get token of committed datatype at /g0 */ if((tid = H5Topen2(fid_dst, SRC_ROOT_GROUP NAME_GROUP_TOP "/" GROUP_NDT_SHORT, H5P_DEFAULT)) < 0) TEST_ERROR - if(H5Oget_info2(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR - exp_addr_short = oinfo.addr; + if(H5Oget_info3(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR + HDmemcpy(&exp_token_short, &oinfo.token, sizeof(exp_token_short)); if(H5Tclose(tid) < 0) TEST_ERROR /* verify the datatype of first dataset is not committed */ @@ -11357,19 +11405,21 @@ test_copy_cdt_hier_merge(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, hid_t d if(H5Tclose(tid) < 0) TEST_ERROR if(H5Dclose(did) < 0) TEST_ERROR - /* check address of datatype for second dataset */ + /* check token of datatype for second dataset */ if((did = H5Dopen2(fid_dst, SRC_ROOT_GROUP NAME_GROUP_TOP "/" SRC_NDT_DSET2, H5P_DEFAULT)) < 0) TEST_ERROR if((tid = H5Dget_type(did)) < 0) TEST_ERROR - if(H5Oget_info2(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR - if(oinfo.addr != exp_addr_short) TEST_ERROR + if(H5Oget_info3(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR + if(H5Otoken_cmp(tid, &oinfo.token, &exp_token_short, &token_cmp) < 0) TEST_ERROR + if(token_cmp) TEST_ERROR if(H5Tclose(tid) < 0) TEST_ERROR if(H5Dclose(did) < 0) TEST_ERROR - /* check address of datatype for third dataset */ + /* check token of datatype for third dataset */ if((did = H5Dopen2(fid_dst, SRC_ROOT_GROUP NAME_GROUP_TOP "/" SRC_NDT_DSET3, H5P_DEFAULT)) < 0) TEST_ERROR if((tid = H5Dget_type(did)) < 0) TEST_ERROR - if(H5Oget_info2(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR - if(oinfo.addr != exp_addr_int) TEST_ERROR + if(H5Oget_info3(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR + if(H5Otoken_cmp(tid, &oinfo.token, &exp_token_int, &token_cmp) < 0) TEST_ERROR + if(token_cmp) TEST_ERROR if(H5Tclose(tid) < 0) TEST_ERROR if(H5Dclose(did) < 0) TEST_ERROR @@ -11378,10 +11428,11 @@ test_copy_cdt_hier_merge(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, hid_t d */ if(H5Ocopy(fid_src, NAME_GROUP_TOP, fid_dst, NAME_GROUP_TOP, ocpypl_id, H5P_DEFAULT) < 0) TEST_ERROR - /* get address of committed datatype at /g0 */ + /* get token of committed datatype at /g0 */ if((tid = H5Topen2(fid_dst, NAME_GROUP_TOP "/" GROUP_NDT_SHORT, H5P_DEFAULT)) < 0) TEST_ERROR - if(H5Oget_info2(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR - if(oinfo.addr != exp_addr_short) TEST_ERROR + if(H5Oget_info3(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR + if(H5Otoken_cmp(tid, &oinfo.token, &exp_token_short, &token_cmp) < 0) TEST_ERROR + if(token_cmp) TEST_ERROR if(H5Tclose(tid) < 0) TEST_ERROR /* verify the datatype of first dataset is not committed */ @@ -11391,19 +11442,21 @@ test_copy_cdt_hier_merge(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, hid_t d if(H5Tclose(tid) < 0) TEST_ERROR if(H5Dclose(did) < 0) TEST_ERROR - /* check address of datatype for second dataset */ + /* check token of datatype for second dataset */ if((did = H5Dopen2(fid_dst, NAME_GROUP_TOP "/" SRC_NDT_DSET2, H5P_DEFAULT)) < 0) TEST_ERROR if((tid = H5Dget_type(did)) < 0) TEST_ERROR - if(H5Oget_info2(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR - if(oinfo.addr != exp_addr_short) TEST_ERROR + if(H5Oget_info3(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR + if(H5Otoken_cmp(tid, &oinfo.token, &exp_token_short, &token_cmp) < 0) TEST_ERROR + if(token_cmp) TEST_ERROR if(H5Tclose(tid) < 0) TEST_ERROR if(H5Dclose(did) < 0) TEST_ERROR - /* check address of datatype for third dataset */ + /* check token of datatype for third dataset */ if((did = H5Dopen2(fid_dst, NAME_GROUP_TOP "/" SRC_NDT_DSET3, H5P_DEFAULT)) < 0) TEST_ERROR if((tid = H5Dget_type(did)) < 0) TEST_ERROR - if(H5Oget_info2(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR - if(oinfo.addr != exp_addr_int) TEST_ERROR + if(H5Oget_info3(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR + if(H5Otoken_cmp(tid, &oinfo.token, &exp_token_int, &token_cmp) < 0) TEST_ERROR + if(token_cmp) TEST_ERROR if(H5Tclose(tid) < 0) TEST_ERROR if(H5Dclose(did) < 0) TEST_ERROR @@ -11414,19 +11467,21 @@ test_copy_cdt_hier_merge(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, hid_t d if(H5Ocopy(fid_src, NAME_GROUP_TOP "/" SRC_NDT_DSET2, fid_dst, NAME_GROUP_UNCOPIED "/" SRC_NDT_DSET2, ocpypl_id, H5P_DEFAULT) < 0) TEST_ERROR if(H5Ocopy(fid_src, NAME_GROUP_TOP "/" SRC_NDT_DSET3, fid_dst, NAME_GROUP_UNCOPIED "/" SRC_NDT_DSET3, ocpypl_id, H5P_DEFAULT) < 0) TEST_ERROR - /* Open attribute with anon ndt (short), get address */ + /* Open attribute with anon ndt (short), get token */ if((aid = H5Aopen_by_name(fid_dst, NAME_GROUP_UNCOPIED, DST_ATTR_ANON_SHORT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR if((tid = H5Aget_type(aid)) < 0) TEST_ERROR - if(H5Oget_info2(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR - if(oinfo.addr != exp_addr_short) TEST_ERROR + if(H5Oget_info3(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR + if(H5Otoken_cmp(tid, &oinfo.token, &exp_token_short, &token_cmp) < 0) TEST_ERROR + if(token_cmp) TEST_ERROR if(H5Tclose(tid) < 0) TEST_ERROR if(H5Aclose(aid) < 0) TEST_ERROR - /* Open attribute with anon ndt (int), get address */ + /* Open attribute with anon ndt (int), get token */ if((aid = H5Aopen_by_name(fid_dst, NAME_GROUP_UNCOPIED, DST_ATTR_ANON_INT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR if((tid = H5Aget_type(aid)) < 0) TEST_ERROR - if(H5Oget_info2(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR - if(oinfo.addr != exp_addr_int) TEST_ERROR + if(H5Oget_info3(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR + if(H5Otoken_cmp(tid, &oinfo.token, &exp_token_int, &token_cmp) < 0) TEST_ERROR + if(token_cmp) TEST_ERROR if(H5Tclose(tid) < 0) TEST_ERROR if(H5Aclose(aid) < 0) TEST_ERROR @@ -11437,19 +11492,21 @@ test_copy_cdt_hier_merge(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, hid_t d if(H5Tclose(tid) < 0) TEST_ERROR if(H5Dclose(did) < 0) TEST_ERROR - /* check address of datatype for second dataset */ + /* check token of datatype for second dataset */ if((did = H5Dopen2(fid_dst, NAME_GROUP_UNCOPIED "/" SRC_NDT_DSET2, H5P_DEFAULT)) < 0) TEST_ERROR if((tid = H5Dget_type(did)) < 0) TEST_ERROR - if(H5Oget_info2(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR - if(oinfo.addr != exp_addr_short) TEST_ERROR + if(H5Oget_info3(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR + if(H5Otoken_cmp(tid, &oinfo.token, &exp_token_short, &token_cmp) < 0) TEST_ERROR + if(token_cmp) TEST_ERROR if(H5Tclose(tid) < 0) TEST_ERROR if(H5Dclose(did) < 0) TEST_ERROR - /* check address of datatype for third dataset */ + /* check token of datatype for third dataset */ if((did = H5Dopen2(fid_dst, NAME_GROUP_UNCOPIED "/" SRC_NDT_DSET3, H5P_DEFAULT)) < 0) TEST_ERROR if((tid = H5Dget_type(did)) < 0) TEST_ERROR - if(H5Oget_info2(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR - if(oinfo.addr != exp_addr_int) TEST_ERROR + if(H5Oget_info3(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR + if(H5Otoken_cmp(tid, &oinfo.token, &exp_token_int, &token_cmp) < 0) TEST_ERROR + if(token_cmp) TEST_ERROR if(H5Tclose(tid) < 0) TEST_ERROR if(H5Dclose(did) < 0) TEST_ERROR @@ -11522,10 +11579,11 @@ test_copy_cdt_merge_cdt(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, hid_t ds hid_t aid = -1; /* Attribute ID */ hid_t ocpypl_id = -1; /* Object copy plist ID */ hsize_t dim1d[1]; /* dimension sizes */ - H5O_info_t oinfo; /* Object info */ - haddr_t exp_addr; /* Expected object addresses */ + H5O_info2_t oinfo; /* Object info */ + H5O_token_t exp_token; /* Expected object token */ char src_filename[NAME_BUF_SIZE]; /* Source file name */ char dst_filename[NAME_BUF_SIZE]; /* Destination file name */ + int token_cmp; if(reopen) TESTING("H5Ocopy(): merging various committed datatypes with reopen") @@ -11536,8 +11594,8 @@ test_copy_cdt_merge_cdt(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, hid_t ds h5_fixname(FILENAME[0], src_fapl, src_filename, sizeof src_filename); h5_fixname(FILENAME[1], dst_fapl, dst_filename, sizeof dst_filename); - /* Reset file address checking info */ - addr_reset(); + /* Reset file token checking info */ + token_reset(); /* * Populate source file @@ -11649,53 +11707,57 @@ test_copy_cdt_merge_cdt(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, hid_t ds /* * Verification */ - /* get address of committed datatype: /src_root/src_ndt_double */ + /* get token of committed datatype: /src_root/src_ndt_double */ if((tid = H5Topen2(fid_dst, "/" SRC_ROOT_GROUP "/" SRC_NDT_DOUBLE, H5P_DEFAULT)) < 0) TEST_ERROR - if(H5Oget_info2(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR - exp_addr = oinfo.addr; + if(H5Oget_info3(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR + HDmemcpy(&exp_token, &oinfo.token, sizeof(exp_token)); if(H5Tclose(tid) < 0) TEST_ERROR - /* get address of committed datatype: /dst_ndt_double */ + /* get token of committed datatype: /dst_ndt_double */ if((tid = H5Topen2(fid_dst, "/" DST_NDT_DOUBLE, H5P_DEFAULT)) < 0) TEST_ERROR - if(H5Oget_info2(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR - if(oinfo.addr != exp_addr) TEST_ERROR + if(H5Oget_info3(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR + if(H5Otoken_cmp(tid, &oinfo.token, &exp_token, &token_cmp) < 0) TEST_ERROR + if(token_cmp) TEST_ERROR if(H5Tclose(tid) < 0) TEST_ERROR - /* get address of committed datatype: /src_root/src_ndt_float */ + /* get token of committed datatype: /src_root/src_ndt_float */ if((tid = H5Topen2(fid_dst, "/" SRC_ROOT_GROUP "/" SRC_NDT_FLOAT, H5P_DEFAULT)) < 0) TEST_ERROR - if(H5Oget_info2(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR - exp_addr = oinfo.addr; + if(H5Oget_info3(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR + HDmemcpy(&exp_token, &oinfo.token, sizeof(exp_token)); if(H5Tclose(tid) < 0) TEST_ERROR - /* get address of committed datatype: /dst_ndt_float */ + /* get token of committed datatype: /dst_ndt_float */ if((tid = H5Topen2(fid_dst, "/" DST_NDT_FLOAT, H5P_DEFAULT)) < 0) TEST_ERROR - if(H5Oget_info2(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR - if(oinfo.addr != exp_addr) TEST_ERROR + if(H5Oget_info3(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR + if(H5Otoken_cmp(tid, &oinfo.token, &exp_token, &token_cmp) < 0) TEST_ERROR + if(token_cmp) TEST_ERROR if(H5Tclose(tid) < 0) TEST_ERROR - /* get address of committed datatype: /src_root/src_ndt_int */ + /* get token of committed datatype: /src_root/src_ndt_int */ if((tid = H5Topen2(fid_dst, "/" SRC_ROOT_GROUP "/" SRC_NDT_INT, H5P_DEFAULT)) < 0) TEST_ERROR - if(H5Oget_info2(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR - exp_addr = oinfo.addr; + if(H5Oget_info3(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR + HDmemcpy(&exp_token, &oinfo.token, sizeof(exp_token)); if(H5Tclose(tid) < 0) TEST_ERROR - /* get address of committed datatype: /dst_ndt_int */ + /* get token of committed datatype: /dst_ndt_int */ if((tid = H5Topen2(fid_dst, "/" DST_NDT_INT, H5P_DEFAULT)) < 0) TEST_ERROR - if(H5Oget_info2(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR - if(oinfo.addr != exp_addr) TEST_ERROR + if(H5Oget_info3(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR + if(H5Otoken_cmp(tid, &oinfo.token, &exp_token, &token_cmp) < 0) TEST_ERROR + if(token_cmp) TEST_ERROR if(H5Tclose(tid) < 0) TEST_ERROR - /* get address of committed datatype: /src_root/src_ndt_short */ + /* get token of committed datatype: /src_root/src_ndt_short */ if((tid = H5Topen2(fid_dst, "/" SRC_ROOT_GROUP "/" SRC_NDT_SHORT, H5P_DEFAULT)) < 0) TEST_ERROR - if(H5Oget_info2(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR - exp_addr = oinfo.addr; + if(H5Oget_info3(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR + HDmemcpy(&exp_token, &oinfo.token, sizeof(exp_token)); if(H5Tclose(tid) < 0) TEST_ERROR - /* open attribute; get its dtype; get dtype's address: /src_root/src_ndt_double/dst_attr */ + /* open attribute; get its dtype; get dtype's token: /src_root/src_ndt_double/dst_attr */ if((aid = H5Aopen_by_name(fid_dst, "/" SRC_ROOT_GROUP "/" SRC_NDT_DOUBLE, DST_ATTR, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR if((tid = H5Aget_type(aid)) < 0) TEST_ERROR - if(H5Oget_info2(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR - if(oinfo.addr != exp_addr) TEST_ERROR + if(H5Oget_info3(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR + if(H5Otoken_cmp(tid, &oinfo.token, &exp_token, &token_cmp) < 0) TEST_ERROR + if(token_cmp) TEST_ERROR if(H5Tclose(tid) < 0) TEST_ERROR if(H5Aclose(aid) < 0) TEST_ERROR @@ -11748,10 +11810,11 @@ test_copy_cdt_merge_suggs(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, hid_t fid_src = -1, fid_dst = -1; /* File IDs */ hid_t tid = -1; /* Datatype ID */ hid_t ocpypl_id = -1; /* Object copy plist ID */ - H5O_info_t oinfo; /* Object info */ - haddr_t exp_addr; /* Expected object address */ + H5O_info2_t oinfo; /* Object info */ + H5O_token_t exp_token; /* Expected object token */ char src_filename[NAME_BUF_SIZE]; char dst_filename[NAME_BUF_SIZE]; + int token_cmp; if(reopen) TESTING("H5Ocopy(): merging committed datatypes with suggestions and reopen") @@ -11762,8 +11825,8 @@ test_copy_cdt_merge_suggs(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, h5_fixname(FILENAME[0], src_fapl, src_filename, sizeof src_filename); h5_fixname(FILENAME[1], dst_fapl, dst_filename, sizeof dst_filename); - /* Reset file address checking info */ - addr_reset(); + /* Reset file token checking info */ + token_reset(); /* * Populate source file @@ -11823,16 +11886,17 @@ test_copy_cdt_merge_suggs(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDONLY, dst_fapl)) < 0) TEST_ERROR } /* end if */ - /* open committed dtype "/dst_ndt_int", get its address */ + /* open committed dtype "/dst_ndt_int", get its token */ if((tid = H5Topen2(fid_dst, DST_NDT_INT, H5P_DEFAULT)) < 0) TEST_ERROR - if(H5Oget_info2(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR - exp_addr = oinfo.addr; + if(H5Oget_info3(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR + HDmemcpy(&exp_token, &oinfo.token, sizeof(exp_token)); if(H5Tclose(tid) < 0) TEST_ERROR - /* check address of "/uncopied/src_ndt_int" */ + /* check token of "/uncopied/src_ndt_int" */ if((tid = H5Topen2(fid_dst, NAME_GROUP_UNCOPIED "/" SRC_NDT_INT, H5P_DEFAULT)) < 0) TEST_ERROR - if(H5Oget_info2(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR - if(oinfo.addr != exp_addr) TEST_ERROR + if(H5Oget_info3(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR + if(H5Otoken_cmp(tid, &oinfo.token, &exp_token, &token_cmp) < 0) TEST_ERROR + if(token_cmp) TEST_ERROR if(H5Tclose(tid) < 0) TEST_ERROR /* close the DST file */ @@ -11856,16 +11920,17 @@ test_copy_cdt_merge_suggs(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDONLY, dst_fapl)) < 0) TEST_ERROR } /* end if */ - /* open committed dtype "/uncopied/src_ndt_int", get its address */ + /* open committed dtype "/uncopied/src_ndt_int", get its token */ if((tid = H5Topen2(fid_dst, NAME_GROUP_UNCOPIED "/" SRC_NDT_INT, H5P_DEFAULT)) < 0) TEST_ERROR - if(H5Oget_info2(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR - exp_addr = oinfo.addr; + if(H5Oget_info3(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR + HDmemcpy(&exp_token, &oinfo.token, sizeof(exp_token)); if(H5Tclose(tid) < 0) TEST_ERROR - /* check address of "/src_ndt_int" */ + /* check token of "/src_ndt_int" */ if((tid = H5Topen2(fid_dst, SRC_NDT_INT, H5P_DEFAULT)) < 0) TEST_ERROR - if(H5Oget_info2(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR - if(oinfo.addr != exp_addr) TEST_ERROR + if(H5Oget_info3(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR + if(H5Otoken_cmp(tid, &oinfo.token, &exp_token, &token_cmp) < 0) TEST_ERROR + if(token_cmp) TEST_ERROR if(H5Tclose(tid) < 0) TEST_ERROR /* close the DST file */ @@ -11894,16 +11959,17 @@ test_copy_cdt_merge_suggs(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDONLY, dst_fapl)) < 0) TEST_ERROR } /* end if */ - /* Open committed dtype "/uncopied/src_ndt_int", get its address */ + /* Open committed dtype "/uncopied/src_ndt_int", get its token */ if((tid = H5Topen2(fid_dst, NAME_GROUP_UNCOPIED "/" SRC_NDT_INT, H5P_DEFAULT)) < 0) TEST_ERROR - if(H5Oget_info2(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR - exp_addr = oinfo.addr; + if(H5Oget_info3(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR + HDmemcpy(&exp_token, &oinfo.token, sizeof(exp_token)); if(H5Tclose(tid) < 0) TEST_ERROR - /* check address of "/src_ndt_int2" */ + /* check token of "/src_ndt_int2" */ if((tid = H5Topen2(fid_dst, SRC_NDT_INT2, H5P_DEFAULT)) < 0) TEST_ERROR - if(H5Oget_info2(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR - if(oinfo.addr != exp_addr) TEST_ERROR + if(H5Oget_info3(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR + if(H5Otoken_cmp(tid, &oinfo.token, &exp_token, &token_cmp) < 0) TEST_ERROR + if(token_cmp) TEST_ERROR if(H5Tclose(tid) < 0) TEST_ERROR /* close the DST file */ @@ -11928,16 +11994,17 @@ test_copy_cdt_merge_suggs(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDONLY, dst_fapl)) < 0) TEST_ERROR } /* end if */ - /* Open committed dtype "/dst_dt_int", get its address */ + /* Open committed dtype "/dst_dt_int", get its token */ if((tid = H5Topen2(fid_dst, DST_NDT_INT, H5P_DEFAULT)) < 0) TEST_ERROR - if(H5Oget_info2(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR - exp_addr = oinfo.addr; + if(H5Oget_info3(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR + HDmemcpy(&exp_token, &oinfo.token, sizeof(exp_token)); if(H5Tclose(tid) < 0) TEST_ERROR - /* check address of "/uncopied/src_ndt_int2" */ + /* check token of "/uncopied/src_ndt_int2" */ if((tid = H5Topen2(fid_dst, NAME_GROUP_UNCOPIED "/" SRC_NDT_INT2, H5P_DEFAULT)) < 0) TEST_ERROR - if(H5Oget_info2(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR - if(oinfo.addr != exp_addr) TEST_ERROR + if(H5Oget_info3(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR + if(H5Otoken_cmp(tid, &oinfo.token, &exp_token, &token_cmp) < 0) TEST_ERROR + if(token_cmp) TEST_ERROR if(H5Tclose(tid) < 0) TEST_ERROR /* close the DST file */ @@ -11988,10 +12055,11 @@ test_copy_cdt_merge_dset_suggs(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, unsigned int i; /* Local index variables */ hsize_t dim1d[1]; /* Dataset dimensions */ int buf[DIM_SIZE_1]; /* Buffer for writing data */ - H5O_info_t oinfo; /* Object info */ - haddr_t exp_addr; /* Expected object address */ + H5O_info2_t oinfo; /* Object info */ + H5O_token_t exp_token; /* Expected object token */ char src_filename[NAME_BUF_SIZE]; char dst_filename[NAME_BUF_SIZE]; + int token_cmp; if(reopen) TESTING("H5Ocopy(): merging committed datatypes of datasets with suggestions and reopen") @@ -12006,8 +12074,8 @@ test_copy_cdt_merge_dset_suggs(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, h5_fixname(FILENAME[0], src_fapl, src_filename, sizeof src_filename); h5_fixname(FILENAME[1], dst_fapl, dst_filename, sizeof dst_filename); - /* Reset file address checking info */ - addr_reset(); + /* Reset file token checking info */ + token_reset(); /* * Populate source file @@ -12084,17 +12152,18 @@ test_copy_cdt_merge_dset_suggs(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDONLY, dst_fapl)) < 0) TEST_ERROR } /* end if */ - /* Open committed dtype "/dst_ndt_int", get its address */ + /* Open committed dtype "/dst_ndt_int", get its token */ if((tid = H5Topen2(fid_dst, DST_NDT_INT, H5P_DEFAULT)) < 0) TEST_ERROR - if(H5Oget_info2(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR - exp_addr = oinfo.addr; + if(H5Oget_info3(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR + HDmemcpy(&exp_token, &oinfo.token, sizeof(exp_token)); if(H5Tclose(tid) < 0) TEST_ERROR - /* check address of datatype for the copied dataset: "/uncopied/src_ndt_dset" */ + /* check token of datatype for the copied dataset: "/uncopied/src_ndt_dset" */ if((did = H5Dopen2(fid_dst, NAME_GROUP_UNCOPIED "/" SRC_NDT_DSET, H5P_DEFAULT)) < 0) TEST_ERROR if((tid = H5Dget_type(did)) < 0) TEST_ERROR - if(H5Oget_info2(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR - if(oinfo.addr != exp_addr) TEST_ERROR + if(H5Oget_info3(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR + if(H5Otoken_cmp(tid, &oinfo.token, &exp_token, &token_cmp) < 0) TEST_ERROR + if(token_cmp) TEST_ERROR if(H5Tclose(tid) < 0) TEST_ERROR if(H5Dclose(did) < 0) TEST_ERROR @@ -12119,19 +12188,20 @@ test_copy_cdt_merge_dset_suggs(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDONLY, dst_fapl)) < 0) TEST_ERROR } /* end if */ - /* Open committed dtype dataset "/uncopied/src_ndt_dset", get its datatype address */ + /* Open committed dtype dataset "/uncopied/src_ndt_dset", get its datatype token */ if((did = H5Dopen2(fid_dst, NAME_GROUP_UNCOPIED "/" SRC_NDT_DSET, H5P_DEFAULT)) < 0) TEST_ERROR if((tid = H5Dget_type(did)) < 0) TEST_ERROR - if(H5Oget_info2(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR - exp_addr = oinfo.addr; + if(H5Oget_info3(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR + HDmemcpy(&exp_token, &oinfo.token, sizeof(exp_token)); if(H5Tclose(tid) < 0) TEST_ERROR if(H5Dclose(did) < 0) TEST_ERROR - /* check address of datatype for the copied dataset: "/src_ndt_dset" */ + /* check token of datatype for the copied dataset: "/src_ndt_dset" */ if((did = H5Dopen2(fid_dst, SRC_NDT_DSET, H5P_DEFAULT)) < 0) TEST_ERROR if((tid = H5Dget_type(did)) < 0) TEST_ERROR - if(H5Oget_info2(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR - if(oinfo.addr != exp_addr) TEST_ERROR + if(H5Oget_info3(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR + if(H5Otoken_cmp(tid, &oinfo.token, &exp_token, &token_cmp) < 0) TEST_ERROR + if(token_cmp) TEST_ERROR if(H5Tclose(tid) < 0) TEST_ERROR if(H5Dclose(did) < 0) TEST_ERROR @@ -12161,19 +12231,20 @@ test_copy_cdt_merge_dset_suggs(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDONLY, dst_fapl)) < 0) TEST_ERROR } /* end if */ - /* open the copied dataset: /uncopied/src_ndt_dset", get its address */ + /* open the copied dataset: /uncopied/src_ndt_dset", get its token */ if((did = H5Dopen2(fid_dst, NAME_GROUP_UNCOPIED "/" SRC_NDT_DSET, H5P_DEFAULT)) < 0) TEST_ERROR if((tid = H5Dget_type(did)) < 0) TEST_ERROR - if(H5Oget_info2(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR - exp_addr = oinfo.addr; + if(H5Oget_info3(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR + HDmemcpy(&exp_token, &oinfo.token, sizeof(exp_token)); if(H5Tclose(tid) < 0) TEST_ERROR if(H5Dclose(did) < 0) TEST_ERROR - /* check address of datatype for the copied dataset: "/src_ndt_dset2" */ + /* check token of datatype for the copied dataset: "/src_ndt_dset2" */ if((did = H5Dopen2(fid_dst, SRC_NDT_DSET2, H5P_DEFAULT)) < 0) TEST_ERROR if((tid = H5Dget_type(did)) < 0) TEST_ERROR - if(H5Oget_info2(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR - if(oinfo.addr != exp_addr) TEST_ERROR + if(H5Oget_info3(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR + if(H5Otoken_cmp(tid, &oinfo.token, &exp_token, &token_cmp) < 0) TEST_ERROR + if(token_cmp) TEST_ERROR if(H5Tclose(tid) < 0) TEST_ERROR if(H5Dclose(did) < 0) TEST_ERROR @@ -12199,19 +12270,20 @@ test_copy_cdt_merge_dset_suggs(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDONLY, dst_fapl)) < 0) TEST_ERROR } /* end if */ - /* open the copied dataset: "/src_ndt_dset", get its datatype address */ + /* open the copied dataset: "/src_ndt_dset", get its datatype token */ if((did = H5Dopen2(fid_dst, SRC_NDT_DSET, H5P_DEFAULT)) < 0) TEST_ERROR if((tid = H5Dget_type(did)) < 0) TEST_ERROR - if(H5Oget_info2(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR - exp_addr = oinfo.addr; + if(H5Oget_info3(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR + HDmemcpy(&exp_token, &oinfo.token, sizeof(exp_token)); if(H5Tclose(tid) < 0) TEST_ERROR if(H5Dclose(did) < 0) TEST_ERROR - /* check address of datatype for the copied dataset: /uncopied/src_ndt_dset2 */ + /* check token of datatype for the copied dataset: /uncopied/src_ndt_dset2 */ if((did = H5Dopen2(fid_dst, NAME_GROUP_UNCOPIED "/" SRC_NDT_DSET2, H5P_DEFAULT)) < 0) TEST_ERROR if((tid = H5Dget_type(did)) < 0) TEST_ERROR - if(H5Oget_info2(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR - if(oinfo.addr != exp_addr) TEST_ERROR + if(H5Oget_info3(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR + if(H5Otoken_cmp(tid, &oinfo.token, &exp_token, &token_cmp) < 0) TEST_ERROR + if(token_cmp) TEST_ERROR if(H5Tclose(tid) < 0) TEST_ERROR if(H5Dclose(did) < 0) TEST_ERROR @@ -12279,8 +12351,8 @@ test_copy_cdt_merge_all_suggs(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, h5_fixname(FILENAME[0], src_fapl, src_filename, sizeof src_filename); h5_fixname(FILENAME[1], dst_fapl, dst_filename, sizeof dst_filename); - /* Reset file address checking info */ - addr_reset(); + /* Reset file token checking info */ + token_reset(); /* * Populate source file @@ -12544,7 +12616,7 @@ test_copy_cdt_merge_all_suggs(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDONLY, dst_fapl)) < 0) TEST_ERROR } /* end if */ - /* open committed dtype "/dst_grp/dst_dt_int", get its address */ + /* open committed dtype "/dst_grp/dst_dt_int", get its token */ if((exp_tid = H5Topen2(fid_dst, "/" DST_GRP "/" DST_NDT_INT, H5P_DEFAULT)) < 0) TEST_ERROR /* open datatype of dataset */ @@ -12637,7 +12709,7 @@ test_copy_cdt_merge_all_suggs(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, if((aid = H5Aopen_by_name(fid_dst, DST_NDT_DOUBLE, DST_ATTR, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR if((exp_tid = H5Aget_type(aid)) < 0) TEST_ERROR - /* Open datatype of dataset, check address */ + /* Open datatype of dataset, check token */ if((did = H5Dopen2(fid_dst, "A_src_dset", H5P_DEFAULT)) < 0) TEST_ERROR if((tid = H5Dget_type(did)) < 0) TEST_ERROR @@ -12674,7 +12746,7 @@ test_copy_cdt_merge_all_suggs(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, /* open committed dtype "/dst_ndt_short" */ if((exp_tid = H5Topen2(fid_dst, "/" DST_NDT_SHORT, H5P_DEFAULT)) < 0) TEST_ERROR - /* open datatype of dataset, check address */ + /* open datatype of dataset, check token */ if((did = H5Dopen2(fid_dst, "B_src_dset", H5P_DEFAULT)) < 0) TEST_ERROR if((tid = H5Dget_type(did)) < 0) TEST_ERROR @@ -12756,11 +12828,12 @@ test_copy_set_mcdt_search_cb(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, unsigned int i; /* Local index variables */ hsize_t dim1d[1]; /* Dataset dimensions */ int buf[DIM_SIZE_1]; /* Buffer for writing data */ - H5O_info_t oinfo; /* Object info */ - haddr_t exp_addr; /* Expected object address */ + H5O_info2_t oinfo; /* Object info */ + H5O_token_t exp_token; /* Expected object token */ char src_filename[NAME_BUF_SIZE]; char dst_filename[NAME_BUF_SIZE]; mcdt_search_cb_ud cb_udata; /* User data for callback */ + int token_cmp; if(reopen) TESTING("H5Ocopy(): H5Pset_mcdt_search_cb and reopen") @@ -12775,8 +12848,8 @@ test_copy_set_mcdt_search_cb(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, h5_fixname(FILENAME[0], src_fapl, src_filename, sizeof src_filename); h5_fixname(FILENAME[1], dst_fapl, dst_filename, sizeof dst_filename); - /* Reset file address checking info */ - addr_reset(); + /* Reset file token checking info */ + token_reset(); /* create source file */ if((fid_src = H5Fcreate(src_filename, H5F_ACC_TRUNC, fcpl_src, src_fapl)) < 0) TEST_ERROR @@ -12868,17 +12941,18 @@ test_copy_set_mcdt_search_cb(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDONLY, dst_fapl)) < 0) TEST_ERROR } /* end if */ - /* Open committed dtype "b", get address */ + /* Open committed dtype "b", get token */ if((tid = H5Topen2(fid_dst, "/b", H5P_DEFAULT)) < 0) TEST_ERROR - if(H5Oget_info2(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR - exp_addr = oinfo.addr; + if(H5Oget_info3(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR + HDmemcpy(&exp_token, &oinfo.token, sizeof(exp_token)); if(H5Tclose(tid) < 0) TEST_ERROR - /* Open dset dtype, check address */ + /* Open dset dtype, check token */ if((did = H5Dopen2(fid_dst, NAME_DATASET_SIMPLE, H5P_DEFAULT)) < 0) TEST_ERROR if((tid = H5Dget_type(did)) < 0) TEST_ERROR - if(H5Oget_info2(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR - if(oinfo.addr != exp_addr) TEST_ERROR + if(H5Oget_info3(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR + if(H5Otoken_cmp(tid, &oinfo.token, &exp_token, &token_cmp) < 0) TEST_ERROR + if(token_cmp) TEST_ERROR if(H5Tclose(tid) < 0) TEST_ERROR if(H5Dclose(did) < 0) TEST_ERROR @@ -12916,17 +12990,18 @@ test_copy_set_mcdt_search_cb(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDONLY, dst_fapl)) < 0) TEST_ERROR } /* end if */ - /* Open committed dtype "a", get address */ + /* Open committed dtype "a", get token */ if((tid = H5Topen2(fid_dst, "/a", H5P_DEFAULT)) < 0) TEST_ERROR - if(H5Oget_info2(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR - exp_addr = oinfo.addr; + if(H5Oget_info3(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR + HDmemcpy(&exp_token, &oinfo.token, sizeof(exp_token)); if(H5Tclose(tid) < 0) TEST_ERROR - /* Open copied dataset and its dtype, check address */ + /* Open copied dataset and its dtype, check token */ if((did = H5Dopen2(fid_dst, NAME_DATASET_SIMPLE2, H5P_DEFAULT)) < 0) TEST_ERROR if((tid = H5Dget_type(did)) < 0) TEST_ERROR - if(H5Oget_info2(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR - if(oinfo.addr != exp_addr) TEST_ERROR + if(H5Oget_info3(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR + if(H5Otoken_cmp(tid, &oinfo.token, &exp_token, &token_cmp) < 0) TEST_ERROR + if(token_cmp) TEST_ERROR if(H5Tclose(tid) < 0) TEST_ERROR if(H5Dclose(did) < 0) TEST_ERROR @@ -12955,31 +13030,33 @@ test_copy_set_mcdt_search_cb(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDONLY, dst_fapl)) < 0) TEST_ERROR } /* end if */ - /* Open committed dtype "a", get address */ + /* Open committed dtype "a", get token */ if((tid = H5Topen2(fid_dst, "/a", H5P_DEFAULT)) < 0) TEST_ERROR - if(H5Oget_info2(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR - exp_addr = oinfo.addr; + if(H5Oget_info3(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR + HDmemcpy(&exp_token, &oinfo.token, sizeof(exp_token)); if(H5Tclose(tid) < 0) TEST_ERROR - /* Open the copied dataset and get its dtype, addresses should not be equal */ + /* Open the copied dataset and get its dtype, tokens should not be equal */ if((did = H5Dopen2(fid_dst, NAME_DATASET_SIMPLE3, H5P_DEFAULT)) < 0) TEST_ERROR if((tid = H5Dget_type(did)) < 0) TEST_ERROR - if(H5Oget_info2(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR - if(oinfo.addr == exp_addr) TEST_ERROR + if(H5Oget_info3(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR + if(H5Otoken_cmp(tid, &oinfo.token, &exp_token, &token_cmp) < 0) TEST_ERROR + if(!token_cmp) TEST_ERROR if(H5Tclose(tid) < 0) TEST_ERROR if(H5Dclose(did) < 0) TEST_ERROR - /* Open committed dtype "b", get address */ + /* Open committed dtype "b", get token */ if((tid = H5Topen2(fid_dst, "/b", H5P_DEFAULT)) < 0) TEST_ERROR - if(H5Oget_info2(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR - exp_addr = oinfo.addr; + if(H5Oget_info3(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR + HDmemcpy(&exp_token, &oinfo.token, sizeof(exp_token)); if(H5Tclose(tid) < 0) TEST_ERROR - /* Open the copied dataset and get its dtype, addresses should not be equal */ + /* Open the copied dataset and get its dtype, tokens should not be equal */ if((did = H5Dopen2(fid_dst, NAME_DATASET_SIMPLE3, H5P_DEFAULT)) < 0) TEST_ERROR if((tid = H5Dget_type(did)) < 0) TEST_ERROR - if(H5Oget_info2(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR - if(oinfo.addr == exp_addr) TEST_ERROR + if(H5Oget_info3(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR + if(H5Otoken_cmp(tid, &oinfo.token, &exp_token, &token_cmp) < 0) TEST_ERROR + if(!token_cmp) TEST_ERROR if(H5Tclose(tid) < 0) TEST_ERROR if(H5Dclose(did) < 0) TEST_ERROR @@ -13015,31 +13092,33 @@ test_copy_set_mcdt_search_cb(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDONLY, dst_fapl)) < 0) TEST_ERROR } /* end if */ - /* Open committed dtype "a", get address */ + /* Open committed dtype "a", get token */ if((tid = H5Topen2(fid_dst, "/a", H5P_DEFAULT)) < 0) TEST_ERROR - if(H5Oget_info2(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR - exp_addr = oinfo.addr; + if(H5Oget_info3(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR + HDmemcpy(&exp_token, &oinfo.token, sizeof(exp_token)); if(H5Tclose(tid) < 0) TEST_ERROR - /* Open the copied dataset and get its dtype, addresses should not be equal */ + /* Open the copied dataset and get its dtype, tokens should not be equal */ if((did = H5Dopen2(fid_dst, NAME_DATASET_SIMPLE3, H5P_DEFAULT)) < 0) TEST_ERROR if((tid = H5Dget_type(did)) < 0) TEST_ERROR - if(H5Oget_info2(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR - if(oinfo.addr == exp_addr) TEST_ERROR + if(H5Oget_info3(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR + if(H5Otoken_cmp(tid, &oinfo.token, &exp_token, &token_cmp) < 0) TEST_ERROR + if(!token_cmp) TEST_ERROR if(H5Tclose(tid) < 0) TEST_ERROR if(H5Dclose(did) < 0) TEST_ERROR - /* Open committed dtype "b", get address */ + /* Open committed dtype "b", get token */ if((tid = H5Topen2(fid_dst, "/b", H5P_DEFAULT)) < 0) TEST_ERROR - if(H5Oget_info2(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR - exp_addr = oinfo.addr; + if(H5Oget_info3(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR + HDmemcpy(&exp_token, &oinfo.token, sizeof(exp_token)); if(H5Tclose(tid) < 0) TEST_ERROR - /* Open the copied dataset and get its dtype, addresses should not be equal */ + /* Open the copied dataset and get its dtype, tokens should not be equal */ if((did = H5Dopen2(fid_dst, NAME_DATASET_SIMPLE3, H5P_DEFAULT)) < 0) TEST_ERROR if((tid = H5Dget_type(did)) < 0) TEST_ERROR - if(H5Oget_info2(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR - if(oinfo.addr == exp_addr) TEST_ERROR + if(H5Oget_info3(tid, &oinfo, H5O_INFO_BASIC) < 0) TEST_ERROR + if(H5Otoken_cmp(tid, &oinfo.token, &exp_token, &token_cmp) < 0) TEST_ERROR + if(!token_cmp) TEST_ERROR if(H5Tclose(tid) < 0) TEST_ERROR if(H5Dclose(did) < 0) TEST_ERROR @@ -13134,8 +13213,8 @@ test_copy_set_get_mcdt_search_cb(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, h5_fixname(FILENAME[0], src_fapl, src_filename, sizeof src_filename); h5_fixname(FILENAME[1], dst_fapl, dst_filename, sizeof dst_filename); - /* Reset file address checking info */ - addr_reset(); + /* Reset file token checking info */ + token_reset(); /* create source file */ if((fid_src = H5Fcreate(src_filename, H5F_ACC_TRUNC, fcpl_src, src_fapl)) < 0) TEST_ERROR @@ -13382,7 +13461,7 @@ error: */ static herr_t test_copy_iterate_cb(hid_t loc_id, const char *name, - const H5L_info_t H5_ATTR_UNUSED *link_info, void *op_data) + const H5L_info2_t H5_ATTR_UNUSED *link_info, void *op_data) { hid_t dst_loc_id = *((hid_t *)op_data); @@ -13411,8 +13490,8 @@ test_copy_iterate(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, hid_t dst_fapl h5_fixname(FILENAME[0], src_fapl, src_filename, sizeof src_filename); h5_fixname(FILENAME[1], src_fapl, dst_filename, sizeof dst_filename); - /* Reset file address checking info */ - addr_reset(); + /* Reset file token checking info */ + token_reset(); /* Create source file */ if((fid1 = H5Fcreate(src_filename, H5F_ACC_TRUNC, fcpl_src, src_fapl)) < 0) @@ -13442,8 +13521,7 @@ test_copy_iterate(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, hid_t dst_fapl /* Iterate over links in the root group, copying each object */ if((gid = H5Gopen2(fid1, "/", H5P_DEFAULT)) < 0) TEST_ERROR - if(H5Literate(gid, H5_INDEX_NAME, H5_ITER_INC, NULL, test_copy_iterate_cb, - &fid2) < 0) + if(H5Literate2(gid, H5_INDEX_NAME, H5_ITER_INC, NULL, test_copy_iterate_cb, &fid2) < 0) TEST_ERROR /* Close */ @@ -13506,8 +13584,8 @@ test_copy_option(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, hid_t dst_fapl, h5_fixname(FILENAME[0], src_fapl, src_filename, sizeof src_filename); h5_fixname(FILENAME[1], dst_fapl, dst_filename, sizeof dst_filename); - /* Reset file address checking info */ - addr_reset(); + /* Reset file token checking info */ + token_reset(); /* create source file */ if((fid_src = H5Fcreate(src_filename, H5F_ACC_TRUNC, fcpl_src, src_fapl)) < 0) TEST_ERROR @@ -13641,7 +13719,7 @@ test_copy_option(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, hid_t dst_fapl, /* create destination file */ if((fid_dst = H5Fcreate(dst_filename, H5F_ACC_TRUNC, fcpl_dst, dst_fapl)) < 0) TEST_ERROR - /* Create an uncopied object in destination file so that addresses in source and destination + /* Create an uncopied object in destination file so that tokens in source and destination files aren't the same */ if(H5Gclose(H5Gcreate2(fid_dst, NAME_GROUP_UNCOPIED, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR @@ -13827,8 +13905,8 @@ test_copy_dataset_open(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, hid_t dst h5_fixname(FILENAME[0], src_fapl, src_filename, sizeof src_filename); h5_fixname(FILENAME[1], dst_fapl, dst_filename, sizeof dst_filename); - /* Reset file address checking info */ - addr_reset(); + /* Reset file token checking info */ + token_reset(); /* create source file */ if((fid_src = H5Fcreate(src_filename, H5F_ACC_TRUNC, fcpl_src, src_fapl)) < 0) TEST_ERROR @@ -13836,7 +13914,7 @@ test_copy_dataset_open(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, hid_t dst /* create destination file */ if((fid_dst = H5Fcreate(dst_filename, H5F_ACC_TRUNC, fcpl_dst, dst_fapl)) < 0) TEST_ERROR - /* Create an uncopied object in destination file so that addresses in source and destination files aren't the same */ + /* Create an uncopied object in destination file so that tokens in source and destination files aren't the same */ if(H5Gclose(H5Gcreate2(fid_dst, NAME_GROUP_UNCOPIED, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR /* Set dataspace dimensions */ @@ -14373,8 +14451,8 @@ main(void) */ } /* end for */ - /* Reset file address checking info */ - addr_reset(); + /* Reset file token checking info */ + token_reset(); /* Verify symbol table messages are cached */ nerrors += (h5_verify_cached_stabs(FILENAME, fapl) < 0 ? 1 : 0); diff --git a/test/objcopy_ref.c b/test/objcopy_ref.c index 4637f23..20c6138 100644 --- a/test/objcopy_ref.c +++ b/test/objcopy_ref.c @@ -72,9 +72,9 @@ unsigned num_attributes_g; /* Number of attributes created */ /* Table containing object id and object name */ /* (Used for detecting duplicate objects when comparing groups */ static struct { - size_t nalloc; /* number of slots allocated */ - size_t nobjs; /* number of objects */ - haddr_t *obj; /* Addresses of objects seen */ + size_t nalloc; /* number of slots allocated */ + size_t nobjs; /* number of objects */ + H5O_token_t *obj; /* tokens for objects seen */ } idtab_g; /* Local function prototypes */ @@ -87,9 +87,9 @@ static int compare_groups(hid_t gid, hid_t gid2, hid_t pid, int depth, unsigned copy_flags); /*------------------------------------------------------------------------- - * Function: addr_insert + * Function: token_insert * - * Purpose: Add an address to the table. + * Purpose: Add a token to the table. * * Return: void * @@ -99,31 +99,31 @@ compare_groups(hid_t gid, hid_t gid2, hid_t pid, int depth, unsigned copy_flags) *------------------------------------------------------------------------- */ static void -addr_insert(H5O_info_t *oi) +token_insert(H5O_info2_t *oinfo) { size_t n; /* Don't add it if the link count is 1 because such an object can only * be encountered once. */ - if(oi->rc < 2) + if(oinfo->rc < 2) return; /* Extend the table */ if(idtab_g.nobjs >= idtab_g.nalloc) { - idtab_g.nalloc = MAX(256, 2*idtab_g.nalloc); - idtab_g.obj = (haddr_t *)HDrealloc(idtab_g.obj, idtab_g.nalloc * sizeof(idtab_g.obj[0])); - } /* end if */ + idtab_g.nalloc = MAX(256, 2 * idtab_g.nalloc); + idtab_g.obj = (H5O_token_t *)HDrealloc(idtab_g.obj, idtab_g.nalloc * sizeof(idtab_g.obj[0])); + } /* Insert the entry */ n = idtab_g.nobjs++; - idtab_g.obj[n] = oi->addr; -} /* end addr_insert() */ + idtab_g.obj[n] = oinfo->token; +} /* end token_insert() */ /*------------------------------------------------------------------------- - * Function: addr_lookup + * Function: token_lookup * - * Purpose: Check if address has already been encountered + * Purpose: Check if a token has already been encountered * * Return: Success: TRUE/FALSE * Failure: (can't fail) @@ -134,24 +134,29 @@ addr_insert(H5O_info_t *oi) *------------------------------------------------------------------------- */ static H5_ATTR_PURE hbool_t -addr_lookup(H5O_info_t *oi) +token_lookup(hid_t loc_id, H5O_info2_t *oinfo) { - size_t n; + size_t n; + int token_cmp; - if(oi->rc < 2) return FALSE; /*only one link possible*/ + if(oinfo->rc < 2) + return FALSE; /*only one link possible*/ - for(n = 0; n < idtab_g.nobjs; n++) - if(H5F_addr_eq(idtab_g.obj[n], oi->addr)) + for(n = 0; n < idtab_g.nobjs; n++) { + if(H5Otoken_cmp(loc_id, &(idtab_g.obj[n]), &oinfo->token, &token_cmp) < 0) + return FALSE; + if(0 == token_cmp) return TRUE; + } return FALSE; -} /* end addr_lookup() */ +} /* end token_lookup() */ /*------------------------------------------------------------------------- - * Function: addr_reset + * Function: token_reset * - * Purpose: Reset the address tracking data structures + * Purpose: Reset the token tracking data structures * * Return: void * @@ -161,13 +166,13 @@ addr_lookup(H5O_info_t *oi) *------------------------------------------------------------------------- */ static void -addr_reset(void) +token_reset(void) { if(idtab_g.obj) HDfree(idtab_g.obj); idtab_g.obj = NULL; idtab_g.nalloc = idtab_g.nobjs = 0; -} /* end addr_reset() */ +} /* end token_reset() */ /*------------------------------------------------------------------------- @@ -625,7 +630,7 @@ static int compare_std_attributes(hid_t oid, hid_t oid2, hid_t pid) { hid_t aid = -1, aid2 = -1; /* Attribute IDs */ - H5O_info_t oinfo1, oinfo2; /* Object info */ + H5O_info2_t oinfo1, oinfo2; /* Object info */ unsigned cpy_flags; /* Object copy flags */ /* Retrieve the object copy flags from the property list, if it's non-DEFAULT */ @@ -636,10 +641,10 @@ compare_std_attributes(hid_t oid, hid_t oid2, hid_t pid) cpy_flags = 0; /* Check the number of attributes on source dataset */ - if(H5Oget_info2(oid, &oinfo1, H5O_INFO_NUM_ATTRS) < 0) TEST_ERROR + if(H5Oget_info3(oid, &oinfo1, H5O_INFO_NUM_ATTRS) < 0) TEST_ERROR /* Check the number of attributes on destination dataset */ - if(H5Oget_info2(oid2, &oinfo2, H5O_INFO_NUM_ATTRS) < 0) TEST_ERROR + if(H5Oget_info3(oid2, &oinfo2, H5O_INFO_NUM_ATTRS) < 0) TEST_ERROR if(cpy_flags & H5O_COPY_WITHOUT_ATTR_FLAG) { /* Check that the destination has no attributes */ @@ -808,11 +813,11 @@ compare_data(hid_t parent1, hid_t parent2, hid_t pid, hid_t tid, size_t nelmts, /* Check for object or region reference */ if(H5Tequal(tid, H5T_STD_REF) > 0) { - const H5R_ref_t *ref_buf1, *ref_buf2; /* Aliases for buffers to compare */ + H5R_ref_t *ref_buf1, *ref_buf2; /* Aliases for buffers to compare */ /* Loop over elements in buffers */ - ref_buf1 = (const H5R_ref_t *)buf1; - ref_buf2 = (const H5R_ref_t *)buf2; + ref_buf1 = (H5R_ref_t *)buf1; + ref_buf2 = (H5R_ref_t *)buf2; for(u = 0; u < nelmts; u++, ref_buf1++, ref_buf2++) { hid_t obj1_id, obj2_id; /* IDs for objects referenced */ H5O_type_t obj1_type, obj2_type; /* Types of objects referenced */ @@ -828,11 +833,13 @@ compare_data(hid_t parent1, hid_t parent2, hid_t pid, hid_t tid, size_t nelmts, /* break the infinite loop when the ref_object points to itself */ if(obj_owner > 0) { - H5O_info_t oinfo1, oinfo2; + H5O_info2_t oinfo1, oinfo2; + int token_cmp; - if(H5Oget_info2(obj_owner, &oinfo1, H5O_INFO_BASIC) < 0) TEST_ERROR - if(H5Oget_info2(obj1_id, &oinfo2, H5O_INFO_BASIC) < 0) TEST_ERROR - if(H5F_addr_eq(oinfo1.addr, oinfo2.addr)) { + if(H5Oget_info3(obj_owner, &oinfo1, H5O_INFO_BASIC) < 0) TEST_ERROR + if(H5Oget_info3(obj1_id, &oinfo2, H5O_INFO_BASIC) < 0) TEST_ERROR + if(H5Otoken_cmp(obj1_id, &oinfo1.token, &oinfo2.token, &token_cmp) < 0) TEST_ERROR + if(0 == token_cmp) { if(H5Oclose(obj1_id) < 0) TEST_ERROR if(H5Oclose(obj2_id) < 0) TEST_ERROR return TRUE; @@ -1110,8 +1117,8 @@ compare_groups(hid_t gid, hid_t gid2, hid_t pid, int depth, unsigned copy_flags) if(ginfo2.nlinks > 0) { char objname[NAME_BUF_SIZE]; /* Name of object in group */ char objname2[NAME_BUF_SIZE]; /* Name of object in group */ - H5L_info_t linfo; /* Link information */ - H5L_info_t linfo2; /* Link information */ + H5L_info2_t linfo; /* Link information */ + H5L_info2_t linfo2; /* Link information */ /* Loop over contents of groups */ for(idx = 0; idx < ginfo.nlinks; idx++) { @@ -1121,18 +1128,24 @@ compare_groups(hid_t gid, hid_t gid2, hid_t pid, int depth, unsigned copy_flags) if(HDstrcmp(objname, objname2)) TEST_ERROR /* Get link info */ - if(H5Lget_info(gid, objname, &linfo, H5P_DEFAULT) < 0) TEST_ERROR - if(H5Lget_info(gid2, objname2, &linfo2, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Lget_info2(gid, objname, &linfo, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Lget_info2(gid2, objname2, &linfo2, H5P_DEFAULT) < 0) TEST_ERROR if(linfo.type != linfo2.type) TEST_ERROR /* Extra checks for "real" objects */ if(linfo.type == H5L_TYPE_HARD) { - hid_t oid, oid2; /* IDs of objects within group */ - H5O_info_t oinfo, oinfo2; /* Object info */ + hid_t oid, oid2; /* IDs of objects within group */ + H5O_info2_t oinfo, oinfo2; /* Data model object info */ + H5O_native_info_t ninfo, ninfo2; /* Native file format object info */ /* Compare some pieces of the object info */ - if(H5Oget_info_by_name2(gid, objname, &oinfo, H5O_INFO_BASIC|H5O_INFO_HDR, H5P_DEFAULT) < 0) TEST_ERROR - if(H5Oget_info_by_name2(gid2, objname2, &oinfo2, H5O_INFO_BASIC|H5O_INFO_HDR, H5P_DEFAULT) < 0) TEST_ERROR + /* Get data model object info */ + if(H5Oget_info_by_name3(gid, objname, &oinfo, H5O_INFO_BASIC, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Oget_info_by_name3(gid2, objname2, &oinfo2, H5O_INFO_BASIC, H5P_DEFAULT) < 0) TEST_ERROR + + /* Get native object info */ + if(H5Oget_native_info_by_name(gid, objname, &ninfo, H5O_NATIVE_INFO_HDR, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Oget_native_info_by_name(gid2, objname2, &ninfo2, H5O_NATIVE_INFO_HDR, H5P_DEFAULT) < 0) TEST_ERROR if(oinfo.type != oinfo2.type) TEST_ERROR if(oinfo.rc != oinfo2.rc) TEST_ERROR @@ -1143,17 +1156,18 @@ compare_groups(hid_t gid, hid_t gid2, hid_t pid, int depth, unsigned copy_flags) * of messages hasn't increased. */ if(H5O_COPY_PRESERVE_NULL_FLAG & copy_flags) { - if(oinfo.hdr.nmesgs != oinfo2.hdr.nmesgs) + if(ninfo.hdr.nmesgs != ninfo2.hdr.nmesgs) ; else - if(oinfo.hdr.nmesgs < oinfo2.hdr.nmesgs) TEST_ERROR + if(ninfo.hdr.nmesgs < ninfo2.hdr.nmesgs) + TEST_ERROR } /* Check for object already having been compared */ - if(addr_lookup(&oinfo)) + if(token_lookup(gid, &oinfo)) continue; else - addr_insert(&oinfo); + token_insert(&oinfo); /* Open objects */ if((oid = H5Oopen(gid, objname, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR @@ -1269,8 +1283,8 @@ test_copy_option(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, hid_t dst_fapl, h5_fixname(FILENAME[0], src_fapl, src_filename, sizeof src_filename); h5_fixname(FILENAME[1], dst_fapl, dst_filename, sizeof dst_filename); - /* Reset file address checking info */ - addr_reset(); + /* Reset file token checking info */ + token_reset(); /* create source file */ if((fid_src = H5Fcreate(src_filename, H5F_ACC_TRUNC, fcpl_src, src_fapl)) < 0) TEST_ERROR @@ -1404,7 +1418,7 @@ test_copy_option(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, hid_t dst_fapl, /* create destination file */ if((fid_dst = H5Fcreate(dst_filename, H5F_ACC_TRUNC, fcpl_dst, dst_fapl)) < 0) TEST_ERROR - /* Create an uncopied object in destination file so that addresses in source and destination + /* Create an uncopied object in destination file so that tokens in source and destination files aren't the same */ if(H5Gclose(H5Gcreate2(fid_dst, NAME_GROUP_UNCOPIED, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR @@ -1636,8 +1650,8 @@ main(void) FALSE, "H5Ocopy(): expand object reference"); } /* end for */ - /* Reset file address checking info */ - addr_reset(); + /* Reset file token checking info */ + token_reset(); /* Verify symbol table messages are cached */ nerrors += (h5_verify_cached_stabs(FILENAME, fapl) < 0 ? 1 : 0); diff --git a/test/ohdr.c b/test/ohdr.c index 53d2f59..120935c 100644 --- a/test/ohdr.c +++ b/test/ohdr.c @@ -322,7 +322,7 @@ test_ohdr_swmr(hbool_t new_format) hsize_t dims[1]; /* Dimension sizes */ size_t u; /* Iterator */ int n; /* Data variable */ - H5O_info_t obj_info; /* Information for the object */ + H5O_native_info_t ninfo; /* Information for the object */ if(new_format) { TESTING("exercise the coding for the re-read of the object header for SWMR access: latest-format"); @@ -392,16 +392,16 @@ test_ohdr_swmr(hbool_t new_format) FAIL_STACK_ERROR /* Get the object information */ - if(H5Oget_info2(did, &obj_info, H5O_INFO_HDR) < 0) + if(H5Oget_native_info(did, &ninfo, H5O_NATIVE_INFO_HDR) < 0) FAIL_STACK_ERROR if(new_format) - if(obj_info.hdr.version != OBJ_VERSION_LATEST) + if(ninfo.hdr.version != OBJ_VERSION_LATEST) FAIL_STACK_ERROR /* The size of object header should be greater than the speculative read size of H5O_SPEC_READ_SIZE */ /* This will exercise the coding for the re-read of the object header for SWMR access */ - if(obj_info.hdr.space.total < H5O_SPEC_READ_SIZE) + if(ninfo.hdr.space.total < H5O_SPEC_READ_SIZE) TEST_ERROR; /* Close the dataset */ @@ -757,10 +757,10 @@ error: */ static int count_attributes(hid_t dset_id) -{ - H5O_info_t info; - - if(H5Oget_info2(dset_id, &info, H5O_INFO_NUM_ATTRS) < 0) +{ + H5O_info2_t info; + + if(H5Oget_info3(dset_id, &info, H5O_INFO_NUM_ATTRS) < 0) return -1; else return (int)info.num_attrs; /* should never exceed int bounds */ @@ -774,10 +774,13 @@ count_attributes(hid_t dset_id) static herr_t _oh_getsize(hid_t did, hsize_t *size_out) { - H5O_info_t info; - if(FAIL == H5Oget_info2(did, &info, H5O_INFO_HDR)) + H5O_native_info_t ninfo; + + if(FAIL == H5Oget_native_info(did, &ninfo, H5O_NATIVE_INFO_HDR)) return FAIL; - *size_out = info.hdr.space.total; + + *size_out = ninfo.hdr.space.total; + return SUCCEED; } /* _oh_getsize */ diff --git a/test/stab.c b/test/stab.c index 80c8b06..215d748 100644 --- a/test/stab.c +++ b/test/stab.c @@ -70,8 +70,10 @@ const char *FILENAME[] = { #define GCPL_ON_ROOT_MAX_COMPACT 4 #define GCPL_ON_ROOT_MIN_DENSE 2 +#ifndef H5_NO_DEPRECATED_SYMBOLS /* Definitions for 'old_api' test */ #define OLD_API_GROUP "/old_api" +#endif /* H5_NO_DEPRECATED_SYMBOLS */ /* Definitions for 'corrupt_stab_msg' test */ #define CORRUPT_STAB_FILE "corrupt_stab_msg.h5" @@ -328,7 +330,7 @@ lifecycle(hid_t fcpl, hid_t fapl2) unsigned est_num_entries; /* Estimated # of entries in group */ unsigned est_name_len; /* Estimated length of entry name */ unsigned nmsgs; /* Number of messages in group's header */ - H5O_info_t oinfo; /* Object info */ + H5O_native_info_t ninfo; /* Object info */ char objname[NAME_BUF_SIZE]; /* Object name */ char filename[NAME_BUF_SIZE]; h5_stat_size_t empty_size; /* Size of an empty file */ @@ -419,11 +421,11 @@ lifecycle(hid_t fcpl, hid_t fapl2) if(H5G__is_new_dense_test(gid) != FALSE) TEST_ERROR /* Check that the object header is only one chunk and the space has been allocated correctly */ - if(H5Oget_info2(gid, &oinfo, H5O_INFO_HDR) < 0) TEST_ERROR - if(oinfo.hdr.space.total != 151) TEST_ERROR - if(oinfo.hdr.space.free != 0) TEST_ERROR - if(oinfo.hdr.nmesgs != 6) TEST_ERROR - if(oinfo.hdr.nchunks != 1) TEST_ERROR + if(H5Oget_native_info(gid, &ninfo, H5O_NATIVE_INFO_HDR) < 0) TEST_ERROR + if(ninfo.hdr.space.total != 151) TEST_ERROR + if(ninfo.hdr.space.free != 0) TEST_ERROR + if(ninfo.hdr.nmesgs != 6) TEST_ERROR + if(ninfo.hdr.nchunks != 1) TEST_ERROR /* Create one more "bottom" group, which should push top group into using a symbol table */ HDsprintf(objname, LIFECYCLE_BOTTOM_GROUP, u); @@ -441,11 +443,11 @@ lifecycle(hid_t fcpl, hid_t fapl2) if(H5G__is_new_dense_test(gid) != TRUE) TEST_ERROR /* Check that the object header is still one chunk and the space has been allocated correctly */ - if(H5Oget_info2(gid, &oinfo, H5O_INFO_HDR) < 0) TEST_ERROR - if(oinfo.hdr.space.total != 151) TEST_ERROR - if(oinfo.hdr.space.free != 92) TEST_ERROR - if(oinfo.hdr.nmesgs != 3) TEST_ERROR - if(oinfo.hdr.nchunks != 1) TEST_ERROR + if(H5Oget_native_info(gid, &ninfo, H5O_NATIVE_INFO_HDR) < 0) TEST_ERROR + if(ninfo.hdr.space.total != 151) TEST_ERROR + if(ninfo.hdr.space.free != 92) TEST_ERROR + if(ninfo.hdr.nmesgs != 3) TEST_ERROR + if(ninfo.hdr.nchunks != 1) TEST_ERROR /* Unlink objects from top group */ while(u >= LIFECYCLE_MIN_DENSE) { diff --git a/test/tattr.c b/test/tattr.c index b89ec3f..bcd8698 100644 --- a/test/tattr.c +++ b/test/tattr.c @@ -20,6 +20,7 @@ *************************************************************/ #include "testhdf5.h" +#include "H5VLnative_private.h" /* * This file needs to access private information from the H5O package. @@ -427,7 +428,7 @@ test_attr_basic_read(hid_t fapl) hid_t dataset; /* Dataset ID */ hid_t group; /* Group ID */ hid_t attr; /* Attribute ID */ - H5O_info_t oinfo; /* Object info */ + H5O_info2_t oinfo; /* Object info */ int read_data1[ATTR1_DIM1] = {0}; /* Buffer for reading 1st attribute */ int read_data2[ATTR2_DIM1][ATTR2_DIM2] = {{0}}; /* Buffer for reading 2nd attribute */ int i, j; /* Local index variables */ @@ -445,9 +446,9 @@ test_attr_basic_read(hid_t fapl) CHECK(dataset, FAIL, "H5Dopen2"); /* Verify the correct number of attributes */ - ret = H5Oget_info2(dataset, &oinfo, H5O_INFO_NUM_ATTRS); - CHECK(ret, FAIL, "H5Oget_info"); - VERIFY(oinfo.num_attrs, 2, "H5Oget_info"); + ret = H5Oget_info3(dataset, &oinfo, H5O_INFO_NUM_ATTRS); + CHECK(ret, FAIL, "H5Oget_info3"); + VERIFY(oinfo.num_attrs, 2, "H5Oget_info3"); /* Open first attribute for the dataset */ attr = H5Aopen(dataset, ATTR_TMP_NAME, H5P_DEFAULT); @@ -474,9 +475,9 @@ test_attr_basic_read(hid_t fapl) CHECK(group, FAIL, "H5Gopen2"); /* Verify the correct number of attributes */ - ret = H5Oget_info2(group, &oinfo, H5O_INFO_NUM_ATTRS); - CHECK(ret, FAIL, "H5Oget_info"); - VERIFY(oinfo.num_attrs, 1, "H5Oget_info"); + ret = H5Oget_info3(group, &oinfo, H5O_INFO_NUM_ATTRS); + CHECK(ret, FAIL, "H5Oget_info3"); + VERIFY(oinfo.num_attrs, 1, "H5Oget_info3"); /* Open the attribute for the group */ attr = H5Aopen(group, ATTR2_NAME, H5P_DEFAULT); @@ -811,7 +812,7 @@ test_attr_compound_read(hid_t fapl) hid_t field; /* Attribute field datatype */ struct attr4_struct read_data4[ATTR4_DIM1][ATTR4_DIM2]; /* Buffer for reading 4th attribute */ ssize_t name_len; /* Length of attribute name */ - H5O_info_t oinfo; /* Object info */ + H5O_info2_t oinfo; /* Object info */ int i, j; /* Local index variables */ herr_t ret; /* Generic return value */ @@ -827,9 +828,9 @@ test_attr_compound_read(hid_t fapl) CHECK(dataset, FAIL, "H5Dopen2"); /* Verify the correct number of attributes */ - ret = H5Oget_info2(dataset, &oinfo, H5O_INFO_NUM_ATTRS); - CHECK(ret, FAIL, "H5Oget_info"); - VERIFY(oinfo.num_attrs, 1, "H5Oget_info"); + ret = H5Oget_info3(dataset, &oinfo, H5O_INFO_NUM_ATTRS); + CHECK(ret, FAIL, "H5Oget_info3"); + VERIFY(oinfo.num_attrs, 1, "H5Oget_info3"); /* Open 1st attribute for the dataset */ attr = H5Aopen_by_idx(dataset, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, (hsize_t)0, H5P_DEFAULT, H5P_DEFAULT); @@ -1016,7 +1017,7 @@ test_attr_scalar_read(hid_t fapl) hid_t attr; /* Attribute ID */ H5S_class_t stype; /* Dataspace class */ float rdata = 0.0F; /* Buffer for reading 1st attribute */ - H5O_info_t oinfo; /* Object info */ + H5O_info2_t oinfo; /* Object info */ herr_t ret; /* Generic return value */ /* Output message about test being performed */ @@ -1031,9 +1032,9 @@ test_attr_scalar_read(hid_t fapl) CHECK(dataset, FAIL, "H5Dopen2"); /* Verify the correct number of attributes */ - ret = H5Oget_info2(dataset, &oinfo, H5O_INFO_NUM_ATTRS); - CHECK(ret, FAIL, "H5Oget_info"); - VERIFY(oinfo.num_attrs, 1, "H5Oget_info"); + ret = H5Oget_info3(dataset, &oinfo, H5O_INFO_NUM_ATTRS); + CHECK(ret, FAIL, "H5Oget_info3"); + VERIFY(oinfo.num_attrs, 1, "H5Oget_info3"); /* Open an attribute for the dataset */ attr = H5Aopen(dataset, ATTR5_NAME, H5P_DEFAULT); @@ -1218,7 +1219,7 @@ test_attr_mult_read(hid_t fapl) int read_data2[ATTR2_DIM1][ATTR2_DIM2] = {{0}}; /* Buffer for reading 2nd attribute */ double read_data3[ATTR3_DIM1][ATTR3_DIM2][ATTR3_DIM3] = {{{0}}}; /* Buffer for reading 3rd attribute */ ssize_t name_len; /* Length of attribute name */ - H5O_info_t oinfo; /* Object info */ + H5O_info2_t oinfo; /* Object info */ int i, j, k; /* Local index values */ herr_t ret; /* Generic return value */ @@ -1234,9 +1235,9 @@ test_attr_mult_read(hid_t fapl) CHECK(dataset, FAIL, "H5Dopen2"); /* Verify the correct number of attributes */ - ret = H5Oget_info2(dataset, &oinfo, H5O_INFO_NUM_ATTRS); - CHECK(ret, FAIL, "H5Oget_info"); - VERIFY(oinfo.num_attrs, 3, "H5Oget_info"); + ret = H5Oget_info3(dataset, &oinfo, H5O_INFO_NUM_ATTRS); + CHECK(ret, FAIL, "H5Oget_info3"); + VERIFY(oinfo.num_attrs, 3, "H5Oget_info3"); /* Open 1st attribute for the dataset */ attr = H5Aopen_by_idx(dataset, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, (hsize_t)0, H5P_DEFAULT, H5P_DEFAULT); @@ -1468,7 +1469,7 @@ test_attr_iterate(hid_t fapl) hid_t dataset; /* Dataset ID */ hid_t sid; /* Dataspace ID */ int count; /* operator data for the iterator */ - H5O_info_t oinfo; /* Object info */ + H5O_info2_t oinfo; /* Object info */ herr_t ret; /* Generic return value */ /* Output message about test being performed */ @@ -1491,9 +1492,9 @@ test_attr_iterate(hid_t fapl) CHECK(ret, FAIL, "H5Sclose"); /* Verify the correct number of attributes */ - ret = H5Oget_info2(dataset, &oinfo, H5O_INFO_NUM_ATTRS); - CHECK(ret, FAIL, "H5Oget_info"); - VERIFY(oinfo.num_attrs, 0, "H5Oget_info"); + ret = H5Oget_info3(dataset, &oinfo, H5O_INFO_NUM_ATTRS); + CHECK(ret, FAIL, "H5Oget_info3"); + VERIFY(oinfo.num_attrs, 0, "H5Oget_info3"); /* Iterate over attributes on dataset */ count = 0; @@ -1509,9 +1510,9 @@ test_attr_iterate(hid_t fapl) CHECK(dataset, FAIL, "H5Dopen2"); /* Verify the correct number of attributes */ - ret = H5Oget_info2(dataset, &oinfo, H5O_INFO_NUM_ATTRS); - CHECK(ret, FAIL, "H5Oget_info"); - VERIFY(oinfo.num_attrs, 3, "H5Oget_info"); + ret = H5Oget_info3(dataset, &oinfo, H5O_INFO_NUM_ATTRS); + CHECK(ret, FAIL, "H5Oget_info3"); + VERIFY(oinfo.num_attrs, 3, "H5Oget_info3"); /* Iterate over attributes on dataset */ count = 0; @@ -1541,7 +1542,7 @@ test_attr_delete(hid_t fapl) hid_t attr; /* Attribute ID */ char attr_name[ATTR_NAME_LEN]; /* Buffer for attribute names */ ssize_t name_len; /* Length of attribute name */ - H5O_info_t oinfo; /* Object info */ + H5O_info2_t oinfo; /* Object info */ herr_t ret; /* Generic return value */ /* Output message about test being performed */ @@ -1556,27 +1557,27 @@ test_attr_delete(hid_t fapl) CHECK(dataset, FAIL, "H5Dopen2"); /* Verify the correct number of attributes */ - ret = H5Oget_info2(dataset, &oinfo, H5O_INFO_NUM_ATTRS); - CHECK(ret, FAIL, "H5Oget_info"); - VERIFY(oinfo.num_attrs, 3, "H5Oget_info"); + ret = H5Oget_info3(dataset, &oinfo, H5O_INFO_NUM_ATTRS); + CHECK(ret, FAIL, "H5Oget_info3"); + VERIFY(oinfo.num_attrs, 3, "H5Oget_info3"); /* Try to delete bogus attribute */ ret = H5Adelete(dataset, "Bogus"); VERIFY(ret, FAIL, "H5Adelete"); /* Verify the correct number of attributes */ - ret = H5Oget_info2(dataset, &oinfo, H5O_INFO_NUM_ATTRS); - CHECK(ret, FAIL, "H5Oget_info"); - VERIFY(oinfo.num_attrs, 3, "H5Oget_info"); + ret = H5Oget_info3(dataset, &oinfo, H5O_INFO_NUM_ATTRS); + CHECK(ret, FAIL, "H5Oget_info3"); + VERIFY(oinfo.num_attrs, 3, "H5Oget_info3"); /* Delete middle (2nd) attribute */ ret = H5Adelete(dataset, ATTR2_NAME); CHECK(ret, FAIL, "H5Adelete"); /* Verify the correct number of attributes */ - ret = H5Oget_info2(dataset, &oinfo, H5O_INFO_NUM_ATTRS); - CHECK(ret, FAIL, "H5Oget_info"); - VERIFY(oinfo.num_attrs, 2, "H5Oget_info"); + ret = H5Oget_info3(dataset, &oinfo, H5O_INFO_NUM_ATTRS); + CHECK(ret, FAIL, "H5Oget_info3"); + VERIFY(oinfo.num_attrs, 2, "H5Oget_info3"); /* Open 1st attribute for the dataset */ attr = H5Aopen_by_idx(dataset, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, (hsize_t)0, H5P_DEFAULT, H5P_DEFAULT); @@ -1611,9 +1612,9 @@ test_attr_delete(hid_t fapl) CHECK(ret, FAIL, "H5Adelete"); /* Verify the correct number of attributes */ - ret = H5Oget_info2(dataset, &oinfo, H5O_INFO_NUM_ATTRS); - CHECK(ret, FAIL, "H5Oget_info"); - VERIFY(oinfo.num_attrs, 1, "H5Oget_info"); + ret = H5Oget_info3(dataset, &oinfo, H5O_INFO_NUM_ATTRS); + CHECK(ret, FAIL, "H5Oget_info3"); + VERIFY(oinfo.num_attrs, 1, "H5Oget_info3"); /* Open last (formally 3rd) attribute for the dataset */ attr = H5Aopen_by_idx(dataset, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, (hsize_t)0, H5P_DEFAULT, H5P_DEFAULT); @@ -1634,9 +1635,9 @@ test_attr_delete(hid_t fapl) CHECK(ret, FAIL, "H5Adelete"); /* Verify the correct number of attributes */ - ret = H5Oget_info2(dataset, &oinfo, H5O_INFO_NUM_ATTRS); - CHECK(ret, FAIL, "H5Oget_info"); - VERIFY(oinfo.num_attrs, 0, "H5Oget_info"); + ret = H5Oget_info3(dataset, &oinfo, H5O_INFO_NUM_ATTRS); + CHECK(ret, FAIL, "H5Oget_info3"); + VERIFY(oinfo.num_attrs, 0, "H5Oget_info3"); /* Close dataset */ ret = H5Dclose(dataset); @@ -1664,7 +1665,7 @@ test_attr_dtype_shared(hid_t fapl) hid_t attr_id; /* Attribute ID */ int data = 8; /* Data to write */ int rdata = 0; /* Read read in */ - H5O_info_t oinfo; /* Object's information */ + H5O_info2_t oinfo; /* Object's information */ h5_stat_size_t empty_filesize; /* Size of empty file */ h5_stat_size_t filesize; /* Size of file after modifications */ herr_t ret; /* Generic return value */ @@ -1698,9 +1699,9 @@ test_attr_dtype_shared(hid_t fapl) CHECK(ret, FAIL, "H5Tcommit2"); /* Check reference count on named datatype */ - ret = H5Oget_info_by_name2(file_id, TYPE1_NAME, &oinfo, H5O_INFO_BASIC, H5P_DEFAULT); - CHECK(ret, FAIL, "H5Oget_info_by_name"); - VERIFY(oinfo.rc, 1, "H5Oget_info_by_name"); + ret = H5Oget_info_by_name3(file_id, TYPE1_NAME, &oinfo, H5O_INFO_BASIC, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Oget_info_by_name3"); + VERIFY(oinfo.rc, 1, "H5Oget_info_by_name3"); /* Create dataspace for dataset */ space_id = H5Screate(H5S_SCALAR); @@ -1711,18 +1712,18 @@ test_attr_dtype_shared(hid_t fapl) CHECK(dset_id, FAIL, "H5Dcreate2"); /* Check reference count on named datatype */ - ret = H5Oget_info_by_name2(file_id, TYPE1_NAME, &oinfo, H5O_INFO_BASIC, H5P_DEFAULT); - CHECK(ret, FAIL, "H5Oget_info_by_name"); - VERIFY(oinfo.rc, 2, "H5Oget_info_by_name"); + ret = H5Oget_info_by_name3(file_id, TYPE1_NAME, &oinfo, H5O_INFO_BASIC, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Oget_info_by_name3"); + VERIFY(oinfo.rc, 2, "H5Oget_info_by_name3"); /* Create attribute on dataset */ attr_id = H5Acreate2(dset_id, ATTR1_NAME, type_id, space_id, H5P_DEFAULT, H5P_DEFAULT); CHECK(attr_id, FAIL, "H5Acreate2"); /* Check reference count on named datatype */ - ret = H5Oget_info_by_name2(file_id, TYPE1_NAME, &oinfo, H5O_INFO_BASIC, H5P_DEFAULT); - CHECK(ret, FAIL, "H5Oget_info_by_name"); - VERIFY(oinfo.rc, 3, "H5Oget_info_by_name"); + ret = H5Oget_info_by_name3(file_id, TYPE1_NAME, &oinfo, H5O_INFO_BASIC, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Oget_info_by_name3"); + VERIFY(oinfo.rc, 3, "H5Oget_info_by_name3"); /* Close attribute */ ret = H5Aclose(attr_id); @@ -1733,18 +1734,18 @@ test_attr_dtype_shared(hid_t fapl) CHECK(ret, FAIL, "H5Adelete"); /* Check reference count on named datatype */ - ret = H5Oget_info_by_name2(file_id, TYPE1_NAME, &oinfo, H5O_INFO_BASIC, H5P_DEFAULT); - CHECK(ret, FAIL, "H5Oget_info_by_name"); - VERIFY(oinfo.rc, 2, "H5Oget_info_by_name"); + ret = H5Oget_info_by_name3(file_id, TYPE1_NAME, &oinfo, H5O_INFO_BASIC, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Oget_info_by_name3"); + VERIFY(oinfo.rc, 2, "H5Oget_info_by_name3"); /* Create attribute on dataset */ attr_id = H5Acreate2(dset_id, ATTR1_NAME, type_id, space_id, H5P_DEFAULT, H5P_DEFAULT); CHECK(attr_id, FAIL, "H5Acreate2"); /* Check reference count on named datatype */ - ret = H5Oget_info_by_name2(file_id, TYPE1_NAME, &oinfo, H5O_INFO_BASIC, H5P_DEFAULT); - CHECK(ret, FAIL, "H5Oget_info_by_name"); - VERIFY(oinfo.rc, 3, "H5Oget_info_by_name"); + ret = H5Oget_info_by_name3(file_id, TYPE1_NAME, &oinfo, H5O_INFO_BASIC, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Oget_info_by_name3"); + VERIFY(oinfo.rc, 3, "H5Oget_info_by_name3"); /* Write data into the attribute */ ret = H5Awrite(attr_id, H5T_NATIVE_INT, &data); @@ -1797,18 +1798,18 @@ test_attr_dtype_shared(hid_t fapl) CHECK(ret, FAIL, "H5Dclose"); /* Check reference count on named datatype */ - ret = H5Oget_info_by_name2(file_id, TYPE1_NAME, &oinfo, H5O_INFO_BASIC, H5P_DEFAULT); - CHECK(ret, FAIL, "H5Oget_info_by_name"); - VERIFY(oinfo.rc, 3, "H5Oget_info_by_name"); + ret = H5Oget_info_by_name3(file_id, TYPE1_NAME, &oinfo, H5O_INFO_BASIC, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Oget_info_by_name3"); + VERIFY(oinfo.rc, 3, "H5Oget_info_by_name3"); /* Unlink the dataset */ ret = H5Ldelete(file_id, DSET1_NAME, H5P_DEFAULT); CHECK(ret, FAIL, "H5Ldelete"); /* Check reference count on named datatype */ - ret = H5Oget_info_by_name2(file_id, TYPE1_NAME, &oinfo, H5O_INFO_BASIC, H5P_DEFAULT); - CHECK(ret, FAIL, "H5Oget_info_by_name"); - VERIFY(oinfo.rc, 1, "H5Oget_info_by_name"); + ret = H5Oget_info_by_name3(file_id, TYPE1_NAME, &oinfo, H5O_INFO_BASIC, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Oget_info_by_name3"); + VERIFY(oinfo.rc, 1, "H5Oget_info_by_name3"); /* Unlink the named datatype */ ret = H5Ldelete(file_id, TYPE1_NAME, H5P_DEFAULT); @@ -2440,7 +2441,7 @@ test_attr_dense_delete(hid_t fcpl, hid_t fapl) unsigned u; /* Local index variable */ h5_stat_size_t empty_filesize; /* Size of empty file */ h5_stat_size_t filesize; /* Size of file after modifications */ - H5O_info_t oinfo; /* Object info */ + H5O_info2_t oinfo; /* Object info */ int use_min_dset_oh = (dcpl_g != H5P_DEFAULT); herr_t ret; /* Generic return value */ @@ -2523,9 +2524,9 @@ test_attr_dense_delete(hid_t fcpl, hid_t fapl) CHECK(ret, FAIL, "H5Aclose"); /* Check # of attributes */ - ret = H5Oget_info2(dataset, &oinfo, H5O_INFO_NUM_ATTRS); - CHECK(ret, FAIL, "H5Oget_info"); - VERIFY(oinfo.num_attrs, (u + 1), "H5Oget_info"); + ret = H5Oget_info3(dataset, &oinfo, H5O_INFO_NUM_ATTRS); + CHECK(ret, FAIL, "H5Oget_info3"); + VERIFY(oinfo.num_attrs, (u + 1), "H5Oget_info3"); } /* end for */ /* Check on dataset's attribute storage status */ @@ -2634,7 +2635,7 @@ test_attr_dense_rename(hid_t fcpl, hid_t fapl) htri_t is_dense; /* Are attributes stored densely? */ h5_stat_size_t empty_filesize; /* Size of empty file */ h5_stat_size_t filesize; /* Size of file after modifications */ - H5O_info_t oinfo; /* Object info */ + H5O_info2_t oinfo; /* Object info */ unsigned u; /* Local index variable */ int use_min_dset_oh = (dcpl_g != H5P_DEFAULT); unsigned use_corder; /* Track creation order or not */ @@ -2726,9 +2727,9 @@ test_attr_dense_rename(hid_t fcpl, hid_t fapl) CHECK(ret, FAIL, "H5Arename_by_name"); /* Check # of attributes */ - ret = H5Oget_info2(dataset, &oinfo, H5O_INFO_NUM_ATTRS); - CHECK(ret, FAIL, "H5Oget_info"); - VERIFY(oinfo.num_attrs, (u + 1), "H5Oget_info"); + ret = H5Oget_info3(dataset, &oinfo, H5O_INFO_NUM_ATTRS); + CHECK(ret, FAIL, "H5Oget_info3"); + VERIFY(oinfo.num_attrs, (u + 1), "H5Oget_info3"); } /* end for */ /* Check on dataset's attribute storage status */ @@ -2826,7 +2827,7 @@ test_attr_dense_unlink(hid_t fcpl, hid_t fapl) size_t mesg_count; /* # of shared messages */ h5_stat_size_t empty_filesize; /* Size of empty file */ h5_stat_size_t filesize; /* Size of file after modifications */ - H5O_info_t oinfo; /* Object info */ + H5O_info2_t oinfo; /* Object info */ unsigned u; /* Local index variable */ int use_min_dset_oh = (dcpl_g != H5P_DEFAULT); herr_t ret; /* Generic return value */ @@ -2904,9 +2905,9 @@ test_attr_dense_unlink(hid_t fcpl, hid_t fapl) CHECK(ret, FAIL, "H5Aclose"); /* Check # of attributes */ - ret = H5Oget_info2(dataset, &oinfo, H5O_INFO_NUM_ATTRS); - CHECK(ret, FAIL, "H5Oget_info"); - VERIFY(oinfo.num_attrs, (u + 1), "H5Oget_info"); + ret = H5Oget_info3(dataset, &oinfo, H5O_INFO_NUM_ATTRS); + CHECK(ret, FAIL, "H5Oget_info3"); + VERIFY(oinfo.num_attrs, (u + 1), "H5Oget_info3"); } /* end for */ /* Check on dataset's attribute storage status */ @@ -10863,9 +10864,10 @@ test_attr_bug8(hid_t fcpl, hid_t fapl) hid_t gid; /* Group ID */ hid_t oid; /* Object ID */ hsize_t dims = 256; /* Attribute dimensions */ - H5O_info_t oinfo; /* Object info */ + H5O_info2_t oinfo; /* Object info */ H5A_info_t ainfo; /* Attribute info */ haddr_t root_addr; /* Root group address */ + haddr_t link_addr; /* Link (to root group) address */ herr_t ret; /* Generic return status */ /* Output message about test being performed */ @@ -10881,9 +10883,10 @@ test_attr_bug8(hid_t fcpl, hid_t fapl) CHECK(gid, FAIL, "H5Gcreate2"); /* Get root group address */ - ret = H5Oget_info2(fid, &oinfo, H5O_INFO_BASIC); + ret = H5Oget_info3(fid, &oinfo, H5O_INFO_BASIC); CHECK(ret, FAIL, "H5Oget_info"); - root_addr = oinfo.addr; + ret = H5VLnative_token_to_addr(fid, oinfo.token, &root_addr); + CHECK(ret, FAIL, "H5VLnative_token_to_addr"); /* * Create link to root group @@ -10906,10 +10909,12 @@ test_attr_bug8(hid_t fcpl, hid_t fapl) CHECK(gid, FAIL, "H5Gopen2"); oid = H5Oopen(gid, LINK1_NAME, H5P_DEFAULT); CHECK(oid, FAIL, "H5Oopen"); - ret = H5Oget_info2(oid, &oinfo, H5O_INFO_BASIC); + ret = H5Oget_info3(oid, &oinfo, H5O_INFO_BASIC); CHECK(ret, FAIL, "H5Oget_info"); - if(oinfo.addr != root_addr) - TestErrPrintf("incorrect link target address: addr: %llu, expected: %llu\n", (long long unsigned)oinfo.addr, (long long unsigned)root_addr); + ret = H5VLnative_token_to_addr(fid, oinfo.token, &link_addr); + CHECK(ret, FAIL, "H5VLnative_token_to_addr"); + if(link_addr != root_addr) + TestErrPrintf("incorrect link target address: addr: %llu, expected: %llu\n", (long long unsigned)link_addr, (long long unsigned)root_addr); /* Close file */ ret = H5Fclose(fid); @@ -10951,10 +10956,12 @@ test_attr_bug8(hid_t fcpl, hid_t fapl) CHECK(gid, FAIL, "H5Gopen2"); oid = H5Oopen(gid, LINK1_NAME, H5P_DEFAULT); CHECK(oid, FAIL, "H5Oopen"); - ret = H5Oget_info2(oid, &oinfo, H5O_INFO_BASIC); + ret = H5Oget_info3(oid, &oinfo, H5O_INFO_BASIC); CHECK(ret, FAIL, "H5Oget_info"); - if(oinfo.addr != root_addr) - TestErrPrintf("incorrect link target address: addr: %llu, expected: %llu\n", (long long unsigned)oinfo.addr, (long long unsigned)root_addr); + ret = H5VLnative_token_to_addr(fid, oinfo.token, &link_addr); + CHECK(ret, FAIL, "H5VLnative_token_to_addr"); + if(link_addr != root_addr) + TestErrPrintf("incorrect link target address: addr: %llu, expected: %llu\n", (long long unsigned)link_addr, (long long unsigned)root_addr); ret = H5Aget_info_by_name(gid, ".", ATTR1_NAME, &ainfo, H5P_DEFAULT); CHECK(ret, FAIL, "H5Aget_info_by_name"); if(ainfo.data_size != dims) diff --git a/test/tfile.c b/test/tfile.c index 7da8b85..4c23488 100644 --- a/test/tfile.c +++ b/test/tfile.c @@ -5177,7 +5177,7 @@ test_libver_bounds_real(H5F_libver_t libver_create, unsigned oh_vers_create, { hid_t file, group; /* Handles */ hid_t fapl; /* File access property list */ - H5O_info_t oinfo; /* Object info */ + H5O_native_info_t ninfo; /* Object info */ herr_t ret; /* Return value */ /* @@ -5195,9 +5195,9 @@ test_libver_bounds_real(H5F_libver_t libver_create, unsigned oh_vers_create, /* * Make sure the root group has the correct object header version */ - ret = H5Oget_info_by_name2(file, "/", &oinfo, H5O_INFO_HDR, H5P_DEFAULT); - CHECK(ret, FAIL, "H5Oget_info_by_name"); - VERIFY(oinfo.hdr.version, oh_vers_create, "H5Oget_info_by_name"); + ret = H5Oget_native_info_by_name(file, "/", &ninfo, H5O_NATIVE_INFO_HDR, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Oget_native_info_by_name"); + VERIFY(ninfo.hdr.version, oh_vers_create, "H5Oget_native_info_by_name"); /* * Reopen the file and make sure the root group still has the correct version @@ -5211,9 +5211,9 @@ test_libver_bounds_real(H5F_libver_t libver_create, unsigned oh_vers_create, file = H5Fopen("tfile5.h5", H5F_ACC_RDWR, fapl); CHECK(file, FAIL, "H5Fopen"); - ret = H5Oget_info_by_name2(file, "/", &oinfo, H5O_INFO_HDR, H5P_DEFAULT); - CHECK(ret, FAIL, "H5Oget_info_by_name"); - VERIFY(oinfo.hdr.version, oh_vers_create, "H5Oget_info_by_name"); + ret = H5Oget_native_info_by_name(file, "/", &ninfo, H5O_NATIVE_INFO_HDR, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Oget_native_info_by_name"); + VERIFY(ninfo.hdr.version, oh_vers_create, "H5Oget_native_info_by_name"); /* * Create a group named "G1" in the file, and make sure it has the correct @@ -5222,9 +5222,9 @@ test_libver_bounds_real(H5F_libver_t libver_create, unsigned oh_vers_create, group = H5Gcreate2(file, "/G1", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); CHECK(group, FAIL, "H5Gcreate"); - ret = H5Oget_info2(group, &oinfo, H5O_INFO_HDR); - CHECK(ret, FAIL, "H5Oget_info"); - VERIFY(oinfo.hdr.version, oh_vers_mod, "H5Oget_info"); + ret = H5Oget_native_info(group, &ninfo, H5O_NATIVE_INFO_HDR); + CHECK(ret, FAIL, "H5Oget_native)info"); + VERIFY(ninfo.hdr.version, oh_vers_mod, "H5Oget_native_info"); ret = H5Gclose(group); CHECK(ret, FAIL, "H5Gclose"); @@ -5236,9 +5236,9 @@ test_libver_bounds_real(H5F_libver_t libver_create, unsigned oh_vers_create, group = H5Gcreate2(file, "/G1/G3", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); CHECK(group, FAIL, "H5Gcreate"); - ret = H5Oget_info2(group, &oinfo, H5O_INFO_HDR); - CHECK(ret, FAIL, "H5Oget_info_by_name"); - VERIFY(oinfo.hdr.version, oh_vers_mod, "H5Oget_info_by_name"); + ret = H5Oget_native_info(group, &ninfo, H5O_NATIVE_INFO_HDR); + CHECK(ret, FAIL, "H5Oget_native_info"); + VERIFY(ninfo.hdr.version, oh_vers_mod, "H5Oget_native_info"); ret = H5Gclose(group); CHECK(ret, FAIL, "H5Gclose"); @@ -5246,9 +5246,9 @@ test_libver_bounds_real(H5F_libver_t libver_create, unsigned oh_vers_create, /* * Make sure the root group still has the correct object header version */ - ret = H5Oget_info_by_name2(file, "/", &oinfo, H5O_INFO_HDR, H5P_DEFAULT); - CHECK(ret, FAIL, "H5Oget_info_by_name"); - VERIFY(oinfo.hdr.version, oh_vers_create, "H5Oget_info_by_name"); + ret = H5Oget_native_info_by_name(file, "/", &ninfo, H5O_NATIVE_INFO_HDR, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Oget_native_info_by_name"); + VERIFY(ninfo.hdr.version, oh_vers_create, "H5Oget_native_info_by_name"); ret = H5Fclose(file); CHECK(ret, FAIL, "H5Fclose"); @@ -6034,7 +6034,7 @@ test_libver_bounds_obj(hid_t fapl) hid_t new_fapl = H5I_INVALID_HID; /* File access property list */ H5F_t *f = NULL; /* Internal file pointer */ H5F_libver_t low, high; /* Low and high bounds */ - H5O_info_t oinfo; /* Object info */ + H5O_native_info_t ninfo; /* Object info */ H5G_info_t ginfo; /* Group info */ herr_t ret; /* Return value */ @@ -6058,11 +6058,11 @@ test_libver_bounds_obj(hid_t fapl) CHECK(fid, H5I_INVALID_HID, "H5Fcreate"); /* Get root group's object info */ - ret = H5Oget_info_by_name2(fid, "/", &oinfo, H5O_INFO_HDR, H5P_DEFAULT); - CHECK(ret, FAIL, "H5Oget_info_by_name"); + ret = H5Oget_native_info_by_name(fid, "/", &ninfo, H5O_NATIVE_INFO_HDR, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Oget_native_info_by_name"); /* Verify object header version is 2 because shared message is enabled */ - VERIFY(oinfo.hdr.version, H5O_VERSION_2, "H5O_obj_ver_bounds"); + VERIFY(ninfo.hdr.version, H5O_VERSION_2, "H5O_obj_ver_bounds"); /* Close the file */ ret = H5Fclose(fid); @@ -6077,11 +6077,11 @@ test_libver_bounds_obj(hid_t fapl) CHECK(fid, H5I_INVALID_HID, "H5Fcreate"); /* Get root group's object info */ - ret = H5Oget_info_by_name2(fid, "/", &oinfo, H5O_INFO_HDR, H5P_DEFAULT); - CHECK(ret, FAIL, "H5Oget_info_by_name"); + ret = H5Oget_native_info_by_name(fid, "/", &ninfo, H5O_NATIVE_INFO_HDR, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Oget_native_info_by_name"); /* Verify object header version is as indicated by low_bound */ - VERIFY(oinfo.hdr.version, H5O_obj_ver_bounds[low], "H5O_obj_ver_bounds"); + VERIFY(ninfo.hdr.version, H5O_obj_ver_bounds[low], "H5O_obj_ver_bounds"); /* Close the file */ ret = H5Fclose(fid); @@ -6132,11 +6132,11 @@ test_libver_bounds_obj(hid_t fapl) VERIFY(ginfo.storage_type, H5G_STORAGE_TYPE_SYMBOL_TABLE, "H5Gget_info"); /* Get object header information */ - ret = H5Oget_info_by_name2(gid, GRP_NAME, &oinfo, H5O_INFO_HDR, H5P_DEFAULT); - CHECK(ret, FAIL, "H5Oget_info_by_name"); + ret = H5Oget_native_info_by_name(gid, GRP_NAME, &ninfo, H5O_NATIVE_INFO_HDR, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Oget_native_info_by_name"); /* Verify object header version as indicated by low_bound */ - VERIFY(oinfo.hdr.version, H5O_obj_ver_bounds[f->shared->low_bound], "H5O_obj_ver_bounds"); + VERIFY(ninfo.hdr.version, H5O_obj_ver_bounds[f->shared->low_bound], "H5O_obj_ver_bounds"); /* Close the group */ ret = H5Gclose(gid); diff --git a/test/th5o.c b/test/th5o.c index 354245f..ab4a8de 100644 --- a/test/th5o.c +++ b/test/th5o.c @@ -20,6 +20,9 @@ *************************************************************/ #include "testhdf5.h" +#include "H5Fprivate.h" +#include "H5VLprivate.h" +#include "H5VLnative_private.h" #define TEST_FILENAME "th5o_file" @@ -231,6 +234,7 @@ test_h5o_close(void) } +#ifndef H5_NO_DEPRECATED_SYMBOLS /**************************************************************** ** ** test_h5o_open_by_addr(): Test H5Oopen_by_addr function. @@ -239,17 +243,17 @@ test_h5o_close(void) static void test_h5o_open_by_addr(void) { - hid_t fid; /* HDF5 File ID */ - hid_t grp, dset, dtype, dspace; /* Object identifiers */ - H5L_info_t li; /* Buffer for H5Lget_info */ - haddr_t grp_addr; /* Addresses for objects */ - haddr_t dset_addr; - haddr_t dtype_addr; - hsize_t dims[RANK]; - H5I_type_t id_type; /* Type of IDs returned from H5Oopen */ - H5G_info_t ginfo; /* Group info struct */ - H5T_class_t type_class; /* Class of the datatype */ - herr_t ret; /* Value returned from API calls */ + hid_t fid; /* HDF5 File ID */ + hid_t grp, dset, dtype, dspace; /* Object identifiers */ + H5L_info2_t li; /* Buffer for H5Lget_info */ + haddr_t grp_addr; /* Addresses for objects */ + haddr_t dset_addr; + haddr_t dtype_addr; + hsize_t dims[RANK]; + H5I_type_t id_type; /* Type of IDs returned from H5Oopen */ + H5G_info_t ginfo; /* Group info struct */ + H5T_class_t type_class; /* Class of the datatype */ + herr_t ret; /* Value returned from API calls */ /* Create a new HDF5 file */ fid = H5Fcreate(TEST_FILENAME, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); @@ -285,15 +289,20 @@ test_h5o_open_by_addr(void) CHECK(ret, FAIL, "H5Sclose"); /* Get address for each object */ - ret = H5Lget_info(fid, "group", &li, H5P_DEFAULT); - CHECK(ret, FAIL, "H5Lget_info"); - grp_addr = li.u.address; - ret = H5Lget_info(fid, "group/datatype", &li, H5P_DEFAULT); - CHECK(ret, FAIL, "H5Lget_info"); - dtype_addr = li.u.address; - ret = H5Lget_info(fid, "dataset", &li, H5P_DEFAULT); - CHECK(ret, FAIL, "H5Lget_info"); - dset_addr = li.u.address; + ret = H5Lget_info2(fid, "group", &li, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Lget_info2"); + ret = H5VLnative_token_to_addr(fid, li.u.token, &grp_addr); + CHECK(ret, FAIL, "H5VLnative_token_to_addr"); + + ret = H5Lget_info2(fid, "group/datatype", &li, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Lget_info2"); + ret = H5VLnative_token_to_addr(fid, li.u.token, &dtype_addr); + CHECK(ret, FAIL, "H5VLnative_token_to_addr"); + + ret = H5Lget_info2(fid, "dataset", &li, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Lget_info2"); + ret = H5VLnative_token_to_addr(fid, li.u.token, &dset_addr); + CHECK(ret, FAIL, "H5VLnative_token_to_addr"); /* Now make sure that H5Oopen_by_addr can open all three types of objects */ grp = H5Oopen_by_addr(fid, grp_addr); @@ -366,7 +375,122 @@ test_h5o_open_by_addr(void) }H5E_END_TRY VERIFY(dtype, FAIL, "H5Oopen_by_addr"); } /* test_h5o_open_by_addr() */ +#endif /* H5_NO_DEPRECATED_SYMBOLS */ + + +/**************************************************************** +** +** test_h5o_open_by_token(): Test H5Oopen_by_token function. +** +****************************************************************/ +static void +test_h5o_open_by_token(void) +{ + hid_t fid; /* HDF5 File ID */ + hid_t grp, dset, dtype, dspace; /* Object identifiers */ + H5L_info2_t li; /* Buffer for H5Lget_info */ + hsize_t dims[RANK]; + H5I_type_t id_type; /* Type of IDs returned from H5Oopen */ + H5G_info_t ginfo; /* Group info struct */ + H5T_class_t type_class; /* Class of the datatype */ + herr_t ret; /* Value returned from API calls */ + + /* Create a new HDF5 file */ + fid = H5Fcreate(TEST_FILENAME, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + CHECK(fid, FAIL, "H5Fcreate"); + + /* Create a group, dataset, and committed datatype within the file */ + /* Create the group */ + grp = H5Gcreate2(fid, "group", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(grp, FAIL, "H5Gcreate2"); + ret = H5Gclose(grp); + CHECK(ret, FAIL, "H5Gclose"); + + /* Commit the type inside the group */ + dtype = H5Tcopy(H5T_NATIVE_INT); + CHECK(dtype, FAIL, "H5Tcopy"); + ret = H5Tcommit2(fid, "group/datatype", dtype, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Tcommit2"); + ret = H5Tclose(dtype); + CHECK(ret, FAIL, "H5Tclose"); + + /* Create the data space for the dataset. */ + dims[0] = DIM0; + dims[1] = DIM1; + dspace = H5Screate_simple(RANK, dims, NULL); + CHECK(dspace, FAIL, "H5Screate_simple"); + + /* Create the dataset. */ + dset = H5Dcreate2(fid, "dataset", H5T_NATIVE_INT, dspace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(dset, FAIL, "H5Dcreate2"); + ret = H5Dclose(dset); + CHECK(ret, FAIL, "H5Dclose"); + ret = H5Sclose(dspace); + CHECK(ret, FAIL, "H5Sclose"); + + /* Make sure that H5Oopen_by_token can open all three types of objects */ + ret = H5Lget_info2(fid, "group", &li, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Lget_info"); + grp = H5Oopen_by_token(fid, li.u.token); + CHECK(grp, FAIL, "H5Oopen_by_token"); + + ret = H5Lget_info2(fid, "group/datatype", &li, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Lget_info"); + dtype = H5Oopen_by_token(fid, li.u.token); + CHECK(dtype, FAIL, "H5Oopen_by_token"); + + ret = H5Lget_info2(fid, "dataset", &li, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Lget_info"); + /* Check that we can use the group ID as a valid location */ + dset = H5Oopen_by_token(grp, li.u.token); + CHECK(dset, FAIL, "H5Oopen_by_token"); + + /* Make sure that each is the right kind of ID */ + id_type = H5Iget_type(grp); + VERIFY(id_type, H5I_GROUP, "H5Iget_type for group ID"); + id_type = H5Iget_type(dtype); + VERIFY(id_type, H5I_DATATYPE, "H5Iget_type for datatype ID"); + id_type = H5Iget_type(dset); + VERIFY(id_type, H5I_DATASET, "H5Iget_type for dataset ID"); + + /* Do something more complex with each of the IDs to make sure they "work" */ + ret = H5Gget_info(grp, &ginfo); + CHECK(ret, FAIL, "H5Gget_info"); + VERIFY(ginfo.nlinks, 1, "H5Gget_info"); /* There should be one object, the datatype */ + + type_class = H5Tget_class(dtype); + VERIFY(type_class, H5T_INTEGER, "H5Tget_class"); + + dspace = H5Dget_space(dset); + CHECK(dspace, FAIL, "H5Dget_space"); + + /* Close the IDs */ + ret = H5Sclose(dspace); + CHECK(ret, FAIL, "H5Sclose"); + ret = H5Gclose(grp); + CHECK(ret, FAIL, "H5Gclose"); + ret = H5Tclose(dtype); + CHECK(ret, FAIL, "H5Tclose"); + ret = H5Dclose(dset); + CHECK(ret, FAIL, "H5Dclose"); + + /* Try giving some bogus values to H5O_open_by_token */ + /* Try opening an object using H5O_TOKEN_UNDEF (should fail) */ + H5E_BEGIN_TRY{ + dtype = H5Oopen_by_token(fid, H5O_TOKEN_UNDEF); + }H5E_END_TRY + VERIFY(dtype, FAIL, "H5Oopen_by_token"); + + ret = H5Fclose(fid); + CHECK(ret, FAIL, "H5Fclose"); + + /* Also, trying to open an object without a valid location (should fail) */ + H5E_BEGIN_TRY{ + dtype = H5Oopen_by_token(fid, li.u.token); + }H5E_END_TRY + VERIFY(dtype, FAIL, "H5Oopen_by_token"); +} /* test_h5o_open_by_token() */ /**************************************************************** ** @@ -378,7 +502,7 @@ test_h5o_refcount(void) { hid_t fid; /* HDF5 File ID */ hid_t grp, dset, dtype, dspace; /* Object identifiers */ - H5O_info_t oinfo; /* Object info struct */ + H5O_info2_t oinfo; /* Object info struct */ hsize_t dims[RANK]; herr_t ret; /* Value returned from API calls */ @@ -410,15 +534,15 @@ test_h5o_refcount(void) CHECK(ret, FAIL, "H5Sclose"); /* Get ref counts for each object. They should all be 1, since each object has a hard link. */ - ret = H5Oget_info_by_name2(fid, "group", &oinfo, H5O_INFO_BASIC, H5P_DEFAULT); - CHECK(ret, FAIL, "H5Oget_info_by_name"); - VERIFY(oinfo.rc, 1, "reference count in H5Oget_info_by_name"); - ret = H5Oget_info_by_name2(fid, "datatype", &oinfo, H5O_INFO_BASIC, H5P_DEFAULT); - CHECK(ret, FAIL, "H5Oget_info_by_name"); - VERIFY(oinfo.rc, 1, "reference count in H5Oget_info_by_name"); - ret = H5Oget_info_by_name2(fid, "dataset", &oinfo, H5O_INFO_BASIC, H5P_DEFAULT); - CHECK(ret, FAIL, "H5Oget_info_by_name"); - VERIFY(oinfo.rc, 1, "reference count in H5Oget_info_by_name"); + ret = H5Oget_info_by_name3(fid, "group", &oinfo, H5O_INFO_BASIC, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Oget_info_by_name3"); + VERIFY(oinfo.rc, 1, "reference count in H5Oget_info_by_name3"); + ret = H5Oget_info_by_name3(fid, "datatype", &oinfo, H5O_INFO_BASIC, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Oget_info_by_name3"); + VERIFY(oinfo.rc, 1, "reference count in H5Oget_info_by_name3"); + ret = H5Oget_info_by_name3(fid, "dataset", &oinfo, H5O_INFO_BASIC, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Oget_info_by_name3"); + VERIFY(oinfo.rc, 1, "reference count in H5Oget_info_by_name3"); /* Increment each object's reference count. */ ret = H5Oincr_refcount(grp); @@ -429,15 +553,15 @@ test_h5o_refcount(void) CHECK(ret, FAIL, "H5Oincr_refcount"); /* Get ref counts for each object. They should all be 2 now. */ - ret = H5Oget_info_by_name2(fid, "group", &oinfo, H5O_INFO_BASIC, H5P_DEFAULT); - CHECK(ret, FAIL, "H5Oget_info_by_name"); - VERIFY(oinfo.rc, 2, "reference count in H5Oget_info_by_name"); - ret = H5Oget_info_by_name2(fid, "datatype", &oinfo, H5O_INFO_BASIC, H5P_DEFAULT); - CHECK(ret, FAIL, "H5Oget_info_by_name"); - VERIFY(oinfo.rc, 2, "reference count in H5Oget_info_by_name"); - ret = H5Oget_info_by_name2(fid, "dataset", &oinfo, H5O_INFO_BASIC, H5P_DEFAULT); - CHECK(ret, FAIL, "H5Oget_info_by_name"); - VERIFY(oinfo.rc, 2, "reference count in H5Oget_info_by_name"); + ret = H5Oget_info_by_name3(fid, "group", &oinfo, H5O_INFO_BASIC, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Oget_info_by_name3"); + VERIFY(oinfo.rc, 2, "reference count in H5Oget_info_by_name3"); + ret = H5Oget_info_by_name3(fid, "datatype", &oinfo, H5O_INFO_BASIC, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Oget_info_by_name3"); + VERIFY(oinfo.rc, 2, "reference count in H5Oget_info_by_name3"); + ret = H5Oget_info_by_name3(fid, "dataset", &oinfo, H5O_INFO_BASIC, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Oget_info_by_name3"); + VERIFY(oinfo.rc, 2, "reference count in H5Oget_info_by_name3"); /* Decrement the reference counts and check that they decrease back to 1. */ ret = H5Odecr_refcount(grp); @@ -447,15 +571,15 @@ test_h5o_refcount(void) ret = H5Odecr_refcount(dset); CHECK(ret, FAIL, "H5Odecr_refcount"); - ret = H5Oget_info_by_name2(fid, "group", &oinfo, H5O_INFO_BASIC, H5P_DEFAULT); - CHECK(ret, FAIL, "H5Oget_info_by_name"); - VERIFY(oinfo.rc, 1, "reference count in H5Oget_info_by_name"); - ret = H5Oget_info_by_name2(fid, "datatype", &oinfo, H5O_INFO_BASIC, H5P_DEFAULT); - CHECK(ret, FAIL, "H5Oget_info_by_name"); - VERIFY(oinfo.rc, 1, "reference count in H5Oget_info_by_name"); - ret = H5Oget_info_by_name2(fid, "dataset", &oinfo, H5O_INFO_BASIC, H5P_DEFAULT); - CHECK(ret, FAIL, "H5Oget_info_by_name"); - VERIFY(oinfo.rc, 1, "reference count in H5Oget_info_by_name"); + ret = H5Oget_info_by_name3(fid, "group", &oinfo, H5O_INFO_BASIC, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Oget_info_by_name3"); + VERIFY(oinfo.rc, 1, "reference count in H5Oget_info_by_name3"); + ret = H5Oget_info_by_name3(fid, "datatype", &oinfo, H5O_INFO_BASIC, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Oget_info_by_name3"); + VERIFY(oinfo.rc, 1, "reference count in H5Oget_info_by_name3"); + ret = H5Oget_info_by_name3(fid, "dataset", &oinfo, H5O_INFO_BASIC, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Oget_info_by_name3"); + VERIFY(oinfo.rc, 1, "reference count in H5Oget_info_by_name3"); /* Increment the reference counts and then close the file to make sure the increment is permanant */ ret = H5Oincr_refcount(grp); @@ -485,15 +609,15 @@ test_h5o_refcount(void) dset = H5Dopen2(fid, "dataset", H5P_DEFAULT); CHECK(dset, FAIL, "H5Dopen2"); - ret = H5Oget_info_by_name2(fid, "group", &oinfo, H5O_INFO_BASIC, H5P_DEFAULT); - CHECK(ret, FAIL, "H5Oget_info_by_name"); - VERIFY(oinfo.rc, 2, "reference count in H5Oget_info_by_name"); - ret = H5Oget_info_by_name2(fid, "datatype", &oinfo, H5O_INFO_BASIC, H5P_DEFAULT); - CHECK(ret, FAIL, "H5Oget_info_by_name"); - VERIFY(oinfo.rc, 2, "reference count in H5Oget_info_by_name"); - ret = H5Oget_info_by_name2(fid, "dataset", &oinfo, H5O_INFO_BASIC, H5P_DEFAULT); - CHECK(ret, FAIL, "H5Oget_info_by_name"); - VERIFY(oinfo.rc, 2, "reference count in H5Oget_info_by_name"); + ret = H5Oget_info_by_name3(fid, "group", &oinfo, H5O_INFO_BASIC, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Oget_info_by_name3"); + VERIFY(oinfo.rc, 2, "reference count in H5Oget_info_by_name3"); + ret = H5Oget_info_by_name3(fid, "datatype", &oinfo, H5O_INFO_BASIC, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Oget_info_by_name3"); + VERIFY(oinfo.rc, 2, "reference count in H5Oget_info_by_name3"); + ret = H5Oget_info_by_name3(fid, "dataset", &oinfo, H5O_INFO_BASIC, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Oget_info_by_name3"); + VERIFY(oinfo.rc, 2, "reference count in H5Oget_info_by_name3"); /* Decrement the reference counts and close the file */ ret = H5Odecr_refcount(grp); @@ -523,15 +647,15 @@ test_h5o_refcount(void) dset = H5Dopen2(fid, "dataset", H5P_DEFAULT); CHECK(dset, FAIL, "H5Dopen2"); - ret = H5Oget_info_by_name2(fid, "group", &oinfo, H5O_INFO_BASIC, H5P_DEFAULT); - CHECK(ret, FAIL, "H5Oget_info_by_name"); - VERIFY(oinfo.rc, 1, "reference count in H5Oget_info_by_name"); - ret = H5Oget_info_by_name2(fid, "datatype", &oinfo, H5O_INFO_BASIC, H5P_DEFAULT); - CHECK(ret, FAIL, "H5Oget_info_by_name"); - VERIFY(oinfo.rc, 1, "reference count in H5Oget_info_by_name"); - ret = H5Oget_info_by_name2(fid, "dataset", &oinfo, H5O_INFO_BASIC, H5P_DEFAULT); - CHECK(ret, FAIL, "H5Oget_info_by_name"); - VERIFY(oinfo.rc, 1, "reference count in H5Oget_info_by_name"); + ret = H5Oget_info_by_name3(fid, "group", &oinfo, H5O_INFO_BASIC, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Oget_info_by_name3"); + VERIFY(oinfo.rc, 1, "reference count in H5Oget_info_by_name3"); + ret = H5Oget_info_by_name3(fid, "datatype", &oinfo, H5O_INFO_BASIC, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Oget_info_by_name3"); + VERIFY(oinfo.rc, 1, "reference count in H5Oget_info_by_name3"); + ret = H5Oget_info_by_name3(fid, "dataset", &oinfo, H5O_INFO_BASIC, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Oget_info_by_name3"); + VERIFY(oinfo.rc, 1, "reference count in H5Oget_info_by_name3"); /* Close the IDs */ ret = H5Gclose(grp); @@ -1254,7 +1378,7 @@ test_h5o_getinfo_same_file(void) { hid_t fid1, fid2; /* HDF5 File ID */ hid_t gid1, gid2; /* Group IDs */ - H5O_info_t oinfo1, oinfo2; /* Object info structs */ + H5O_info2_t oinfo1, oinfo2; /* Object info structs */ herr_t ret; /* Value returned from API calls */ /* Create a new HDF5 file */ @@ -1272,24 +1396,24 @@ test_h5o_getinfo_same_file(void) HDmemset(&oinfo2, 0, sizeof(oinfo2)); /* Query the object info for each object, through group IDs */ - ret = H5Oget_info2(gid1, &oinfo1, H5O_INFO_BASIC); - CHECK(ret, FAIL, "H5Oget_info"); - ret = H5Oget_info2(gid2, &oinfo2, H5O_INFO_BASIC); - CHECK(ret, FAIL, "H5Oget_info"); + ret = H5Oget_info3(gid1, &oinfo1, H5O_INFO_BASIC); + CHECK(ret, FAIL, "H5Oget_info3"); + ret = H5Oget_info3(gid2, &oinfo2, H5O_INFO_BASIC); + CHECK(ret, FAIL, "H5Oget_info3"); - VERIFY(oinfo1.fileno, oinfo2.fileno, "file number from H5Oget_info"); + VERIFY(oinfo1.fileno, oinfo2.fileno, "file number from H5Oget_info3"); /* Reset object info */ HDmemset(&oinfo1, 0, sizeof(oinfo1)); HDmemset(&oinfo2, 0, sizeof(oinfo2)); /* Query the object info for each object, by name */ - ret = H5Oget_info_by_name2(fid1, "group1", &oinfo1, H5O_INFO_BASIC, H5P_DEFAULT); - CHECK(ret, FAIL, "H5Oget_info_by_name"); - ret = H5Oget_info_by_name2(fid1, "group2", &oinfo2, H5O_INFO_BASIC, H5P_DEFAULT); - CHECK(ret, FAIL, "H5Oget_info_by_name"); + ret = H5Oget_info_by_name3(fid1, "group1", &oinfo1, H5O_INFO_BASIC, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Oget_info_by_name3"); + ret = H5Oget_info_by_name3(fid1, "group2", &oinfo2, H5O_INFO_BASIC, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Oget_info_by_name3"); - VERIFY(oinfo1.fileno, oinfo2.fileno, "file number from H5Oget_info"); + VERIFY(oinfo1.fileno, oinfo2.fileno, "file number from H5Oget_info3"); /* Close everything */ ret = H5Gclose(gid1); @@ -1317,24 +1441,24 @@ test_h5o_getinfo_same_file(void) HDmemset(&oinfo2, 0, sizeof(oinfo2)); /* Query the object info for each object, through group IDs */ - ret = H5Oget_info2(gid1, &oinfo1, H5O_INFO_BASIC); - CHECK(ret, FAIL, "H5Oget_info"); - ret = H5Oget_info2(gid2, &oinfo2, H5O_INFO_BASIC); - CHECK(ret, FAIL, "H5Oget_info"); + ret = H5Oget_info3(gid1, &oinfo1, H5O_INFO_BASIC); + CHECK(ret, FAIL, "H5Oget_info3"); + ret = H5Oget_info3(gid2, &oinfo2, H5O_INFO_BASIC); + CHECK(ret, FAIL, "H5Oget_info3"); - VERIFY(oinfo1.fileno, oinfo2.fileno, "file number from H5Oget_info"); + VERIFY(oinfo1.fileno, oinfo2.fileno, "file number from H5Oget_info3"); /* Reset object info */ HDmemset(&oinfo1, 0, sizeof(oinfo1)); HDmemset(&oinfo2, 0, sizeof(oinfo2)); /* Query the object info for each object, by name */ - ret = H5Oget_info_by_name2(fid1, "group1", &oinfo1, H5O_INFO_BASIC, H5P_DEFAULT); - CHECK(ret, FAIL, "H5Oget_info_by_name"); - ret = H5Oget_info_by_name2(fid1, "group2", &oinfo2, H5O_INFO_BASIC, H5P_DEFAULT); - CHECK(ret, FAIL, "H5Oget_info_by_name"); + ret = H5Oget_info_by_name3(fid1, "group1", &oinfo1, H5O_INFO_BASIC, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Oget_info_by_name3"); + ret = H5Oget_info_by_name3(fid1, "group2", &oinfo2, H5O_INFO_BASIC, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Oget_info_by_name3"); - VERIFY(oinfo1.fileno, oinfo2.fileno, "file number from H5Oget_info"); + VERIFY(oinfo1.fileno, oinfo2.fileno, "file number from H5Oget_info3"); /* Close everything */ ret = H5Gclose(gid1); @@ -1352,6 +1476,143 @@ test_h5o_getinfo_same_file(void) /**************************************************************** ** +** test_h5o_open_by_addr_deprec(): Test H5Oopen_by_addr function. +** +****************************************************************/ +static void +test_h5o_open_by_addr_deprec(void) +{ + hid_t fid; /* HDF5 File ID */ + hid_t grp, dset, dtype, dspace; /* Object identifiers */ + H5L_info1_t li; /* Buffer for H5Lget_info1 */ + haddr_t grp_addr; /* Addresses for objects */ + haddr_t dset_addr; + haddr_t dtype_addr; + hsize_t dims[RANK]; + H5I_type_t id_type; /* Type of IDs returned from H5Oopen */ + H5G_info_t ginfo; /* Group info struct */ + H5T_class_t type_class; /* Class of the datatype */ + herr_t ret; /* Value returned from API calls */ + + /* Create a new HDF5 file */ + fid = H5Fcreate(TEST_FILENAME, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + CHECK(fid, FAIL, "H5Fcreate"); + + /* Create a group, dataset, and committed datatype within the file */ + /* Create the group */ + grp = H5Gcreate2(fid, "group", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(grp, FAIL, "H5Gcreate2"); + ret = H5Gclose(grp); + CHECK(ret, FAIL, "H5Gclose"); + + /* Commit the type inside the group */ + dtype = H5Tcopy(H5T_NATIVE_INT); + CHECK(dtype, FAIL, "H5Tcopy"); + ret = H5Tcommit2(fid, "group/datatype", dtype, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Tcommit2"); + ret = H5Tclose(dtype); + CHECK(ret, FAIL, "H5Tclose"); + + /* Create the data space for the dataset. */ + dims[0] = DIM0; + dims[1] = DIM1; + dspace = H5Screate_simple(RANK, dims, NULL); + CHECK(dspace, FAIL, "H5Screate_simple"); + + /* Create the dataset. */ + dset = H5Dcreate2(fid, "dataset", H5T_NATIVE_INT, dspace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(dset, FAIL, "H5Dcreate2"); + ret = H5Dclose(dset); + CHECK(ret, FAIL, "H5Dclose"); + ret = H5Sclose(dspace); + CHECK(ret, FAIL, "H5Sclose"); + + /* Get address for each object */ + ret = H5Lget_info1(fid, "group", &li, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Lget_info"); + grp_addr = li.u.address; + ret = H5Lget_info1(fid, "group/datatype", &li, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Lget_info"); + dtype_addr = li.u.address; + ret = H5Lget_info1(fid, "dataset", &li, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Lget_info"); + dset_addr = li.u.address; + + /* Now make sure that H5Oopen_by_addr can open all three types of objects */ + grp = H5Oopen_by_addr(fid, grp_addr); + CHECK(grp, FAIL, "H5Oopen_by_addr"); + dtype = H5Oopen_by_addr(fid, dtype_addr); + CHECK(dtype, FAIL, "H5Oopen_by_addr"); + /* Check that we can use the group ID as a valid location */ + dset = H5Oopen_by_addr(grp, dset_addr); + CHECK(dset, FAIL, "H5Oopen_by_addr"); + + /* Make sure that each is the right kind of ID */ + id_type = H5Iget_type(grp); + VERIFY(id_type, H5I_GROUP, "H5Iget_type for group ID"); + id_type = H5Iget_type(dtype); + VERIFY(id_type, H5I_DATATYPE, "H5Iget_type for datatype ID"); + id_type = H5Iget_type(dset); + VERIFY(id_type, H5I_DATASET, "H5Iget_type for dataset ID"); + + /* Do something more complex with each of the IDs to make sure they "work" */ + ret = H5Gget_info(grp, &ginfo); + CHECK(ret, FAIL, "H5Gget_info"); + VERIFY(ginfo.nlinks, 1, "H5Gget_info"); /* There should be one object, the datatype */ + + type_class = H5Tget_class(dtype); + VERIFY(type_class, H5T_INTEGER, "H5Tget_class"); + + dspace = H5Dget_space(dset); + CHECK(dspace, FAIL, "H5Dget_space"); + + /* Close the IDs */ + ret = H5Sclose(dspace); + CHECK(ret, FAIL, "H5Sclose"); + ret = H5Gclose(grp); + CHECK(ret, FAIL, "H5Gclose"); + ret = H5Tclose(dtype); + CHECK(ret, FAIL, "H5Tclose"); + ret = H5Dclose(dset); + CHECK(ret, FAIL, "H5Dclose"); + + /* Try giving some bogus values to H5O_open_by_addr. */ + /* Try to open an object with a bad address */ + grp_addr += 20; + H5E_BEGIN_TRY{ + grp = H5Oopen_by_addr(fid, grp_addr); + }H5E_END_TRY + VERIFY(grp, FAIL, "H5Oopen_by_addr"); + + /* For instance, an objectno smaller than the end of the file's superblock should + * trigger an error */ + grp_addr = 10; + H5E_BEGIN_TRY{ + grp = H5Oopen_by_addr(fid, grp_addr); + }H5E_END_TRY + VERIFY(grp, FAIL, "H5Oopen_by_addr"); + + /* Likewise, an objectno larger than the size of the file should fail */ + grp_addr = 0; + grp_addr = 1000000000; + H5E_BEGIN_TRY{ + grp = H5Oopen_by_addr(fid, grp_addr); + }H5E_END_TRY + VERIFY(grp, FAIL, "H5Oopen_by_addr"); + + ret = H5Fclose(fid); + CHECK(ret, FAIL, "H5Fclose"); + + /* Also, trying to open an object without a valid location should fail */ + H5E_BEGIN_TRY{ + dtype = H5Oopen_by_addr(fid, dtype_addr); + }H5E_END_TRY + VERIFY(dtype, FAIL, "H5Oopen_by_addr"); +} /* test_h5o_open_by_addr_deprec() */ + + +/**************************************************************** +** ** visit_obj_cb(): ** This is the callback function invoked by H5Ovisit1() in ** test_h5o_getinfo_visit(): @@ -1360,10 +1621,10 @@ test_h5o_getinfo_same_file(void) ** ****************************************************************/ static int -visit_obj_cb(hid_t group_id, const char *name, const H5O_info_t *oinfo1, +visit_obj_cb(hid_t group_id, const char *name, const H5O_info1_t *oinfo1, void H5_ATTR_UNUSED *_op_data) { - H5O_info_t oinfo2; /* Object info structs */ + H5O_info1_t oinfo2; /* Object info structs */ /* Verify the object info for "group1", "group2" and the root group */ if(!(HDstrcmp(name, "group1"))) { @@ -1399,7 +1660,7 @@ test_h5o_getinfo_visit(void) hid_t gid1 = -1, gid2 = -1; /* Group IDs */ hid_t sid = -1; /* Dataspace ID */ hid_t aid = -1; /* Attribute ID */ - H5O_info_t oinfo1, oinfo2; /* Object info structs */ + H5O_info1_t oinfo1, oinfo2; /* Object info structs */ char attrname[25]; /* Attribute name */ int j; /* Local index variable */ herr_t ret; /* Value returned from API calls */ @@ -1438,9 +1699,9 @@ test_h5o_getinfo_visit(void) /* Query the object info for "group1" via H5Oget_info1 and H5Oget_info2 */ ret = H5Oget_info1(gid1, &oinfo1); - CHECK(ret, FAIL, "H5Oget_info"); + CHECK(ret, FAIL, "H5Oget_info1"); ret = H5Oget_info2(gid1, &oinfo2, H5O_INFO_BASIC|H5O_INFO_NUM_ATTRS); - CHECK(ret, FAIL, "H5Oget_info"); + CHECK(ret, FAIL, "H5Oget_info2"); /* Verify the object info for "group1" is correct */ VERIFY(oinfo1.fileno, oinfo2.fileno, "obj info from H5Oget_info1/2"); @@ -1452,9 +1713,9 @@ test_h5o_getinfo_visit(void) /* Query the object info for "group2" via H5Oget_info1 and H5Oget_info2 */ ret = H5Oget_info_by_name1(fid, "group2", &oinfo1, H5P_DEFAULT); - CHECK(ret, FAIL, "H5Oget_info_by_name"); + CHECK(ret, FAIL, "H5Oget_native_info_by_name"); ret = H5Oget_info_by_name2(fid, "group2", &oinfo2, H5O_INFO_HDR|H5O_INFO_META_SIZE, H5P_DEFAULT); - CHECK(ret, FAIL, "H5Oget_info_by_name"); + CHECK(ret, FAIL, "H5Oget_native_info_by_name"); /* Verify the object info for "group2" is correct */ VERIFY(oinfo1.hdr.nmesgs, oinfo2.hdr.nmesgs, "obj info from H5Oget_info1/2"); @@ -1491,18 +1752,22 @@ test_h5o(void) /* Output message about test being performed */ MESSAGE(5, ("Testing Objects\n")); - test_h5o_open(); /* Test generic open function */ - test_h5o_open_by_addr(); /* Test opening objects by address */ - test_h5o_close(); /* Test generic close function */ - test_h5o_refcount(); /* Test incrementing and decrementing reference count */ - test_h5o_plist(); /* Test object creation properties */ - test_h5o_link(); /* Test object link routine */ - test_h5o_comment(); /* Test routines for comment */ - test_h5o_comment_by_name(); /* Test routines for comment by name */ - test_h5o_getinfo_same_file(); /* Test info for objects in the same file */ + test_h5o_open(); /* Test generic open function */ #ifndef H5_NO_DEPRECATED_SYMBOLS - test_h5o_getinfo_visit(); /* Test object info for H5Oget_info1/2 and H5Ovisit1 */ -#endif + test_h5o_open_by_addr(); /* Test opening objects by address */ +#endif /* H5_NO_DEPRECATED_SYMBOLS */ + test_h5o_open_by_token(); /* Test opening objects by token */ + test_h5o_close(); /* Test generic close function */ + test_h5o_refcount(); /* Test incrementing and decrementing reference count */ + test_h5o_plist(); /* Test object creation properties */ + test_h5o_link(); /* Test object link routine */ + test_h5o_comment(); /* Test routines for comment */ + test_h5o_comment_by_name(); /* Test routines for comment by name */ + test_h5o_getinfo_same_file(); /* Test info for objects in the same file */ +#ifndef H5_NO_DEPRECATED_SYMBOLS + test_h5o_open_by_addr_deprec(); /* Test opening objects by address with H5Lget_info1 */ + test_h5o_getinfo_visit(); /* Test object info for H5Oget_info1/2 and H5Ovisit1 */ +#endif /* H5_NO_DEPRECATED_SYMBOLS */ } /* test_h5o() */ diff --git a/test/titerate.c b/test/titerate.c index 669a094..9d60915 100644 --- a/test/titerate.c +++ b/test/titerate.c @@ -68,9 +68,9 @@ static int find_err_msg_cb(unsigned n, const H5E_error2_t *err_desc, void *_clie /* Local functions */ int iter_strcmp(const void *s1, const void *s2); int iter_strcmp2(const void *s1, const void *s2); -static herr_t liter_cb(hid_t group, const char *name, const H5L_info_t *info, +static herr_t liter_cb(hid_t group, const char *name, const H5L_info2_t *info, void *op_data); -static herr_t liter_cb2(hid_t group, const char *name, const H5L_info_t *info, +static herr_t liter_cb2(hid_t group, const char *name, const H5L_info2_t *info, void *op_data); herr_t aiter_cb(hid_t group, const char *name, const H5A_info_t *ainfo, void *op_data); @@ -91,7 +91,7 @@ H5_ATTR_PURE int iter_strcmp(const void *s1, const void *s2) ** ****************************************************************/ static herr_t -liter_cb(hid_t H5_ATTR_UNUSED group, const char *name, const H5L_info_t H5_ATTR_UNUSED *link_info, +liter_cb(hid_t H5_ATTR_UNUSED group, const char *name, const H5L_info2_t H5_ATTR_UNUSED *link_info, void *op_data) { iter_info *info = (iter_info *)op_data; @@ -153,8 +153,8 @@ test_iter_group(hid_t fapl, hbool_t new_format) /* Test iterating over empty group */ info.command = RET_ZERO; idx = 0; - ret = H5Literate(file, H5_INDEX_NAME, H5_ITER_INC, &idx, liter_cb, &info); - VERIFY(ret, SUCCEED, "H5Literate"); + ret = H5Literate2(file, H5_INDEX_NAME, H5_ITER_INC, &idx, liter_cb, &info); + VERIFY(ret, SUCCEED, "H5Literate2"); datatype = H5Tcopy(H5T_NATIVE_INT); CHECK(datatype, FAIL, "H5Tcopy"); @@ -220,12 +220,12 @@ test_iter_group(hid_t fapl, hbool_t new_format) VERIFY(ginfo.nlinks, (NDATASETS + 2), "H5Gget_info"); for(i = 0; i< (int)ginfo.nlinks; i++) { - H5O_info_t oinfo; /* Object info */ + H5O_info2_t oinfo; /* Object info */ ret = (herr_t)H5Lget_name_by_idx(root_group, ".", H5_INDEX_NAME, H5_ITER_INC, (hsize_t)i, dataset_name, (size_t)NAMELEN, H5P_DEFAULT); CHECK(ret, FAIL, "H5Lget_name_by_idx"); - ret = H5Oget_info_by_idx2(root_group, ".", H5_INDEX_NAME, H5_ITER_INC, (hsize_t)i, &oinfo, H5O_INFO_BASIC, H5P_DEFAULT); + ret = H5Oget_info_by_idx3(root_group, ".", H5_INDEX_NAME, H5_ITER_INC, (hsize_t)i, &oinfo, H5O_INFO_BASIC, H5P_DEFAULT); CHECK(ret, FAIL, "H5Oget_info_by_idx"); } /* end for */ @@ -246,13 +246,13 @@ test_iter_group(hid_t fapl, hbool_t new_format) VERIFY(ginfo.nlinks, NDATASETS + 2, "H5Gget_info"); for(i = 0; i< (int)ginfo.nlinks; i++) { - H5O_info_t oinfo; /* Object info */ + H5O_info2_t oinfo; /* Object info */ ret = (herr_t)H5Lget_name_by_idx(file, ".", H5_INDEX_NAME, H5_ITER_INC, (hsize_t)i, dataset_name, (size_t)NAMELEN, H5P_DEFAULT); CHECK(ret, FAIL, "H5Lget_name_by_idx"); - ret = H5Oget_info_by_idx2(file, ".", H5_INDEX_NAME, H5_ITER_INC, (hsize_t)i, &oinfo, H5O_INFO_BASIC, H5P_DEFAULT); - CHECK(ret, FAIL, "H5Oget_info_by_idx"); + ret = H5Oget_info_by_idx3(file, ".", H5_INDEX_NAME, H5_ITER_INC, (hsize_t)i, &oinfo, H5O_INFO_BASIC, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Oget_info_by_idx3"); } /* end for */ H5E_BEGIN_TRY { @@ -264,28 +264,28 @@ test_iter_group(hid_t fapl, hbool_t new_format) info.command = RET_ZERO; idx = (hsize_t)-1; H5E_BEGIN_TRY { - ret = H5Literate(file, H5_INDEX_NAME, H5_ITER_INC, &idx, liter_cb, &info); + ret = H5Literate2(file, H5_INDEX_NAME, H5_ITER_INC, &idx, liter_cb, &info); } H5E_END_TRY; - VERIFY(ret, FAIL, "H5Literate"); + VERIFY(ret, FAIL, "H5Literate2"); /* Test skipping exactly as many entries as in the group */ idx = NDATASETS + 2; H5E_BEGIN_TRY { - ret = H5Literate(file, H5_INDEX_NAME, H5_ITER_INC, &idx, liter_cb, &info); + ret = H5Literate2(file, H5_INDEX_NAME, H5_ITER_INC, &idx, liter_cb, &info); } H5E_END_TRY; - VERIFY(ret, FAIL, "H5Literate"); + VERIFY(ret, FAIL, "H5Literate2"); /* Test skipping more entries than are in the group */ idx = NDATASETS + 3; H5E_BEGIN_TRY { - ret = H5Literate(file, H5_INDEX_NAME, H5_ITER_INC, &idx, liter_cb, &info); + ret = H5Literate2(file, H5_INDEX_NAME, H5_ITER_INC, &idx, liter_cb, &info); } H5E_END_TRY; - VERIFY(ret, FAIL, "H5Literate"); + VERIFY(ret, FAIL, "H5Literate2"); /* Test all objects in group, when callback always returns 0 */ info.command = RET_ZERO; idx = 0; - if((ret = H5Literate(file, H5_INDEX_NAME, H5_ITER_INC, &idx, liter_cb, &info)) > 0) + if((ret = H5Literate2(file, H5_INDEX_NAME, H5_ITER_INC, &idx, liter_cb, &info)) > 0) TestErrPrintf("Group iteration function didn't return zero correctly!\n"); /* Test all objects in group, when callback always returns 1 */ @@ -293,15 +293,15 @@ test_iter_group(hid_t fapl, hbool_t new_format) info.command = RET_TWO; i = 0; idx = 0; - while((ret = H5Literate(file, H5_INDEX_NAME, H5_ITER_INC, &idx, liter_cb, &info)) > 0) { + while((ret = H5Literate2(file, H5_INDEX_NAME, H5_ITER_INC, &idx, liter_cb, &info)) > 0) { /* Verify return value from iterator gets propagated correctly */ - VERIFY(ret, 2, "H5Literate"); + VERIFY(ret, 2, "H5Literate2"); /* Increment the number of times "2" is returned */ i++; /* Verify that the index is the correct value */ - VERIFY(idx, (hsize_t)i, "H5Literate"); + VERIFY(idx, (hsize_t)i, "H5Literate2"); if(idx > (NDATASETS + 2)) TestErrPrintf("Group iteration function walked too far!\n"); @@ -309,7 +309,7 @@ test_iter_group(hid_t fapl, hbool_t new_format) if(HDstrcmp(info.name, lnames[(size_t)(idx - 1)]) != 0) TestErrPrintf("Group iteration function didn't return name correctly for link - lnames[%u] = '%s'!\n", (unsigned)(idx - 1), lnames[(size_t)(idx - 1)]); } /* end while */ - VERIFY(ret, -1, "H5Literate"); + VERIFY(ret, -1, "H5Literate2"); if(i != (NDATASETS + 2)) TestErrPrintf("%u: Group iteration function didn't perform multiple iterations correctly!\n", __LINE__); @@ -319,15 +319,15 @@ test_iter_group(hid_t fapl, hbool_t new_format) info.command = new_format ? RET_CHANGE2 : RET_CHANGE; i = 0; idx = 0; - while((ret = H5Literate(file, H5_INDEX_NAME, H5_ITER_INC, &idx, liter_cb, &info)) >= 0) { + while((ret = H5Literate2(file, H5_INDEX_NAME, H5_ITER_INC, &idx, liter_cb, &info)) >= 0) { /* Verify return value from iterator gets propagated correctly */ - VERIFY(ret, 1, "H5Literate"); + VERIFY(ret, 1, "H5Literate2"); /* Increment the number of times "1" is returned */ i++; /* Verify that the index is the correct value */ - VERIFY(idx, (hsize_t)(i + 10), "H5Literate"); + VERIFY(idx, (hsize_t)(i + 10), "H5Literate2"); if(idx > (NDATASETS + 2)) TestErrPrintf("Group iteration function walked too far!\n"); @@ -335,7 +335,7 @@ test_iter_group(hid_t fapl, hbool_t new_format) if(HDstrcmp(info.name, lnames[(size_t)(idx - 1)]) != 0) TestErrPrintf("Group iteration function didn't return name correctly for link - lnames[%u] = '%s'!\n", (unsigned)(idx - 1), lnames[(size_t)(idx - 1)]); } /* end while */ - VERIFY(ret, -1, "H5Literate"); + VERIFY(ret, -1, "H5Literate2"); if(i != 42 || idx != 52) TestErrPrintf("%u: Group iteration function didn't perform multiple iterations correctly!\n", __LINE__); @@ -550,11 +550,11 @@ H5_ATTR_PURE int iter_strcmp2(const void *s1, const void *s2) ** ****************************************************************/ static herr_t -liter_cb2(hid_t loc_id, const char *name, const H5L_info_t H5_ATTR_UNUSED *link_info, +liter_cb2(hid_t loc_id, const char *name, const H5L_info2_t H5_ATTR_UNUSED *link_info, void *opdata) { const iter_info *test_info = (const iter_info *)opdata; - H5O_info_t oinfo; + H5O_info2_t oinfo; herr_t ret; /* Generic return value */ if(HDstrcmp(name, test_info->name)) { @@ -565,8 +565,8 @@ liter_cb2(hid_t loc_id, const char *name, const H5L_info_t H5_ATTR_UNUSED *link_ /* * Get type of the object and check it. */ - ret = H5Oget_info_by_name2(loc_id, name, &oinfo, H5O_INFO_BASIC, H5P_DEFAULT); - CHECK(ret, FAIL, "H5Oget_info_by_name"); + ret = H5Oget_info_by_name3(loc_id, name, &oinfo, H5O_INFO_BASIC, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Oget_info_by_name3"); if(test_info->type != oinfo.type) { TestErrPrintf("test_info->type = %d, oinfo.type = %d\n", test_info->type, (int)oinfo.type); @@ -683,14 +683,14 @@ test_iter_group_large(hid_t fapl) /* Iterate through the file to see members of the root group */ curr_name = &names[0]; - ret = H5Literate(file, H5_INDEX_NAME, H5_ITER_INC, NULL, liter_cb2, curr_name); - CHECK(ret, FAIL, "H5Literate"); + ret = H5Literate2(file, H5_INDEX_NAME, H5_ITER_INC, NULL, liter_cb2, curr_name); + CHECK(ret, FAIL, "H5Literate2"); for(i = 1; i < 100; i++) { hsize_t idx = (hsize_t)i; curr_name = &names[i]; - ret = H5Literate(file, H5_INDEX_NAME, H5_ITER_INC, &idx, liter_cb2, curr_name); - CHECK(ret, FAIL, "H5Literate"); + ret = H5Literate2(file, H5_INDEX_NAME, H5_ITER_INC, &idx, liter_cb2, curr_name); + CHECK(ret, FAIL, "H5Literate2"); } /* end for */ /* Close file */ @@ -793,7 +793,7 @@ static void test_grp_memb_funcs(hid_t fapl) VERIFY(ginfo.nlinks, (NDATASETS + 2), "H5Gget_info"); for(i = 0; i < (int)ginfo.nlinks; i++) { - H5O_info_t oinfo; /* Object info */ + H5O_info2_t oinfo; /* Object info */ /* Test with NULL for name, to query length */ name_len = H5Lget_name_by_idx(root_group, ".", H5_INDEX_NAME, H5_ITER_INC, (hsize_t)i, NULL, (size_t)NAMELEN, H5P_DEFAULT); @@ -809,8 +809,8 @@ static void test_grp_memb_funcs(hid_t fapl) obj_names[i] = HDstrdup(dataset_name); CHECK_PTR(obj_names[i], "strdup"); - ret = H5Oget_info_by_idx2(root_group, ".", H5_INDEX_NAME, H5_ITER_INC, (hsize_t)i, &oinfo, H5O_INFO_BASIC, H5P_DEFAULT); - CHECK(ret, FAIL, "H5Oget_info_by_idx"); + ret = H5Oget_info_by_idx3(root_group, ".", H5_INDEX_NAME, H5_ITER_INC, (hsize_t)i, &oinfo, H5O_INFO_BASIC, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Oget_info_by_idx3"); if(!HDstrcmp(dataset_name, "grp")) VERIFY(oinfo.type, H5O_TYPE_GROUP, "H5Lget_name_by_idx"); @@ -890,21 +890,21 @@ static void test_links(hid_t fapl) /* Test these two functions, H5Oget_info_by_idx and H5Lget_name_by_idx */ for(i = 0; i < ginfo.nlinks; i++) { - H5O_info_t oinfo; /* Object info */ - H5L_info_t linfo; /* Link info */ + H5O_info2_t oinfo; /* Object info */ + H5L_info2_t linfo; /* Link info */ /* Get link name */ name_len = H5Lget_name_by_idx(gid, ".", H5_INDEX_NAME, H5_ITER_INC, i, obj_name, (size_t)NAMELEN, H5P_DEFAULT); CHECK(name_len, FAIL, "H5Lget_name_by_idx"); /* Get link type */ - ret = H5Lget_info_by_idx(gid, ".", H5_INDEX_NAME, H5_ITER_INC, (hsize_t)i, &linfo, H5P_DEFAULT); - CHECK(ret, FAIL, "H5Lget_info_by_idx"); + ret = H5Lget_info_by_idx2(gid, ".", H5_INDEX_NAME, H5_ITER_INC, (hsize_t)i, &linfo, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Lget_info_by_idx2"); /* Get object type */ if(linfo.type == H5L_TYPE_HARD) { - ret = H5Oget_info_by_idx2(gid, ".", H5_INDEX_NAME, H5_ITER_INC, (hsize_t)i, &oinfo, H5O_INFO_BASIC, H5P_DEFAULT); - CHECK(ret, FAIL, "H5Oget_info_by_idx"); + ret = H5Oget_info_by_idx3(gid, ".", H5_INDEX_NAME, H5_ITER_INC, (hsize_t)i, &oinfo, H5O_INFO_BASIC, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Oget_info_by_idx3"); } /* end if */ if(!HDstrcmp(obj_name, "g1.1")) @@ -1015,6 +1015,87 @@ static void test_corrupted_attnamelen(void) } /* test_corrupted_attnamelen() */ +#ifndef H5_NO_DEPRECATED_SYMBOLS +/**************************************************************** +** +** test_links_deprec(): Test soft and hard link iteration +** +****************************************************************/ +static void test_links_deprec(hid_t fapl) +{ + hid_t file; /* File ID */ + char obj_name[NAMELEN]; /* Names of the object in group */ + ssize_t name_len; /* Length of object's name */ + hid_t gid, gid1; + H5G_info_t ginfo; /* Buffer for querying object's info */ + hsize_t i; + herr_t ret; /* Generic return value */ + + /* Output message about test being performed */ + MESSAGE(5, ("Testing Soft and Hard Link Iteration Functionality Using Deprecated Routines\n")); + + /* Create the test file with the datasets */ + file = H5Fcreate(DATAFILE, H5F_ACC_TRUNC, H5P_DEFAULT, fapl); + CHECK(file, FAIL, "H5Fcreate"); + + /* create groups */ + gid = H5Gcreate2(file, "/g1", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(gid, FAIL, "H5Gcreate2"); + + gid1 = H5Gcreate2(file, "/g1/g1.1", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(gid1, FAIL, "H5Gcreate2"); + + /* create soft and hard links to the group "/g1". */ + ret = H5Lcreate_soft("something", gid, "softlink", H5P_DEFAULT, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Lcreate_soft"); + + ret = H5Lcreate_hard(gid, "/g1", H5L_SAME_LOC, "hardlink", H5P_DEFAULT, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Lcreate_hard"); + + ret = H5Gget_info(gid, &ginfo); + CHECK(ret, FAIL, "H5Gget_info"); + VERIFY(ginfo.nlinks, 3, "H5Gget_info"); + + /* Test these two functions, H5Oget_info_by_idx and H5Lget_name_by_idx */ + for(i = 0; i < ginfo.nlinks; i++) { + H5O_info2_t oinfo; /* Object info */ + H5L_info2_t linfo; /* Link info */ + + /* Get link name */ + name_len = H5Lget_name_by_idx(gid, ".", H5_INDEX_NAME, H5_ITER_INC, i, obj_name, (size_t)NAMELEN, H5P_DEFAULT); + CHECK(name_len, FAIL, "H5Lget_name_by_idx"); + + /* Get link type */ + ret = H5Lget_info_by_idx2(gid, ".", H5_INDEX_NAME, H5_ITER_INC, (hsize_t)i, &linfo, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Lget_info_by_idx1"); + + /* Get object type */ + if(linfo.type == H5L_TYPE_HARD) { + ret = H5Oget_info_by_idx3(gid, ".", H5_INDEX_NAME, H5_ITER_INC, (hsize_t)i, &oinfo, H5O_INFO_BASIC, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Oget_info_by_idx"); + } /* end if */ + + if(!HDstrcmp(obj_name, "g1.1")) + VERIFY(oinfo.type, H5O_TYPE_GROUP, "H5Lget_name_by_idx"); + else if(!HDstrcmp(obj_name, "hardlink")) + VERIFY(oinfo.type, H5O_TYPE_GROUP, "H5Lget_name_by_idx"); + else if(!HDstrcmp(obj_name, "softlink")) + VERIFY(linfo.type, H5L_TYPE_SOFT, "H5Lget_name_by_idx"); + else + CHECK(0, 0, "unknown object name"); + } /* end for */ + + ret = H5Gclose(gid); + CHECK(ret, FAIL, "H5Gclose"); + + ret = H5Gclose(gid1); + CHECK(ret, FAIL, "H5Gclose"); + + ret = H5Fclose(file); + CHECK(ret, FAIL, "H5Fclose"); +} /* test_links_deprec() */ +#endif + /**************************************************************** ** ** test_iterate(): Main iteration testing routine. @@ -1049,6 +1130,9 @@ test_iterate(void) test_iter_attr(new_format ? fapl2 : fapl, new_format); /* Test attribute iteration */ test_grp_memb_funcs(new_format ? fapl2 : fapl); /* Test group member information functions */ test_links(new_format ? fapl2 : fapl); /* Test soft and hard link iteration */ +#ifndef H5_NO_DEPRECATED_SYMBOLS + test_links_deprec(new_format ? fapl2 : fapl); /* Test soft and hard link iteration */ +#endif } /* end for */ /* Test the fix for issue HDFFV-10588 */ diff --git a/test/tmisc.c b/test/tmisc.c index d637802..7b7f5ba 100644 --- a/test/tmisc.c +++ b/test/tmisc.c @@ -309,6 +309,7 @@ typedef struct /* Definitions for misc. test #30 */ #define MISC30_FILE "tmisc30.h5" +#ifndef H5_NO_DEPRECATED_SYMBOLS /* Definitions for misc. test #31 */ #define MISC31_FILE "tmisc31.h5" #define MISC31_DSETNAME "dset" @@ -317,6 +318,7 @@ typedef struct #define MISC31_GROUPNAME "group" #define MISC31_PROPNAME "misc31_prop" #define MISC31_DTYPENAME "dtype" +#endif /* H5_NO_DEPRECATED_SYMBOLS */ /* Definitions for misc. test #33 */ /* Note that this test file is generated by "gen_bad_offset.c" */ @@ -649,7 +651,7 @@ static void test_misc4(void) { hid_t file1, file2, group1, group2, group3; - H5O_info_t oinfo1, oinfo2, oinfo3; + H5O_info2_t oinfo1, oinfo2, oinfo3; herr_t ret; /* Output message about test being performed */ @@ -674,12 +676,12 @@ test_misc4(void) CHECK(group3, FAIL, "H5Gcreate2"); /* Get the stat information for each group */ - ret = H5Oget_info_by_name2(file1, MISC4_GROUP_1, &oinfo1, H5O_INFO_BASIC, H5P_DEFAULT); - CHECK(ret, FAIL, "H5Oget_info_by_name"); - ret = H5Oget_info_by_name2(file1, MISC4_GROUP_2, &oinfo2, H5O_INFO_BASIC, H5P_DEFAULT); - CHECK(ret, FAIL, "H5Oget_info_by_name"); - ret = H5Oget_info_by_name2(file2, MISC4_GROUP_1, &oinfo3, H5O_INFO_BASIC, H5P_DEFAULT); - CHECK(ret, FAIL, "H5Oget_info_by_name"); + ret = H5Oget_info_by_name3(file1, MISC4_GROUP_1, &oinfo1, H5O_INFO_BASIC, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Oget_info_by_name3"); + ret = H5Oget_info_by_name3(file1, MISC4_GROUP_2, &oinfo2, H5O_INFO_BASIC, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Oget_info_by_name3"); + ret = H5Oget_info_by_name3(file2, MISC4_GROUP_1, &oinfo3, H5O_INFO_BASIC, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Oget_info_by_name3"); /* Verify that the fileno values are the same for groups from file1 */ VERIFY(oinfo1.fileno, oinfo2.fileno, "H5Oget_info_by_name"); @@ -2911,7 +2913,11 @@ test_misc18(void) hid_t sid; /* 'Space ID */ hid_t did1, did2; /* Dataset IDs */ hid_t aid; /* Attribute ID */ - H5O_info_t oinfo; /* Information about object */ +#ifndef H5_NO_DEPRECATED_SYMBOLS + H5O_info1_t old_oinfo; /* (deprecated) information about object */ +#endif /* H5_NO_DEPRECATED_SYMBOLS */ + H5O_info2_t oinfo; /* Data model information about object */ + H5O_native_info_t ninfo; /* Native file format information about object */ char attr_name[32]; /* Attribute name buffer */ unsigned u; /* Local index variable */ herr_t ret; /* Generic return value */ @@ -2929,26 +2935,48 @@ test_misc18(void) CHECK(did1, FAIL, "H5Dcreate2"); /* Get object information */ - ret = H5Oget_info_by_name2(fid, MISC18_DSET1_NAME, &oinfo, H5O_INFO_HDR|H5O_INFO_NUM_ATTRS, H5P_DEFAULT); + ret = H5Oget_info_by_name3(fid, MISC18_DSET1_NAME, &oinfo, H5O_INFO_NUM_ATTRS, H5P_DEFAULT); CHECK(ret, FAIL, "H5Oget_info_by_name"); - VERIFY(oinfo.hdr.nmesgs, 6, "H5Oget_info_by_name"); - VERIFY(oinfo.hdr.nchunks, 1, "H5Oget_info_by_name"); - VERIFY(oinfo.hdr.space.total, 272, "H5Oget_info_by_name"); - VERIFY(oinfo.hdr.space.free, 152, "H5Oget_info_by_name"); VERIFY(oinfo.num_attrs, 0, "H5Oget_info_by_name"); +#ifndef H5_NO_DEPRECATED_SYMBOLS + ret = H5Oget_info_by_name2(fid, MISC18_DSET1_NAME, &old_oinfo, H5O_INFO_HDR|H5O_INFO_NUM_ATTRS, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Oget_info_by_name"); + VERIFY(old_oinfo.hdr.nmesgs, 6, "H5Oget_info_by_name"); + VERIFY(old_oinfo.hdr.nchunks, 1, "H5Oget_info_by_name"); + VERIFY(old_oinfo.hdr.space.total, 272, "H5Oget_info_by_name"); + VERIFY(old_oinfo.hdr.space.free, 152, "H5Oget_info_by_name"); + VERIFY(old_oinfo.num_attrs, 0, "H5Oget_info_by_name"); +#endif /* H5_NO_DEPRECATED_SYMBOLS */ + ret = H5Oget_native_info_by_name(fid, MISC18_DSET1_NAME, &ninfo, H5O_NATIVE_INFO_HDR, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Oget_native_info_by_name"); + VERIFY(ninfo.hdr.nmesgs, 6, "H5Oget_native_info_by_name"); + VERIFY(ninfo.hdr.nchunks, 1, "H5Oget_native_info_by_name"); + VERIFY(ninfo.hdr.space.total, 272, "H5Oget_native_info_by_name"); + VERIFY(ninfo.hdr.space.free, 152, "H5Oget_native_info_by_name"); /* Create second dataset */ did2 = H5Dcreate2(fid, MISC18_DSET2_NAME, H5T_STD_U32LE, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); CHECK(did2, FAIL, "H5Dcreate2"); /* Get object information */ - ret = H5Oget_info_by_name2(fid, MISC18_DSET2_NAME, &oinfo, H5O_INFO_HDR|H5O_INFO_NUM_ATTRS, H5P_DEFAULT); + ret = H5Oget_info_by_name3(fid, MISC18_DSET2_NAME, &oinfo, H5O_INFO_NUM_ATTRS, H5P_DEFAULT); CHECK(ret, FAIL, "H5Oget_info_by_name"); - VERIFY(oinfo.hdr.nmesgs, 6, "H5Oget_info_by_name"); - VERIFY(oinfo.hdr.nchunks, 1, "H5Oget_info_by_name"); - VERIFY(oinfo.hdr.space.total, 272, "H5Oget_info_by_name"); - VERIFY(oinfo.hdr.space.free, 152, "H5Oget_info_by_name"); VERIFY(oinfo.num_attrs, 0, "H5Oget_info_by_name"); +#ifndef H5_NO_DEPRECATED_SYMBOLS + ret = H5Oget_info_by_name2(fid, MISC18_DSET2_NAME, &old_oinfo, H5O_INFO_HDR|H5O_INFO_NUM_ATTRS, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Oget_info_by_name"); + VERIFY(old_oinfo.hdr.nmesgs, 6, "H5Oget_info_by_name"); + VERIFY(old_oinfo.hdr.nchunks, 1, "H5Oget_info_by_name"); + VERIFY(old_oinfo.hdr.space.total, 272, "H5Oget_info_by_name"); + VERIFY(old_oinfo.hdr.space.free, 152, "H5Oget_info_by_name"); + VERIFY(old_oinfo.num_attrs, 0, "H5Oget_info_by_name"); +#endif /* H5_NO_DEPRECATED_SYMBOLS */ + ret = H5Oget_native_info_by_name(fid, MISC18_DSET2_NAME, &ninfo, H5O_NATIVE_INFO_HDR, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Oget_native_info_by_name"); + VERIFY(ninfo.hdr.nmesgs, 6, "H5Oget_native_info_by_name"); + VERIFY(ninfo.hdr.nchunks, 1, "H5Oget_native_info_by_name"); + VERIFY(ninfo.hdr.space.total, 272, "H5Oget_native_info_by_name"); + VERIFY(ninfo.hdr.space.free, 152, "H5Oget_native_info_by_name"); /* Loop creating attributes on each dataset, flushing them to the file each time */ for(u = 0; u < 10; u++) { @@ -2975,22 +3003,44 @@ test_misc18(void) } /* end for */ /* Get object information for dataset #1 now */ - ret = H5Oget_info_by_name2(fid, MISC18_DSET1_NAME, &oinfo, H5O_INFO_HDR|H5O_INFO_NUM_ATTRS, H5P_DEFAULT); + ret = H5Oget_info_by_name3(fid, MISC18_DSET1_NAME, &oinfo, H5O_INFO_NUM_ATTRS, H5P_DEFAULT); CHECK(ret, FAIL, "H5Oget_info_by_name"); - VERIFY(oinfo.hdr.nmesgs, 24, "H5Oget_info_by_name"); - VERIFY(oinfo.hdr.nchunks, 9, "H5Oget_info_by_name"); - VERIFY(oinfo.hdr.space.total, 888, "H5Oget_info_by_name"); - VERIFY(oinfo.hdr.space.free, 16, "H5Oget_info_by_name"); VERIFY(oinfo.num_attrs, 10, "H5Oget_info_by_name"); +#ifndef H5_NO_DEPRECATED_SYMBOLS + ret = H5Oget_info_by_name2(fid, MISC18_DSET1_NAME, &old_oinfo, H5O_INFO_HDR|H5O_INFO_NUM_ATTRS, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Oget_info_by_name"); + VERIFY(old_oinfo.hdr.nmesgs, 24, "H5Oget_info_by_name"); + VERIFY(old_oinfo.hdr.nchunks, 9, "H5Oget_info_by_name"); + VERIFY(old_oinfo.hdr.space.total, 888, "H5Oget_info_by_name"); + VERIFY(old_oinfo.hdr.space.free, 16, "H5Oget_info_by_name"); + VERIFY(old_oinfo.num_attrs, 10, "H5Oget_info_by_name"); +#endif /* H5_NO_DEPRECATED_SYMBOLS */ + ret = H5Oget_native_info_by_name(fid, MISC18_DSET1_NAME, &ninfo, H5O_NATIVE_INFO_HDR, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Oget_native_info_by_name"); + VERIFY(ninfo.hdr.nmesgs, 24, "H5Oget_native_info_by_name"); + VERIFY(ninfo.hdr.nchunks, 9, "H5Oget_native_info_by_name"); + VERIFY(ninfo.hdr.space.total, 888, "H5Oget_native_info_by_name"); + VERIFY(ninfo.hdr.space.free, 16, "H5Oget_native_info_by_name"); /* Get object information for dataset #2 now */ - ret = H5Oget_info_by_name2(fid, MISC18_DSET2_NAME, &oinfo, H5O_INFO_HDR|H5O_INFO_NUM_ATTRS, H5P_DEFAULT); + ret = H5Oget_info_by_name3(fid, MISC18_DSET2_NAME, &oinfo, H5O_INFO_NUM_ATTRS, H5P_DEFAULT); CHECK(ret, FAIL, "H5Oget_info_by_name"); - VERIFY(oinfo.hdr.nmesgs, 24, "H5Oget_info_by_name"); - VERIFY(oinfo.hdr.nchunks, 9, "H5Oget_info_by_name"); - VERIFY(oinfo.hdr.space.total, 888, "H5Oget_info_by_name"); - VERIFY(oinfo.hdr.space.free, 16, "H5Oget_info_by_name"); VERIFY(oinfo.num_attrs, 10, "H5Oget_info_by_name"); +#ifndef H5_NO_DEPRECATED_SYMBOLS + ret = H5Oget_info_by_name2(fid, MISC18_DSET2_NAME, &old_oinfo, H5O_INFO_HDR|H5O_INFO_NUM_ATTRS, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Oget_info_by_name"); + VERIFY(old_oinfo.hdr.nmesgs, 24, "H5Oget_info_by_name"); + VERIFY(old_oinfo.hdr.nchunks, 9, "H5Oget_info_by_name"); + VERIFY(old_oinfo.hdr.space.total, 888, "H5Oget_info_by_name"); + VERIFY(old_oinfo.hdr.space.free, 16, "H5Oget_info_by_name"); + VERIFY(old_oinfo.num_attrs, 10, "H5Oget_info_by_name"); +#endif /* H5_NO_DEPRECATED_SYMBOLS */ + ret = H5Oget_native_info_by_name(fid, MISC18_DSET2_NAME, &ninfo, H5O_NATIVE_INFO_HDR, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Oget_mative_info_by_name"); + VERIFY(ninfo.hdr.nmesgs, 24, "H5Oget_native_info_by_name"); + VERIFY(ninfo.hdr.nchunks, 9, "H5Oget_native_info_by_name"); + VERIFY(ninfo.hdr.space.total, 888, "H5Oget_native_info_by_name"); + VERIFY(ninfo.hdr.space.free, 16, "H5Oget_native_info_by_name"); /* Close second dataset */ ret = H5Dclose(did2); @@ -3915,7 +3965,7 @@ test_misc23(void) hid_t file_id=0, group_id=0, type_id=0, space_id=0, tmp_id=0, create_id=H5P_DEFAULT, access_id=H5P_DEFAULT; char objname[MISC23_NAME_BUF_SIZE]; /* Name of object */ - H5O_info_t oinfo; + H5O_info2_t oinfo; htri_t tri_status; ssize_t namelen; herr_t status; @@ -3998,9 +4048,9 @@ test_misc23(void) tmp_id = H5Gopen2(file_id, "/A/B01", H5P_DEFAULT); CHECK(tmp_id, FAIL, "H5Gopen2"); - status = H5Oget_info2(tmp_id, &oinfo, H5O_INFO_BASIC); - CHECK(status, FAIL, "H5Oget_info"); - VERIFY(oinfo.rc, 1, "H5Oget_info"); + status = H5Oget_info3(tmp_id, &oinfo, H5O_INFO_BASIC); + CHECK(status, FAIL, "H5Oget_info3"); + VERIFY(oinfo.rc, 1, "H5Oget_info3"); status = H5Gclose(tmp_id); CHECK(status, FAIL, "H5Gclose"); @@ -5274,18 +5324,18 @@ test_misc29(void) static int -test_misc30_get_info_cb(hid_t loc_id, const char *name, const H5L_info_t H5_ATTR_UNUSED *info, +test_misc30_get_info_cb(hid_t loc_id, const char *name, const H5L_info2_t H5_ATTR_UNUSED *info, void H5_ATTR_UNUSED *op_data) { - H5O_info_t object_info; + H5O_info2_t object_info; - return H5Oget_info_by_name2(loc_id, name, &object_info, H5O_INFO_BASIC, H5P_DEFAULT); + return H5Oget_info_by_name3(loc_id, name, &object_info, H5O_INFO_BASIC, H5P_DEFAULT); } static int test_misc30_get_info(hid_t loc_id) { - return H5Literate(loc_id, H5_INDEX_NAME, H5_ITER_INC, NULL, test_misc30_get_info_cb, NULL); + return H5Literate2(loc_id, H5_INDEX_NAME, H5_ITER_INC, NULL, test_misc30_get_info_cb, NULL); } @@ -5364,6 +5414,7 @@ test_misc30(void) static void test_misc31(void) { +#ifndef H5_NO_DEPRECATED_SYMBOLS hid_t file_id; /* File id */ hid_t space_id; /* Dataspace id */ hid_t dset_id; /* Dataset id */ @@ -5371,6 +5422,7 @@ test_misc31(void) hid_t group_id; /* Group id */ hid_t dtype_id; /* Datatype id */ herr_t ret; /* Generic return value */ +#endif /* H5_NO_DEPRECATED_SYMBOLS */ /* Output message about test being performed */ MESSAGE(5, ("Deprecated routines initialize after H5close()\n")); @@ -5533,7 +5585,7 @@ test_misc33(void) { hid_t fid = -1; /* File ID */ const char *testfile = H5_get_srcdir_filename(MISC33_FILE); /* Corrected test file name */ - H5O_info_t oinfo; /* Structure for object metadata information */ + H5O_info2_t oinfo; /* Structure for object metadata information */ herr_t ret; /* Generic return value */ /* Output message about test being performed */ @@ -5545,21 +5597,21 @@ test_misc33(void) /* Case (1) */ H5E_BEGIN_TRY { - ret = H5Oget_info_by_name2(fid, "/soft_two", &oinfo, H5O_INFO_BASIC, H5P_DEFAULT); + ret = H5Oget_info_by_name3(fid, "/soft_two", &oinfo, H5O_INFO_BASIC, H5P_DEFAULT); } H5E_END_TRY; - VERIFY(ret, FAIL, "H5Oget_info_by_name"); + VERIFY(ret, FAIL, "H5Oget_info_by_name3"); /* Case (2) */ H5E_BEGIN_TRY { - ret = H5Oget_info_by_name2(fid, "/dsetA", &oinfo, H5O_INFO_BASIC, H5P_DEFAULT); + ret = H5Oget_info_by_name3(fid, "/dsetA", &oinfo, H5O_INFO_BASIC, H5P_DEFAULT); } H5E_END_TRY; - VERIFY(ret, FAIL, "H5Oget_info_by_name"); + VERIFY(ret, FAIL, "H5Oget_info_by_name3"); /* Case (3) */ H5E_BEGIN_TRY { - ret = H5Oget_info_by_name2(fid, "/soft_one", &oinfo, H5O_INFO_BASIC, H5P_DEFAULT); + ret = H5Oget_info_by_name3(fid, "/soft_one", &oinfo, H5O_INFO_BASIC, H5P_DEFAULT); } H5E_END_TRY; - VERIFY(ret, FAIL, "H5Oget_info_by_name"); + VERIFY(ret, FAIL, "H5Oget_info_by_name3"); /* Close the file */ ret = H5Fclose(fid); @@ -5728,6 +5780,8 @@ cleanup_misc(void) HDremove(MISC28_FILE); HDremove(MISC29_COPY_FILE); HDremove(MISC30_FILE); +#ifndef H5_NO_DEPRECATED_SYMBOLS HDremove(MISC31_FILE); +#endif /* H5_NO_DEPRECATED_SYMBOLS */ } /* end cleanup_misc() */ diff --git a/test/trefer.c b/test/trefer.c index dec049e..441b7aa 100644 --- a/test/trefer.c +++ b/test/trefer.c @@ -568,7 +568,7 @@ test_reference_region(H5F_libver_t libver_low, H5F_libver_t libver_high) hsize_t high[SPACE2_RANK]; /* Selection bounds */ H5R_ref_t *wbuf, /* buffer to write to disk */ *rbuf; /* buffer read from disk */ - H5R_ref_t nvrbuf[3]={{{0}},{{101}},{{-128}}}; /* buffer with non-valid refs */ + H5R_ref_t nvrbuf[3]={{{{0}}},{{{101}}},{{{255}}}}; /* buffer with non-valid refs */ uint8_t *dwbuf, /* Buffer for writing numeric data to disk */ *drbuf; /* Buffer for reading numeric data from disk */ uint8_t *tu8; /* Temporary pointer to uint8 data */ @@ -1380,7 +1380,7 @@ test_reference_obj_deleted(void) ** ****************************************************************/ static herr_t -test_deref_iter_op(hid_t H5_ATTR_UNUSED group, const char *name, const H5L_info_t H5_ATTR_UNUSED *info, +test_deref_iter_op(hid_t H5_ATTR_UNUSED group, const char *name, const H5L_info2_t H5_ATTR_UNUSED *info, void *op_data) { int *count = (int *)op_data; /* Pointer to name counter */ @@ -1430,7 +1430,7 @@ test_reference_group(void) H5R_ref_t rref; /* Reference to read */ H5G_info_t ginfo; /* Group info struct */ char objname[NAME_SIZE]; /* Buffer to store name */ - H5O_info_t oinfo; /* Object info struct */ + H5O_info2_t oinfo; /* Object info struct */ int count = 0; /* Count within iterated group */ ssize_t size; /* Name length */ herr_t ret; @@ -1508,7 +1508,7 @@ test_reference_group(void) CHECK(gid, H5I_INVALID_HID, "H5Ropen_object"); /* Iterate through objects in dereferenced group */ - ret = H5Literate(gid, H5_INDEX_NAME, H5_ITER_INC, NULL, test_deref_iter_op, &count); + ret = H5Literate2(gid, H5_INDEX_NAME, H5_ITER_INC, NULL, test_deref_iter_op, &count); CHECK(ret, FAIL, "H5Literate"); /* Various queries on the group opened */ @@ -1520,9 +1520,9 @@ test_reference_group(void) CHECK(size, (-1), "H5Lget_name_by_idx"); VERIFY_STR(objname, DSETNAME2, "H5Lget_name_by_idx"); - ret = H5Oget_info_by_idx2(gid, ".", H5_INDEX_NAME, H5_ITER_INC, (hsize_t)0, &oinfo, H5O_INFO_BASIC, H5P_DEFAULT); - CHECK(ret, FAIL, "H5Oget_info_by_idx"); - VERIFY(oinfo.type, H5O_TYPE_DATASET, "H5Oget_info_by_idx"); + ret = H5Oget_info_by_idx3(gid, ".", H5_INDEX_NAME, H5_ITER_INC, (hsize_t)0, &oinfo, H5O_INFO_BASIC, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Oget_info_by_idx3"); + VERIFY(oinfo.type, H5O_TYPE_DATASET, "H5Oget_info_by_idx3"); /* Unlink one of the objects in the dereferenced group */ ret = H5Ldelete(gid, GROUPNAME2, H5P_DEFAULT); diff --git a/test/trefer_deprec.c b/test/trefer_deprec.c index 6322894..a830314 100644 --- a/test/trefer_deprec.c +++ b/test/trefer_deprec.c @@ -517,7 +517,7 @@ test_reference_region(H5F_libver_t libver_low, H5F_libver_t libver_high) hsize_t high[SPACE2_RANK]; /* Selection bounds */ hdset_reg_ref_t *wbuf, /* buffer to write to disk */ *rbuf; /* buffer read from disk */ - hdset_reg_ref_t nvrbuf[3]={{{0}},{{101}},{{-128}}}; /* buffer with non-valid refs */ + hdset_reg_ref_t nvrbuf[3]={{{0}},{{101}},{{255}}}; /* buffer with non-valid refs */ uint8_t *dwbuf, /* Buffer for writing numeric data to disk */ *drbuf; /* Buffer for reading numeric data from disk */ uint8_t *tu8; /* Temporary pointer to uint8 data */ @@ -1313,7 +1313,7 @@ test_reference_obj_deleted(void) ** ****************************************************************/ static herr_t -test_deref_iter_op(hid_t H5_ATTR_UNUSED group, const char *name, const H5L_info_t H5_ATTR_UNUSED *info, +test_deref_iter_op(hid_t H5_ATTR_UNUSED group, const char *name, const H5L_info2_t H5_ATTR_UNUSED *info, void *op_data) { int *count = (int *)op_data; /* Pointer to name counter */ @@ -1363,7 +1363,7 @@ test_reference_group(void) hobj_ref_t rref; /* Reference to read */ H5G_info_t ginfo; /* Group info struct */ char objname[NAME_SIZE]; /* Buffer to store name */ - H5O_info_t oinfo; /* Object info struct */ + H5O_info2_t oinfo; /* Object info struct */ int count = 0; /* Count within iterated group */ ssize_t size; /* Name length */ herr_t ret; @@ -1438,7 +1438,7 @@ test_reference_group(void) CHECK(gid, FAIL, "H5Rdereference2"); /* Iterate through objects in dereferenced group */ - ret = H5Literate(gid, H5_INDEX_NAME, H5_ITER_INC, NULL, test_deref_iter_op, &count); + ret = H5Literate2(gid, H5_INDEX_NAME, H5_ITER_INC, NULL, test_deref_iter_op, &count); CHECK(ret, FAIL, "H5Literate"); /* Various queries on the group opened */ @@ -1450,9 +1450,9 @@ test_reference_group(void) CHECK(size, FAIL, "H5Lget_name_by_idx"); VERIFY_STR(objname, DSETNAME2, "H5Lget_name_by_idx"); - ret = H5Oget_info_by_idx2(gid, ".", H5_INDEX_NAME, H5_ITER_INC, (hsize_t)0, &oinfo, H5O_INFO_BASIC, H5P_DEFAULT); - CHECK(ret, FAIL, "H5Oget_info_by_idx"); - VERIFY(oinfo.type, H5O_TYPE_DATASET, "H5Oget_info_by_idx"); + ret = H5Oget_info_by_idx3(gid, ".", H5_INDEX_NAME, H5_ITER_INC, (hsize_t)0, &oinfo, H5O_INFO_BASIC, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Oget_info_by_idx3"); + VERIFY(oinfo.type, H5O_TYPE_DATASET, "H5Oget_info_by_idx3"); /* Unlink one of the objects in the dereferenced group */ ret = H5Ldelete(gid, GROUPNAME2, H5P_DEFAULT); diff --git a/test/tsohm.c b/test/tsohm.c index c126608..f39b5e5 100644 --- a/test/tsohm.c +++ b/test/tsohm.c @@ -743,7 +743,7 @@ size1_helper(hid_t file, const char *filename, hid_t fapl_id, hbool_t test_file_ */ static h5_stat_size_t getsize_testsize1(const char *filename, hid_t fcpl_id, hid_t fapl_id, - hbool_t test_file_closing, H5O_info_t *oinfo) + hbool_t test_file_closing, H5O_native_info_t *ninfo) { hid_t fid = H5I_INVALID_HID; herr_t ret; @@ -758,8 +758,8 @@ getsize_testsize1(const char *filename, hid_t fcpl_id, hid_t fapl_id, fid = size1_helper(fid, filename, fapl_id, test_file_closing); CHECK(fid, H5I_INVALID_HID, "size1_helper"); - ret = H5Oget_info_by_name2(fid, DSETNAME[0], oinfo, H5O_INFO_HDR, H5P_DEFAULT); - CHECK(ret, FAIL, "H5Oget_info_by_name"); + ret = H5Oget_native_info_by_name(fid, DSETNAME[0], ninfo, H5O_NATIVE_INFO_HDR, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Oget_native_info_by_name"); ret = H5Fclose(fid); CHECK(ret, FAIL, "H5Fclose"); @@ -807,7 +807,7 @@ test_sohm_size1(void) h5_stat_size_t sohm_final_filesize2; h5_stat_size_t sohm_btree_final_filesize2; - H5O_info_t oinfo; + H5O_native_info_t ninfo; unsigned num_indexes = 1; unsigned index_flags = H5O_SHMESG_DTYPE_FLAG; unsigned min_mesg_size = 50; @@ -866,10 +866,10 @@ test_sohm_size1(void) /* size of populated file, with different populating behaviors */ test_open_close = TRUE; - file_sizes[size_index++] = getsize_testsize1(FILENAME, fcpl_id, fapl_id, test_open_close, &oinfo); + file_sizes[size_index++] = getsize_testsize1(FILENAME, fcpl_id, fapl_id, test_open_close, &ninfo); test_open_close = FALSE; - file_sizes[size_index++] = getsize_testsize1(FILENAME, fcpl_id, fapl_id, test_open_close, &oinfo); - oh_sizes[oh_size_index++] = oinfo.hdr.space.total; + file_sizes[size_index++] = getsize_testsize1(FILENAME, fcpl_id, fapl_id, test_open_close, &ninfo); + oh_sizes[oh_size_index++] = ninfo.hdr.space.total; ret = H5Pclose(fcpl_id); CHECK_I(ret, "H5Pclose"); @@ -974,7 +974,7 @@ test_sohm_size_consistency_open_create(void) unsigned use_btree; hsize_t oh_size_open; hsize_t oh_size_create; - H5O_info_t oinfo; + H5O_native_info_t oinfo; unsigned num_indexes = 1; unsigned index_flags = H5O_SHMESG_DTYPE_FLAG; unsigned min_mesg_size = 50; @@ -1024,8 +1024,8 @@ test_sohm_size_consistency_open_create(void) CHECK_I(file, "size1_helper"); /* Get the size of a dataset object header */ - ret = H5Oget_info_by_name2(file, DSETNAME[0], &oinfo, H5O_INFO_HDR, H5P_DEFAULT); - CHECK_I(ret, "H5Oget_info_by_name"); + ret = H5Oget_native_info_by_name(file, DSETNAME[0], &oinfo, H5O_NATIVE_INFO_HDR, H5P_DEFAULT); + CHECK_I(ret, "H5Oget_native_info_by_name"); oh_size_open = oinfo.hdr.space.total; ret = H5Fclose(file); @@ -1039,8 +1039,8 @@ test_sohm_size_consistency_open_create(void) CHECK_I(file, "size1_helper"); /* Get the size of a dataset object header */ - ret = H5Oget_info_by_name2(file, DSETNAME[0], &oinfo, H5O_INFO_HDR, H5P_DEFAULT); - CHECK_I(ret, "H5Oget_info_by_name"); + ret = H5Oget_native_info_by_name(file, DSETNAME[0], &oinfo, H5O_NATIVE_INFO_HDR, H5P_DEFAULT); + CHECK_I(ret, "H5Oget_native_info_by_name"); oh_size_create = oinfo.hdr.space.total; ret = H5Fclose(file); diff --git a/test/tvlstr.c b/test/tvlstr.c index 731270c..b93d646 100644 --- a/test/tvlstr.c +++ b/test/tvlstr.c @@ -861,13 +861,12 @@ static void test_write_same_element(void) hid_t file1, dataset1; hid_t mspace, fspace, dtype; hsize_t fdim[] = {SPACE1_DIM1}; - char *val[SPACE1_DIM1] = {"But", "reuniting", "is a", "great joy"}; + const char *wdata[SPACE1_DIM1] = {"Parting", "is such a", "sweet", "sorrow."}; + const char *val[SPACE1_DIM1] = {"But", "reuniting", "is a", "great joy"}; hsize_t marray[] = {NUMP}; hsize_t coord[SPACE1_RANK][NUMP]; herr_t ret; - char *wdata[SPACE1_DIM1] = {"Parting", "is such a", "sweet", "sorrow."}; - file1 = H5Fcreate(DATAFILE3, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); CHECK(file1, FAIL, "H5Fcreate"); diff --git a/test/unlink.c b/test/unlink.c index 5199dcf..48dd79d 100644 --- a/test/unlink.c +++ b/test/unlink.c @@ -433,10 +433,11 @@ test_new_move(hid_t fapl) static int check_new_move(hid_t fapl) { - hid_t file; - H5O_info_t oi_hard1, oi_hard2; - char filename[1024]; - char linkval[1024]; + H5O_info2_t oi_hard1, oi_hard2; + hid_t file; + char filename[1024]; + char linkval[1024]; + int token_cmp; TESTING("check new move function"); @@ -446,15 +447,17 @@ check_new_move(hid_t fapl) FAIL_STACK_ERROR /* Get hard link info */ - if(H5Oget_info_by_name2(file, "/group2/group_new_name", &oi_hard1, H5O_INFO_BASIC, H5P_DEFAULT) < 0) + if(H5Oget_info_by_name3(file, "/group2/group_new_name", &oi_hard1, H5O_INFO_BASIC, H5P_DEFAULT) < 0) FAIL_STACK_ERROR - if(H5Oget_info_by_name2(file, "/group1/hard", &oi_hard2, H5O_INFO_BASIC, H5P_DEFAULT) < 0) + if(H5Oget_info_by_name3(file, "/group1/hard", &oi_hard2, H5O_INFO_BASIC, H5P_DEFAULT) < 0) FAIL_STACK_ERROR /* Check hard links */ if(H5O_TYPE_GROUP != oi_hard1.type || H5O_TYPE_GROUP != oi_hard2.type) FAIL_PUTS_ERROR(" Unexpected object type, should have been a group") - if(H5F_addr_ne(oi_hard1.addr, oi_hard2.addr)) + if(H5Otoken_cmp(file, &oi_hard1.token, &oi_hard2.token, &token_cmp) < 0) + FAIL_PUTS_ERROR(" H5Otoken_cmp failed") + if(token_cmp) FAIL_PUTS_ERROR(" Hard link test failed. Link seems not to point to the expected file location.") /* Check soft links */ @@ -2156,7 +2159,7 @@ test_full_group_compact(hid_t fapl) { hid_t file_id = -1; hid_t gid = -1, gid2 = -1; /* Group IDs */ - H5O_info_t oi; /* Stat buffer for object */ + H5O_info2_t oi; /* Stat buffer for object */ char objname[128]; /* Buffer for name of objects to create */ char objname2[128]; /* Buffer for name of objects to create */ char filename[1024]; /* Buffer for filename */ @@ -2228,7 +2231,7 @@ test_full_group_compact(hid_t fapl) /* Check reference count on objects to keep */ for(u = 0; u < FULL_GROUP_NUM_KEEP; u++) { HDsprintf(objname, "/keep/keep %u\n", u); - if(H5Oget_info_by_name2(file_id, objname, &oi, H5O_INFO_BASIC, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + if(H5Oget_info_by_name3(file_id, objname, &oi, H5O_INFO_BASIC, H5P_DEFAULT) < 0) FAIL_STACK_ERROR if(oi.rc != 2) TEST_ERROR } /* end for */ @@ -2245,7 +2248,7 @@ test_full_group_compact(hid_t fapl) /* Check reference count on objects to keep */ for(u = 0; u < FULL_GROUP_NUM_KEEP; u++) { HDsprintf(objname, "/keep/keep %u\n", u); - if(H5Oget_info_by_name2(file_id, objname, &oi, H5O_INFO_BASIC, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + if(H5Oget_info_by_name3(file_id, objname, &oi, H5O_INFO_BASIC, H5P_DEFAULT) < 0) FAIL_STACK_ERROR if(oi.rc != 1) TEST_ERROR } /* end for */ @@ -2290,7 +2293,7 @@ test_full_group_dense(hid_t fapl) hid_t file_id = -1; hid_t gcpl = (-1); /* Group creation property list ID */ hid_t gid = -1, gid2 = -1; /* Group IDs */ - H5O_info_t oi; /* Stat buffer for object */ + H5O_info2_t oi; /* Stat buffer for object */ char objname[128]; /* Buffer for name of objects to create */ char objname2[128]; /* Buffer for name of objects to create */ char filename[1024]; /* Buffer for filename */ @@ -2374,7 +2377,7 @@ test_full_group_dense(hid_t fapl) /* Check reference count on objects to keep */ for(u = 0; u < FULL_GROUP_NUM_KEEP; u++) { HDsprintf(objname, "/keep/keep %u\n", u); - if(H5Oget_info_by_name2(file_id, objname, &oi, H5O_INFO_BASIC, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + if(H5Oget_info_by_name3(file_id, objname, &oi, H5O_INFO_BASIC, H5P_DEFAULT) < 0) FAIL_STACK_ERROR if(oi.rc != 2) TEST_ERROR } /* end for */ @@ -2391,7 +2394,7 @@ test_full_group_dense(hid_t fapl) /* Check reference count on objects to keep */ for(u = 0; u < FULL_GROUP_NUM_KEEP; u++) { HDsprintf(objname, "/keep/keep %u\n", u); - if(H5Oget_info_by_name2(file_id, objname, &oi, H5O_INFO_BASIC, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + if(H5Oget_info_by_name3(file_id, objname, &oi, H5O_INFO_BASIC, H5P_DEFAULT) < 0) FAIL_STACK_ERROR if(oi.rc != 1) TEST_ERROR } /* end for */ diff --git a/test/vds.c b/test/vds.c index f724e67..f0f3695 100644 --- a/test/vds.c +++ b/test/vds.c @@ -317,7 +317,7 @@ test_api_get_ex_dcpl(test_api_config_t config, hid_t fapl, hid_t dcpl, hid_t dset = -1; /* Virtual dataset */ H5D_space_status_t space_status; /* Dataset space status */ void *plist_buf = NULL; /* Serialized property list buffer */ - H5O_info_t oinfo; /* Object info struct */ + H5O_native_info_t ninfo; /* Object info struct */ htri_t tri_ret; HDassert((config >= TEST_API_BASIC) && (config < TEST_API_NTESTS)); @@ -372,23 +372,23 @@ test_api_get_ex_dcpl(test_api_config_t config, hid_t fapl, hid_t dcpl, TEST_ERROR /* Test H5Oget_info returns correct metadata size */ - if(H5Oget_info2(dset, &oinfo, H5O_INFO_META_SIZE) < 0) + if(H5Oget_native_info(dset, &ninfo, H5O_NATIVE_INFO_META_SIZE) < 0) TEST_ERROR - if(oinfo.meta_size.obj.index_size != (hsize_t)0) + if(ninfo.meta_size.obj.index_size != (hsize_t)0) TEST_ERROR if(config == TEST_API_REOPEN_FILE) { - if(oinfo.meta_size.obj.heap_size != exp_meta_size) { - HDprintf("VDS metadata size: %llu Expected: %llu\n", (long long unsigned)oinfo.meta_size.obj.heap_size, (long long unsigned)exp_meta_size); + if(ninfo.meta_size.obj.heap_size != exp_meta_size) { + HDprintf("VDS metadata size: %llu Expected: %llu\n", (long long unsigned)ninfo.meta_size.obj.heap_size, (long long unsigned)exp_meta_size); TEST_ERROR } } else - if((oinfo.meta_size.obj.heap_size != exp_meta_size) - && (oinfo.meta_size.obj.heap_size != (hsize_t)0)) + if((ninfo.meta_size.obj.heap_size != exp_meta_size) + && (ninfo.meta_size.obj.heap_size != (hsize_t)0)) TEST_ERROR - if(oinfo.meta_size.attr.index_size != (hsize_t)0) + if(ninfo.meta_size.attr.index_size != (hsize_t)0) TEST_ERROR - if(oinfo.meta_size.attr.index_size != (hsize_t)0) + if(ninfo.meta_size.attr.index_size != (hsize_t)0) TEST_ERROR /* Test H5Dget_space_status */ diff --git a/test/vol.c b/test/vol.c index e7020e7..d26499e 100644 --- a/test/vol.c +++ b/test/vol.c @@ -141,6 +141,11 @@ static const H5VL_class_t fake_vol_g = { NULL, /* specific */ NULL /* optional */ }, + { /* token_cls */ + NULL, /* cmp */ + NULL, /* to_str */ + NULL /* from_str */ + }, NULL /* optional */ }; @@ -228,7 +233,7 @@ test_vol_registration(void) TEST_ERROR; /* Try to unregister the native VOL connector (should fail) */ - if (H5I_INVALID_HID == (native_id = H5VLget_connector_id(H5VL_NATIVE_NAME))) + if (H5I_INVALID_HID == (native_id = H5VLget_connector_id_by_name(H5VL_NATIVE_NAME))) TEST_ERROR; H5E_BEGIN_TRY { ret = H5VLunregister_connector(native_id); @@ -870,7 +875,7 @@ test_basic_object_operation(void) hid_t oid = H5I_INVALID_HID; char filename[1024]; - H5O_info_t object_info; + H5O_info2_t object_info; TESTING("Basic VOL object operations"); @@ -884,11 +889,11 @@ test_basic_object_operation(void) TEST_ERROR; /* H5Oget_info */ - if (H5Oget_info2(fid, &object_info, H5O_INFO_ALL) < 0) + if (H5Oget_info3(fid, &object_info, H5O_INFO_ALL) < 0) TEST_ERROR; /* H5Oget_info_by_name */ - if (H5Oget_info_by_name2(fid, NATIVE_VOL_TEST_GROUP_NAME, &object_info, H5O_INFO_ALL, H5P_DEFAULT) < 0) + if (H5Oget_info_by_name3(fid, NATIVE_VOL_TEST_GROUP_NAME, &object_info, H5O_INFO_ALL, H5P_DEFAULT) < 0) TEST_ERROR; /* H5Oexists_by_name */ diff --git a/test/vol_plugin.c b/test/vol_plugin.c index 236a67e..e4f171b 100644 --- a/test/vol_plugin.c +++ b/test/vol_plugin.c @@ -233,7 +233,7 @@ test_getters(void) TEST_ERROR; /* Get the connector's ID */ - if((vol_id_out = H5VLget_connector_id(NULL_VOL_CONNECTOR_NAME)) < 0) + if((vol_id_out = H5VLget_connector_id_by_name(NULL_VOL_CONNECTOR_NAME)) < 0) TEST_ERROR; if(vol_id != vol_id_out) FAIL_PUTS_ERROR("VOL connector IDs don't match"); diff --git a/tools/lib/h5diff.c b/tools/lib/h5diff.c index d7fc991..870c256 100644 --- a/tools/lib/h5diff.c +++ b/tools/lib/h5diff.c @@ -276,7 +276,7 @@ build_match_list (const char *objname1, trav_info_t *info1, const char *objname2 H5TOOLS_DEBUG("build_match_list start - errstat:%d", opts->err_stat); /* init */ - trav_table_init(&table); + trav_table_init(info1->fid, &table); if (table == NULL) { H5TOOLS_INFO("Cannot create traverse table"); H5TOOLS_GOTO_DONE_NO_RET(); @@ -314,10 +314,20 @@ build_match_list (const char *objname1, trav_info_t *info1, const char *objname2 trav_table_addflags(infile, path1_lp, info1->paths[curr1].type, table); /* if the two point to the same target object, * mark that in table */ - if (info1->paths[curr1].fileno == info2->paths[curr2].fileno && - info1->paths[curr1].objno == info2->paths[curr2].objno) { - idx = table->nobjs - 1; - table->objs[idx].is_same_trgobj = 1; + if(info1->paths[curr1].fileno == info2->paths[curr2].fileno) { + int token_cmp; + + if(H5Otoken_cmp(info1->fid, &info1->paths[curr1].obj_token, + &info2->paths[curr2].obj_token, &token_cmp) < 0) { + H5TOOLS_INFO("Failed to compare object tokens"); + opts->err_stat = H5DIFF_ERR; + H5TOOLS_GOTO_DONE_NO_RET(); + } + + if(!token_cmp) { + idx = table->nobjs - 1; + table->objs[idx].is_same_trgobj = 1; + } } } curr1++; @@ -382,7 +392,7 @@ done: * Purpose: Call back function from h5trav_visit(). *------------------------------------------------------------------------*/ static herr_t -trav_grp_objs(const char *path, const H5O_info_t *oinfo, +trav_grp_objs(const char *path, const H5O_info2_t *oinfo, const char *already_visited, void *udata) { trav_info_visit_obj(path, oinfo, already_visited, udata); @@ -397,7 +407,7 @@ trav_grp_objs(const char *path, const H5O_info_t *oinfo, * Track and extra checkings while visiting all symbolic-links. *------------------------------------------------------------------------*/ static herr_t -trav_grp_symlinks(const char *path, const H5L_info_t *linfo, void *udata) +trav_grp_symlinks(const char *path, const H5L_info2_t *linfo, void *udata) { trav_info_t *tinfo = (trav_info_t *)udata; diff_opt_t *opts = (diff_opt_t *)tinfo->opts; @@ -523,7 +533,7 @@ h5diff(const char *fname1, h5trav_type_t obj1type = H5TRAV_TYPE_GROUP; h5trav_type_t obj2type = H5TRAV_TYPE_GROUP; /* for single object */ - H5O_info_t oinfo1, oinfo2; /* object info */ + H5O_info2_t oinfo1, oinfo2; /* object info */ trav_info_t *info1_obj = NULL; trav_info_t *info2_obj = NULL; /* for group object */ @@ -533,8 +543,8 @@ h5diff(const char *fname1, trav_info_t *info1_lp = NULL; trav_info_t *info2_lp = NULL; /* link info from specified object */ - H5L_info_t src_linfo1; - H5L_info_t src_linfo2; + H5L_info2_t src_linfo1; + H5L_info2_t src_linfo2; /* link info from member object */ h5tool_link_info_t trg_linfo1; h5tool_link_info_t trg_linfo2; @@ -635,7 +645,7 @@ h5diff(const char *fname1, H5TOOLS_GOTO_ERROR(H5DIFF_ERR, "Error: Object could not be found"); } /* get info from link */ - if(H5Lget_info(file1_id, obj1fullname, &src_linfo1, H5P_DEFAULT) < 0) { + if(H5Lget_info2(file1_id, obj1fullname, &src_linfo1, H5P_DEFAULT) < 0) { parallel_print("Unable to get link info from <%s>\n", obj1fullname); H5TOOLS_GOTO_ERROR(H5DIFF_ERR, "H5Lget_info failed"); } @@ -651,14 +661,14 @@ h5diff(const char *fname1, /* optional data pass */ info1_obj->opts = (diff_opt_t*)opts; - if(H5Oget_info_by_name2(file1_id, obj1fullname, &oinfo1, H5O_INFO_BASIC, H5P_DEFAULT) < 0) { + if(H5Oget_info_by_name3(file1_id, obj1fullname, &oinfo1, H5O_INFO_BASIC, H5P_DEFAULT) < 0) { parallel_print("Error: Could not get file contents\n"); H5TOOLS_GOTO_ERROR(H5DIFF_ERR, "Error: Could not get file contents"); } obj1type = (h5trav_type_t)oinfo1.type; trav_info_add(info1_obj, obj1fullname, obj1type); idx = info1_obj->nused - 1; - info1_obj->paths[idx].objno = oinfo1.addr; + HDmemcpy(&info1_obj->paths[idx].obj_token, &oinfo1.token, sizeof(H5O_token_t)); info1_obj->paths[idx].fileno = oinfo1.fileno; } else if (src_linfo1.type == H5L_TYPE_SOFT) { @@ -685,7 +695,7 @@ h5diff(const char *fname1, H5TOOLS_GOTO_ERROR(H5DIFF_ERR, "Error: Object could not be found"); } /* get info from link */ - if(H5Lget_info(file2_id, obj2fullname, &src_linfo2, H5P_DEFAULT) < 0) { + if(H5Lget_info2(file2_id, obj2fullname, &src_linfo2, H5P_DEFAULT) < 0) { parallel_print("Unable to get link info from <%s>\n", obj2fullname); H5TOOLS_GOTO_ERROR(H5DIFF_ERR, "H5Lget_info failed"); } @@ -701,14 +711,14 @@ h5diff(const char *fname1, /* optional data pass */ info2_obj->opts = (diff_opt_t*)opts; - if(H5Oget_info_by_name2(file2_id, obj2fullname, &oinfo2, H5O_INFO_BASIC, H5P_DEFAULT) < 0) { + if(H5Oget_info_by_name3(file2_id, obj2fullname, &oinfo2, H5O_INFO_BASIC, H5P_DEFAULT) < 0) { parallel_print("Error: Could not get file contents\n"); H5TOOLS_GOTO_ERROR(H5DIFF_ERR, "Error: Could not get file contents"); } obj2type = (h5trav_type_t)oinfo2.type; trav_info_add(info2_obj, obj2fullname, obj2type); idx = info2_obj->nused - 1; - info2_obj->paths[idx].objno = oinfo2.addr; + HDmemcpy(&info2_obj->paths[idx].obj_token, &oinfo2.token, sizeof(H5O_token_t)); info2_obj->paths[idx].fileno = oinfo2.fileno; } else if (src_linfo2.type == H5L_TYPE_SOFT) { @@ -778,8 +788,8 @@ h5diff(const char *fname1, size_t idx = info1_lp->nused - 1; H5TOOLS_DEBUG("h5diff ... ... ... info1_obj not null"); + HDmemcpy(&info1_lp->paths[idx].obj_token, &trg_linfo1.obj_token, sizeof(H5O_token_t)); info1_lp->paths[idx].type = (h5trav_type_t)trg_linfo1.trg_type; - info1_lp->paths[idx].objno = trg_linfo1.objno; info1_lp->paths[idx].fileno = trg_linfo1.fileno; } H5TOOLS_DEBUG("h5diff check symbolic link (object1) finished"); @@ -818,8 +828,8 @@ h5diff(const char *fname1, size_t idx = info2_lp->nused - 1; H5TOOLS_DEBUG("h5diff ... ... ... info2_obj not null"); + HDmemcpy(&info2_lp->paths[idx].obj_token, &trg_linfo2.obj_token, sizeof(H5O_token_t)); info2_lp->paths[idx].type = (h5trav_type_t)trg_linfo2.trg_type; - info2_lp->paths[idx].objno = trg_linfo2.objno; info2_lp->paths[idx].fileno = trg_linfo2.fileno; } H5TOOLS_DEBUG("h5diff check symbolic link (object1) finished"); diff --git a/tools/lib/h5diff_array.c b/tools/lib/h5diff_array.c index f671b06..8321a98 100644 --- a/tools/lib/h5diff_array.c +++ b/tools/lib/h5diff_array.c @@ -746,8 +746,8 @@ static hsize_t diff_datum( /* if (type_size == H5R_STD_REF_SIZE) */ hid_t region1_id = H5I_INVALID_HID; hid_t region2_id = H5I_INVALID_HID; - H5R_ref_t *ref1_buf = (const H5R_ref_t *)_mem1; - H5R_ref_t *ref2_buf = (const H5R_ref_t *)_mem2; + H5R_ref_t *ref1_buf = (H5R_ref_t *)_mem1; + H5R_ref_t *ref2_buf = (H5R_ref_t *)_mem2; H5O_type_t obj1_type = -1; /* Object type */ H5O_type_t obj2_type = -1; /* Object type */ H5R_type_t ref_type; /* Reference type */ @@ -920,7 +920,7 @@ static hsize_t diff_datum( /* if (obj_id < 0) - could mean that no reference was written do not throw failure */ obj1_id = H5Ropen_object(ref1_buf, H5P_DEFAULT, H5P_DEFAULT); obj2_id = H5Ropen_object(ref2_buf, H5P_DEFAULT, H5P_DEFAULT); - if((obj1_id < 0) || (obj1_id < 0)) { + if((obj1_id < 0) || (obj2_id < 0)) { H5TOOLS_INFO("H5Ropen_object H5R_DATASET_REGION2 failed"); } else { @@ -979,7 +979,7 @@ static hsize_t diff_datum( H5TOOLS_INFO("H5Ropen_attr object 2 failed"); } - if((obj1_id < 0) || (obj1_id < 0)) { + if((obj1_id < 0) || (obj2_id < 0)) { H5TOOLS_INFO("H5Ropen_attr H5R_ATTR failed"); } else { @@ -2394,14 +2394,22 @@ static hsize_t diff_region(hid_t obj1_id, hid_t obj2_id, hid_t region1_id, hid_t /* print differences if found */ if (nfound_b && opts->m_verbose) { - H5O_info_t oi1, oi2; + H5O_info2_t oi1, oi2; + char *obj1_str = NULL, *obj2_str = NULL; - H5Oget_info2(obj1_id, &oi1, H5O_INFO_BASIC); - H5Oget_info2(obj2_id, &oi2, H5O_INFO_BASIC); + H5Oget_info3(obj1_id, &oi1, H5O_INFO_BASIC); + H5Oget_info3(obj2_id, &oi2, H5O_INFO_BASIC); - parallel_print("Referenced dataset %lu %lu\n", (unsigned long) oi1.addr, (unsigned long) oi2.addr); + /* Convert object tokens into printable output */ + H5Otoken_to_str(obj1_id, &oi1.token, &obj1_str); + H5Otoken_to_str(obj2_id, &oi2.token, &obj2_str); + + parallel_print("Referenced dataset %s %s\n", obj1_str, obj2_str); parallel_print( "------------------------------------------------------------\n"); + H5free_memory(obj1_str); + H5free_memory(obj2_str); + parallel_print("Region blocks\n"); for (i = 0; i < nblocks1; i++) { parallel_print("block #%d", i); diff --git a/tools/lib/h5diff_attr.c b/tools/lib/h5diff_attr.c index e92e141..d1b4697 100644 --- a/tools/lib/h5diff_attr.c +++ b/tools/lib/h5diff_attr.c @@ -140,7 +140,7 @@ static void table_attr_mark_exist(unsigned *exist, char *name, table_attrs_t *ta static herr_t build_match_list_attrs(hid_t loc1_id, hid_t loc2_id, table_attrs_t ** table_out, diff_opt_t *opts) { table_attrs_t *table_lp = NULL; - H5O_info_t oinfo1, oinfo2; /* Object info */ + H5O_info2_t oinfo1, oinfo2; /* Object info */ hid_t attr1_id = H5I_INVALID_HID; /* attr ID */ hid_t attr2_id = H5I_INVALID_HID; /* attr ID */ size_t curr1 = 0; @@ -155,14 +155,14 @@ static herr_t build_match_list_attrs(hid_t loc1_id, hid_t loc2_id, table_attrs_t H5TOOLS_DEBUG("build_match_list_attrs start - errstat:%d", opts->err_stat); - if(H5Oget_info2(loc1_id, &oinfo1, H5O_INFO_NUM_ATTRS) < 0) { + if(H5Oget_info3(loc1_id, &oinfo1, H5O_INFO_NUM_ATTRS) < 0) { H5TOOLS_GOTO_ERROR(FAIL, "H5Oget_info first object failed"); } - H5TOOLS_DEBUG("H5Oget_info2 loc1id=%d", oinfo1.num_attrs); - if(H5Oget_info2(loc2_id, &oinfo2, H5O_INFO_NUM_ATTRS) < 0) { + H5TOOLS_DEBUG("H5Oget_info3 loc1id=%d", oinfo1.num_attrs); + if(H5Oget_info3(loc2_id, &oinfo2, H5O_INFO_NUM_ATTRS) < 0) { H5TOOLS_GOTO_ERROR(FAIL, "H5Oget_info second object failed"); } - H5TOOLS_DEBUG("H5Oget_info2 loc2id=%d", oinfo2.num_attrs); + H5TOOLS_DEBUG("H5Oget_info3 loc2id=%d", oinfo2.num_attrs); table_attrs_init(&table_lp); if (table_lp == NULL) @@ -336,7 +336,6 @@ hsize_t diff_attr_data(hid_t attr1_id, hid_t attr2_id, const char *name1, const hsize_t dims2[H5S_MAX_RANK]; /* dimensions of dataset */ char np1[512]; char np2[512]; - unsigned u; /* Local index variable */ hsize_t nfound = 0; int j; diff_err_t ret_value = opts->err_stat; diff --git a/tools/lib/h5tools.c b/tools/lib/h5tools.c index 7aa2419..cb9b92c 100644 --- a/tools/lib/h5tools.c +++ b/tools/lib/h5tools.c @@ -1480,8 +1480,6 @@ render_bin_output(FILE *stream, hid_t container, hid_t tid, void *_mem, hsize_t break; } /* end switch */ -done: - CATCH H5TOOLS_ENDDEBUG("exit"); return ret_value; @@ -1806,21 +1804,27 @@ hbool_t h5tools_is_obj_same(hid_t loc_id1, const char *name1, hid_t loc_id2, const char *name2) { - H5O_info_t oinfo1, oinfo2; + H5O_info2_t oinfo1, oinfo2; hbool_t ret_val = FALSE; if ( name1 && HDstrcmp(name1, ".")) - H5Oget_info_by_name2(loc_id1, name1, &oinfo1, H5O_INFO_BASIC, H5P_DEFAULT); + H5Oget_info_by_name3(loc_id1, name1, &oinfo1, H5O_INFO_BASIC, H5P_DEFAULT); else - H5Oget_info2(loc_id1, &oinfo1, H5O_INFO_BASIC); + H5Oget_info3(loc_id1, &oinfo1, H5O_INFO_BASIC); if ( name2 && HDstrcmp(name2, ".")) - H5Oget_info_by_name2(loc_id2, name2, &oinfo2, H5O_INFO_BASIC, H5P_DEFAULT); + H5Oget_info_by_name3(loc_id2, name2, &oinfo2, H5O_INFO_BASIC, H5P_DEFAULT); else - H5Oget_info2(loc_id2, &oinfo2, H5O_INFO_BASIC); + H5Oget_info3(loc_id2, &oinfo2, H5O_INFO_BASIC); + + if (oinfo1.fileno == oinfo2.fileno) { + int token_cmp_val; - if (oinfo1.fileno == oinfo2.fileno && oinfo1.addr==oinfo2.addr) - ret_val = TRUE; + H5Otoken_cmp(loc_id1, &oinfo1.token, &oinfo2.token, &token_cmp_val); + + if(!token_cmp_val) + ret_val = TRUE; + } return ret_val; } diff --git a/tools/lib/h5tools_dump.c b/tools/lib/h5tools_dump.c index 3af2bd8..79802c3 100644 --- a/tools/lib/h5tools_dump.c +++ b/tools/lib/h5tools_dump.c @@ -2088,15 +2088,20 @@ h5tools_print_datatype(FILE *stream, h5tools_str_t *buffer, const h5tool_format_ if((type_class = H5Tget_class(type)) < 0) H5TOOLS_THROW((-1), "H5Tget_class failed"); if (object_search && H5Tcommitted(type) > 0) { - H5O_info_t oinfo; - obj_t *obj = NULL; /* Found object */ + H5O_info2_t oinfo; + obj_t *obj = NULL; /* Found object */ - H5Oget_info2(type, &oinfo, H5O_INFO_BASIC); - obj = search_obj(h5dump_type_table, oinfo.addr); + H5Oget_info3(type, &oinfo, H5O_INFO_BASIC); + obj = search_obj(h5dump_type_table, &oinfo.token); if(obj) { - if(!obj->recorded) - h5tools_str_append(buffer,"\"/#"H5_PRINTF_HADDR_FMT"\"", obj->objno); + if(!obj->recorded) { + char *obj_addr_str = NULL; + + H5Otoken_to_str(type, &oinfo.token, &obj_addr_str); + h5tools_str_append(buffer,"\"/#%s\"", obj_addr_str); + H5free_memory(obj_addr_str); + } else h5tools_str_append(buffer, "\"%s\"", obj->objname); } @@ -2629,8 +2634,6 @@ h5tools_print_datatype(FILE *stream, h5tools_str_t *buffer, const h5tool_format_ break; } -done: - CATCH H5TOOLS_ENDDEBUG("exit"); return ret_value; @@ -4052,7 +4055,7 @@ h5tools_dump_data(FILE *stream, const h5tool_format_t *info, h5tools_context_t * init_acc_pos(&datactx, total_size); datactx.need_prefix = TRUE; - if (NULL != (ref_buf = (H5R_ref_t *)HDcalloc(MAX(sizeof(unsigned), sizeof(H5R_ref_t)), ndims))) { + if (NULL != (ref_buf = (H5R_ref_t *)HDcalloc(MAX(sizeof(unsigned), sizeof(H5R_ref_t)), (size_t)ndims))) { if(obj_data) { if(H5Dread(obj_id, H5T_STD_REF, H5S_ALL, H5S_ALL, H5P_DEFAULT, ref_buf) < 0) { HDfree(ref_buf); @@ -4067,7 +4070,7 @@ h5tools_dump_data(FILE *stream, const h5tool_format_t *info, h5tools_context_t * H5TOOLS_GOTO_DONE_NO_RET(); } } - for(i = 0; i < ndims; i++, datactx.cur_elmt++, elmt_counter++) { + for(i = 0; i < (size_t)ndims; i++, datactx.cur_elmt++, elmt_counter++) { H5O_type_t obj_type = -1; /* Object type */ H5R_type_t ref_type; /* Reference type */ diff --git a/tools/lib/h5tools_ref.c b/tools/lib/h5tools_ref.c index e98a8e2..0e1fa03 100644 --- a/tools/lib/h5tools_ref.c +++ b/tools/lib/h5tools_ref.c @@ -17,6 +17,7 @@ #include "h5tools.h" #include "h5tools_utils.h" #include "h5trav.h" +#include "H5VLnative_private.h" /* @@ -34,14 +35,14 @@ */ typedef struct { - haddr_t objno; /* Object ID (i.e. address) */ - char *path; /* Object path */ + H5O_token_t obj_token; /* Object token */ + char *path; /* Object path */ } ref_path_node_t; static H5SL_t *ref_path_table = NULL; /* the "table" (implemented with a skip list) */ static hid_t thefile = (-1); -static int ref_path_table_put(const char *, haddr_t objno); +static int ref_path_table_put(const char *, const H5O_token_t *token); /*------------------------------------------------------------------------- * Function: free_ref_path_info @@ -80,19 +81,47 @@ free_ref_path_info(void *item, void H5_ATTR_UNUSED *key, void H5_ATTR_UNUSED *op *------------------------------------------------------------------------- */ static herr_t -init_ref_path_cb(const char *obj_name, const H5O_info_t *oinfo, +init_ref_path_cb(const char *obj_name, const H5O_info2_t *oinfo, const char *already_seen, void H5_ATTR_UNUSED *_udata) { /* Check if the object is already in the path table */ if(NULL == already_seen) { /* Insert the object into the path table */ - ref_path_table_put(obj_name, oinfo->addr); + ref_path_table_put(obj_name, &oinfo->token); } /* end if */ return 0; } /*------------------------------------------------------------------------- + * Function: ref_path_table_cmp + * + * Purpose: Skip list key comparison function which compares two + * H5O_token_t objects. + * + * Return: Negative (if token2 is greater than token1) + * 0 (if tokens are equal) + * or + * Positive (if token1 is greater than token2) + * + *------------------------------------------------------------------------- + */ +static int +ref_path_table_cmp(const void *key1, const void *key2) +{ + const H5O_token_t *token1 = (const H5O_token_t *)key1; + const H5O_token_t *token2 = (const H5O_token_t *)key2; + int cmp_value = 0; + + if(thefile > 0) + H5Otoken_cmp(thefile, token1, token2, &cmp_value); + else + cmp_value = HDmemcmp(token1, token2, sizeof(H5O_token_t)); + + return cmp_value; +} + +/*------------------------------------------------------------------------- * Function: init_ref_path_table * * Purpose: Initalize the reference path table @@ -109,7 +138,7 @@ init_ref_path_table(void) /* Sanity check */ if(thefile > 0) { /* Create skip list to store reference path information */ - if((ref_path_table = H5SL_create(H5SL_TYPE_HADDR, NULL))==NULL) + if((ref_path_table = H5SL_create(H5SL_TYPE_GENERIC, ref_path_table_cmp)) == NULL) return (-1); /* Iterate over objects in this file */ @@ -153,8 +182,10 @@ term_ref_path_table(void) * Purpose: Looks up a table entry given a path name. * Used during construction of the table. * - * Return: The table entre (pte) or NULL if not in the - * table. + * Return: Negative on failure, Non-negative on success. The object + * token for the table entry is returned through the token + * parameter if the table entry is found by the given path + * name. * * Programmer: REMcG * @@ -162,33 +193,35 @@ term_ref_path_table(void) * *------------------------------------------------------------------------- */ -haddr_t -ref_path_table_lookup(const char *thepath) +int +ref_path_table_lookup(const char *thepath, H5O_token_t *token) { - H5O_info_t oi; + H5O_info2_t oi; if((thepath == NULL) || (HDstrlen(thepath) == 0)) - return HADDR_UNDEF; + return -1; /* Allow lookups on the root group, even though it doesn't have any link info */ if(HDstrcmp(thepath, "/")) { - H5L_info_t li; + H5L_info2_t li; /* Check for external link first, so we don't return the OID of an object in another file */ - if(H5Lget_info(thefile, thepath, &li, H5P_DEFAULT) < 0) - return HADDR_UNDEF; + if(H5Lget_info2(thefile, thepath, &li, H5P_DEFAULT) < 0) + return -1; /* UD links can't be followed, so they always "dangle" like soft links. */ if(li.type >= H5L_TYPE_UD_MIN) - return HADDR_UNDEF; + return -1; } /* end if */ /* Get the object info now */ /* (returns failure for dangling soft links) */ - if(H5Oget_info_by_name2(thefile, thepath, &oi, H5O_INFO_BASIC, H5P_DEFAULT) < 0) - return HADDR_UNDEF; + if(H5Oget_info_by_name3(thefile, thepath, &oi, H5O_INFO_BASIC, H5P_DEFAULT) < 0) + return -1; - /* Return OID */ - return(oi.addr); + /* Return object token through parameter */ + HDmemcpy(token, &oi.token, sizeof(H5O_token_t)); + + return 0; } /*------------------------------------------------------------------------- @@ -211,7 +244,7 @@ ref_path_table_lookup(const char *thepath) *------------------------------------------------------------------------- */ static int -ref_path_table_put(const char *path, haddr_t objno) +ref_path_table_put(const char *path, const H5O_token_t *token) { ref_path_node_t *new_node; @@ -219,10 +252,10 @@ ref_path_table_put(const char *path, haddr_t objno) if((new_node = (ref_path_node_t *)HDmalloc(sizeof(ref_path_node_t))) == NULL) return(-1); - new_node->objno = objno; + HDmemcpy(&new_node->obj_token, token, sizeof(H5O_token_t)); new_node->path = HDstrdup(path); - return(H5SL_insert(ref_path_table, new_node, &(new_node->objno))); + return(H5SL_insert(ref_path_table, new_node, &(new_node->obj_token))); } else return (-1); @@ -239,46 +272,50 @@ int get_next_xid(void) { /* * This counter is used to create fake object ID's - * The idea is to set it to the largest possible offest, which + * The idea is to set it to the largest possible offset, which * minimizes the chance of collision with a real object id. * */ haddr_t fake_xid = HADDR_MAX; -haddr_t -get_fake_xid (void) { - return (fake_xid--); + +void +get_fake_token(H5O_token_t *token) { + if(thefile > 0) { + /* TODO: potential for this to be called with non-native connector objects */ + if(H5VLnative_addr_to_token(thefile, fake_xid, token) < 0) + *token = H5O_TOKEN_UNDEF; + fake_xid--; + } + else + *token = H5O_TOKEN_UNDEF; } /* - * for an object that does not have an object id (e.g., soft link), - * create a table entry with a fake object id as the key. + * for an object that does not have an object token (e.g., soft link), + * create a table entry with a fake object token as the key. * * Assumes 'path' is for an object that is not in the table. * */ -haddr_t -ref_path_table_gen_fake(const char *path) +void +ref_path_table_gen_fake(const char *path, H5O_token_t *token) { - haddr_t fake_objno; - - /* Generate fake ID for string */ - fake_objno = get_fake_xid(); + /* Generate fake object token for string */ + get_fake_token(token); /* Create ref path table, if it hasn't already been created */ if(ref_path_table == NULL) init_ref_path_table(); /* Insert "fake" object into table */ - ref_path_table_put(path, fake_objno); - - return(fake_objno); + ref_path_table_put(path, token); } /*------------------------------------------------------------------------- * Function: lookup_ref_path * - * Purpose: Lookup the path to the object with refernce 'ref'. + * Purpose: Lookup the path to the object with the reference 'refbuf'. * * Return: Return a path to the object, or NULL if not found. * @@ -289,19 +326,48 @@ ref_path_table_gen_fake(const char *path) *------------------------------------------------------------------------- */ const char * -lookup_ref_path(haddr_t ref) +lookup_ref_path(H5R_ref_t refbuf) { + H5O_info2_t oinfo; + H5R_type_t ref_type; + hid_t ref_object; ref_path_node_t *node; /* Be safer for h5ls */ if(thefile < 0) return(NULL); + /* Retrieve reference type */ + if(H5R_BADTYPE == (ref_type = H5Rget_type(&refbuf))) + return(NULL); + + /* Open the referenced object */ + switch (ref_type) { + case H5R_OBJECT1: + case H5R_OBJECT2: + if((ref_object = H5Ropen_object(&refbuf, H5P_DEFAULT, H5P_DEFAULT)) < 0) + return(NULL); + break; + + /* Invalid referenced object type */ + case H5R_DATASET_REGION1: + case H5R_DATASET_REGION2: + case H5R_ATTR: + case H5R_MAXTYPE: + case H5R_BADTYPE: + default: + return(NULL); + } + + /* Retrieve info about the referenced object */ + if(H5Oget_info3(ref_object, &oinfo, H5O_INFO_ALL) < 0) + return(NULL); + /* Create ref path table, if it hasn't already been created */ if(ref_path_table == NULL) init_ref_path_table(); - node = (ref_path_node_t *)H5SL_search(ref_path_table, &ref); + node = (ref_path_node_t *)H5SL_search(ref_path_table, &oinfo.token); return(node ? node->path : NULL); } diff --git a/tools/lib/h5tools_ref.h b/tools/lib/h5tools_ref.h index b7bd9a3..debbea1 100644 --- a/tools/lib/h5tools_ref.h +++ b/tools/lib/h5tools_ref.h @@ -21,11 +21,11 @@ extern "C" { #endif H5TOOLS_DLL herr_t fill_ref_path_table(hid_t fid); -H5TOOLS_DLL const char *lookup_ref_path(haddr_t ref); +H5TOOLS_DLL const char *lookup_ref_path(H5R_ref_t refbuf); H5TOOLS_DLL int get_next_xid(void); -H5TOOLS_DLL haddr_t get_fake_xid(void); -H5TOOLS_DLL haddr_t ref_path_table_lookup(const char *); -H5TOOLS_DLL haddr_t ref_path_table_gen_fake(const char *); +H5TOOLS_DLL void get_fake_token(H5O_token_t *token); +H5TOOLS_DLL int ref_path_table_lookup(const char *thepath, H5O_token_t *token); +H5TOOLS_DLL void ref_path_table_gen_fake(const char *path, H5O_token_t *token); H5TOOLS_DLL int term_ref_path_table(void); #ifdef __cplusplus diff --git a/tools/lib/h5tools_str.c b/tools/lib/h5tools_str.c index 0aa5152..c9e7e94 100644 --- a/tools/lib/h5tools_str.c +++ b/tools/lib/h5tools_str.c @@ -1091,7 +1091,7 @@ h5tools_str_sprint(h5tools_str_t *str, const h5tool_format_t *info, hid_t contai if (H5Tequal(type, H5T_STD_REF)) { H5O_type_t obj_type = -1; /* Object type */ H5R_type_t ref_type; /* Reference type */ - const H5R_ref_t *ref_vp = (const H5R_ref_t *)vp; + H5R_ref_t *ref_vp = (H5R_ref_t *)vp; H5TOOLS_DEBUG("H5T_REFERENCE:H5T_STD_REF"); ref_type = H5Rget_type(ref_vp); @@ -1100,13 +1100,13 @@ h5tools_str_sprint(h5tools_str_t *str, const h5tool_format_t *info, hid_t contai case H5R_OBJECT1: { /* Object references -- show the type and OID of the referenced object. */ - H5O_info_t oi; + H5O_info2_t oi; + char *obj_addr_str = NULL; H5TOOLS_DEBUG("ref_type is H5R_OBJECT1"); if((obj = H5Ropen_object(ref_vp, H5P_DEFAULT, H5P_DEFAULT)) >= 0) { - H5Oget_info2(obj, &oi, H5O_INFO_BASIC); - if(H5Oclose(obj) < 0) - H5TOOLS_ERROR(NULL, "H5Oclose H5R_OBJECT1 failed"); + H5Oget_info3(obj, &oi, H5O_INFO_BASIC); + H5Otoken_to_str(obj, &oi.token, &obj_addr_str); } else H5TOOLS_ERROR(NULL, "H5Ropen_object H5R_OBJECT1 failed"); @@ -1132,20 +1132,30 @@ h5tools_str_sprint(h5tools_str_t *str, const h5tool_format_t *info, hid_t contai h5tools_str_append(str, "%u-%s", (unsigned) oi.type, H5_TOOLS_UNKNOWN); break; } /* end switch */ - H5Oclose(obj); - h5tools_str_sprint_reference(str, info, container, ref_vp); + + h5tools_str_sprint_reference(str, ref_vp); /* Print OID */ if(info->obj_hidefileno) - h5tools_str_append(str, info->obj_format, oi.addr); + h5tools_str_append(str, info->obj_format, obj_addr_str); else - h5tools_str_append(str, info->obj_format, oi.fileno, oi.addr); + h5tools_str_append(str, info->obj_format, oi.fileno, obj_addr_str); + + if(obj_addr_str) { + H5free_memory(obj_addr_str); + obj_addr_str = NULL; } + + if(obj >= 0) + if(H5Oclose(obj) < 0) + H5TOOLS_ERROR(NULL, "H5Oclose H5R_OBJECT1 failed"); + } + break; case H5R_DATASET_REGION1: H5TOOLS_DEBUG("ref_type is H5R_DATASET_REGION1"); h5tools_str_append(str, H5_TOOLS_DATASET); - h5tools_str_sprint_reference(str, info, container, ref_vp); + h5tools_str_sprint_reference(str, ref_vp); break; case H5R_OBJECT2: H5TOOLS_DEBUG("ref_type is H5R_OBJECT2"); @@ -1169,17 +1179,17 @@ h5tools_str_sprint(h5tools_str_t *str, const h5tool_format_t *info, hid_t contai h5tools_str_append(str, H5_TOOLS_UNKNOWN); break; } /* end switch */ - h5tools_str_sprint_reference(str, info, container, ref_vp); + h5tools_str_sprint_reference(str, ref_vp); break; case H5R_DATASET_REGION2: H5TOOLS_DEBUG("ref_type is H5R_DATASET_REGION2"); h5tools_str_append(str, H5_TOOLS_DATASET); - h5tools_str_sprint_reference(str, info, container, ref_vp); + h5tools_str_sprint_reference(str, ref_vp); break; case H5R_ATTR: H5TOOLS_DEBUG("ref_type is H5R_ATTR"); h5tools_str_append(str, H5_TOOLS_ATTRIBUTE); - h5tools_str_sprint_reference(str, info, container, ref_vp); + h5tools_str_sprint_reference(str, ref_vp); break; case H5R_BADTYPE: case H5R_MAXTYPE: @@ -1334,7 +1344,6 @@ h5tools_str_sprint(h5tools_str_t *str, const h5tool_format_t *info, hid_t contai } /* end switch */ } -done: ret_value = h5tools_str_fmt(str, start, OPT(info->elmt_fmt, "%s")); H5TOOLS_ENDDEBUG("exit with %s", ret_value); @@ -1351,8 +1360,7 @@ done: *------------------------------------------------------------------------- */ void -h5tools_str_sprint_reference(h5tools_str_t *str, const h5tool_format_t *info, - hid_t container, H5R_ref_t *ref_vp) +h5tools_str_sprint_reference(h5tools_str_t *str, H5R_ref_t *ref_vp) { ssize_t buf_size; @@ -1363,7 +1371,7 @@ h5tools_str_sprint_reference(h5tools_str_t *str, const h5tool_format_t *info, H5TOOLS_DEBUG("buf_size=%ld", buf_size); if (buf_size) { char *file_name = (char *)HDmalloc(sizeof(char) * (size_t)buf_size + 1); - if (H5Rget_file_name(ref_vp, file_name, buf_size + 1) >= 0) { + if (H5Rget_file_name(ref_vp, file_name, (size_t)buf_size + 1) >= 0) { file_name[buf_size] = '\0'; H5TOOLS_DEBUG("name=%s", file_name); h5tools_str_append(str, "%s", file_name); @@ -1375,7 +1383,7 @@ h5tools_str_sprint_reference(h5tools_str_t *str, const h5tool_format_t *info, H5TOOLS_DEBUG("buf_size=%ld", buf_size); if (buf_size) { char *obj_name = (char *)HDmalloc(sizeof(char) * (size_t)buf_size + 1); - if (H5Rget_obj_name(ref_vp, H5P_DEFAULT, obj_name, buf_size + 1) >= 0) { + if (H5Rget_obj_name(ref_vp, H5P_DEFAULT, obj_name, (size_t)buf_size + 1) >= 0) { obj_name[buf_size] = '\0'; H5TOOLS_DEBUG("name=%s", obj_name); h5tools_str_append(str, "%s", obj_name); @@ -1388,7 +1396,7 @@ h5tools_str_sprint_reference(h5tools_str_t *str, const h5tool_format_t *info, H5TOOLS_DEBUG("buf_size=%ld", buf_size); if (buf_size) { char *attr_name = (char *)HDmalloc(sizeof(char) * (size_t)buf_size + 1); - if (H5Rget_attr_name(ref_vp, attr_name, buf_size + 1) >= 0) { + if (H5Rget_attr_name(ref_vp, attr_name, (size_t)buf_size + 1) >= 0) { attr_name[buf_size] = '\0'; H5TOOLS_DEBUG("name=%s", attr_name); h5tools_str_append(str, "/%s", attr_name); diff --git a/tools/lib/h5tools_str.h b/tools/lib/h5tools_str.h index 6fdf36a..02bfe40 100644 --- a/tools/lib/h5tools_str.h +++ b/tools/lib/h5tools_str.h @@ -41,7 +41,7 @@ H5TOOLS_DLL char *h5tools_str_region_prefix(h5tools_str_t *str, const h5tool_ H5TOOLS_DLL void h5tools_str_dump_space_slabs(h5tools_str_t *, hid_t, const h5tool_format_t *, h5tools_context_t *ctx); H5TOOLS_DLL void h5tools_str_dump_space_blocks(h5tools_str_t *, hid_t, const h5tool_format_t *); H5TOOLS_DLL void h5tools_str_dump_space_points(h5tools_str_t *, hid_t, const h5tool_format_t *); -H5TOOLS_DLL void h5tools_str_sprint_reference(h5tools_str_t *str, const h5tool_format_t *info, hid_t container, H5R_ref_t *vp); +H5TOOLS_DLL void h5tools_str_sprint_reference(h5tools_str_t *str, H5R_ref_t *vp); H5TOOLS_DLL char *h5tools_str_sprint(h5tools_str_t *str, const h5tool_format_t *info, hid_t container, hid_t type, void *vp, h5tools_context_t *ctx); diff --git a/tools/lib/h5tools_utils.c b/tools/lib/h5tools_utils.c index 323c9b3..45e436c 100644 --- a/tools/lib/h5tools_utils.c +++ b/tools/lib/h5tools_utils.c @@ -53,11 +53,11 @@ unsigned outBuffOffset; FILE* overflow_file = NULL; /* local functions */ -static void init_table(table_t **tbl); +static void init_table(hid_t fid, table_t **tbl); #ifdef H5DUMP_DEBUG -static void dump_table(char* tablename, table_t *table); +static void dump_table(hid_t fid, char* tablename, table_t *table); #endif /* H5DUMP_DEBUG */ -static void add_obj(table_t *table, haddr_t objno, const char *objname, hbool_t recorded); +static void add_obj(table_t *table, const H5O_token_t *obj_token, const char *objname, hbool_t recorded); /*------------------------------------------------------------------------- * Function: parallel_print @@ -599,10 +599,11 @@ print_version(const char *progname) *------------------------------------------------------------------------- */ static void -init_table(table_t **tbl) +init_table(hid_t fid, table_t **tbl) { table_t *table = (table_t *)HDmalloc(sizeof(table_t)); + table->fid = fid; table->size = 20; table->nobjs = 0; table->objs = (obj_t *)HDmalloc(table->size * sizeof(obj_t)); @@ -644,15 +645,21 @@ free_table(table_t *table) *------------------------------------------------------------------------- */ static void -dump_table(char* tablename, table_t *table) +dump_table(hid_t fid, char* tablename, table_t *table) { unsigned u; + char *obj_addr_str = NULL; PRINTSTREAM(rawoutstream,"%s: # of entries = %d\n", tablename,table->nobjs); - for (u = 0; u < table->nobjs; u++) - PRINTSTREAM(rawoutstream,"%a %s %d %d\n", table->objs[u].objno, + for (u = 0; u < table->nobjs; u++) { + H5VLconnector_token_to_str(fid, table->objs[u].obj_token, &obj_addr_str); + + PRINTSTREAM(rawoutstream,"%s %s %d %d\n", obj_addr_str, table->objs[u].objname, table->objs[u].displayed, table->objs[u].recorded); + + H5VLfree_token_str(fid, obj_addr_str); + } } @@ -667,9 +674,9 @@ dump_table(char* tablename, table_t *table) void dump_tables(find_objs_t *info) { - dump_table("group_table", info->group_table); - dump_table("dset_table", info->dset_table); - dump_table("type_table", info->type_table); + dump_table(info->fid, "group_table", info->group_table); + dump_table(info->fid, "dset_table", info->dset_table); + dump_table(info->fid, "type_table", info->type_table); } #endif /* H5DUMP_DEBUG */ @@ -685,13 +692,17 @@ dump_tables(find_objs_t *info) *------------------------------------------------------------------------- */ H5_ATTR_PURE obj_t * -search_obj(table_t *table, haddr_t objno) +search_obj(table_t *table, const H5O_token_t *obj_token) { unsigned u; + int token_cmp; - for(u = 0; u < table->nobjs; u++) - if(table->objs[u].objno == objno) + for(u = 0; u < table->nobjs; u++) { + if(H5Otoken_cmp(table->fid, &table->objs[u].obj_token, obj_token, &token_cmp) < 0) + return NULL; + if(!token_cmp) return &(table->objs[u]); + } return NULL; } @@ -708,7 +719,7 @@ search_obj(table_t *table, haddr_t objno) *------------------------------------------------------------------------- */ static herr_t -find_objs_cb(const char *name, const H5O_info_t *oinfo, const char *already_seen, void *op_data) +find_objs_cb(const char *name, const H5O_info2_t *oinfo, const char *already_seen, void *op_data) { find_objs_t *info = (find_objs_t*)op_data; herr_t ret_value = 0; @@ -716,7 +727,7 @@ find_objs_cb(const char *name, const H5O_info_t *oinfo, const char *already_seen switch(oinfo->type) { case H5O_TYPE_GROUP: if(NULL == already_seen) - add_obj(info->group_table, oinfo->addr, name, TRUE); + add_obj(info->group_table, &oinfo->token, name, TRUE); break; case H5O_TYPE_DATASET: @@ -724,18 +735,18 @@ find_objs_cb(const char *name, const H5O_info_t *oinfo, const char *already_seen hid_t dset = H5I_INVALID_HID; /* Add the dataset to the list of objects */ - add_obj(info->dset_table, oinfo->addr, name, TRUE); + add_obj(info->dset_table, &oinfo->token, name, TRUE); /* Check for a dataset that uses a named datatype */ if((dset = H5Dopen2(info->fid, name, H5P_DEFAULT)) >= 0) { hid_t type = H5Dget_type(dset); if(H5Tcommitted(type) > 0) { - H5O_info_t type_oinfo; + H5O_info2_t type_oinfo; - H5Oget_info2(type, &type_oinfo, H5O_INFO_BASIC); - if(search_obj(info->type_table, type_oinfo.addr) == NULL) - add_obj(info->type_table, type_oinfo.addr, name, FALSE); + H5Oget_info3(type, &type_oinfo, H5O_INFO_BASIC); + if(search_obj(info->type_table, &type_oinfo.token) == NULL) + add_obj(info->type_table, &type_oinfo.token, name, FALSE); } /* end if */ H5Tclose(type); @@ -750,8 +761,8 @@ find_objs_cb(const char *name, const H5O_info_t *oinfo, const char *already_seen if(NULL == already_seen) { obj_t *found_obj; - if((found_obj = search_obj(info->type_table, oinfo->addr)) == NULL) - add_obj(info->type_table, oinfo->addr, name, TRUE); + if((found_obj = search_obj(info->type_table, &oinfo->token)) == NULL) + add_obj(info->type_table, &oinfo->token, name, TRUE); else { /* Use latest version of name */ HDfree(found_obj->objname); @@ -791,9 +802,9 @@ init_objs(hid_t fid, find_objs_t *info, table_t **group_table, herr_t ret_value = SUCCEED; /* Initialize the tables */ - init_table(group_table); - init_table(dset_table); - init_table(type_table); + init_table(fid, group_table); + init_table(fid, dset_table); + init_table(fid, type_table); /* Init the find_objs_t */ info->fid = fid; @@ -829,7 +840,7 @@ done: *------------------------------------------------------------------------- */ static void -add_obj(table_t *table, haddr_t objno, const char *objname, hbool_t record) +add_obj(table_t *table, const H5O_token_t *obj_token, const char *objname, hbool_t record) { size_t u; @@ -843,7 +854,7 @@ add_obj(table_t *table, haddr_t objno, const char *objname, hbool_t record) u = table->nobjs++; /* Set information about object */ - table->objs[u].objno = objno; + HDmemcpy(&table->objs[u].obj_token, obj_token, sizeof(H5O_token_t)); table->objs[u].objname = HDstrdup(objname); table->objs[u].recorded = record; table->objs[u].displayed = 0; @@ -893,7 +904,7 @@ int H5tools_get_symlink_info(hid_t file_id, const char * linkpath, h5tool_link_info_t *link_info, hbool_t get_obj_type) { htri_t l_ret; - H5O_info_t trg_oinfo; + H5O_info2_t trg_oinfo; hid_t fapl = H5P_DEFAULT; hid_t lapl = H5P_DEFAULT; int ret_value = -1; /* init to fail */ @@ -915,7 +926,7 @@ H5tools_get_symlink_info(hid_t file_id, const char * linkpath, h5tool_link_info_ } /* end if */ /* get info from link */ - if(H5Lget_info(file_id, linkpath, &(link_info->linfo), H5P_DEFAULT) < 0) { + if(H5Lget_info2(file_id, linkpath, &(link_info->linfo), H5P_DEFAULT) < 0) { if(link_info->opt.msg_mode == 1) parallel_print("Warning: unable to get link info from <%s>\n",linkpath); H5TOOLS_GOTO_DONE(FAIL); @@ -971,7 +982,7 @@ H5tools_get_symlink_info(hid_t file_id, const char * linkpath, h5tool_link_info_ } /* get target object info */ - if(H5Oget_info_by_name2(file_id, linkpath, &trg_oinfo, H5O_INFO_BASIC, lapl) < 0) { + if(H5Oget_info_by_name3(file_id, linkpath, &trg_oinfo, H5O_INFO_BASIC, lapl) < 0) { if(link_info->opt.msg_mode == 1) parallel_print("Warning: unable to get object information for <%s>\n", linkpath); H5TOOLS_GOTO_DONE(FAIL); @@ -985,8 +996,8 @@ H5tools_get_symlink_info(hid_t file_id, const char * linkpath, h5tool_link_info_ } /* end if */ /* set target obj type to return */ + HDmemcpy(&link_info->obj_token, &trg_oinfo.token, sizeof(H5O_token_t)); link_info->trg_type = trg_oinfo.type; - link_info->objno = trg_oinfo.addr; link_info->fileno = trg_oinfo.fileno; } /* end if */ else diff --git a/tools/lib/h5tools_utils.h b/tools/lib/h5tools_utils.h index 17c16bf..366800a 100644 --- a/tools/lib/h5tools_utils.h +++ b/tools/lib/h5tools_utils.h @@ -95,14 +95,15 @@ H5TOOLS_DLL int get_option(int argc, const char **argv, const char *opt, const s /*struct taken from the dumper. needed in table struct*/ typedef struct obj_t { - haddr_t objno; - char *objname; - hbool_t displayed; /* Flag to indicate that the object has been displayed */ - hbool_t recorded; /* Flag for named datatypes to indicate they were found in the group hierarchy */ + H5O_token_t obj_token; + char *objname; + hbool_t displayed; /* Flag to indicate that the object has been displayed */ + hbool_t recorded; /* Flag for named datatypes to indicate they were found in the group hierarchy */ } obj_t; /*struct for the tables that the find_objs function uses*/ typedef struct table_t { + hid_t fid; size_t size; size_t nobjs; obj_t *objs; @@ -131,7 +132,7 @@ H5TOOLS_DLL void free_table(table_t *table); H5TOOLS_DLL void dump_tables(find_objs_t *info) #endif /* H5DUMP_DEBUG */ H5TOOLS_DLL herr_t init_objs(hid_t fid, find_objs_t *info, table_t **group_table, table_t **dset_table, table_t **type_table); -H5TOOLS_DLL obj_t *search_obj(table_t *temp, haddr_t objno); +H5TOOLS_DLL obj_t *search_obj(table_t *temp, const H5O_token_t *obj_token); #ifndef H5_HAVE_TMPFILE H5TOOLS_DLL FILE *tmpfile(void); #endif @@ -158,9 +159,9 @@ typedef struct { H5O_type_t trg_type; /* OUT: target type */ char *trg_path; /* OUT: target obj path. This must be freed * when used with H5tools_get_symlink_info() */ - haddr_t objno; /* OUT: target object address */ + H5O_token_t obj_token; /* OUT: target object token */ unsigned long fileno; /* OUT: File number that target object is located in */ - H5L_info_t linfo; /* OUT: link info */ + H5L_info2_t linfo; /* OUT: link info */ h5tool_opt_t opt; /* IN: options */ } h5tool_link_info_t; diff --git a/tools/lib/h5trav.c b/tools/lib/h5trav.c index fb768a4..dc7e27d 100644 --- a/tools/lib/h5trav.c +++ b/tools/lib/h5trav.c @@ -21,7 +21,7 @@ *------------------------------------------------------------------------- */ typedef struct trav_addr_path_t { - haddr_t addr; + H5O_token_t token; char *path; } trav_addr_path_t; @@ -43,7 +43,7 @@ typedef struct { hbool_t is_absolute; /* Whether the traversal has absolute paths */ const char *base_grp_name; /* Name of the group that serves as the base * for iteration */ - unsigned fields; /* Fields needed in H5O_info_t struct */ + unsigned fields; /* Fields needed in H5O_info2_t struct */ } trav_ud_traverse_t; typedef struct { @@ -65,10 +65,10 @@ typedef struct trav_path_op_data_t { */ static void trav_table_add(trav_table_t *table, const char *objname, - const H5O_info_t *oinfo); + const H5O_info2_t *oinfo); static void trav_table_addlink(trav_table_t *table, - haddr_t objno, + const H5O_token_t *obj_token, const char *path); /*------------------------------------------------------------------------- @@ -116,15 +116,15 @@ h5trav_set_verbose(int print_verbose) /*------------------------------------------------------------------------- - * Function: trav_addr_add + * Function: trav_token_add * - * Purpose: Add a hardlink address to visited data structure + * Purpose: Add an object token to visited data structure * * Return: void *------------------------------------------------------------------------- */ static void -trav_addr_add(trav_addr_t *visited, haddr_t addr, const char *path) +trav_token_add(trav_addr_t *visited, H5O_token_t *token, const char *path) { size_t idx; /* Index of address to use */ @@ -136,33 +136,37 @@ trav_addr_add(trav_addr_t *visited, haddr_t addr, const char *path) /* Append it */ idx = visited->nused++; - visited->objs[idx].addr = addr; + HDmemcpy(&visited->objs[idx].token, token, sizeof(H5O_token_t)); visited->objs[idx].path = HDstrdup(path); -} /* end trav_addr_add() */ +} /* end trav_token_add() */ /*------------------------------------------------------------------------- - * Function: trav_addr_visited + * Function: trav_token_visited * - * Purpose: Check if an address has already been visited + * Purpose: Check if an object token has already been seen * * Return: TRUE/FALSE *------------------------------------------------------------------------- */ H5_ATTR_PURE static const char * -trav_addr_visited(trav_addr_t *visited, haddr_t addr) +trav_token_visited(hid_t loc_id, trav_addr_t *visited, H5O_token_t *token) { size_t u; /* Local index variable */ + int token_cmp; /* Look for address */ - for(u = 0; u < visited->nused; u++) + for(u = 0; u < visited->nused; u++) { /* Check for address already in array */ - if(visited->objs[u].addr == addr) + if(H5Otoken_cmp(loc_id, &visited->objs[u].token, token, &token_cmp) < 0) + return NULL; + if(!token_cmp) return(visited->objs[u].path); + } - /* Didn't find address */ + /* Didn't find object token */ return(NULL); -} /* end trav_addr_visited() */ +} /* end trav_token_visited() */ /*------------------------------------------------------------------------- @@ -172,7 +176,7 @@ trav_addr_visited(trav_addr_t *visited, haddr_t addr) *------------------------------------------------------------------------- */ static herr_t -traverse_cb(hid_t loc_id, const char *path, const H5L_info_t *linfo, +traverse_cb(hid_t loc_id, const char *path, const H5L_info2_t *linfo, void *_udata) { trav_ud_traverse_t *udata = (trav_ud_traverse_t *)_udata; /* User data */ @@ -199,10 +203,10 @@ traverse_cb(hid_t loc_id, const char *path, const H5L_info_t *linfo, /* Perform the correct action for different types of links */ if(linfo->type == H5L_TYPE_HARD) { - H5O_info_t oinfo; + H5O_info2_t oinfo; /* Get information about the object */ - if(H5Oget_info_by_name2(loc_id, path, &oinfo, udata->fields, H5P_DEFAULT) < 0) { + if(H5Oget_info_by_name3(loc_id, path, &oinfo, udata->fields, H5P_DEFAULT) < 0) { if(new_name) HDfree(new_name); return(H5_ITER_ERROR); @@ -212,8 +216,8 @@ traverse_cb(hid_t loc_id, const char *path, const H5L_info_t *linfo, * already visited, if it isn't there already */ if(oinfo.rc > 1) - if(NULL == (already_visited = trav_addr_visited(udata->seen, oinfo.addr))) - trav_addr_add(udata->seen, oinfo.addr, full_name); + if(NULL == (already_visited = trav_token_visited(loc_id, udata->seen, &oinfo.token))) + trav_token_add(udata->seen, &oinfo.token, full_name); /* Make 'visit object' callback */ if(udata->visitor->visit_obj) @@ -254,11 +258,11 @@ static int traverse(hid_t file_id, const char *grp_name, hbool_t visit_start, hbool_t recurse, const trav_visitor_t *visitor, unsigned fields) { - H5O_info_t oinfo; /* Object info for starting group */ + H5O_info2_t oinfo; /* Object info for starting group */ int ret_value = 0; /* Get info for starting object */ - if(H5Oget_info_by_name2(file_id, grp_name, &oinfo, fields, H5P_DEFAULT) < 0) + if(H5Oget_info_by_name3(file_id, grp_name, &oinfo, fields, H5P_DEFAULT) < 0) H5TOOLS_GOTO_ERROR((-1), "H5Oget_info_by_name failed"); /* Visit the starting object */ @@ -276,7 +280,7 @@ traverse(hid_t file_id, const char *grp_name, hbool_t visit_start, /* Check for multiple links to top group */ if(oinfo.rc > 1) - trav_addr_add(&seen, oinfo.addr, grp_name); + trav_token_add(&seen, &oinfo.token, grp_name); /* Set up user data structure */ udata.seen = &seen; @@ -288,12 +292,12 @@ traverse(hid_t file_id, const char *grp_name, hbool_t visit_start, /* Check for iteration of links vs. visiting all links recursively */ if(recurse) { /* Visit all links in group, recursively */ - if(H5Lvisit_by_name(file_id, grp_name, trav_index_by, trav_index_order, traverse_cb, &udata, H5P_DEFAULT) < 0) + if(H5Lvisit_by_name2(file_id, grp_name, trav_index_by, trav_index_order, traverse_cb, &udata, H5P_DEFAULT) < 0) H5TOOLS_GOTO_ERROR((-1), "H5Lvisit_by_name failed"); } /* end if */ else { /* Iterate over links in group */ - if(H5Literate_by_name(file_id, grp_name, trav_index_by, trav_index_order, NULL, traverse_cb, &udata, H5P_DEFAULT) < 0) + if(H5Literate_by_name2(file_id, grp_name, trav_index_by, trav_index_order, NULL, traverse_cb, &udata, H5P_DEFAULT) < 0) H5TOOLS_GOTO_ERROR((-1), "H5Literate_by_name failed"); } /* end else */ @@ -338,7 +342,9 @@ trav_info_add(trav_info_t *info, const char *path, h5trav_type_t obj_type) info->paths[idx].path = HDstrdup(path); info->paths[idx].type = obj_type; info->paths[idx].fileno = 0; - info->paths[idx].objno = HADDR_UNDEF; + + /* Set token to 'undefined' values */ + info->paths[idx].obj_token = H5O_TOKEN_UNDEF; } } /* end trav_info_add() */ @@ -354,15 +360,15 @@ trav_info_add(trav_info_t *info, const char *path, h5trav_type_t obj_type) void trav_fileinfo_add(trav_info_t *info, hid_t loc_id) { - H5O_info_t oinfo; + H5O_info2_t oinfo; size_t idx = info->nused - 1; - if ( info->paths[idx].path && HDstrcmp(info->paths[idx].path, ".")) - H5Oget_info_by_name2(loc_id, info->paths[idx].path, &oinfo, H5O_INFO_BASIC, H5P_DEFAULT); + if(info->paths[idx].path && HDstrcmp(info->paths[idx].path, ".")) + H5Oget_info_by_name3(loc_id, info->paths[idx].path, &oinfo, H5O_INFO_BASIC, H5P_DEFAULT); else - H5Oget_info2(loc_id, &oinfo, H5O_INFO_BASIC); + H5Oget_info3(loc_id, &oinfo, H5O_INFO_BASIC); - info->paths[idx].objno = oinfo.addr; + HDmemcpy(&info->paths[idx].obj_token, &oinfo.token, sizeof(H5O_token_t)); info->paths[idx].fileno = oinfo.fileno; } /* end trav_fileinfo_add() */ @@ -377,7 +383,7 @@ trav_fileinfo_add(trav_info_t *info, hid_t loc_id) *------------------------------------------------------------------------- */ int -trav_info_visit_obj(const char *path, const H5O_info_t *oinfo, +trav_info_visit_obj(const char *path, const H5O_info2_t *oinfo, const char H5_ATTR_UNUSED *already_visited, void *udata) { size_t idx; @@ -390,7 +396,7 @@ trav_info_visit_obj(const char *path, const H5O_info_t *oinfo, /* set object addr and fileno. These are for checking same object */ info_p = (trav_info_t *) udata; idx = info_p->nused - 1; - info_p->paths[idx].objno = oinfo->addr; + HDmemcpy(&info_p->paths[idx].obj_token, &oinfo->token, sizeof(H5O_token_t)); info_p->paths[idx].fileno = oinfo->fileno; return(0); @@ -407,7 +413,7 @@ trav_info_visit_obj(const char *path, const H5O_info_t *oinfo, *------------------------------------------------------------------------- */ int -trav_info_visit_lnk(const char *path, const H5L_info_t *linfo, void *udata) +trav_info_visit_lnk(const char *path, const H5L_info2_t *linfo, void *udata) { /* Add the link to the 'info' struct */ trav_info_add((trav_info_t *)udata, path, ((linfo->type == H5L_TYPE_SOFT) ? H5TRAV_TYPE_LINK : H5TRAV_TYPE_UDLINK)); @@ -547,7 +553,7 @@ trav_info_free(trav_info_t *info) *------------------------------------------------------------------------- */ static int -trav_table_visit_obj(const char *path, const H5O_info_t *oinfo, +trav_table_visit_obj(const char *path, const H5O_info2_t *oinfo, const char *already_visited, void *udata) { trav_table_t *table = (trav_table_t *)udata; @@ -558,7 +564,7 @@ trav_table_visit_obj(const char *path, const H5O_info_t *oinfo, trav_table_add(table, path, oinfo); else /* Add alias for object to table */ - trav_table_addlink(table, oinfo->addr, path); + trav_table_addlink(table, &oinfo->token, path); return 0; } /* end trav_table_visit_obj() */ @@ -574,7 +580,7 @@ trav_table_visit_obj(const char *path, const H5O_info_t *oinfo, *------------------------------------------------------------------------- */ static int -trav_table_visit_lnk(const char *path, const H5L_info_t H5_ATTR_UNUSED *linfo, void *udata) +trav_table_visit_lnk(const char *path, const H5L_info2_t H5_ATTR_UNUSED *linfo, void *udata) { /* Add the link to the 'table' struct */ trav_table_add((trav_table_t *)udata, path, NULL); @@ -663,9 +669,7 @@ h5trav_getindext(const char *name, const trav_table_t *table) *------------------------------------------------------------------------- */ static void -trav_table_add(trav_table_t *table, - const char *path, - const H5O_info_t *oinfo) +trav_table_add(trav_table_t *table, const char *path, const H5O_info2_t *oinfo) { size_t new_obj; @@ -676,7 +680,11 @@ trav_table_add(trav_table_t *table, } /* end if */ new_obj = table->nobjs++; - table->objs[new_obj].objno = oinfo ? oinfo->addr : HADDR_UNDEF; + if(oinfo) + HDmemcpy(&table->objs[new_obj].obj_token, &oinfo->token, sizeof(H5O_token_t)); + else + /* Set token to 'undefined' values */ + table->objs[new_obj].obj_token = H5O_TOKEN_UNDEF; table->objs[new_obj].flags[0] = table->objs[new_obj].flags[1] = 0; table->objs[new_obj].is_same_trgobj = 0; table->objs[new_obj].name = (char *)HDstrdup(path); @@ -696,13 +704,16 @@ trav_table_add(trav_table_t *table, *------------------------------------------------------------------------- */ static void -trav_table_addlink(trav_table_t *table, haddr_t objno, const char *path) +trav_table_addlink(trav_table_t *table, const H5O_token_t *obj_token, const char *path) { size_t i; /* Local index variable */ + int token_cmp; if(table) { for(i = 0; i < table->nobjs; i++) { - if(table->objs[i].objno == objno) { + if(H5Otoken_cmp(table->fid, &table->objs[i].obj_token, obj_token, &token_cmp) < 0) + return; + if(!token_cmp) { size_t n; /* already inserted? */ @@ -720,9 +731,9 @@ trav_table_addlink(trav_table_t *table, haddr_t objno, const char *path) table->objs[i].links[n].new_name = (char *)HDstrdup(path); return; - } /* end for */ + } /* end if */ } /* end for */ - } + } /* end if */ } @@ -748,7 +759,10 @@ void trav_table_addflags(unsigned *flags, } /* end if */ new_obj = table->nobjs++; - table->objs[new_obj].objno = 0; + + /* Set token to 'undefined' values */ + table->objs[new_obj].obj_token = H5O_TOKEN_UNDEF; + table->objs[new_obj].flags[0] = flags[0]; table->objs[new_obj].flags[1] = flags[1]; table->objs[new_obj].is_same_trgobj = 0; @@ -769,10 +783,11 @@ void trav_table_addflags(unsigned *flags, * Return: void *------------------------------------------------------------------------- */ -void trav_table_init(trav_table_t **tbl) +void trav_table_init(hid_t fid, trav_table_t **tbl) { trav_table_t* table = (trav_table_t*) HDmalloc(sizeof(trav_table_t)); if(table) { + table->fid = fid; table->size = 0; table->nobjs = 0; table->objs = NULL; @@ -893,8 +908,8 @@ trav_attr(hid_t *------------------------------------------------------------------------- */ static int -trav_print_visit_obj(const char *path, const H5O_info_t *oinfo, - const char *already_visited, void *udata) +trav_print_visit_obj(const char *path, const H5O_info2_t *oinfo, + const char *already_visited, void *udata) { trav_print_udata_t *print_udata = (trav_print_udata_t *)udata; /* Print the name of the object */ @@ -951,7 +966,7 @@ trav_print_visit_obj(const char *path, const H5O_info_t *oinfo, *------------------------------------------------------------------------- */ static int -trav_print_visit_lnk(const char *path, const H5L_info_t *linfo, void *udata) +trav_print_visit_lnk(const char *path, const H5L_info2_t *linfo, void *udata) { trav_print_udata_t *print_udata = (trav_print_udata_t *)udata; diff --git a/tools/lib/h5trav.h b/tools/lib/h5trav.h index a1d33b7..88473ad 100644 --- a/tools/lib/h5trav.h +++ b/tools/lib/h5trav.h @@ -17,9 +17,9 @@ #include "hdf5.h" /* Typedefs for visiting objects */ -typedef herr_t (*h5trav_obj_func_t)(const char *path_name, const H5O_info_t *oinfo, +typedef herr_t (*h5trav_obj_func_t)(const char *path_name, const H5O_info2_t *oinfo, const char *first_seen, void *udata); -typedef herr_t (*h5trav_lnk_func_t)(const char *path_name, const H5L_info_t *linfo, +typedef herr_t (*h5trav_lnk_func_t)(const char *path_name, const H5L_info2_t *linfo, void *udata); /*------------------------------------------------------------------------- @@ -65,7 +65,7 @@ typedef struct symlink_trav_t { typedef struct trav_path_t { char *path; h5trav_type_t type; - haddr_t objno; /* object address */ + H5O_token_t obj_token; /* object token */ unsigned long fileno; /* File number that object is located in */ } trav_path_t; @@ -95,7 +95,7 @@ typedef struct trav_link_t { */ typedef struct trav_obj_t { - haddr_t objno; /* object address */ + H5O_token_t obj_token; /* object token */ unsigned flags[2]; /* h5diff.object is present or not in both files*/ hbool_t is_same_trgobj; /* same target object? no need to compare */ char *name; /* name */ @@ -112,6 +112,7 @@ typedef struct trav_obj_t { */ typedef struct trav_table_t { + hid_t fid; size_t size; size_t nobjs; trav_obj_t *objs; @@ -144,8 +145,8 @@ H5TOOLS_DLL hbool_t symlink_is_visited(symlink_trav_t *visited, H5L_type_t type, */ H5TOOLS_DLL int h5trav_getinfo(hid_t file_id, trav_info_t *info); H5TOOLS_DLL ssize_t h5trav_getindex(const trav_info_t *info, const char *obj); -H5TOOLS_DLL int trav_info_visit_obj (const char *path, const H5O_info_t *oinfo, const char *already_visited, void *udata); -H5TOOLS_DLL int trav_info_visit_lnk (const char *path, const H5L_info_t *linfo, void *udata); +H5TOOLS_DLL int trav_info_visit_obj(const char *path, const H5O_info2_t *oinfo, const char *already_visited, void *udata); +H5TOOLS_DLL int trav_info_visit_lnk(const char *path, const H5L_info2_t *linfo, void *udata); /*------------------------------------------------------------------------- * "h5trav table" public functions @@ -184,7 +185,7 @@ H5TOOLS_DLL void trav_fileinfo_add(trav_info_t *info, hid_t loc_id); *------------------------------------------------------------------------- */ -H5TOOLS_DLL void trav_table_init(trav_table_t **table); +H5TOOLS_DLL void trav_table_init(hid_t fid, trav_table_t **table); H5TOOLS_DLL void trav_table_free(trav_table_t *table); diff --git a/tools/src/h5dump/h5dump.c b/tools/src/h5dump/h5dump.c index 731fcd7..d97fdc0 100644 --- a/tools/src/h5dump/h5dump.c +++ b/tools/src/h5dump/h5dump.c @@ -1398,7 +1398,7 @@ main(int argc, const char *argv[]) hid_t fapl_id = H5P_DEFAULT; H5E_auto2_t func; H5E_auto2_t tools_func; - H5O_info_t oi; + H5O_info2_t oi; struct handler_t *hand = NULL; int i; unsigned u; @@ -1567,7 +1567,7 @@ main(int argc, const char *argv[]) } /* Get object info for root group */ - if(H5Oget_info_by_name2(fid, "/", &oi, H5O_INFO_BASIC, H5P_DEFAULT) < 0) { + if(H5Oget_info_by_name3(fid, "/", &oi, H5O_INFO_BASIC, H5P_DEFAULT) < 0) { error_msg("internal error (file %s:line %d)\n", __FILE__, __LINE__); h5tools_setstatus(EXIT_FAILURE); goto done; diff --git a/tools/src/h5dump/h5dump_ddl.c b/tools/src/h5dump/h5dump_ddl.c index 2eb11fd..a410fda 100644 --- a/tools/src/h5dump/h5dump_ddl.c +++ b/tools/src/h5dump/h5dump_ddl.c @@ -31,7 +31,7 @@ typedef struct { } trav_attr_udata_t; /* callback function used by H5Literate() */ -static herr_t dump_all_cb(hid_t group, const char *name, const H5L_info_t *linfo, void *op_data); +static herr_t dump_all_cb(hid_t group, const char *name, const H5L_info2_t *linfo, void *op_data); static int dump_extlink(hid_t group, const char *linkname, const char *objname); /*------------------------------------------------------------------------- @@ -152,7 +152,7 @@ dump_attr_cb(hid_t oid, const char *attr_name, const H5A_info_t H5_ATTR_UNUSED * *------------------------------------------------------------------------- */ static herr_t -dump_all_cb(hid_t group, const char *name, const H5L_info_t *linfo, void H5_ATTR_UNUSED *op_data) +dump_all_cb(hid_t group, const char *name, const H5L_info2_t *linfo, void H5_ATTR_UNUSED *op_data) { hid_t obj; hid_t dapl_id = H5P_DEFAULT; /* dataset access property list ID */ @@ -200,10 +200,10 @@ dump_all_cb(hid_t group, const char *name, const H5L_info_t *linfo, void H5_ATTR HDstrcat(obj_path, name); if(linfo->type == H5L_TYPE_HARD) { - H5O_info_t oinfo; + H5O_info2_t oinfo; /* Stat the object */ - if(H5Oget_info_by_name2(group, name, &oinfo, H5O_INFO_BASIC, H5P_DEFAULT) < 0) { + if(H5Oget_info_by_name3(group, name, &oinfo, H5O_INFO_BASIC, H5P_DEFAULT) < 0) { error_msg("unable to get object information for \"%s\"\n", name); h5tools_setstatus(EXIT_FAILURE); ret = FAIL; @@ -259,7 +259,7 @@ dump_all_cb(hid_t group, const char *name, const H5L_info_t *linfo, void H5_ATTR if(oinfo.rc > 1 || hit_elink) { obj_t *found_obj; /* Found object */ - found_obj = search_obj(dset_table, oinfo.addr); + found_obj = search_obj(dset_table, &oinfo.token); if(found_obj == NULL) { ctx.indent_level++; @@ -596,9 +596,9 @@ link_iteration(hid_t gid, unsigned crt_order_flags) /* if there is a request to do H5_INDEX_CRT_ORDER and tracking order is set in the group, then, sort by creation order, otherwise by name */ if((sort_by == H5_INDEX_CRT_ORDER) && (crt_order_flags & H5P_CRT_ORDER_TRACKED)) - H5Literate(gid, sort_by, sort_order, NULL, dump_all_cb, NULL); + H5Literate2(gid, sort_by, sort_order, NULL, dump_all_cb, NULL); else - H5Literate(gid, H5_INDEX_NAME, sort_order, NULL, dump_all_cb, NULL); + H5Literate2(gid, H5_INDEX_NAME, sort_order, NULL, dump_all_cb, NULL); } /*------------------------------------------------------------------------- @@ -612,7 +612,7 @@ link_iteration(hid_t gid, unsigned crt_order_flags) void dump_named_datatype(hid_t tid, const char *name) { - H5O_info_t oinfo; + H5O_info2_t oinfo; unsigned attr_crt_order_flags; hid_t tcpl_id = H5I_INVALID_HID; /* datatype creation property list ID */ hsize_t curr_pos = 0; /* total data element position */ @@ -670,7 +670,7 @@ dump_named_datatype(hid_t tid, const char *name) h5tools_dump_header_format->datatypeblockbegin); h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0); - H5Oget_info2(tid, &oinfo, H5O_INFO_BASIC); + H5Oget_info3(tid, &oinfo, H5O_INFO_BASIC); /* Must check for uniqueness of all objects if we've traversed an elink, * otherwise only check if the reference count > 1. @@ -678,7 +678,7 @@ dump_named_datatype(hid_t tid, const char *name) if(oinfo.rc > 1 || hit_elink) { obj_t *found_obj; /* Found object */ - found_obj = search_obj(type_table, oinfo.addr); + found_obj = search_obj(type_table, &oinfo.token); if (found_obj == NULL) { error_msg("internal error (file %s:line %d)\n", __FILE__, __LINE__); @@ -739,7 +739,7 @@ done: void dump_group(hid_t gid, const char *name) { - H5O_info_t oinfo; + H5O_info2_t oinfo; hid_t dset; hid_t type; hid_t gcpl_id; @@ -816,9 +816,15 @@ dump_group(hid_t gid, const char *name) /* dump unamed type in root group */ for(u = 0; u < type_table->nobjs; u++) if(!type_table->objs[u].recorded) { + char *obj_addr_str = NULL; + dset = H5Dopen2(gid, type_table->objs[u].objname, H5P_DEFAULT); type = H5Dget_type(dset); - HDsprintf(type_name, "#"H5_PRINTF_HADDR_FMT, type_table->objs[u].objno); + + H5Otoken_to_str(dset, &type_table->objs[u].obj_token, &obj_addr_str); + HDsprintf(type_name, "#%s", obj_addr_str); + H5free_memory(obj_addr_str); + dump_function_table->dump_named_datatype_function(type, type_name); H5Tclose(type); H5Dclose(dset); @@ -830,7 +836,7 @@ dump_group(hid_t gid, const char *name) h5tools_dump_comment(rawoutstream, outputformat, &ctx, gid); - H5Oget_info2(gid, &oinfo, H5O_INFO_BASIC); + H5Oget_info3(gid, &oinfo, H5O_INFO_BASIC); /* Must check for uniqueness of all objects if we've traversed an elink, * otherwise only check if the reference count > 1. @@ -838,7 +844,7 @@ dump_group(hid_t gid, const char *name) if(oinfo.rc > 1 || hit_elink) { obj_t *found_obj; /* Found object */ - found_obj = search_obj(group_table, oinfo.addr); + found_obj = search_obj(group_table, &oinfo.token); if (found_obj == NULL) { error_msg("internal error (file %s:line %d)\n", __FILE__, __LINE__); @@ -1251,8 +1257,13 @@ dump_fcontents(hid_t fid) unsigned u; for (u = 0; u < type_table->nobjs; u++) { - if (!type_table->objs[u].recorded) - PRINTSTREAM(rawoutstream, " %-10s /#"H5_PRINTF_HADDR_FMT"\n", "datatype", type_table->objs[u].objno); + if (!type_table->objs[u].recorded) { + char *obj_addr_str = NULL; + + H5Otoken_to_str(fid, &type_table->objs[u].obj_token, &obj_addr_str); + PRINTSTREAM(rawoutstream, " %-10s /#%s\n", "datatype", obj_addr_str); + H5free_memory(obj_addr_str); + } } } @@ -1319,7 +1330,7 @@ attr_search(hid_t oid, const char *attr_name, const H5A_info_t H5_ATTR_UNUSED *a } /* end attr_search() */ static herr_t -obj_search(const char *path, const H5O_info_t *oi, const char H5_ATTR_UNUSED *already_visited, void *_op_data) +obj_search(const char *path, const H5O_info2_t *oi, const char H5_ATTR_UNUSED *already_visited, void *_op_data) { trav_handle_udata_t *handle_data = (trav_handle_udata_t*)_op_data; const char *op_name = handle_data->op_name; @@ -1356,7 +1367,7 @@ obj_search(const char *path, const H5O_info_t *oi, const char H5_ATTR_UNUSED *al } /* end obj_search() */ static herr_t -lnk_search(const char *path, const H5L_info_t *li, void *_op_data) +lnk_search(const char *path, const H5L_info2_t *li, void *_op_data) { size_t search_len; size_t k; @@ -1608,7 +1619,7 @@ error: void handle_datasets(hid_t fid, const char *dset, void *data, int pe, const char *display_name) { - H5O_info_t oinfo; + H5O_info2_t oinfo; hid_t dsetid; hid_t dapl_id = H5P_DEFAULT; /* dataset access property list ID */ struct subset_t *sset = (struct subset_t *)data; @@ -1719,11 +1730,11 @@ handle_datasets(hid_t fid, const char *dset, void *data, int pe, const char *dis } /* end if */ - H5Oget_info2(dsetid, &oinfo, H5O_INFO_BASIC); + H5Oget_info3(dsetid, &oinfo, H5O_INFO_BASIC); if(oinfo.rc > 1 || hit_elink) { obj_t *found_obj; /* Found object */ - found_obj = search_obj(dset_table, oinfo.addr); + found_obj = search_obj(dset_table, &oinfo.token); if(found_obj) { if (found_obj->displayed) { @@ -1812,9 +1823,9 @@ handle_groups(hid_t fid, const char *group, void H5_ATTR_UNUSED *data, int pe, c void handle_links(hid_t fid, const char *links, void H5_ATTR_UNUSED * data, int H5_ATTR_UNUSED pe, const char H5_ATTR_UNUSED *display_name) { - H5L_info_t linfo; + H5L_info2_t linfo; - if(H5Lget_info(fid, links, &linfo, H5P_DEFAULT) < 0) { + if(H5Lget_info2(fid, links, &linfo, H5P_DEFAULT) < 0) { error_msg("unable to get link info from \"%s\"\n", links); h5tools_setstatus(EXIT_FAILURE); } @@ -1903,8 +1914,12 @@ handle_datatypes(hid_t fid, const char *type, void H5_ATTR_UNUSED * data, int pe char name[128]; if(!type_table->objs[idx].recorded) { + char *obj_addr_string = NULL; + /* unamed datatype */ - HDsprintf(name, "/#"H5_PRINTF_HADDR_FMT, type_table->objs[idx].objno); + H5Otoken_to_str(fid, &type_table->objs[idx].obj_token, &obj_addr_string); + HDsprintf(name, "/#%s", obj_addr_string); + H5free_memory(obj_addr_string); if(!HDstrcmp(name, real_name)) break; @@ -1962,7 +1977,7 @@ static int dump_extlink(hid_t group, const char *linkname, const char *objname) { hid_t oid; - H5O_info_t oi; + H5O_info2_t oi; table_t *old_group_table = group_table; table_t *old_dset_table = dset_table; table_t *old_type_table = type_table; @@ -1974,7 +1989,7 @@ dump_extlink(hid_t group, const char *linkname, const char *objname) goto fail; /* Get object info */ - if (H5Oget_info2(oid, &oi, H5O_INFO_BASIC) < 0) { + if (H5Oget_info3(oid, &oi, H5O_INFO_BASIC) < 0) { H5Oclose(oid); goto fail; } diff --git a/tools/src/h5dump/h5dump_xml.c b/tools/src/h5dump/h5dump_xml.c index c116da8..7a3ad80 100644 --- a/tools/src/h5dump/h5dump_xml.c +++ b/tools/src/h5dump/h5dump_xml.c @@ -106,7 +106,7 @@ static h5tool_format_t xml_dataformat = { /* internal functions */ -static int xml_name_to_XID(const char *, char *, int , int ); +static int xml_name_to_XID(hid_t, const char *, char *, int, int); /* internal functions used by XML option */ static void xml_print_datatype(hid_t, unsigned); @@ -130,7 +130,7 @@ static char *xml_escape_the_name(const char *); *------------------------------------------------------------------------- */ static herr_t -xml_dump_all_cb(hid_t group, const char *name, const H5L_info_t *linfo, void H5_ATTR_UNUSED *op_data) +xml_dump_all_cb(hid_t group, const char *name, const H5L_info2_t *linfo, void H5_ATTR_UNUSED *op_data) { hid_t obj; herr_t ret = SUCCEED; @@ -177,10 +177,10 @@ xml_dump_all_cb(hid_t group, const char *name, const H5L_info_t *linfo, void H5_ HDstrcat(obj_path, name); if(linfo->type == H5L_TYPE_HARD) { - H5O_info_t oinfo; + H5O_info2_t oinfo; /* Stat the object */ - if(H5Oget_info_by_name2(group, name, &oinfo, H5O_INFO_BASIC, H5P_DEFAULT) < 0) { + if(H5Oget_info_by_name3(group, name, &oinfo, H5O_INFO_BASIC, H5P_DEFAULT) < 0) { error_msg("unable to get object information for \"%s\"\n", name); h5tools_setstatus(EXIT_FAILURE); ret = FAIL; @@ -225,7 +225,7 @@ xml_dump_all_cb(hid_t group, const char *name, const H5L_info_t *linfo, void H5_ if(oinfo.rc > 1 || hit_elink) { obj_t *found_obj; /* Found object */ - found_obj = search_obj(dset_table, oinfo.addr); + found_obj = search_obj(dset_table, &oinfo.token); if(found_obj == NULL) { ctx.indent_level++; @@ -272,8 +272,8 @@ xml_dump_all_cb(hid_t group, const char *name, const H5L_info_t *linfo, void H5_ char pointerxid[100]; /* Create OBJ-XIDs for the parent and object */ - xml_name_to_XID(obj_path, dsetxid, (int)sizeof(dsetxid), 1); - xml_name_to_XID(prefix, parentxid, (int)sizeof(parentxid), 1); + xml_name_to_XID(obj, obj_path, dsetxid, (int)sizeof(dsetxid), 1); + xml_name_to_XID(obj, prefix, parentxid, (int)sizeof(parentxid), 1); ctx.need_prefix = TRUE; @@ -290,7 +290,7 @@ xml_dump_all_cb(hid_t group, const char *name, const H5L_info_t *linfo, void H5_ t_prefix); /* H5ParentPaths */ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0); - xml_name_to_XID(found_obj->objname, pointerxid, (int)sizeof(pointerxid), 1); + xml_name_to_XID(obj, found_obj->objname, pointerxid, (int)sizeof(pointerxid), 1); ctx.indent_level++; @@ -393,11 +393,11 @@ xml_dump_all_cb(hid_t group, const char *name, const H5L_info_t *linfo, void H5_ } /* end else */ /* Create OBJ-XIDs for the parent and object */ - xml_name_to_XID(t_obj_path, linkxid, (int)sizeof(linkxid), 1); - xml_name_to_XID(prefix, parentxid, (int)sizeof(parentxid), 1); + xml_name_to_XID(group, t_obj_path, linkxid, (int)sizeof(linkxid), 1); + xml_name_to_XID(group, prefix, parentxid, (int)sizeof(parentxid), 1); /* Try to create an OBJ-XID for the object pointed to */ - res = xml_name_to_XID(t_link_path, targetxid, (int)sizeof(targetxid), 0); + res = xml_name_to_XID(group, t_link_path, targetxid, (int)sizeof(targetxid), 0); if (res == 0) { /* target obj found */ ctx.need_prefix = TRUE; @@ -482,8 +482,8 @@ xml_dump_all_cb(hid_t group, const char *name, const H5L_info_t *linfo, void H5_ char *t_targname = xml_escape_the_name(targname); /* Create OBJ-XIDs for the parent and object */ - xml_name_to_XID(t_obj_path, linkxid, (int)sizeof(linkxid), 1); - xml_name_to_XID(prefix, parentxid, (int)sizeof(parentxid), 1); + xml_name_to_XID(group, t_obj_path, linkxid, (int)sizeof(linkxid), 1); + xml_name_to_XID(group, prefix, parentxid, (int)sizeof(parentxid), 1); ctx.need_prefix = TRUE; @@ -528,8 +528,8 @@ xml_dump_all_cb(hid_t group, const char *name, const H5L_info_t *linfo, void H5_ char *t_obj_path = xml_escape_the_name(obj_path); /* Create OBJ-XIDs for the parent and object */ - xml_name_to_XID(t_obj_path, linkxid, (int)sizeof(linkxid), 1); - xml_name_to_XID(prefix, parentxid, (int)sizeof(parentxid), 1); + xml_name_to_XID(group, t_obj_path, linkxid, (int)sizeof(linkxid), 1); + xml_name_to_XID(group, prefix, parentxid, (int)sizeof(parentxid), 1); ctx.need_prefix = TRUE; @@ -575,20 +575,26 @@ done: * 1 - generate a fake entry and return fake id. */ int -xml_name_to_XID(const char *str , char *outstr, int outlen, int gen) +xml_name_to_XID(hid_t loc_id, const char *str, char *outstr, int outlen, int gen) { - haddr_t objno; /* Object ID for object at path */ + H5O_token_t obj_token; + char *obj_addr_str = NULL; + int lookup_ret; if (outlen < 22) return 1; - objno = ref_path_table_lookup(str); - if (objno == HADDR_UNDEF) { + lookup_ret = ref_path_table_lookup(str, &obj_token); + if (lookup_ret < 0) { if (HDstrlen(str) == 0) { - objno = ref_path_table_lookup("/"); - if (objno == HADDR_UNDEF) { + lookup_ret = ref_path_table_lookup("/", &obj_token); + if (lookup_ret < 0) { if (gen) { - objno = ref_path_table_gen_fake(str); - HDsprintf(outstr, "xid_"H5_PRINTF_HADDR_FMT, objno); + ref_path_table_gen_fake(str, &obj_token); + + H5Otoken_to_str(loc_id, &obj_token, &obj_addr_str); + HDsprintf(outstr, "xid_%s", obj_addr_str); + H5free_memory(obj_addr_str); + return 0; } else { @@ -598,8 +604,12 @@ xml_name_to_XID(const char *str , char *outstr, int outlen, int gen) } else { if (gen) { - objno = ref_path_table_gen_fake(str); - HDsprintf(outstr, "xid_"H5_PRINTF_HADDR_FMT, objno); + ref_path_table_gen_fake(str, &obj_token); + + H5Otoken_to_str(loc_id, &obj_token, &obj_addr_str); + HDsprintf(outstr, "xid_%s", obj_addr_str); + H5free_memory(obj_addr_str); + return 0; } else { @@ -608,7 +618,9 @@ xml_name_to_XID(const char *str , char *outstr, int outlen, int gen) } } - HDsprintf(outstr, "xid_"H5_PRINTF_HADDR_FMT, objno); + H5Otoken_to_str(loc_id, &obj_token, &obj_addr_str); + HDsprintf(outstr, "xid_%s", obj_addr_str); + H5free_memory(obj_addr_str); return 0; } @@ -878,12 +890,12 @@ xml_print_datatype(hid_t type, unsigned in_group) outputformat = &string_dataformat; if(!in_group && H5Tcommitted(type) > 0) { - H5O_info_t oinfo; + H5O_info2_t oinfo; obj_t *found_obj; /* Found object */ /* detect a shared datatype, output only once */ - H5Oget_info2(type, &oinfo, H5O_INFO_BASIC); - found_obj = search_obj(type_table, oinfo.addr); + H5Oget_info3(type, &oinfo, H5O_INFO_BASIC); + found_obj = search_obj(type_table, &oinfo.token); if(found_obj) { /* This should be defined somewhere else */ @@ -891,7 +903,7 @@ xml_print_datatype(hid_t type, unsigned in_group) probably will have something different eventually */ char * dtxid = (char *)HDmalloc((size_t)100); - xml_name_to_XID(found_obj->objname, dtxid, 100, 1); + xml_name_to_XID(type, found_obj->objname, dtxid, 100, 1); if (!found_obj->recorded) { /* 'anonymous' NDT. Use it's object num. as it's name. */ @@ -1531,19 +1543,19 @@ xml_dump_datatype(hid_t type) dump_indent += COL; if(H5Tcommitted(type) > 0) { - H5O_info_t oinfo; + H5O_info2_t oinfo; obj_t *found_obj; /* Found object */ /* Datatype is a shared or named datatype */ - H5Oget_info2(type, &oinfo, H5O_INFO_BASIC); - found_obj = search_obj(type_table, oinfo.addr); + H5Oget_info3(type, &oinfo, H5O_INFO_BASIC); + found_obj = search_obj(type_table, &oinfo.token); if(found_obj) { /* Shared datatype, must be entered as an object */ /* These 2 cases are the same now, but may change */ char *dtxid = (char *)HDmalloc((size_t)100); - xml_name_to_XID(found_obj->objname, dtxid, 100, 1); + xml_name_to_XID(type, found_obj->objname, dtxid, 100, 1); if (!found_obj->recorded) { /* anonymous stored datatype: following the dumper's current @@ -2293,8 +2305,8 @@ xml_dump_named_datatype(hid_t type, const char *name) t_prefix = xml_escape_the_name(prefix); t_name = xml_escape_the_name(name); - xml_name_to_XID(tmp, dtxid, 100, 1); - xml_name_to_XID(prefix, parentxid, 100, 1); + xml_name_to_XID(type, tmp, dtxid, 100, 1); + xml_name_to_XID(type, prefix, parentxid, 100, 1); if(HDstrncmp(name, "#", (size_t)1) == 0) { /* Special: this is an 'anonymous' NDT, deleted but still in use. @@ -2317,7 +2329,7 @@ xml_dump_named_datatype(hid_t type, const char *name) h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0); } else { - H5O_info_t oinfo; /* Object info */ + H5O_info2_t oinfo; /* Object info */ ctx.need_prefix = TRUE; @@ -2331,12 +2343,12 @@ xml_dump_named_datatype(hid_t type, const char *name) h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0); /* Check uniqueness of named datatype */ - H5Oget_info2(type, &oinfo, H5O_INFO_BASIC); + H5Oget_info3(type, &oinfo, H5O_INFO_BASIC); if(oinfo.rc > 1) { obj_t *found_obj; /* Found object */ /* Group with more than one link to it... */ - found_obj = search_obj(type_table, oinfo.addr); + found_obj = search_obj(type_table, &oinfo.token); if (found_obj == NULL) { indentation(dump_indent); @@ -2353,7 +2365,7 @@ xml_dump_named_datatype(hid_t type, const char *name) ctx.indent_level++; - xml_name_to_XID(found_obj->objname, pointerxid, (int)sizeof(pointerxid), 1); + xml_name_to_XID(type, found_obj->objname, pointerxid, (int)sizeof(pointerxid), 1); ctx.need_prefix = TRUE; @@ -2436,7 +2448,7 @@ done: void xml_dump_group(hid_t gid, const char *name) { - H5O_info_t oinfo; + H5O_info2_t oinfo; hid_t gcpl_id; hid_t dset, type; unsigned crt_order_flags; @@ -2517,13 +2529,13 @@ xml_dump_group(hid_t gid, const char *name) } } - H5Oget_info2(gid, &oinfo, H5O_INFO_BASIC); + H5Oget_info3(gid, &oinfo, H5O_INFO_BASIC); if(oinfo.rc > 1) { obj_t *found_obj; /* Found object */ /* Group with more than one link to it... */ - found_obj = search_obj(group_table, oinfo.addr); + found_obj = search_obj(group_table, &oinfo.token); if (found_obj == NULL) { indentation(dump_indent); @@ -2541,7 +2553,7 @@ xml_dump_group(hid_t gid, const char *name) /* already seen: enter a groupptr */ if(isRoot) { /* probably can't happen! */ - xml_name_to_XID("/", grpxid, 100, 1); + xml_name_to_XID(gid, "/", grpxid, 100, 1); ctx.need_prefix = TRUE; @@ -2554,8 +2566,8 @@ xml_dump_group(hid_t gid, const char *name) else { t_objname = xml_escape_the_name(found_obj->objname); par_name = xml_escape_the_name(par); - xml_name_to_XID(tmp, grpxid, 100, 1); - xml_name_to_XID(par, parentxid, 100, 1); + xml_name_to_XID(gid, tmp, grpxid, 100, 1); + xml_name_to_XID(gid, par, parentxid, 100, 1); ctx.need_prefix = TRUE; @@ -2573,8 +2585,8 @@ xml_dump_group(hid_t gid, const char *name) t_objname = xml_escape_the_name(found_obj->objname);/* point to the NDT by name */ par_name = xml_escape_the_name(par); - xml_name_to_XID(found_obj->objname, ptrstr, 100, 1); - xml_name_to_XID(par, parentxid, 100, 1); + xml_name_to_XID(gid, found_obj->objname, ptrstr, 100, 1); + xml_name_to_XID(gid, par, parentxid, 100, 1); ctx.need_prefix = TRUE; @@ -2597,7 +2609,7 @@ xml_dump_group(hid_t gid, const char *name) /* first time this group has been seen -- describe it */ if(isRoot) { - xml_name_to_XID("/", grpxid, 100, 1); + xml_name_to_XID(gid, "/", grpxid, 100, 1); ctx.need_prefix = TRUE; @@ -2611,8 +2623,8 @@ xml_dump_group(hid_t gid, const char *name) char *t_tmp = xml_escape_the_name(tmp); par_name = xml_escape_the_name(par); - xml_name_to_XID(tmp, grpxid, 100, 1); - xml_name_to_XID(par, parentxid, 100, 1); + xml_name_to_XID(gid, tmp, grpxid, 100, 1); + xml_name_to_XID(gid, par, parentxid, 100, 1); ctx.need_prefix = TRUE; @@ -2652,9 +2664,15 @@ xml_dump_group(hid_t gid, const char *name) /* Very special case: dump unamed type in root group */ for(u = 0; u < type_table->nobjs; u++) { if(!type_table->objs[u].recorded) { + char *obj_addr_str = NULL; + dset = H5Dopen2(gid, type_table->objs[u].objname, H5P_DEFAULT); type = H5Dget_type(dset); - HDsprintf(type_name, "#"H5_PRINTF_HADDR_FMT, type_table->objs[u].objno); + + H5Otoken_to_str(dset, &type_table->objs[u].obj_token, &obj_addr_str); + HDsprintf(type_name, "#%s", obj_addr_str); + H5free_memory(obj_addr_str); + dump_function_table->dump_named_datatype_function(type, type_name); H5Tclose(type); H5Dclose(dset); @@ -2665,9 +2683,9 @@ xml_dump_group(hid_t gid, const char *name) /* iterate through all the links */ if((sort_by == H5_INDEX_CRT_ORDER) && (crt_order_flags & H5P_CRT_ORDER_TRACKED)) - H5Literate(gid, sort_by, sort_order, NULL, xml_dump_all_cb, NULL); + H5Literate2(gid, sort_by, sort_order, NULL, xml_dump_all_cb, NULL); else - H5Literate(gid, H5_INDEX_NAME, sort_order, NULL, xml_dump_all_cb, NULL); + H5Literate2(gid, H5_INDEX_NAME, sort_order, NULL, xml_dump_all_cb, NULL); dump_indent -= COL; ctx.indent_level--; @@ -2689,15 +2707,15 @@ xml_dump_group(hid_t gid, const char *name) h5tools_str_reset(&buffer); if(isRoot) { - xml_name_to_XID("/", grpxid, 100, 1); + xml_name_to_XID(gid, "/", grpxid, 100, 1); h5tools_str_append(&buffer, "<%sRootGroup OBJ-XID=\"%s\" H5Path=\"%s\">", xmlnsprefix, grpxid, "/"); } else { char *t_tmp = xml_escape_the_name(tmp); par_name = xml_escape_the_name(par); - xml_name_to_XID(tmp, grpxid, 100, 1); - xml_name_to_XID(par, parentxid, 100, 1); + xml_name_to_XID(gid, tmp, grpxid, 100, 1); + xml_name_to_XID(gid, par, parentxid, 100, 1); h5tools_str_append(&buffer, "<%sGroup Name=\"%s\" OBJ-XID=\"%s\" H5Path=\"%s\" " "Parents=\"%s\" H5ParentPaths=\"%s\" >", xmlnsprefix, t_name, grpxid, t_tmp, parentxid, par_name); @@ -2734,9 +2752,15 @@ xml_dump_group(hid_t gid, const char *name) /* Very special case: dump unamed type in root group */ for(u = 0; u < type_table->nobjs; u++) { if(!type_table->objs[u].recorded) { + char *obj_addr_str = NULL; + dset = H5Dopen2(gid, type_table->objs[u].objname, H5P_DEFAULT); type = H5Dget_type(dset); - HDsprintf(type_name, "#"H5_PRINTF_HADDR_FMT, type_table->objs[u].objno); + + H5Otoken_to_str(dset, &type_table->objs[u].obj_token, &obj_addr_str); + HDsprintf(type_name, "#%s", obj_addr_str); + H5free_memory(obj_addr_str); + dump_function_table->dump_named_datatype_function(type, type_name); H5Tclose(type); H5Dclose(dset); @@ -2747,9 +2771,9 @@ xml_dump_group(hid_t gid, const char *name) /* iterate through all the links */ if((sort_by == H5_INDEX_CRT_ORDER) && (crt_order_flags & H5P_CRT_ORDER_TRACKED)) - H5Literate(gid, sort_by, sort_order, NULL, xml_dump_all_cb, NULL); + H5Literate2(gid, sort_by, sort_order, NULL, xml_dump_all_cb, NULL); else - H5Literate(gid, H5_INDEX_NAME, sort_order, NULL, xml_dump_all_cb, NULL); + H5Literate2(gid, H5_INDEX_NAME, sort_order, NULL, xml_dump_all_cb, NULL); dump_indent -= COL; ctx.indent_level--; @@ -2791,8 +2815,7 @@ xml_print_refs(hid_t did, int source) hid_t space = H5I_INVALID_HID; hssize_t ssiz = -1; hsize_t i; - size_t tsiz; - hobj_ref_t *refbuf = NULL; + H5R_ref_t *refbuf = NULL; char *buf = NULL; h5tools_str_t buffer; /* string into which to render */ h5tools_context_t ctx; /* print context */ @@ -2823,13 +2846,11 @@ xml_print_refs(hid_t did, int source) space = H5Dget_space(did); if ((ssiz = H5Sget_simple_extent_npoints(space)) < 0) goto error; - if ((tsiz = H5Tget_size(type)) == 0) - goto error; - buf = (char *) HDcalloc((size_t)ssiz, tsiz); + buf = (char *) HDcalloc((size_t)ssiz, sizeof(H5R_ref_t)); if (buf == NULL) goto error; - e = H5Dread(did, H5T_STD_REF_OBJ, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf); + e = H5Dread(did, H5T_STD_REF, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf); /* need to check result here */ if (e < 0) goto error; @@ -2838,19 +2859,17 @@ xml_print_refs(hid_t did, int source) space = H5Aget_space(did); if ((ssiz = H5Sget_simple_extent_npoints(space)) < 0) goto error; - if ((tsiz = H5Tget_size(type)) == 0) - goto error; - buf = (char *) HDcalloc((size_t)ssiz, tsiz); + buf = (char *) HDcalloc((size_t)ssiz, sizeof(H5R_ref_t)); if (buf == NULL) goto error; - e = H5Aread(did, H5T_STD_REF_OBJ, buf); + e = H5Aread(did, H5T_STD_REF, buf); /* need to check the result here */ if (e < 0) goto error; } - refbuf = (hobj_ref_t *)((void *)buf); + refbuf = (H5R_ref_t *)((void *)buf); /* setup */ HDmemset(&buffer, 0, sizeof(h5tools_str_t)); @@ -2901,6 +2920,8 @@ xml_print_refs(hid_t did, int source) } ctx.indent_level--; + H5Rdestroy(refbuf); + refbuf++; } @@ -3290,7 +3311,7 @@ xml_dump_fill_value(hid_t dcpl, hid_t type) H5Pget_fill_value(dcpl, type, buf); if (H5Tget_class(type) == H5T_REFERENCE) { - const char * path = lookup_ref_path(*(hobj_ref_t *) buf); + const char * path = lookup_ref_path(*(H5R_ref_t *) buf); ctx.need_prefix = TRUE; @@ -3324,6 +3345,8 @@ xml_dump_fill_value(hid_t dcpl, hid_t type) h5tools_str_reset(&buffer); h5tools_str_append(&buffer, "", xmlnsprefix); h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0); + + H5Rdestroy((H5R_ref_t *) buf); } else if (H5Tget_class(type) == H5T_STRING) { /* ????? */ @@ -3610,8 +3633,8 @@ xml_dump_dataset(hid_t did, const char *name, struct subset_t H5_ATTR_UNUSED *ss string_dataformat.do_escape = display_escape; outputformat = &string_dataformat; - xml_name_to_XID(tmp, rstr, 100, 1); - xml_name_to_XID(prefix, pstr, 100, 1); + xml_name_to_XID(did, tmp, rstr, 100, 1); + xml_name_to_XID(did, prefix, pstr, 100, 1); ctx.need_prefix = TRUE; diff --git a/tools/src/h5format_convert/h5format_convert.c b/tools/src/h5format_convert/h5format_convert.c index f5234f4..bb606ac 100644 --- a/tools/src/h5format_convert/h5format_convert.c +++ b/tools/src/h5format_convert/h5format_convert.c @@ -362,7 +362,7 @@ error: *------------------------------------------------------------------------- */ static int -convert_dsets_cb(const char *path, const H5O_info_t *oi, const char *already_visited, void *_fid) +convert_dsets_cb(const char *path, const H5O_info2_t *oi, const char *already_visited, void *_fid) { hid_t fid = *(hid_t *)_fid; diff --git a/tools/src/h5ls/h5ls.c b/tools/src/h5ls/h5ls.c index e8a7a2b..88f1d2b 100644 --- a/tools/src/h5ls/h5ls.c +++ b/tools/src/h5ls/h5ls.c @@ -1260,10 +1260,17 @@ print_type(h5tools_str_t *buffer, hid_t type, int ind) /* Shared? If so then print the type's OID */ if (H5Tcommitted(type)) { - H5O_info_t oi; + H5O_info2_t oi; - if (H5Oget_info2(type, &oi, H5O_INFO_BASIC) >= 0) - h5tools_str_append(buffer,"shared-%lu:"H5_PRINTF_HADDR_FMT" ", oi.fileno, oi.addr); + if (H5Oget_info3(type, &oi, H5O_INFO_BASIC) >= 0) { + char *type_string = NULL; + + H5Otoken_to_str(type, &oi.token, &type_string); + + h5tools_str_append(buffer,"shared-%lu:%s", oi.fileno, type_string); + + H5free_memory(type_string); + } /* end if */ else h5tools_str_append(buffer,"shared "); } /* end if */ @@ -2284,7 +2291,7 @@ datatype_list2(hid_t type, const char H5_ATTR_UNUSED *name) *------------------------------------------------------------------------- */ static herr_t -list_obj(const char *name, const H5O_info_t *oinfo, const char *first_seen, void *_iter) +list_obj(const char *name, const H5O_info2_t *oinfo, const char *first_seen, void *_iter) { H5O_type_t obj_type = oinfo->type; /* Type of the object */ iter_t *iter = (iter_t*)_iter; @@ -2355,6 +2362,7 @@ list_obj(const char *name, const H5O_info_t *oinfo, const char *first_seen, void if (verbose_g > 0) { size_t buf_size = 0; char* comment = NULL; + char* obj_addr_str = NULL; ssize_t cmt_bufsize = -1; /* Display attributes */ @@ -2363,11 +2371,15 @@ list_obj(const char *name, const H5O_info_t *oinfo, const char *first_seen, void H5Aiterate2(obj, H5_INDEX_NAME, H5_ITER_INC, NULL, list_attr, NULL); /* Object location & reference count */ + H5Otoken_to_str(obj, &oinfo->token, &obj_addr_str); + h5tools_str_reset(&buffer); - h5tools_str_append(&buffer, " %-10s %lu:"H5_PRINTF_HADDR_FMT"\n", "Location:", oinfo->fileno, oinfo->addr); + h5tools_str_append(&buffer, " %-10s %lu:%s\n", "Location:", oinfo->fileno, obj_addr_str); h5tools_str_append(&buffer, " %-10s %u\n", "Links:", (unsigned)oinfo->rc); h5tools_render_element(rawoutstream, info, &ctx, &buffer, &curr_pos, (size_t)info->line_ncols, (hsize_t)0, (hsize_t)0); + H5free_memory(obj_addr_str); + /* Modification time */ if (oinfo->mtime > 0) { char buf[256]; @@ -2442,7 +2454,7 @@ done: *------------------------------------------------------------------------- */ static herr_t -list_lnk(const char *name, const H5L_info_t *linfo, void *_iter) +list_lnk(const char *name, const H5L_info2_t *linfo, void *_iter) { char *buf = NULL; iter_t *iter = (iter_t*)_iter; @@ -2628,7 +2640,7 @@ static herr_t visit_obj(hid_t file, const char *oname, iter_t *iter) { int retval = 0; - H5O_info_t oi; /* Information for object */ + H5O_info2_t oi; /* Information for object */ hsize_t curr_pos = 0; /* total data element position */ h5tools_str_t buffer; /* string into which to render */ h5tools_context_t ctx; /* print context */ @@ -2640,7 +2652,7 @@ visit_obj(hid_t file, const char *oname, iter_t *iter) h5tools_str_reset(&buffer); /* Retrieve info for object to list */ - if (H5Oget_info_by_name2(file, oname, &oi, H5O_INFO_BASIC|H5O_INFO_TIME, H5P_DEFAULT) < 0) { + if (H5Oget_info_by_name3(file, oname, &oi, H5O_INFO_BASIC|H5O_INFO_TIME, H5P_DEFAULT) < 0) { if (iter->symlink_target) { h5tools_str_append(&buffer, "{**NOT FOUND**}\n"); iter->symlink_target = FALSE; @@ -3279,7 +3291,7 @@ main(int argc, const char *argv[]) * doesn't exist). */ show_file_name_g = (argc-argno > 1); /*show file names if more than one*/ while(argno < argc) { - H5L_info_t li; + H5L_info2_t li; iter_t iter; symlink_trav_t symlink_list; size_t u; @@ -3360,7 +3372,7 @@ main(int argc, const char *argv[]) /* Check for root group as object name */ if (HDstrcmp(oname, root_name)) { /* Check the type of link given */ - if (H5Lget_info(file_id, oname, &li, H5P_DEFAULT) < 0) { + if (H5Lget_info2(file_id, oname, &li, H5P_DEFAULT) < 0) { hsize_t curr_pos = 0; /* total data element position */ h5tools_str_t buffer; /* string into which to render */ h5tools_context_t ctx; /* print context */ diff --git a/tools/src/h5repack/h5repack.c b/tools/src/h5repack/h5repack.c index b138896..8eeaa0e 100644 --- a/tools/src/h5repack/h5repack.c +++ b/tools/src/h5repack/h5repack.c @@ -222,18 +222,27 @@ h5repack_addlayout(const char *str, pack_opt_t *options) hid_t copy_named_datatype(hid_t type_in, hid_t fidout, named_dt_t **named_dt_head_p, trav_table_t *travt, pack_opt_t *options) { - named_dt_t *dt = *named_dt_head_p; /* Stack pointer */ - named_dt_t *dt_ret = NULL; /* Datatype to return */ - H5O_info_t oinfo; /* Object info of input dtype */ - hid_t ret_value = H5I_INVALID_HID; + named_dt_t *dt = *named_dt_head_p; /* Stack pointer */ + named_dt_t *dt_ret = NULL; /* Datatype to return */ + H5O_info2_t oinfo; /* Object info of input dtype */ + int token_cmp; + hid_t ret_value = H5I_INVALID_HID; - if (H5Oget_info2(type_in, &oinfo, H5O_INFO_BASIC) < 0) + if (H5Oget_info3(type_in, &oinfo, H5O_INFO_BASIC) < 0) H5TOOLS_GOTO_ERROR(H5I_INVALID_HID, "H5Oget_info failed"); if (*named_dt_head_p) { + if (H5Otoken_cmp(type_in, &dt->obj_token, &oinfo.token, &token_cmp) < 0) + H5TOOLS_GOTO_ERROR(H5I_INVALID_HID, "failed to compare object tokens"); + /* Stack already exists, search for the datatype */ - while (dt && dt->addr_in != oinfo.addr) + while (dt && token_cmp) { dt = dt->next; + + if (H5Otoken_cmp(type_in, &dt->obj_token, &oinfo.token, &token_cmp) < 0) + H5TOOLS_GOTO_ERROR(H5I_INVALID_HID, "failed to compare object tokens"); + } + dt_ret = dt; } else { @@ -249,13 +258,14 @@ copy_named_datatype(hid_t type_in, hid_t fidout, named_dt_t **named_dt_head_p, t *named_dt_head_p = dt; /* Update the address and id */ - dt->addr_in = travt->objs[i].objno; + HDmemcpy(&dt->obj_token, &travt->objs[i].obj_token, sizeof(H5O_token_t)); dt->id_out = H5I_INVALID_HID; /* Check if this type is the one requested */ - if (oinfo.addr == dt->addr_in) { + if (H5Otoken_cmp(type_in, &oinfo.token, &dt->obj_token, &token_cmp) < 0) + H5TOOLS_GOTO_ERROR(H5I_INVALID_HID, "failed to compare object tokens"); + if (!token_cmp) dt_ret = dt; - } } /* end if named datatype */ } /* end for each object in traversal table */ } /* end else (create the stack) */ @@ -271,7 +281,7 @@ copy_named_datatype(hid_t type_in, hid_t fidout, named_dt_t **named_dt_head_p, t *named_dt_head_p = dt_ret; /* Update the address and id */ - dt_ret->addr_in = oinfo.addr; + HDmemcpy(&dt_ret->obj_token, &oinfo.token, sizeof(H5O_token_t)); dt_ret->id_out = H5I_INVALID_HID; } /* end if requested datatype not found */ @@ -355,14 +365,14 @@ copy_attr(hid_t loc_in, hid_t loc_out, named_dt_t **named_dt_head_p, trav_table_ htri_t is_named; /* Whether the datatype is named */ hsize_t dims[H5S_MAX_RANK];/* dimensions of dataset */ char name[255]; - H5O_info_t oinfo; /* object info */ + H5O_info2_t oinfo; /* object info */ int j; unsigned u; hbool_t is_ref = 0; H5T_class_t type_class = -1; int ret_value = 0; - if (H5Oget_info2(loc_in, &oinfo, H5O_INFO_NUM_ATTRS) < 0) + if (H5Oget_info3(loc_in, &oinfo, H5O_INFO_NUM_ATTRS) < 0) H5TOOLS_GOTO_ERROR((-1), "H5Oget_info failed"); /*------------------------------------------------------------------------- @@ -752,7 +762,7 @@ check_objects(const char* fname, pack_opt_t *options) /* Initialize indexing options */ h5trav_set_index(sort_by, sort_order); /* init table */ - trav_table_init(&travt); + trav_table_init(fid, &travt); /* get the list of objects in the file */ if (h5trav_gettable(fid, travt) < 0) diff --git a/tools/src/h5repack/h5repack.h b/tools/src/h5repack/h5repack.h index a0e0387..52ecb0e 100644 --- a/tools/src/h5repack/h5repack.h +++ b/tools/src/h5repack/h5repack.h @@ -131,7 +131,7 @@ typedef struct { typedef struct named_dt_t { - haddr_t addr_in; /* Address of the named dtype in the in file */ + H5O_token_t obj_token; /* Object token for the named dtype in the in file */ hid_t id_out; /* Open identifier for the dtype in the out file */ struct named_dt_t *next; /* Next dtype */ } named_dt_t; diff --git a/tools/src/h5repack/h5repack_copy.c b/tools/src/h5repack/h5repack_copy.c index 7336125..1044244 100644 --- a/tools/src/h5repack/h5repack_copy.c +++ b/tools/src/h5repack/h5repack_copy.c @@ -316,7 +316,7 @@ print_user_block(fnamein, fidin); /* Initialize indexing options */ h5trav_set_index(sort_by, sort_order); /* init table */ - trav_table_init(&travt); + trav_table_init(fidin, &travt); if (travt) { /* get the list of objects in the file */ diff --git a/tools/src/h5repack/h5repack_refs.c b/tools/src/h5repack/h5repack_refs.c index 70204c8..e6a747d 100644 --- a/tools/src/h5repack/h5repack_refs.c +++ b/tools/src/h5repack/h5repack_refs.c @@ -439,7 +439,7 @@ static int copy_refs_attr(hid_t loc_in, hsize_t nelmts; /* number of elements in dataset */ hsize_t dims[H5S_MAX_RANK];/* dimensions of dataset */ char name[255]; - H5O_info_t oinfo; /* Object info */ + H5O_info2_t oinfo; /* Object info */ unsigned u, i, j; int rank; H5T_class_t type_class = -1; @@ -454,7 +454,7 @@ static int copy_refs_attr(hid_t loc_in, int ref_comp_field_n = 0; int ret_value = 0; - if(H5Oget_info2(loc_in, &oinfo, H5O_INFO_NUM_ATTRS) < 0) + if(H5Oget_info3(loc_in, &oinfo, H5O_INFO_NUM_ATTRS) < 0) H5TOOLS_GOTO_ERROR((-1), "H5Oget_info failed"); for(u = 0; u < (unsigned)oinfo.num_attrs; u++) { @@ -796,16 +796,19 @@ MapIdToName(hid_t refobj_id, trav_table_t *travt) if(travt->objs[u].type == (h5trav_type_t)H5O_TYPE_DATASET || travt->objs[u].type == (h5trav_type_t)H5O_TYPE_GROUP || travt->objs[u].type == (h5trav_type_t)H5O_TYPE_NAMED_DATATYPE) { - H5O_info_t ref_oinfo; /* Stat for the refobj id */ + H5O_info2_t ref_oinfo; /* Stat for the refobj id */ + int token_cmp; /* obtain information to identify the referenced object uniquely */ - if(H5Oget_info2(refobj_id, &ref_oinfo, H5O_INFO_BASIC) < 0) + if(H5Oget_info3(refobj_id, &ref_oinfo, H5O_INFO_BASIC) < 0) goto out; - if(ref_oinfo.addr == travt->objs[u].objno) { + if(H5Otoken_cmp(refobj_id, &ref_oinfo.token, &travt->objs[u].obj_token, &token_cmp) < 0) + goto out; + if(!token_cmp) { ret = travt->objs[u].name; goto out; - } /* end if */ + } } /* end if */ } /* u */ diff --git a/tools/src/h5repack/h5repack_verify.c b/tools/src/h5repack/h5repack_verify.c index 84cbf60..683988c 100644 --- a/tools/src/h5repack/h5repack_verify.c +++ b/tools/src/h5repack/h5repack_verify.c @@ -95,7 +95,7 @@ h5repack_verify(const char *in_fname, const char *out_fname, pack_opt_t *options * close *------------------------------------------------------------------------- */ - if(H5Pclose(pid) < 0) + if (H5Pclose(pid) < 0) H5TOOLS_GOTO_ERROR((-1), "H5Pclose failed"); if (H5Sclose(sid) < 0) H5TOOLS_GOTO_ERROR((-1), "H5Sclose failed"); @@ -114,7 +114,7 @@ h5repack_verify(const char *in_fname, const char *out_fname, pack_opt_t *options /* Initialize indexing options */ h5trav_set_index(sort_by, sort_order); /* init table */ - trav_table_init(&travt); + trav_table_init(fidout, &travt); /* get the list of objects in the file */ if(h5trav_gettable(fidout, travt) < 0) @@ -386,7 +386,7 @@ int h5repack_cmp_pl(const char *fname1, const char *fname2) /* Initialize indexing options */ h5trav_set_index(sort_by, sort_order); /* init table */ - trav_table_init(&trav); + trav_table_init(fid1, &trav); if(h5trav_gettable(fid1, trav) < 0) H5TOOLS_GOTO_ERROR((-1), "h5trav_gettable failed"); diff --git a/tools/src/h5stat/h5stat.c b/tools/src/h5stat/h5stat.c index f160671..adc905a 100644 --- a/tools/src/h5stat/h5stat.c +++ b/tools/src/h5stat/h5stat.c @@ -379,13 +379,13 @@ ceil_log10(unsigned long x) *------------------------------------------------------------------------- */ static herr_t -attribute_stats(iter_t *iter, const H5O_info_t *oi) +attribute_stats(iter_t *iter, const H5O_info2_t *oi, const H5O_native_info_t *native_oi) { unsigned bin; /* "bin" the number of objects falls in */ /* Update dataset & attribute metadata info */ - iter->attrs_btree_storage_size += oi->meta_size.attr.index_size; - iter->attrs_heap_storage_size += oi->meta_size.attr.heap_size; + iter->attrs_btree_storage_size += native_oi->meta_size.attr.index_size; + iter->attrs_heap_storage_size += native_oi->meta_size.attr.heap_size; /* Update small # of attribute count & limits */ if(oi->num_attrs <= (hsize_t)sattrs_threshold) @@ -440,7 +440,7 @@ attribute_stats(iter_t *iter, const H5O_info_t *oi) *------------------------------------------------------------------------- */ static herr_t -group_stats(iter_t *iter, const char *name, const H5O_info_t *oi) +group_stats(iter_t *iter, const char *name, const H5O_info2_t *oi, const H5O_native_info_t *native_oi) { H5G_info_t ginfo; /* Group information */ unsigned bin; /* "bin" the number of objects falls in */ @@ -450,8 +450,8 @@ group_stats(iter_t *iter, const char *name, const H5O_info_t *oi) iter->uniq_groups++; /* Get object header information */ - iter->group_ohdr_info.total_size += oi->hdr.space.total; - iter->group_ohdr_info.free_size += oi->hdr.space.free; + iter->group_ohdr_info.total_size += native_oi->hdr.space.total; + iter->group_ohdr_info.free_size += native_oi->hdr.space.free; /* Get group information */ if((ret_value = H5Gget_info_by_name(iter->fid, name, &ginfo, H5P_DEFAULT)) < 0) @@ -484,11 +484,11 @@ group_stats(iter_t *iter, const char *name, const H5O_info_t *oi) (iter->group_bins[bin])++; /* Update group metadata info */ - iter->groups_btree_storage_size += oi->meta_size.obj.index_size; - iter->groups_heap_storage_size += oi->meta_size.obj.heap_size; + iter->groups_btree_storage_size += native_oi->meta_size.obj.index_size; + iter->groups_heap_storage_size += native_oi->meta_size.obj.heap_size; /* Update attribute metadata info */ - if((ret_value = attribute_stats(iter, oi)) < 0) + if((ret_value = attribute_stats(iter, oi, native_oi)) < 0) H5TOOLS_GOTO_ERROR(FAIL, "attribute_stats failed"); done: @@ -510,7 +510,7 @@ done: *------------------------------------------------------------------------- */ static herr_t -dataset_stats(iter_t *iter, const char *name, const H5O_info_t *oi) +dataset_stats(iter_t *iter, const char *name, const H5O_info2_t *oi, const H5O_native_info_t *native_oi) { unsigned bin; /* "bin" the number of objects falls in */ hid_t did; /* Dataset ID */ @@ -533,18 +533,18 @@ dataset_stats(iter_t *iter, const char *name, const H5O_info_t *oi) iter->uniq_dsets++; /* Get object header information */ - iter->dset_ohdr_info.total_size += oi->hdr.space.total; - iter->dset_ohdr_info.free_size += oi->hdr.space.free; + iter->dset_ohdr_info.total_size += native_oi->hdr.space.total; + iter->dset_ohdr_info.free_size += native_oi->hdr.space.free; if((did = H5Dopen2(iter->fid, name, H5P_DEFAULT)) < 0) H5TOOLS_GOTO_ERROR(FAIL, "H5Dopen() failed"); /* Update dataset metadata info */ - iter->datasets_index_storage_size += oi->meta_size.obj.index_size; - iter->datasets_heap_storage_size += oi->meta_size.obj.heap_size; + iter->datasets_index_storage_size += native_oi->meta_size.obj.index_size; + iter->datasets_heap_storage_size += native_oi->meta_size.obj.heap_size; /* Update attribute metadata info */ - if((ret_value = attribute_stats(iter, oi)) < 0) + if((ret_value = attribute_stats(iter, oi, native_oi)) < 0) H5TOOLS_GOTO_ERROR(FAIL, "attribute_stats() failed"); /* Get storage info */ @@ -702,7 +702,7 @@ done: *------------------------------------------------------------------------- */ static herr_t -datatype_stats(iter_t *iter, const H5O_info_t *oi) +datatype_stats(iter_t *iter, const H5O_info2_t *oi, const H5O_native_info_t *native_oi) { herr_t ret_value = SUCCEED; @@ -710,11 +710,11 @@ datatype_stats(iter_t *iter, const H5O_info_t *oi) iter->uniq_dtypes++; /* Get object header information */ - iter->dtype_ohdr_info.total_size += oi->hdr.space.total; - iter->dtype_ohdr_info.free_size += oi->hdr.space.free; + iter->dtype_ohdr_info.total_size += native_oi->hdr.space.total; + iter->dtype_ohdr_info.free_size += native_oi->hdr.space.free; /* Update attribute metadata info */ - if((ret_value = attribute_stats(iter, oi)) < 0) + if((ret_value = attribute_stats(iter, oi, native_oi)) < 0) H5TOOLS_GOTO_ERROR(FAIL, "attribute_stats() failed"); done: return ret_value; @@ -735,31 +735,36 @@ done: *------------------------------------------------------------------------- */ static herr_t -obj_stats(const char *path, const H5O_info_t *oi, const char *already_visited, +obj_stats(const char *path, const H5O_info2_t *oi, const char *already_visited, void *_iter) { + H5O_native_info_t native_info; iter_t *iter = (iter_t *)_iter; herr_t ret_value = SUCCEED; /* If the object has already been seen then just return */ if(NULL == already_visited) { + /* Retrieve the native info for the object */ + if(H5Oget_native_info_by_name(iter->fid, path, &native_info, H5O_NATIVE_INFO_ALL, H5P_DEFAULT) < 0) + H5TOOLS_GOTO_ERROR(FAIL, "H5Oget_native_info_by_name failed"); + /* Gather some general statistics about the object */ if(oi->rc > iter->max_links) iter->max_links = oi->rc; switch(oi->type) { case H5O_TYPE_GROUP: - if(group_stats(iter, path, oi) < 0) + if(group_stats(iter, path, oi, &native_info) < 0) H5TOOLS_GOTO_ERROR(FAIL, "group_stats failed"); break; case H5O_TYPE_DATASET: - if(dataset_stats(iter, path, oi) < 0) + if(dataset_stats(iter, path, oi, &native_info) < 0) H5TOOLS_GOTO_ERROR(FAIL, "dataset_stats failed"); break; case H5O_TYPE_NAMED_DATATYPE: - if(datatype_stats(iter, oi) < 0) + if(datatype_stats(iter, oi, &native_info) < 0) H5TOOLS_GOTO_ERROR(FAIL, "datatype_stats failed"); break; @@ -792,7 +797,7 @@ done: *------------------------------------------------------------------------- */ static herr_t -lnk_stats(const char H5_ATTR_UNUSED *path, const H5L_info_t *li, void *_iter) +lnk_stats(const char H5_ATTR_UNUSED *path, const H5L_info2_t *li, void *_iter) { iter_t *iter = (iter_t *)_iter; diff --git a/tools/test/h5dump/errfiles/tdset-2.err b/tools/test/h5dump/errfiles/tdset-2.err index 2d70b35..39bbb0e 100644 --- a/tools/test/h5dump/errfiles/tdset-2.err +++ b/tools/test/h5dump/errfiles/tdset-2.err @@ -27,7 +27,7 @@ HDF5-DIAG: Error detected in HDF5 (version (number)) thread (IDs): major: Symbol table minor: Object not found HDF5-DIAG: Error detected in HDF5 (version (number)) thread (IDs): - #000: (file name) line (number) in H5Lget_info(): unable to get link info + #000: (file name) line (number) in H5Lget_info2(): unable to get link info major: Links minor: Can't get value #001: (file name) line (number) in H5VL_link_get(): link get failed diff --git a/tools/test/h5dump/errfiles/tperror.err b/tools/test/h5dump/errfiles/tperror.err index b0b908b..e2f24c1 100644 --- a/tools/test/h5dump/errfiles/tperror.err +++ b/tools/test/h5dump/errfiles/tperror.err @@ -27,7 +27,7 @@ HDF5-DIAG: Error detected in HDF5 (version (number)) thread (IDs): major: Symbol table minor: Object not found HDF5-DIAG: Error detected in HDF5 (version (number)) thread (IDs): - #000: (file name) line (number) in H5Lget_info(): unable to get link info + #000: (file name) line (number) in H5Lget_info2(): unable to get link info major: Links minor: Can't get value #001: (file name) line (number) in H5VL_link_get(): link get failed diff --git a/tools/test/h5dump/errfiles/tqmarkfile.err b/tools/test/h5dump/errfiles/tqmarkfile.err index 2c4f1ff..4c3b2ef 100644 --- a/tools/test/h5dump/errfiles/tqmarkfile.err +++ b/tools/test/h5dump/errfiles/tqmarkfile.err @@ -15,7 +15,7 @@ HDF5-DIAG: Error detected in HDF5 (version (number)) thread (IDs): major: Symbol table minor: Object not found HDF5-DIAG: Error detected in HDF5 (version (number)) thread (IDs): - #000: (file name) line (number) in H5Lget_info(): unable to get link info + #000: (file name) line (number) in H5Lget_info2(): unable to get link info major: Symbol table minor: Object not found #001: (file name) line (number) in H5L_get_info(): name doesn't exist -- cgit v0.12 7V}8zӬhf"j:#R{6uX=G!}+1Fj歘kU4ЬF*([3Nk@6RDT~HNSܸ-7_(sa[NGd$LEڵ[tyD<]H 2ysP'#] i`@!0ɺwhgUUhr*pS*7sBEqZ Tse yfYȴ^}h,YHR9+:ߵr'on9M8ׁ Cl|r^ʈ^aMsϻ7@gI.J9ި =M"U.S0x]H=6="R\Ġde?B`r1{rh* Jv`}SϽ{lfFmz D;zbDAI x)=lܽ2/ճHiyDBԌe ]-Ir-2iK$jҰsX…hIՅ$Qخ'/?o7g#k;,=@\٠ƜEA(`b7}WtyԂyB~C H'ѻ#hy!Wyg**SX[ A˱pjSQ>bi}pzaY⪼,HE xhe/"yShq#zʵW )7n$N,|idR4:YњkHgݸo5e[ywd>+ɨ5ϴ"a)pK lkzyZ採Au,d)& 4rr)JeOj 6$C< bRYt< q^4yyD'YFA`M0FG'As]3̥;E'; q3W e(HF`ҬQk}1G{ !+7bpjp1K׻uQ|GDz 5845`Ptwz+SeaJ[U3<-oCg<M@qw/M]A_ Uos8$z]Vˆ2aKUOGMyo"d4*:-B5] ^aD/f6߃ TL8:rj{9qGu}ۋs-d"DEiʴAjv8/" ArTWSDVՍ Un%u㬅q(XQAo xQ$ MWy4ˈ43jBOYg4}<,8% ,+lj>5OL3yfgb Z]{x VGnV8HmMwTCK!o0OAB$8KI^\s),k@=\<8Op&5]oڦD/$>#*,;s/COxN`峢荒0gfhKsCg {O .)*brIH b#'kFiځtq8ҡl@G8q s(|@S8$ڹot. x{fEKDvoX4]4=4aua!flυwSqmg4=oVhh{q"qfouC,G8X>;֥=.v߹c8 9ղ{DW }pPMZMco6d޻{&|̜Y8VuJ6d 1Ӧ8dW(,CL6i+*me]TU:~!X淶/}ڴ>蘎< DphKX|p?}Pv[7Sq[jH}0oOXl 0+I=4{Q4+7AÎ1`qҌ놧z!A )=uif:Iv,4HPk7Q߂FFu^qזHlv,Ŵ4WY/xoS#T𽥠EW9zinyuUA7gqOyp>b"aVOol2qCʊ*XC2R3.g! 'RlI@- FG)KDJ T_]|_+Ң a{BtYH  !Ƣ5~Lg:5I 1SjH? w+rR@q>hhD;$:Dl=/ ШT;^[%])G9jP]A*`Ӡl벟|`~[8eT6Ph Նi)/3y%8jP d ]h[)1C;_z C% 7 UÞsj #sh%)Sq'$8ǛA|<}O$$cU(q :PfD8/UTVUpH*siWL̬@B % 2!0ZX1Zuq]W( 9wa*DG1yM{l ڔrfdќ ]_7ftd:;} g4t'jV4Y}oKGaFNm@@!C8B-Lͫ1D$sn g!G &z뀉npw`ƾDx<ԌR=eW%BKF%%1zS!NxBժ{2y,G* /Zp^Gѧ;ycDᐐc~&"F}Tt(X0FBu5tj(nP< ES,x 'tAl3U[޶:6%f^'4VU5GN֫7I HPEI'B#aey~x{MB2> =\2 ,뭻ܢ^ ÄM| 7rbfxcX~Cلu?z p_Mфx#nݐ- e MywCWGWa96X CƏZ~VGdx*2b>**ݡYx |I\GMz]A`xpI"Pp/ DǁQ9p, o`I*"p_ho @ !ʗ5Kc)wOy-dy@qHHJ6E&;+޲Wz*ӡ9<(K}3.85B*~{=:K #{ŝioNS E6IB / w+,JC&lXK؟z`na \YGO&DuR@|ݤ/q.|na:;LROhW 1xaa֟X;DTn?Y:..>&W& MՍX,d+(*5 YN`4Iњ37Cjgpv!'w(Xd'f3&"f mDƮ"&bҶk"W.uӦtAneY?eGAG~Nr(XD e8OK2f`@HD v]&8gFc p7"PgaFˆ#'Q{Ŕ騔W^HO)ۤh d]PL9xb}4c" >iȿ QNv9VfjN ôRAL+eon=ko#vv-@uo{h#$stl``x ǓfHD."γ9x-=NC*0jjɆ:8)1 #tnRꮖ[3H ItV{fs>-K#4L1V/ ҁ0X7 2<8)/KBV!g$C`T->ab$ԋGa5苽ڶ<^>CEQGd&ߋ3qP89uzsj2ނ<1%P@ "C>8zܽaWBq!x7&gն3HB }P{=!Eơ 0R~C5XD3 sg1f trf`PXU6VUv uC!CtVtFzS)5#O7FyS=\oڧMG;[J1-pLu Yh8pkwૄkxPЍKR.deՍa])12n0^Қ:SGKN\jJ6P+DnWj-CmtDfZUt\rOp(!:l˄ιdCQ4zwpH×Ls/7[DsMeJMYvMEQxY8L>J E3̈́E]+J!Ƚ-u=0(NwIn*#Lþ1Lׅ(QȂ/}}qbkbݥQ7UĕV&GRPb脄g1.0)6$a4h=fAvP Ũ5il^ 136$,29ڗKʍᶞf dS0>l dz ̸U$(=s?3>[J#6U8[6陙U٧Ý*.K֤`˟Ds{2Wdzv=NɾWBO,GuMݽ=qQ@lP'߾!AA=/v~SSsvZZ^ɐvO4*OoOY^ t^ ! ՃVfmV)*"7< SMΩ9T@(ۨ"`UQ.zg#HQJ{r&@6Al 2/r]$W7F6χS8dK-xvI CAz$y qGLFF~>hBQ_J] pOpikPVk¼oVYY]! L(WzRGF0]pȳBxP¾K `.Z51Wy(i}sv}#5Knd/ U an3fzL^Q;qA榤}wQ􃔯G^zAb-E154cAjI@$&wg/"Vk4ꈱ\~ՀhTܦ,l% o1(^}7NWNwh=L3Ł<DGRƺxw^nV]HAxJ/ݪͪ^*"W\Rp%YOOz>h /TR8foT*إ o/Q Qvzp=yqx*axCK:95Q ge`(ãmVμ",K$1W.Xmޘpז;@Μ!m(:B|#fp#Gm~PwGśYP>J!C-A<ʛ$Lkw9Eۆ BFB!)%eelEsBMޠqbgFcnkDTDחu9+w=[F{ej6Rpkw>6jeoUgr;=4R@L׀÷sX:9۬{Qv&:0i;je=(!dIUl^)diE*gPOcwp+zV7k'1pYx隨1rW'ͫӾa\vU!{﬿x}fB[8R%{p%h =X[I@J]z(ؾAFǶ*aa ]P8h66F}X>풆~k[ꂟh/\[`k8M~ꦯ}PqRrQVvA! ėUZy RѭZ'-Qc{ۣO|<,Cmx7qJqYb q7oT%Ot ج0UB.`р=h0idcujHxrZԾ@&Ӆ7Ֆ3rfԥ U)^p=E@YS!vLayXHW]v*hoo ,. XϦn<]B04y /)`c>] !B~@c6gWcf=Anii>@^{BGDݗrW$oLa@ZNEq3콲=͏{`} pؿY@M+3s2`e5q /O ZU[v{Jte 0t `ev=㧬BtXr ӱU-dA౥<-LUevgw).) ,*=^Z;*5ѫPwwU=ӘC+NjєV9IyFVNZl 2R^T )U\޺[$vK_zÈ:.myRCh$|XԷDs[Td!,l -^%1Da^YPԧ@֮ꕻFUNx>F-/eOc̓;D0gWWx*ù:*GV2lf*ϭbgo1u5SWHڲixào=uvKgO+jxKx|}_-Ҏʭ+>Gi u^I'<&dgw*U;- Xjq8ژڠ,NVu]!r:Mv.KenreFfTY);T3T\!2RzI8t2$ٳ{wh5y8q:fиz,^,Nl\ѹ2-W{vJ}l/z!6]rGz7ݟ< yt4y)޿kqdUѽ(p.EL+ZWti;΃ }ͬ(-:R"3u\*г9C\{_T+=s4i&}qО=JX;c R68e,ÎUyY(뢲gʵ^f5AQqHN./ZCYmI,a^ ⏵Il!p҂+Lt.)٬*[n 4>-o yj?{×]wW<ó1L#g\4c|}YYyw;JuB?N^ %_띫ڋ>֟vHGϚIG@V_|xw롂& `ɱ}lwIR-wvB)b{JHy[X`cN+%5&ny[X55]{̘ *gFa}F`<Ɗq @y+ͤ4!yJ%ƚ(nṧ>j؛[Ssio]]\ٴ=}1A=@CxJܡ\LNoΐ /StsbsHmכ`5)ְo/с1s,炚j )' k ژ`s4^k9 IPX"G㒘`95ʂ`NyƟ({B$R'@-+=1]!:^ڑUD L>^b{rxIӑ;0s~z)=}?#rӑ }htxvP?@(5<[' 0L`uG04@pX`8k^V-s9t5j>AV&ycI 5P8vϣ{]/cm^sω pO sqlI'0ߒO..&hm &fkXjNg(]p{*T/Y')!І4R((ZX9tsn<W;u9HK_?wW㭙DEpl朮VpV]8DqstQ}^ V/0ow}ܒ4wz,o4|Eb톸j[p]³.d}|;9~_ǹM*(Fuhi̅VTT'Yus(LEW?la:q*ZlªCo1/ira6yko)kriFw=ܓXO&$G'qFw_ưFNr6wEa^R 7ۗ;O)Z楳,s8hh<5A$t䘹xɹ_&sooN;ÎorhvL<'&pm1p'5 r6l3ItJvc~sB;G2ׁCP?('lYyZ CCaOd4^AIU2U!Bxq^ciȄ|-?r:}̻a @>vTtԫ*B֨Q%1xv~ XO !A$a6,3cbxvEEG{  ϐߴwГ̀a ¯؝>{\|K!9)bAб[De8bH\"]wwK-% d.0"x'w?Y,03\kLЪɝWON+)O~:8IӯzҝA,XUS5M{W-*F4TV(tGbކ6e J>ʪd"DJQÖBϮ+ @!iӤ(ɂXüP{<^oM_-:B";3Qץ9 y `8Tx͓裏5w}a0qDso͑"| jD3u^Dkoxs.a uLGa}Бp2k_\ɯY7f Yk uDè,9w4SwVBt (TV2V@hH]$<$ OѸ9G?C}xw?w9-s|̀8Ño1|'362BkbFf-sUتml4%RrbC5455R[ܶ1&7 ى^콁䢛 l읻)Ne*;E")H(*퐨N;h `UHP  G$i,K7474YQᔉ%)T aP;PQ"8eu-s: a]M1;`sÙ.`yd as2"Õ̞2@ PYX]cd A !/@b \6<ɡx(Hrm0]^s;EAs#xۊ^Fvljs{sϦ뼣JRr 'byM_]OH=7us s[>y m5k9 Q8Oۺ'5GB7I_,;ۛ.9r>H;]G,N+%ΩhSV'E ^Cs%6cУe <52Ō#3!g2<SiXd!bNf"ٶLsg8@Cwp]TA~f5(eb r4}DEڬS k[ҽD@CeB W7Jc@`R=@#_*~! %3θhu0$<@Y8tVΐŖ"=^$L)wdOcؿfO* bLLS4 +'byA7xys4gha(ȑb-9I0a~w56y`q(<%AGy^pW3pn|@86&oaLW:*13iAe RB6-Qd(:@LQ%*t1:y@YP4ɸ 4A;I.*6wP1uz yІ)og}VWh% Oa|7*aM|9W֧aȰ4c~_);;7 7RIywXDfIx73jY鮵ac#.6iq<k<ɳo} lWKupc0XD&(iX cz<"db%]%7_f?r5$iF|<Z'tY>; K@O h  =>O1 >hj|bOЉi BU5jl*jPe zw]Eg!y }ZdW3& -z'[`e1dTcq?fz'dA:xxa⽽ AJ}%Ĕ 10z^|a:$YIQ})a} ݅@\u^4u5-FE+-%c ƅ㸅Ԟ4y02ldWZ8\'pUኻ=bbAJv_pgkVxT_jK2f`+MFMPˍ?Ɠ~GqNTyebiQ"B(~? 쑵(Kw4d޹T)S>iyp3jXSE-bJ%!ϟ}OȎ?0Y+▌E5o~h=m'@\ `]zn0%$GQ:sUb ~Ic̟ 7 p2$AH`<*CD;xp hNY!C8b.DL!ٰaJǁ mWe,rj'!(Pv0p\!)ȉn1'9%rD6 srE7/:Kw (>r׽$nia듋G@,M$3~Rl6N_CqiϰH$5A05qiq=~4nbyYC/%7;di3wy:n^8ID3xp+[]֍ $3Ec >'A||xh5GsǕ2RsU9cXJi9o3b\\ !i6-V6,ˮT%dICH+ L\]*r/]dd6˻Im{2D),F43q)!yi6$m1vi^rsKyOzi<D8Nd`s|fpx֕b BjF tnQX(Fy P\T(.o=O)ZZ K#1GH}+FcynoHr)A=G>JWO9* #HV僠)xmKWσk~Yj2%ITJT_#9Hcμ$ pͅ1F($\64!8-D=G{I %r$-sQF>(O;z+2Bb$lGCZE!u,!yvluA~x"CzqP㇝IJ8äLZB6nuE=YhHCAxm\H,AZuMɘ 8X$@؄J9f6 R>=t/0DP@I&LyhqwI[<2V=̀.pLYzxs1aXFlzqn29Z o M ^1G)m t@UGǛVnP9 u阸t^ MIAAL}xv-8ӝ:2j|vg^qA ~5 =TPp|CV~IX}uNB6fϏ=T>'^M6JѫEh5X<(jj&#ꏫXa~8m墊_LM㨝i-뗍RG͇54NzT'A:1.PD)0+'9O9PB@&e3D\X P ڂD )I6-ֶI;pMpN`šzYڙۂdU4!Hy*?id:F Bľ3'cxy1kN;$ @Uy&@6mg?x{m9J'+~<" ʪ̍>R9Q?'|u+6591Bb̡mo{²;7HsTP=dmFl}UдfO48Rt=UÜfύڙMZj%V5J(JI~GχBoDC}9 g/EAO|s' GUs.9iäT~QWYAiAHӊPD" bau<`.a6I=%_#)Qf <Ϯ}%>fCm$үVyi@&Z!NT'[\uE&Io\n|91Byr9&niиa64yY󪾹Ю90D !@kɷ5/Q8htMUXwT cH+PNAKR('fر3p &۹;1rD =NBxwGy/0mvΕDg$@ҘE*mwV128.ȜN&fJ, (d1pCDDf/o?wl PduP n`BI-$VcWͫ\c&.ss3k_jەmyqb){+2CC# ja5k/8?Wxwlȷ9gyF A5<.D DGL#"n{v5UY a?2zAUkgʎu@x Du}}sD:]躨Tiw0y.O]N±AD~L`'Id3ƏI8EHnQWF@4(b$J"+AヘD044}(ѩxPC- 2`&" ']}r0D92E n؈7ѭo,|G1(, #? hIP[+HYK(ً3\LL&2pR#f `jh{h*$w7dQ2G;[UAHs%9 0Ir) sJ'cag`py ' xB8{}?A@~O((3"*ȫd/EXeV׷sɊw3{bf~K^l9w9wŞ3K=zk y TpE"U)$Zr=tRvO d[Y5z2PMMj"mR~:st}섁yQ=rO?!2 iFe0bwZܯs!N(/~HO!$rG_}4>0o!9m|spR+!pDWДL!^sM&35<o4M$7,;$G"/MMvowdDJ5 R}9x`\M y0l4\}fJ~g>^UMX5fjHgn ȜU`dGs3s|Iw)3&Y4xCDa ͭAߖ绸ԉ LALU]ai$ ǒS2e#ц5=D۝rq_ f~zD4IXN2ݼs3-[gi I^ 8R"\t3y\(`QBPk`k6(XTP\ 9eDŽ8B`j'jcΠ& 6!6JwknV6Q:nit.!+H$)C]_r%6E6QbF[afWiLa S'gcb^f5H䎒˄ʗːSE!M ;EvH̙ztB,svbiN17G1 '`yN 2n#T8),H06}wYp0. H/{ x- kw J<882' va'Ɛ}B`zG ßfVR02x6#)q$1$d @{nɷnDLb/RqSMc ?pp_u\@YA f䤰۴t<^63KtbLF= 짱f+5{G[0;\ :9u7mIDpq35߹mDI<̹g-ҭ-TMc% )@*Yhvgf?M# rKLjс~̀䮴,#ۿH  yfBY)eA Q&ϏtH8 + LZk;TyvI0iK${EKCłHZZ*"fdYӤ.HcHr9l`fy aD`oQdq@h3dbw0: x2`';ď{x/{Ç>5wg(sp3?A= ]Hp= 0'8Bw[+~;G?>j4}ݹ:9:4ygmha]ο'S$!7:tCv$=N⊿[̛:"ݐHHs BqWwN'zKq s\<˗!$cm.<]ۑ#4Gjlǎzd$Wݖǟ/733ަ8"LysX:.1'V h#)yJ|ZHUtFJSbDCE PHA(2$V+L,x k8"H=o.K>}]#8|zoy=ajٮ%S#0:>-vX6r;nx渠y7jkcy*udna݃ͳx|s2y2xh6F-;4 (Ĥ SfvL'x*. N w{^S Ih{ʎ*t{O @S r~s|eGL>xybxӣC.$  :u%_wcpwC%r)((~D=fh=P=/뿻Q߾6n9*?&HjO O% C_yw?rRr?B$=kC$|>k h@LnQ/MԐT@Dhpύ=oykax}[`zaHn킚H'K~xwOq\ hFDDNpQE 2rfG\ɘf%2!)J\^6jUrT@aHض .D(_{1\1+z܁9LY3\h8fkh@.۝{b=$Eڅp;L8FtpKiI9( DjbPČ"39>ԷB2H`\5XbDf7TQ*ZZ8LͳlC\ %6:"D)YUösKfIlȊrpyaA$51?n>B|qxE۾x󁬋>qz:O+t*Gsp?wJ6k@!"tqO j<'yNo-QNK04I.~4ya!#F/lUpO 0b|L◰ku<yޑS:+ȌNFF ۷z!7l%?q19qǼ,0Zlk_0ql6jG5]9ۛmK8^} (/';4f_!Q*5^3nʝ;v`ێnYkLK~~*NC!O%1>OnƔrty-%?j C3ydv '"f0 \ 2JY9v6M )R,ynp8%pO!g=V=+CH韪%0tmgJ(&RoDVi% ^p$"P<3 bR\K}MȦ16SJCfbQ_wԪ(y?u&yH6hkć\_X X,AFn' מ[HEZhCCSNGēȍ{vcŮ4_HvK юih5 XK>*##@#jrH;<RI"ݑ +CP%THFBOz<CSWc(*"p[h're@laLoؒszݭ{/$r(Y2Ԅh59*)#l8NT-_:w(qP9$U*/8H )@yt`Mr300D]Po/0(.Mޒ&2J)#TD8VCW`)2UyC@@das/(JWbꇔ'f#H#DD_ꇲ.?0APЦپnbmImm#k*QOtٴQLnt;o>o?ѳ@488t",lN֕}<.TuJh^vRחP w|t;|Q@HD(=ËSd4Q8E4:ja{Nw2"N~mbO6;? mРEO؄g0>w|wgGtN!w{Maz/dH9&'wk 6F4tHz)#iB,ā߸C CkB晘|y;屍gyd^avB,M 5 !)X* 8ؕurhd*:"F9+.$R&رwnظeA#B[Ȕ+B쁱f;s5Iͧ`! q\3 GI`\(S kUrZל(&kk߇,DX/$Ԣ_7 &Ôԗqɧ;G ^z\pצLy۹ WrxL:wxo;"+gzS$ ^=lnO #1EO0= ~W6]OPR p-钐([Rfr-53ڐΊS{mp.aq}Y'@\%5fRT#ڗg%( Y9Y@opD1ylr<rý~sz+޺Hܳ }pU[oC 6RCK?Z9k+%۵\A| TYD_{sHX#n8`XI)CGuZcq)Iv 87NZ\C@\@zϕH 9~dz+8C}$ P6+.q"5S[#wȉKps˗z\1m1Z@e>Fb ‘%d!X7jV| _#qnt+6os0H<WO!t-x9챸5z(Y !kVݐ*!dwo׎Mu2g wP03y+@J `Q$PЛ+NA<s<?1rPAC|~J UhAhx+WN/aRX' /2OΓZj r_A"́qKybl/{?sv?  "%?5/Ɠ=<MDR Az<~ӿ;$;?="G܃?}_U/ٔQ'J9ϡiD W#)%|0Ci/"jehs1I)˂?AK')lqv{9NA6`6ߞ+ّyϹfؔ$}O>p|&8>Ϳٹ\ă@9IgD}?ﻯ2L>_T!T4yb+$d x3*󋛨BxDRM@Bh L]=L&Ϸ;)$)0E9>@H'EScZvvV1JŵV2Zo&Z3 Qg6< YOԩ.z,R6He{ZₘNBzԕjӶPSBy; 콏ӽ{VI y~h|Y{vXVGb睇^s !P=9A9: q,_yYL\3\]GE4?^!匒A{vn"q\/&qHOq'jbr.e "y8IɂD⸵8 (מsc 50P$'`Ӓ<*(OAy H""ug9=9!P/az,N';b{VC@"Cr[k!hp*"kah3$ZwXNrcP濑=NHҷaf.7o.Es]l86 9\5\u4?aD?c2>Pr";?rJhS|/1?CA9'"4*y1Cd#T醺9 QSt?ڤO?}_`zzyFļ='eVv 翿0"Tp[UEJH*D*TTQ*E*$ETB*J BRU BQ*6chTRQ*JP @UU!( TU**D"EBD DUQJEJ%RU UEI!)   %QTU)PBD* T[dU*J*T*H%A$]n:rj(z=!ݎMznBT%QADR%PI@HQIAR$P"JAQITBTAB%" "$T*B%@NkwW>7)lռ}ogvrn ܁ݸMAwv4>ꠠTNGs HJmv7c׽o'zCvr|nM0 uP@Dq;]E$Tv}y:]uC,N}|;Í6wH9@3ҳ%$zk^'Ӟ'z#u>z2{ٍ*TǮ"$d[<ΎnCݹZ }\ _e{)[Ԡ|XI P>7מ͞^NGܞt׽G&[>Ⴠz:=,uT$AE =:n=#uh;5chàh>@KVv) Pz:}wz8> n{ss}VVz@YŜBE*m;zu]z> XjFFPJ% H" O@J!)P&R'I*mRRTڨ骟0! IJi2rR~ͻfbA sniD \7PlhRlM495 aE 5 (ML));E&\mFdHFMM)bH,lclE.Mws"QRmf.Ƣj5-ESkش6Jʒʖ4m5^ٵ5nmqfţWun-ͩlTF[5J5F}ܭ7]ywXeYR6[["fذhlc׳W{KSϧڭb}5jb/mzCLL[KMB ڨeS Hƒa6V6!Kh}ҦI d;eWI=z{Eҍح!U;=EثTZ-16_`vQڟ,Qfժ]l^͈{Q i_j>ZFil- } WSkrBֹWM[k+&m/VV3hl^xlڭ66]Ջ騴Q[bJ$ݬ6ΧkkM]TVvuڌ#jT[ۻdƋ&F#8(t]u csHni&Lۮu ݯ{\`FfwwDJiN˟w#Xwk$,y)M]1EhW.ZkU&n`)ewõ6^eVjO]i6Vk{9֝Ekcowmo+=|6h >_Oɲ}"ET[IW f &E5{\Vve\殫.ۼۨ-ַԭ].-S4%"#;nݻKnlLRem{!PI,,\Bs@5ٜmm-\ֹ-%nҽW\ەbڟ7OmOU}a*>LISGmThOhj[jM'ğ`E%.B-1PI5m\ѯmjŨ֋jJ5i]Ŷ)6M;o9n[ŃnZ6:dXs@,̠,!2 VʦMbW66׻yYITjM뻍k湶mwvij,Y*ơH )cmI^ ]bك" :0PqU\Oîu l坅,pyt23<*uǗ9NQvJg5nRtts [{Ewd\rFߓ ,1BSeH 9PYc TX*)ATHdՂJT+ˈA`QU 9 Y捔(Q5V1 D"08 bL+2"4,)1# Ye[bRQC"Q)BPPXA@J5l;R.uÑpmvp.!9RD"5L8 9R7UEv1dG&Wwvcwv渗-LY G&ca1l$%&g)(rB$qrlQݶk{W);Ev8"BowrQ*%58dҵP^5u,NVrʐG!Ʋ[MuȽnhusHC$2B -d㛡ۚsp1msu˾łssq(-vIWN]s.׫j7\@'+@]U+PLSuUynh(oW'vDsd+w.SN Df`B9 "RX8d-ʓn%ӧ tk湐1F1bʩ*%`&*PbF\$]7]p;^\EtH" )`,3\g]F.h9tr#h{T^(n:9kcIUHp$bS 0\̱r ŒqrL%3Gm^B\nsnˎ[N]wr Aݭm$h+rswt;*.QEs W.΄\h&HdJ<ƢwNcW-wWI'T DΝ#YNbB˖ɲ2Jf\K5o1%. Q+cs̛ "#br&ţQ.twru$uRʉ 2 D *$YʫݻEl* Ehq#(b]ł5$`0K;rr%Yw;%\1#Wnj4lF76-snn陉69E&4ms] E P5fࠎadv㸎1a6~vJL\ ڮRAQ4Tokv+4}wzrBWv+n-Ah#ڢJ(ѻs reLiI$ldRۚ6  MHcW7ۑFK3Iah*%z(IM+S[KbLf EıZ[\4DZ6:ʮT؄6H˷ZTQd$w[[61$[2{ڤb,Q4ZbFmhvy^zj"E%>Z +u6JMuY4I!yžQ}n bE[HQLX%Mb{ݵeD," ^鈉*"*"=kLȘ}lC,jFf$fE6MLSX54h #{ݪ%60gIAkp, 52U BFMj& d%hBi4 1OvRm&D dqUh,D`sIb%MDEb E0$mAd-IuĶIPmZ Hlou؄ԥIKhcؠQ!&6QQh2I6A&MXZ E% מ-ַ*#bFVLADDhou#mQD)-n{2a11MowLQ22XTlPmIIA$m&"ԞEI$$[oknI`-C1 )- RJA&WfűTi*(QXTAAœؠLlmy`ɱAEE%Ikؓ(DXo$$hĉIbjBHdƫ1QZD}[r*I"Z"X"Hډ4b"1%[E!i 1&,Qld"T2IBѝܐF &6B–ElmQhm'Z]ړb1#1[F34ֹhF V,UHP1 $DDX EbI$m%RZeBo*܍LH%73r5s\h!sY+0Eb5&ՐC CFR0Ԕh"mcb5KbEb֒B2ZJNj4FH!Җ5)b$I6F#{1XQMF2PF"Im&Z4h1)չIk]%FLdjL͞ul&Ѷ ư(m$1n؊Ki6*,ĕ!`рvԙr(#d(o( l&2cEhE(MQA2Ě1LIZ+ H#Qj4F[lDQ\]M@Z"X;,Y ؤ4QlcFeIcIbS2yx%F4YF҃$fBJD!Y BTn ;lQEf6,h $EQ$@ai+ Ƣ5ITmѣh$AHIIW1vFj\Up! TK`[A5NtQmnjbƍlUX+ # ۦ6;[hXԚ)4lEi #b k%ɣM[Z(^{V+#hJ(nn%&Dhe*Y4& &FhH-+|Fl bBVJ*,cA64Db#`ɋmʸۘ#sw^nFQW,ED-2@X] QEb4h,ؠ$F @HbP"UrЅc{nWUbi1`Ě bk^[ &Fơ60m\(I"yҤb4b5%hY M2c P,^ub$6 j殒Fm)QemzAPHШ"mcQaŔUkKmQAl b(4XJ(d%1)0cQcc`cbi 5 A,dL{kV**2d1FAI0XQh(kIE(̶زI"Q~ؐdmMI#Ij**6!QjHc܃ܱb($HIHl"#b+&!*h(DALl0TbXxEuQ-E-s$&0L[F0mDQaӺۥ@(1ʮIĀQAY0lER'牋mJIh (d1cAbEE!6WX<ָ*EW1-y-dcF+{đEFI^ʁH^5]A#BlHŋ#dZF"#mSRBIQhKkz$XV1chdspu\*KE`ر"vLQ%55T&#QΨ؋!+%b,F,`ȔoW^Eɢ(cC$D"2 %ZY45[FX !6c1Pjj2d ja;Y$ץ"Ihh5b$)5hEY5 ɴjY#Fƍ`B e5eC J2[F54h# ך$IZ ) +F4cY omjr+3(Ɖ,dǛ]fVf%!Xcd"ђc4{m8`LFJͮ"QadX41ʮcEZM5sQ^b4=򷞘&6 R;Ȉ0ۖQ\Qb6A DZ MD1HQeblDi4i`H7[숱&LQH d0DX&D-ho WDU Ej(* WIbMѱL,fk&dI`mT\j&ݵؐQ,X $1Dj1k 2ѤQ(!6H7vciAd Dآ)+D4&-&jMQFZh"{i) "植kt(6Qdb6PMy[΃ERl1b&Dc}nbRGm!$-Ad((nPcDEij#i6嫅F \FJƮ VڹEV664cdF  (J"h,ksM"mfh(,kvK%T X) PXKIh"IƤ+"6;;&$R$ITZ %h$xptŏ9lH!AcbwnZĔEd5DQ҉ABܷ ,l*a,1S6(b>G1IQ57+sDYkZ"nQcX QbAk$X u q#k166dwrhYfhMt" ATQ]Tcl[ chP!1u#EswlL=mhأACd]1"pz|c\qmBѩ%]6FR&^‚$E$}#mmrf+Q.qhkDƩ9W6+vdU7-݂ a湊$-sNݙ$6+hؒ̋cq2D{]͸h3i(Ѭlܫ4AtmrFaGuɫ$QsEcd幩㛳Es@,VٳdQ>fj(+JƄ ;Jjs bޣt{؊.ܮ`-͢ѷ4*,HF"ݷ=ݡ&sF&XJ$ez4SmwΌo4j˺\76A99&4ԁ68ݮN4WbB\sq*4Knpw4Y퍔.TTi'd2rqBsDn*([t+ 2 RCrB$pmL mEE%$!!UIpA-a%:1p5ȇw (3nrt-&95pi۰)% TTD8HYI(gQFsY AEkW!lńhl\/!LnIc:7w $b-J łSY-X sW \?=㣑ssp銹PuENʼnE_:#C$d)kmQ b,E.q7JQSv6+E;upȊE-t"Zw M"2EJFYk'*U&q1\)LQ.$A0Stnr*#wz:Fm#9M&CLYm@]]ޙE"Ek6Sqp,jX L\lRa\4]4P.qћ&!VVaJhEJG!E\§J(fq%ޠ[ed,%NDqsYqJH(D(Xb.]·JN۴yrҒ.uF n.̎d(T5:\ѺW~m (pGb*\qr*Q[(,eQ*G&" "es{58f]*y\#.5D8smc€) Mn9x1o 4. Ԟ$85Zu+; 0jk̃`_A95qyRSY^W4u^qu"LqC5"DW}g1}~o^4߯\e--XPcrA'2 'HJ\pU$4DrnWb Y$S/R \eA "1EbRH] +ܸ]^=˔dخXw&㺺wDkZS!R3nwcWsvh EddFgvL6Qi|u jJle45HIPc/v:iBWn‡x9&Pη]lS*RQFFߕ]f#IbJ(f{z_F~cEdwm\)JH?wm\ z cRwurL&5uLu=[FuS/UÍ\ƀ+u^jh"W킌hη(ŌEL%[`9םFF!VI5niuWB(Q+fWDFnEaDgDIQ2HpD1wwh1E tvcr4^dű^Z-&yz >o(@ dyrΙ4L'o;b,/_''._n]cAHm35}|TF29sD!o! L 6"B#4sђ2W7ھxE_nRhMdǗ{]Qm$dk b|wR&,*ZKfQѴ_J Mu-y,b=+y4Z,ZxHCZڈ\ոlI7$E|}^FBrD^4v{fF#tM&yB뺏>_ st˚vf Ð )7s`\wݫmGnזIdz[6)!.4I[p$wyWDb,xʌ:QJH"duQ3R|V#z*DQq32" nG[0jMjvl]RqF6nhF$QUr $3A0֧Tɱh naX+%T̘nJ];bv]mʊ떺̝#,Ri{i\;QsuT][dRW]'PJM}5vn ӒݵN(B̲(̮7Yr\",l\9% RaFLd E -s3}oR->mҒIiȋQuswAp )piQ"' [sbF`K9IMX-tc(ww4Hj&Ḫb:sH]59[tFrW\^=grhl7-t!˗h5tBQtQD)je6F5Uh6*4F&ME#IXĦb2kMwt3Thvnl& ٹhŤ]ι$ES6wd[@h14HHRllhMg|e}%$TDDwq 'q5*1tܩ LQfV7S&BcY7wIT(ڋ2 Md$h6KE(yVЩŚDJq܆:r#Hvs$'ڹDL֒ch 0nݺEw\EEE&7KnۭtQq)4bňݗ+ٹP&ر!o<:XW9GwQTNˣBId ;b rMiu([$$Zh1Qb1 EIIkXƓ.J1DdQchcwv#D\r1Djm# ^ʈ^FB12k4QbTlj(+sPnt5#@hFѳ ݍAJLDcILƃcAErţRZ(0*Eh)"()DFT$Z bIF-4Ih5 JIAUz[lŌEEWK5t2Z5HAh6EEKD%F(\4Ca`+ j0h*CrQ &%W66EDI!Y-+IGJƍb4QSP‰DEQ(H3)zyhAFY6MI4[1* i64TI&ۛthؤiBlnZThh1Ѩ "4IhXPbdXcQI61l"10V13D%3ص mģlFDQchT+AҹC0LM!J["X+dE,QRDZ FV 4d5F)4bd5b ōהb!>k|֋)6,X4P1@b)J ʒFbb12R`F5cRXWs( Ėd75j`ш۬eQX]wRlEF\؈""ѐ2sMQF5"FDb$Fm!FH#& y\RYɃ&( HfM.lmEb)i5#YLԚ64*1&#-u LE&CRh#U%A@jJ4[6RjbI4F8:;oRv6!v79 )y#&sh0X-&Ei"QS3 Ih1F(45FLIQ\"ٺ(-Vf][)+ $ M]ݠcE6.ƙh` $2 b86 PTFJ7Ģ5ҽs ,VHv\DTEa$ō V -(TF']]1Hh hݹ"JQMXJX4XV)\Lk&(űFJF0&56$b4D- cbz5\e2-,#&Q&6h&Gf܍`E%2W+te1 9#daE1E $_]X鹴G5͊m]*,cōzۛETGk-EF0mw],R;‰i6t7.zpI3F`븮vK{WϞ6m蕹n4Z]Wew+3h.q$ 88QɊ bArd1 XH.F`ѻJj}vԕ-2e&FKo}rL8U *J!0ɳns)nX:n!f5}[wuLf*jIn`]1 ͱ@$2Ikr5{7뽬kXƇO]&EkphJEhӭuH&/{y W\Ig{^tr puYȇ@7[\su1$3N:0 k]ow CgѲ`W:6f@׷uIzMOV=9\}*ouM}/wcwNpn.pƈHu`Lby}TDn6;+.nZ@6tQ4mQכwn%cFO롢Ͼs&כ/1}w!ZD"5ztJ%oEFs\g;nC7}:. Rl39sD%{n6Eqs& tRRi$)}j+PP fw ܍w׺xGå&(3jonw1fûE2I0HHH/ 7sdh`2F`DK*U.s,9SCb6aww&i awzDͮl,k*+)"0S&ݼr^ɩsm s\QpS \jdl!2AQb SrHT**FV* +$5e[Tfmfm#VJ6Ŭ65MR2mY)ES5$ͥ6YHҨ,KZU6m25f LIV2V5M̦؍&lFlFɵeiK(ŴڦU$1m*؍-)5i6PeZ)6ڲ6ƪҭRfɡZ2U F֪Ajmj MfhVVQ j15Fk f#j m֪jd&IJ2LSKhm-6ZK)MlVUeUjI,c Z4-RѲєjlEV5bm-)jZئԴlT6Z&!lťXMRmU4Y&3 L + d2MaY٫+Um2a iM֭FK(mCj[FRқR4bbj-lX-KMlMjf [L6Si6jL0d0l`l2jIU2`0[eeh6-kV٨ՔѢhm+b[ dfԶ-&#HUImM2Zɴ&-#*[(ڶj2dmKdfm&jl(XMTked0h26 ͕k3*jbjQ6i6FUdmMšfԛdTV,Djb6--Q0S2l&ɫJdYVM+Teej[mh6*EIjHa26&46`$Zfj[-ZL&TEim6&Xi2lVfL #Ylf6e6iZbmFFm)HhdiZѱm`T٭4STj!lbmMFҶS#Jhl[Y++ej&4dդdZae2-- +KFTmM`e4I`Fj*P4h*mSm665eKle [#LFlYɊқa4mj!lҳT5#iVjjM2ZY)+*mDfeTTLMih̄[K[2S#%4,5TMdѲͶZlY6FjUlY$E1UlƱfF205Y1eMMZmEIJdU6Um1FSYSm#e-m2jJHIM i֑ͳ,U*6C"ٲhilLT Xʌl٬jKkYZc&e$6k*56kMi,)J`Y3mBmRMl- SXYF5J4fm3[eFlhMTزef%maYFVJkĩ0fI5 li,U4ŴVVbehK&ն-YKC2L1e3eTM$j6!ڡE MZ51eLKUjjFVX ՑU+dږ4j2Rb&`ZCmX+KjFYV%daZYV¬mb&&li56P؋mSTVi,ZYLV&Vb,"Ĵ-b!-#IfԭYL[$i-Jjfm $Ѱڥi-*mʬIL56j6mIXd65MQdVQ5S4-URiImmj6MTd%dMS USH2JeM!0ڣ1-Teµ)b56!2L&b1VhVjX2Z5е[B2Fj 0 iYU J4V6RjQ5+Ȱ2&`h-Jd-)Zj,K jJ kV KjTʘF Ԍ )5#jVE2MDZUe l ʌSU5QjL+-ԌPE5FC5il`mԚjk(4LX&-0M[T+`CBj-IcVVVh&hmR(jFm$´iQllڈFcm4*%h4VMҍJ2fCDiVPȴ2iDV5 BeFC"jT1ȘUKTLiL کX6Ud5K Ii2)dd@́YYQcFVCPaaFMi4`i0aV&ScS6, ԍ[AhYMd0Zhd[jچ4XiY(յ MJ)h0b +F 6թlj)&Jjh1je,5XM,&XeiB54e-V[ MKd44TcUlF 0YdZVCLCb5kJdm1V42aZb4ȵa5`jj$Xhڊe,jjd5kU3TfFeV2 [BfU[ ̓di Ҭ 6-ValQ(̑[f2bͪMmU6őj&VF)l%$Mե6Re5&JlM &)V[JVfbƪ6R[E[UmT6[ 6VĦm2lFC2҆ՆaEFVQSbJdi6mԓed6CjKa,ZCRfJl֭& mUک!lm*ll0ѵlʛlEMUmFmU!&K(leVVUZZmJ5#5P&YSUFحMmheiV5-6٣CE6jZ3T*,RZٚ1MM& L#eSj3-jhV چ6[PldjmS`3A2ʴئ2MKb&&+emHbŶ6)hjmFhQMJZlڴAhɵVբXTŦiR̓idISFiZSbM6lM i6CIj3*Mڬ֬hTI[ъkdŬjSd4Q3+RKR6EB@OOKhyŸv )[͂ 3F8SwاL\0_1'8oôXWܳ! Kk䦔&Ui٘AјJ;[65 } ձHa\tH\$ 橎V E[\46 ot4a鄍7秅Kȋ8b;`DEiFMHt )X"W~$bcLc,YyNrY$f&UڅMRSGzL"S30(Nlx=l=˺S>`e>:! p Y~8రCXJ >*&UOmۄAU*1x+[ Ӛ{TD\„Umjn[w=iƴN8`/fBg,oh@,r!P<k36Q! df!O()6ĭ,p{ՠ4t6I^vV$RBT;2s` Hr T6_1W/A_I!D *.*پ 8<nHh5)vN|M>3陸uHg"e90yG= aS}yh,扔Kei,1zrO wӐ\G:/fE"A󏮕Wvډäfu͹QCgZ6w&Aɽ4bϬVhxYZpUHmX~f7U` yGbA@0TvkA=󩶴mnbɳN%L]ؓ9v{;;I -/0.pMuR ёxMΏt]RܙR{5pϱkD ܚWb;oXC,F4 P_S GJnH.g• W8讚(vib Vnd-0օT[wO8ޘYNqLg6 銌PǭUu +ˁ0WCl2Aٱ*&dϴ,j1s !c+5ktٰt)<3vig~X,$AcE.IW{JH[sdX[_=ADmsFDh<>a|񳎞88xMG$|,BAq&zOG99sۂ +ºB.B ᵌb1Kwq^0HScyBWx8f|: {_K0E 5"%,]R,;WrxᘈBh/pmdrֆ#r5WlKE{YK!ypj?;-\,Z8Gnt!jOJcum2Rvλ=LxxlQk=|w'QQFGSgdЧƅT;6 D Cđ ziyIjikTh zLr0OQQv.ωP3{1zJycE= Lp2,LïήS,롾m(-uӶc0['99IK$1 X5>dR/ekGg 8W1d0nسqޛ _o9򗭴@3yѶ>`ߑzAxTv7dh:<)ohT́-bǙ;CYp3K+v<LBi Eo)ë9Ӯh(mf%ܣt>|w27>Mc J>32Ё:u}dD*r^7iYKrCH k*:EӢ\>{nG7ݹLQ7|Rx56. v_cEڌpd4 &0!CH%k @ZD:PslMCPb)S^FF yFXX{짷h7>6J0ȉR,clVLnp̧0|1O)\"xMUQ@4E<{tѡZ6cMB%tKlw]{STQ9PcKr{-ٹ+v^qy#)̚VPͣuSuUauf01g!0w}W: )mjyMS{b|:G+E;ZVcٷxK؎U &U^Jna({Psכ+5+-Aј`v{V8l̖:Nվ+>\XA C{juo{fxϝ3٢WzC#(ïz7;9t̓XF;rFː>[÷3<.gs:X&av6qVvVYBIts*KݢK3ՆVgr{=L83nE(zGm }@c}փ"AYxS*~uYea/">];'xCj`iuR;`q 3,}n{Rowӹb~~ȟc^PRc6Go뱫r}5Z9*wCjeWGxN|MDz_ekU8zrT tc]fn+$S,ձb])7o/ 蝇)y(u72ocѦKݫ6uӋ}(ʵeWCMzyWMdGhB.7ϼ]]uq]ci\9uxJo>ʃGXBB,rJC[޷kmrGn˻ץ37;Z j0F.18lam'i,X{yJ(UΪY[RaBOti+R{{KH9Ƈ=zʼned3*X4zviyt,Y=}۵:`fcО@I:%BA`2NQό´yB.H_FPy}ҽ|JOmp91.w1Ii,:aAgS9ύR uuׅgL=gZ*j9%3 #XjtFBV|w٩Y4*!"1Ӣh *OďEIv:fhkijުݫa6w*n 9XT9]ଃH޶NUH{D<]zT/Uo eb\9&Tݜ:%$7ڌbx{\䄫ޢf7Ѝ쯡؞q6,3OO>>ivV`0#|r%-4]oRΝՌdnzߏ fe{^VK^0.Sr+&u8.18Ep2`cUbd,}m,[=7-t)%2cL97WGɋ]ůP̼MrGyc V6dpŝuDmoBL}]:]q7hv;Py/+8ڡRܒpfq߱-坈KBcJ7WSz'0y]u;F۵,w{Gfv{ǘ_ eG7_Lle*\TmܛM'B;vS9ϞPX&bY;A?fwD=m%^4Won.!nYs(Ȏvlb('ml# Z}1b<座-oE@йy7ÜVSwfD{o"K灍C/K &O=ۏ0Mq暪Eskg0֬[Hc{{G]ʙ^5|JEW8k^X3fLYzLe.bэV=۪!8Ζ]~Wn+q'+%V*(`-vt[wVƳu!=t7!'yg _!hꎛT7pz/v1Ho8(fŜ;'\Ah%~ g >Ė`@W#CzHCkORv/ώjP=Row̏S٭hpO2`Xch`0V}:Smd4glrބ͞JФ}ԺM[LvƕnIRyO|!Llh$mQϳMJ46juS_~\(n.lI\9CUǠ }KN'_-#_ ew3`E9'Wxwo.{QRz+#fsYuHJbۏL[]L,e@o+YA;ZdsdUo8F|=#jr Xjdru‡p .0}2I;=7=V,@F۩Pljs`1y:9D"Ȣ eTZH@3}*(P:p Uk֏-"R^oﻍX3wv'7d,n!WI؎^=Yݸkv̹l܆X7^qUV|׺m AF2 ۧPU$c_WMP{Z&T)] ryN;}xo<2aݰkFJ1oƺ^rnuVwμ.G.E#dz<]Oę-}aG9۴Va eIV.nK EO+zm 8J'}R-fbwZAU;4sapU٧X|_-soPW<ن*Gsͻ싅+ޙ Zy_ClwNO$1$75JkD \scC ٛroq٨Ho4%Sܚ}xԳ4Whn5#ˈɘ:˦zaBCeG/=^]o.v[=!=ͼX;ZSwuO6 ط۬'m,& ո|v3E |:'׭҅3bιy"FGn5,73L||0#5E6(!΍]Rԡ NܨťرNg)prY-Ǿlq+#F<3z8{ޒ#/U[7z`$G\ >1u.ݣ?PJ`)d9M&ȑ`Y4&r[o,Ax{uά=FɕݥWbZg^3ݎ 9« wsӛSyIrr+yǘ?;ift[vl=$}N|3j2岲f\6S꒨2<Mi;"!0vrVcVRݲ01b \V̦Q6MHS˔ޏvJ`[NS5<$Kjc XmFqРCzOg:^DnXƋo̬գk&i{@0譁*v3/-5j$̺P;甃 v=/YfMmV㮍uswZ A37{0bkB M[|whL-wGIS%Yef#4ypwbWxsb+9/@KjHDԵֈw+uXwt6HB|-!Z{HgԚl:mzs7j#{$:u=f.ӗoOCLɒ;7lշOZ(Rh\9szrnՌεiy9BqM29OG9U;C4'bOI7 iH=$LcӺd ;Sa}E pZќ$g [E\k<⽛xubwI:0@~^zH 0 Q 8|FjW~㘄{s+"sÉc:@ڝY/X)ͮRs̩@B x> QIۡ$n}9 =;:w-$O3+mf۵$CbOlQ*'4YL]fb>"1 ˏ*˗qF|Y>ZSf>xwN:N7Z:y"Ǟ ̋kxw48d]@4Wd3vo ߭I /Cg<0up+jU]pŇG[8;o$wh7ޭsWT Tq<:%͌s1,h1}v8 uYoV6#oh[^lYA$[]P&ķZE^t8:{ +3Yx!'nLw0ꂶ Ƈ.]PF⏻b3w9R.FuB6j/g+OqYыo4VO}o髝"˾)8k!ǷJhɦڈkW6ixV0j#y <;nw:{^!cL!yX5E(1coG4Nx=N %#-ޥ27o)<([XRO‡{˫ܩdO9g_6gً<\ggn (R_zu9.5;zo"%NW{xLØ.ьgY>*]x S,WnʷX\NPtI rX&Ή ۀ|rQobZ'ݹ. lLxQ2)X;۝cinVU|vw1;Jb͊ b~b!d}<ڏObpnOW#V@8`>˧m^INbAnXr|]7m-sػH=hŗV:WK$H;G Ss oE.њ#.] <^s˝~SտNDԱmm&*GuғA5*u96Sa˂  32yjyYe,X)O/ѯv<˕<׏)CZWʬ f9bnI\_^}ӹ6evRlVWm% 7lnd37H ^]\;^*.W eoZǜ$kFjߜ8h2U)Yl4􃗻:Ie(o8{Sx^d9ucN[u x;V a ٞɂKRbV=vZsٱhE/ } lZ}Dѓ$u `TsÞn KY]ϔi0/xyZyYx WGokc_gmLA…#9 3;nݞzg969F)$J$/1ckVԣy/&1{wZ JrC BMvnh= Ls2\֎ۭʰxohd˵N=~) T72935J#B3Շ"-LnnyBS1bLɘ[. ט'uKS:yfb\t԰.26YA {v 83Ex/7qTKmPsQRv]tӐ@pY4>(jyqPo^;;3QQ|d{SW Z.c#[V>yfq+ oQS]t;}S^엲`Z2m͉,ɳy'(CwbJ~Ie_kR˸&b+nD\xw#lmngZZvU'yݻ)l{Wy-iH秇֝aCƷ\q{ :UvI1CX848_,ۖAG7dOwv27]qtIUmM]}Ӥið{8m\2[HWA{[Jbz@O# Θ3 Ƈ 2b-j)|y@d3wU4-ܠ\1iAjW4SKWZ)lɇWDi7[7*J𣧤釘:k=Zg^`KoMX{ Y,+]b^ݲ\qǘ͹e,T:!BBd&,xmgx`gognyxUYE:/de檪 }Ş7a|ŕC^)f]}t f+ԍa650'.xޙWUyvX|5yNQ#5azgiHWukBZ}]n8ފw{Q.SXIh5#1 eu/,ԷC2gh(GpyےhE+CLdG5]nMmm/wu8*n/uz=`^ tZV;9‹fS4w^C1㻬U Lۍcl% ɬgC:2LqYu]⪈F-=f e[*Vbū ε׶$s4*z+Q;}pE;T+/Nvdms!5^ Vv=4JnueuG|DExQTE[4`\=kWwnln3bc=ϔs7yu3?f 1a/H>*gj*,[ϸ7vZL01K[c7SZ,hocb27۾B&x'lho1ga%5ntKȮf. I˼[X3BWV4vo/es:Vt8/ԁ-FǣG=qa$.MV,W~y>[jb)BoĞ4$myO':xk$yzM*"t}YF#]ݽySb g_69= +qfNy>sn|mrֺ9ǒ:\|=9iWI۷}̂G̯Plf\s&Krvef]=jvHL|{hI VJBMM^g0m ^s8u}thg.s2+*C0(PY4.VvQ,.IdKE*w=|FC篔3= ۔콙df#Mގi'̄ڽOc(DzO7mEXF[|pKΫ^%Kٳ* \S.ٛ2 '/H[sN畩 ϻ5Dn6TsSyyp@tQ7xvijӹMXKѯܩ]{R#iOK"vEpfm4 qr| {;SDuVʽ| A҂cڴ:ğW5ҮBR9zNƻw kxl$]:,5r賝RjmK暬jOfG}_kgCӺmPםV.{A] @*Uso<nlqQFI^;fJ1w\Gzͫ;VE^f}C^bW%oq zTͫ-Ry解xO9 mյy{_vs*m筗okrH?[.Vqj_UH$> IJ[i_uC@zc;yjRmx`ձy=5hb`)o1Y=γ*ٷ3n8k !6%{q͒l uYi骬94ܺz{ieF5O^Ĺ]H̆1V:|{;pNQz.$jxujۓvۜ¹:,܇ox6۽I^zN[PǕSUB(is*wH{ܩPv7}z."Z':!jfZh f9ewۗodpǡ_>? h2G>ݽS6%׌xm/vYq3un!;Q֮rx cP#u,X\}.9;b<ަV- 3| Ey 'Vj9S}-xKNjRfl:4kgV|~a[g#+ߋ&gmձ_z@1*e)]uTopd(;m5m`k *{i<"h<=įQ2Rrs3+y܀uk!mVs}n+NCp)0ڷ)3il,qY;N&:ҽǹzݥy6ĞB3z"x,NaҐ#ʽgM97;rˆF.N,m-sPhswuVG[ڰ)"v~G'dWz@ś-f9<_gMxg>kx8pt "k=A9ϛ<Ώʇ_k*/(ͫni͋#p{`[+e|h[\OF6.m`qjӣ'%:[-y0\wpA){wSfCp,/bH{K`̯1375jc y-zzDۚh݊ehgm[xޔblgvlJrTk)UMrɏ^xLpMSB8č9nW^XS)M9*Jﻐ]Bn[}WúVz:~XjUZ s9g,OW4&jٙ '<`ǯqQ}Xz0#yތ75(ލ>rIY~I]Xnیlu,Gjx;j{X#B-Ҙ!w8By}nbImlen\aL|sL˝Frpm6cy{uiɴLuLTԴzXEV7T_ 幅"V?zNxNGkԭ Bf*MWo=}p$ىF ].v=K7:emiq-ٿX6jÇVSm96q\9|a;g;N䭬w 'u/|] k=iޖۖ/TZm̱Ӷ+}O=RNٖH$Nsw1U[Ϛ^}orSy?'Yէn֖x1狳6hE+Y{y\?Rc~7*>eLwU,.Cu+o`0@]qKi)_je\cɷTfIyһ_(X }0wvLe]rlu}ܜL0h"voueW-yHfe = LvWT;VmAXmWMz%;#NYS f4zfڲe܇}mfg>MtfqA FL*UٛG<$\l.t@-`~}޷!fwrۗ{5ל s[]ܷNSo}cǧ<&E <*!w 1ާoaAvޓqݶdWEnC[Aٰ3Z+:n,}v>fn.p^U;rl3eSm_Tδif wC\4= )G Ui{ )6)$| .C;xz:Ss<->ۆ7 7ś^%N~j `b~ی=evީK#xhu7TԔ+4[zClfxb8/999Ľ,oF]+t*+&,GdP(m]ifw];uxfo_b|' E1a&eщvi[׽h㔣WnlG.SGIuSB}-I ;t 5 C.}t)9fs 7ɂKn_v}Po e~Άl*Nl vPԇ g@]vij[QZ^/+8z.xo)î؂^nxs39 xym'8f7oHv^=jbyGMwM_kphqk'Tz2 wmݾVO[~7zpOoȶ*y6dIֲ!,C&{ 1qʄ!3Mw/G7MTyjVe(CΨRVܷ*Q] ΔtǵA,PI՚)kF{|Wxk.`&>"-c[{<4+<(QG#~rOGpeVf?> v79u;dlN/^I|A=Uw>mwU.4LPhJ8 w4Uվ"v\ c~2 F#K &B'<߽$L[X,2gM}))-,CO; }E\yWĄ^Ϋ|c>ѭH@Cmrf[HVe@&u"okXaP$ ZPȵ1%(cseƾD)?wTىT" Z_xAl}B㻑 [8(T'+4l,R.; ehW )zC Kڶ֏̀g&f Ve5]yOʣ0*HpI|JnE]q;f9o!Z)60 -Kw1^ҿtR(sKF4,PYlM'5@e|ٗ2a4T^'uJP С  mmg(9Di:H'e0y}Jf¥{9 |$E $yd^%qQ2<*#,*d}A^|`QWRxQMKI8JB *&4hl ] o+.$7s*kOZCM <J@E%pPUM!,k/lakGΘ03UtjXItOws흮FxDY7Nl ?]!!0W4wYUzVmvfef#5ܚ|uY~ZWwOxߵOSޔ`#VϚ|8m ܪ"G+>ԫ'uiO#xj`U57'[0U6WSOb>s]y//  R=NTEU08X^Rz:<Şs:Cx pELu* MS㖘+oDf< kS4`I=*S5Q$N33 2eSP7 X `!Wlm[=4ٜ*96n_O7P.!%s S AB6IT8VwH"a$d /sT(#S-HEy; D?qE]1֡:#,+Ѡ G 7aatãHg& 6`IfpYb8ah=gU7'h@IlOvd+]%>U_[df:#Rꦣ};Pe!f;6:[ׁx0Wr]۠1M7 HJUzPXE 85^|#x %sÏ`0#3UCوdi!tFpHs,;vFt'RC x@"ɶ!cJ {o d.rDM1c#T`mW_h+X -wטi2h"rgZE!ʣSNχ7p:D`Χm~Us7*@&ŕqUQKG Z!ꝇ;V'㼪 Q!㝐,MڙUȖz׋9B%Ӱ7q}+S/g8(4ky5|766zl"id4w}ë:9x?vwKяkΌ/FSC>M^l}`s~|16H ]m!~+,X.Ƌ;Rf=YjB Di/CL@#UE @u&9}FPL݅xǃ9l DŽ>š&JcLHgFMZ\((\DщǔdIpچNH'Kls<P@F"O,n 9@`O$=Gg'l`pfN(o:)4tu-;FJ2ebNjq{s{2xʹ] {G݆U@r} Ҕ+h%ms$1_ ۖNA!c}2{!ۯx鮭.wm>9aK}{kӚNRA+\N&w.ϟfchM^Nab q,F*-R,;*uBT ;3xȘVoM#玽=fjb >u:@Ƃv# g\2oG̓{3Bs{{-8^ROwM!C%kHM=gZxiWlμ7%zZ(EOxWl fs^NJ_} 6OFv&kyKќ/fa}垱=ZNrcit/s{q(0_>nUufSAйǔjs掣/?feGOHiY&_zxygޣ>y&@ȦVŝ/W3;uܲ(FЏ^Μ91C[RٹxsD<ͩt ɫ*.8;W P=dyv4'oT=J)}okX8 zOC}-ѧ@,;v's3` )yo=/˹8kIo^G՚M{]?bv:T,S:S63.5Vǚ2H3) Ma$*2XbLj)-`r'R=6,dgc]'RW1Uq8CT\7J7ͫ][÷ X"m-XӛU 6CYy^]]&exؙWyQ̬Tޟ3'dvpw5}QbST2;p^"ȹ~4JVrҦZ56t.ʊUdos=R n5嶳L44ɌFw\KՋ*n傛>V#BU"SF ;tO*R邊/^ ]wy3ܹfa "}-!P;"B95aQCp Y- B%tBv B5PT4#ÂQfB 8@#d@@.uy.XYjHs!3#aU_MYu,t p>gC=|b?F/ FW8Cw:cH=hd9ƾ_تҥm>ڢ ^ x WJlBN|a8G̭#>ٌAwUҎ| m$25:&ƩD*)!!a@je79فUsPʤ6 d@}6sz/8?s9 ws ל׫BD ZdR'n]K]g8uc02X߮yT 6!j'τ~Tu:{(rl 6,77  ]3tt-*D-( iY nnhqGO\\Ճ `)Q.AT#F @T**;HzvS0lyUo%}dxþ ̀_cDd2PPig FG5|knUYf_Uh~YF)D< 'H\vxW3tj(>GG!懺ЛʹvRmUT8,QamVZ67^OH"z88O'Z!iP )6-U"BH;"/Z!#$!jSwoОil:4ɘ*PD!;ڳv'!Em%swǞB@4 !!|!R%,l$i,770,7wp y|f{^^O<{78͎_秐U;"b"H TkEݯkNF7 qy *q#tR D QSZF$BBlU͗O9s87ݙE])F)R}MG}YbDzOR?XV!Ք >W n@׋DD i e%Р)n$,˦mmF-KqLPAԆ <2v0!QR{UGQC*%)Qe}p(yA39Ȅ2ZJk8T;cQzNCKE&sd[ !=}6x;ĺCWF}|+~~+K9C%h7gW*3~0PXA"?C=e}p;4S'!ڟ|ԥ44E4lB[h(J3b2 GMr7M q(Cf#+Kv5BnjHjQ ;Dv!!]MeЀhd@up-h{Tv=NiH"5C*KL~~zL:|eL<밎=<@||B;υG}x5;ݶ0mnt 0Rȋ2L5z1y/5⚉ h! JOTj̺Y@9 2ɱPDC!SIyT&P$$!^4ii xo ' ͌=UVrFh&[Uۈ߫-6[5=܉,ebInW)G;Ed:3L ˏVHH~wm|r;<X6 sѮn7W!UʹsnmކW.~5d}K պF&굚jFK#;D냏],LZ{$"<rrS3 { 81_&<FrW!S,3 ^[uq*֊w63s*ʋee!x;O.,V_33fK^۷Sv|-JFU`i,]Ußc{/m~"ǴfJ圦m Ա&,ׅ˸[ӹ3 з hù(4y'n{V-AMA_|E))EvtV|^oc4]Р㩞ՅU5;#<Ъ&8^ #;631wL&ͦ^ x]5u톸N8g Mϴh}ry"h-fyDP4:6,5a:53v,K[bʮWGuKU גssΖֶmXpXp=-bځsqMfͭv;pAt se"؊&>P`.Y_VQ_]%+:N6v8T\ e%tuFJHnܻyJX9Oj=r bݸZs-pzok-Tk]kfZ=_t9E{g+=UL܉.qRמyK&݆%[x+Qf^ /;F1a2Rk,{G/V:dtr޴;sEf^~m6Q[:ʘ|O.KP[&>!w/P+("WNVW6DۮCrd+1:99oՙ+T޾I909H'LԐewI哷z,Svz9]n (\8ۨD&܊^7{b!ޞ=eMP%^drb޳ +uVLWF:ɴ710lRbocɘ9tK/tn!SnSym{Ɂ:N3]"\C,=B$]pOsVxfoRkK2mr/u +m8]G;c3vI I}Ъ3BUO#^e$ߟ|}LJYܵZבW!s5^'흷zKb&u }sX$E%یo@֌X6E<$'0s{}-xKVS<'|.Tߧtvo9)s U] n7S~1߯1u^$L 8_$ 4r]5Ũfw \Kܱ%WT)w¢OM"~E2ko+2fG#1<γmnٮsًٍ{/[sgT JGi}=#rH]ZY1㹮>S=jN/J401V_:(Uw,n&{vYxZ7'W}ϛ ݚ \mн\bU\rv.IetZK5 8b4ވ-Yu|srL3-A\o 3wAX7,AJ\ pf cMػv7r8d,莧X|%bo&qjY+QT'^a{IuB9n؎6;USrUu_)j='eyk[iHb}+F{lo=NUuu_Z-KVkt)LsmCٚv͛$urY j"wlj6Loޮ(G 2=6RUzq}^'D7|fZܙ"K,+SrX\Cm]r֙[=0ܾE&>:I,X^c pdiw4 DY:,%T;x˻udswZS~FgxhOXsc=-f0n;^ӛ,ܥL:C([CpTC뮆r="ju >ߒǪ>^|u+zʼjǏ̊tl@EջnVbV{aIsJ;OrrfH3ohBř΢wyF usƹX~NmK7)_we.5N[;zs3O)_4ɻS&:;Q][|&f`=xDP@<|lH sےjif|iKT[8ڹeB>b,Mvo^wӻ$GrQWb{2Κ;!v^ڻUJXkKz. 4u%.s^g &dfp|Xa*` o\QИηjp%tcۗ5pfsݓJY{2[Z*鷷 B窱B{w#ݩ.96k)zXB<7y+o'O.q){e q V3ٙ:)w]0[0j*h-Zȱ}dd] @zb:e$Iͭ`d6N&|=k..c;YT.}t'G4ǔLU] SO?lno4oCJ20ywx.&Vۥ"WN]͜vݽ4H:ޣu4n K=+Ld]雾֔̕n{k{q=ɀ١}<:V:qJɼ=JBsy*HBh!b'qddgM&”tJU೯-9&DSxcf֧g]˩B fs3p;=uSS)rlӶZ$ޖf:rq}V7;vez쩗f+xjHְ*iZ6FPO7A V&=|7%?{.*hIYֵݒ+r`Hbk=-%y#}&'qͯ-n.Þ=[q3uj\%pe+Z ŵĝ(bliqK=1m~1rv|n]#w! `Psܒn'l\ӘJo߫Ɲe(fvtffz5Ğ}7|eҹfj@z35ИOmYzd rMM*!uȔgVvY'忿/݋̭;xIxX~iX<\H>#~^^~dvt{:~FYde+|⽍Jfwh`V)2\vM'4|f8Jqdr^,FQ֡,͘}cKx=gZz mdjc9.%-%c-Mm5'KT3^jMimsT7ѾU#M'{S݉f>J-_VwkŢvy嫛6g.-r+iviU50-/C]ՅOzbQM<^H;l?Kb.;w+ծړm⏜b孾;ڡUrE>6]#[fwJKpa߲_pcE %qr8]URpjG:V+bCvu]:nZ4?pJ5DkGUg8~ϼlYҹvY3c1 ^NnJ8ԗF#9e[ln w#NU,m%`O}xq#$A>;FH//}e!%H+`'Bw*ɳ+v^칶ۭWֽ+wANy|{msqM;n]y5ryS E8,I= <[fT 3=#H/Mǧ5a=ӃG/f{[=3j1oskD>ʛچNYj^]⌼\8'.+tzzؓM"yt#V-+x1frX1jγ(9uh*7LElQ&f^ZE:yjY[dsoMڙw^U ;dڸYEE#MlBmSkϯYbd ;j̹mAc2n_}s;g6wٶ,k9czjGWSisB6r5rjt.loMYb7e_^F59q2;=g=0mGdgmȗRMoj@H[xwvs'= }Ryɔmw;ûga4不7f' lT c",87&zfbx,yz*!ޫa[26x#C|«fR'dP&;{ZB0UlEgZ[>pG Z}s:i#dZ͍ȣ*^΢#0˼AGrg -a!նͣ'%[r`ٓJs ̱Lg$vÁUZ|Ńvn+?\ 3gtvyԛHf縉yekͭC\٭G[kTZJ5{O{% CB/OEl+j^HW:÷00X v*s>w޹f8{vdA9:RÁ!zK/:~uc.+2lTU6ykh+)֩d8yqְ'~q3 g#Oˆ }q3q\u?dGsp_5ݏ͙6lmmuv4-B$b]xX|2򃔺~ 7쏅^s\JA_nV{9/ r7zYN'rH [{mc,>vQe:[d>%sbtvZNGn״V ofk8dDt͡6TIJ;N{Ӣdl=/~ D,w}}/-=Xsq:}0}\%9hƁkGj}JoŹ7Ň$ ._lTnG^vP6JjLݵ;FTo>wSދlPW"6Tn̫wP\!*53^adH{Įmnu 9AjNI(Z&h #ǜ̇2O)8&o 9jm PE3S?m-dԃ:qqpsT2EW@4 4{L@hi;22K3jd@V*[3+/sSD]r˺oB!\viaC@ݩb&߾ YVa9 y=BP7 9m VHμcaJ|6\K0b / W,x[~$"y@F@j}a4 T J0,Y<>aRy&|jTL>oB}ꚓuC%EZJW3Vq[YSڙ"y*WϓFһ` A<}d͹uNLf 99|u! #7u%EFM+]T:$3HѰ!!ӭ"/MRynE W/%:6GP s wxc=3y^N" G_x!ǝ踸]xDBy*^nQ.8`,-" j(l\p8D9DDX*Lcs??<'%%u]6́6qA8 (>^ IP9{;HH"ESAweb]Ylnwru!G#ʿ*[nWKtms{<}˺s{ȱYڭGq4<~M54JN>@@>:mO"oHi0Og_8G9iï\P=^z7QLB|6J ȽsU'tAč+z T2_Fa#cM)1z}gh(!Dh$^1 t_IHϙyȃ jg=kmg۴l\IRBCܙd \W <1kf\3Mm3|lMK0@}w}L. ,^2V\0nkT>DKyhwh'm.-1F,p4j|@j(vxR19ϳ(88"?:Ls^\j;haImMvȾiL?}B^%5^;lKd WʙLlW ݡ} ڻ´{n3qw.e^[ Xf4rpS*2 PdQ2P>5{xgjxY&t@hh`%0nL9vy>!sޜU;[;7xL{{cB|>-v]v(oc8<\/3;R~xp~Fpzy^0)))j.8nw ;DJ+/4iwZ.e {e0ryI8YUe Dc{^b)L:BѰ>yV1񉠫C16x/c7ܵiڦ#. +':zQ Hs (Lզ= R!rPϖTA^ 9=z+MAD|HdD+}b8ԃ~|բysO[l98"~=~&j]6 t;X|~7GE˱`>{fKϧ,fg{6h`hguB\VIU'J{o,|ȿVov~D_Ȗ}S%֫:PwO'%s~{/5J}8Jgu.pA\HS { E6J6@t"7$`hSAtv*I ̫]JRHloH mHmU03{ҾeGye8lKȟeV9ECL@01CGMqFσ<&qO'w;Aw9v(cDj`7DnB{5yE>_qݥ9T}sKa`Z(0,2eb}kGU^T@ȇ(1H? rDMD$rC[s3Tv);Ӳ'h,>xz߷|pt>0PRuFV'tOtWG.'9-ho>>'{yϹ@|XZ_kק >==[<:qVQZݖ 颣8I!q˫#vS~ D;~ 8hj0: aZa1Du`W1\x.w*<zd~x'D>9ǵ4> &dCΎO%>5 mq%t^W=Pj&q2  jQe҆̃RJ 1C0{|"߿쟋Ξ $L^|M!4ģiXU4B6vC! >>s OlTX]%5b˱Ӻ<.<Q$@qmJactk|@=ȪK;=I -B$bؤOFzնހ{q>sYaGRe- YX""JANB;2&Ԣ8&] vtMd'ğ?*#=8y|}C_ds˒}?*wP:w)A-(-TlZJSANNТ 6UE8 ~~Hΐ! 47lk˄1^lS4;6~*rTKm@~]>~n栗ywN]^^xz:uϫ^uRƗtr+](PSb]Ĵ*!wy| @3TSs$(CbAD^UG":l$TکxDȄ DA <?mř(\dY\^l+yng}8q痛wt֡w%y> ܪOƾkޝ0=u.'|:|>_'=燓]y˶⫼{wrCY`(oAaO,T : B.Cjjl$l^&ǡd.vԸGM#B̕XE0U#s ,L=229(`| /3C+[Lr1sw׊( ($ U 3@l2>Cn) "̃;! BaZXESOYxJRȹL!jYY_ߩZ@~NbʊO$ 29ߋQL'y\ LRs8b(~ppP'V-9@PX[Hݘf. UE*~c×R!끯 Q!uIc/lPo%p*aTK=5TXg4w8*X&st!v9Jj[umH[|]3KX#wu "rqYq;SdAs0Y,k&\sG%c*Kw=Wyuwvȅ\ MʼnS?T|=y}x+O6 a7dʶ ;!1>B=w=Frq5n[G|>8Á#IW9Ãj ?2'x!CP\FZ>$$|T2 jd۹pT*P#CͰ.ȇJW*%pRr5說 qz͸9KsuͬDEk7wr.kE^mN9h yfݜusjkC]7=Swan3G6=C,֋|~|l%w66_R^wx?ibϛx)JP'T)YIg"/_E-ky~.,Yõ-3^'/sA6=5{@+.K?UIz x]@i03"(Q-%FyiZvOb-|7e Pd+>iP VM+:nK쁋njg `Mb3MLuLpR/XTёA79aNNTe{ؑw'Y>fbF7& 'jX[OW92'B;I;/1vs;m"J t=ݹFԼ3õ'0D@z!d6m=lC wN "%ƾ2OgμSstk0!Tcey^^9FTn:=]%ٚl'ٛ4h_o7jtBHԚo x,0~|"|#qı,[A*/%ej׾.QïG]ux8>2㧋NבVpaN)俍2w?wevC.1eNә*g<Tb9'u/Wc|吞ЈGiMûg&!e.kC MvMRRNJzVDzH֚z.%ri_KޛVfq+l~4Ad㛎ְ1t9|ױP΂+˶C ټ RngKۮxtw8'tg<*9Y7HZ931OAoPLMɋN%~]'xجp(”y#U&PV #r;U:/ ߸M_vmL.9ge!MK:u#:2"G\R0quz`ȗ<=^wj<-Ι鹺\u)تH:vݦ^:{}7eF,pS=V${er܇q޳&ӤQvH̹)|aW4Fub yڛw|RCBIG<3d/*om~:1nSUx(uc E}=+nn\3U!L"MxU%jM8;Q@[=+/uBtD0#j>h/ x@#`QRtzy`#l>)'8"5,Ӎ }QqS!6ww^Ч}2U-nگr?Z)XϒF-Y_+CY< t~en ӻ.>R@㙯|`>fmˉU8uy\7\n~P(]|Wow "<tU#_[F&vA+x-~_9!m^[ UWDqaq~cR |sKD̰h˧*3͏W܈ϚN]>^BW=Oz_}^[RR"HuEn$s|pGP+pMd$ *p}Q݈Yu)T;9.=)'.(5i@BBӠOfKle(< Z:v)N9P;Q9سTkuNA˻ӾĜ;8,p[[i(j.Sx@1 O/Ӑ|~x;T"YȀ.",<) I ::N\pW}y)]Qpy"pO!\Π P:x:HC9(4kT*IP*!";wWn A8>]ZD(JET\ߏ,Lc!91v{ kW0~_|{T}FհҗǽHx)QʯOyO=(䇟\h!q݃]>@C  wX+gpV-D;rWnO=ϏR=(9Rz;NȆ9(Z7Ϥ_N]_QPWQ6Cиȅ \ *%I"s!}Ca U3kڗ1]l = &|J|^>qu'Ot~~<}~z a}ĸ>b]^zzTzΒqv} u HGn44^2#"$78 {H$TUtUf}kt=MwM|Uڰtv *@\)Tixc"zP^#K5tD︟1tg<OaE,ȏWOyK{Aǂ]J{]*5SS`>4Ol7!Spp@ޢHR澪QAћL TPd4v ?Ngr?w~˯|=xl_D,'.Wj|InB\zW U;E PO{A?~K*A0E,+) ]_yyTiR˸Qc:edr(B"5j2=d$*DG`W=DŽGt\I!UD}KUiu r>_dF)G hZT/ ta z*%[.,qpwO%^>=VٮtǍW}:D皙^H˹ǕԩקI>D3_}P0h⎶8SqHRTw.,ƣJz{s<&J^Ƹdٵsoג.p~\]-I^'w;ͅz{=P*mBQd{xa!Oϼ.;;9 2 (-8:آs' j=]0QH]\?#r]n}싴E-R| pQ^ھ"IwLS>IEz | Py27a⍠"k&m}ha@1OuaՁpjaPsHPN[~w mNQW5s`]5[R 2iH*#kA/;s՞s4ؽ\NC.HYu؆E+ 9Ta}금q\-hNRԋvb'ϓH.bԐ\0q5mrdݶȄ;EI}k3.g QOvQa8O(J4Dh)cj܄ܱG5`c\h\j2.X~w3Ɋr7~iFOGd*#"&Dr`cŖsfO:{N54. )XZ #߭H4(a+qްIKt+̼I13LC /] ϔ{9Ǣ^;#F\j|vm<1g^`'%U,d]x4h-{pF*]b=La4ĥ[;$Г1u3whd!vyWqe!k{7Xs>S i6uud~R*!B>\NRWzԦ;PdND$Aާ9ݙjw9u[9*N\ws"9@M+=2ԮٳnTWc%3zFg0R|#{1ho sl4GD%3[f,hϼP@_cVn<D?N[HڪVPڪUM#soGw=yF ,v]g +LAyo=+GoꤒJ 7sZQpiB_R0GW5 c% (|}sQW,G+Vj^.4KB] pCy}"zg]A]eiW;:x)xy_Ι3oň&fnTB=:њ8w BP9[ӟavi԰?^$a4$g`|n8fӐr%>hh9!8bV\|z<ӑ3{z`PĞtl".s^;ڥX:؅fNiPv{3TRyvc=.W"haU3q Dzyf=f INჱ&/ԏ$=s kJғ9hԭVȻ/=+ۢ7 {cZC O]]lk|S>s z쨛ha])dȴ?gs,0v AS<`'hg$Ęy\5񤟾GP$g:&wG\Ocȸu'&hGj\"Nw3紥j'%GQTsk(i!W\2l[Hi a$a=Զ:KA te*X,?q}A',~Ϟso=&E${HZ/8ZeF<~i_x`ڿݰBEKj^T 1 hz.{\Ey~?DM6]: ip S`~P9qjfa pM>D'v~]ǏX2B\uW,1/rkiQ$Bft4_/8|B>@'SncYT`Yx-(U3rGzuUGױozs}!^ Fv!>ҐdIWWEA2;QM_ۑWmy!$4Й)D+ ?WQ3'ΫClZwKSvz1/C>rW 7||C 󈉁pp].uNӪ.R`ZYPnR0@ }$I ?Z󺇽s p$ӧlhn <v;<{Ozz;9h]Gs.S^eҞFẄ?#a?tSy%%]x}{'CfT ~An?9%}w.O>{ .NqSϝםR{ s x!'S~Q=@ۮ@N(z IP* nfɢ'$‚AeTDI5ڙp+{ peuq d|8֞ʕ[η6Iv{o2P%UU [wO HH!}2`Hk4 4!̸*|>|wDޟS>;FJt8_4uܥuw;_\9Nz࿗{aI*ʢTRJ#oDWtv¨pˬU0Ϧ;'W9Ÿc\8HJoOo(60ď5A`~"h9=|ӝ҇d wӽCb\=KϚ3C/}^?pS^(5Y݂U} %BJ*Jbj*52{9i}O҆<'GyL˃1ɼ O0ӵݩO~g}A " Q TK3!u+LJUy9R\ A;N= xOVK$BZm(Mf6屋8>3cnHŒ{:PzbP sꑨ{@K.^ $I#Ğ91[hsYqCydOހp`_}u$9A+Ӂ;{ܪsw΀:/<{W~:S~òp1CPV@X\1PH{V+Gd; h(x]Wײ!4j,/c >Y+|Å1<'C Fx@HC.s|uNyG9ϓ8r#zwu!ύu=9TtNץ&~ԀJTWBeCh\.SPtd ڻMI3Q5/A+}Eyd{6FFA$Hĩ"z$N%g'r. ʿȒ$"!! dn t;2);A{T$\oԗ~-%$Pn@pt{pWYPQdߛPMDT#" \Z<)>]MBOi #PZ]裷 VHṼ%Rͨ=4To VPNgy}*~+lQ ~*cEGy=O&ˏę2H?b˒+_Hv>2fREqu̒s>T!P5< |a}BDC \9@xܡ"ώ1IXdH>Ldw~x;XI$2}ˬhaL~N"h uhD淈ˠ=q5W [; /cS6Qv d*=wgy*ͫ_]c (}Y1{qUgz󊼶'zA/f{fч㑜//[gfM0,ɒA: BUV:f1|7(H$$eNuTf8&/,NY&wzF&|:>чxq0!{tyQTєAE͢˱!݇yi>FYM ! y/1gj`OD2k#AWӺ;[H{\C1+%nz'` ( z3Aj"H q ^}Ӵh9U?|ƴv% Whi S^\icy=q4@4̈́2IN6,\R=[[}wX]]=I[t!{AVqՄ8yd}ǬsT, Pi/>[Wx;TqpǼ2kzv[ R$rw&<{WwŠ_ cʝCǭ^.UB v R 3H'7Uàx X72]vZ%|~{n+ёte[i% i|%loifg1 80vA¨~,{S )72% 5nWx;LW.! ! es2uRD$lQzr5~xmNˣ~AfIp#x<ZQzĂ4Ax_$>} ' ^2}y=~rUG>K ,(/~!89?Y* %̖‘yd{X|x8+y|;NlqF}AyǬҹ˛UJa)~x_w@y.m[*vZd %WK@E9/_v~Iy؃1KDu|_8Q塜__S@k4wN~T~0OW=hϫ׽uPZs_zX^zޏth\AG!>_MOz"dU%J@cCbo)nVQـBW]i?)?t培W{u'M4r2MFrq-\<HEo}'bU}\:ùʏ{FE8|+ϫ8+;N;DLROQ? 7ɴ.P6(SUZO.-r%ĸjB>q4jCj)lUEƳL3YW+,GppHFg=ڳW#Oq="'OO@=&O~p:i-@-ޘ^Uy'>=D>>D=BV/=>tѯzPq?'e?J46ʒZTDp@_)qMBGfȒ\׮CE\'eɻXX|"~;}e\>E?_]^Qh =+lU/H!Dbu4I:%nBX$Ͱ'O0 ̛rr:h{N q޾⏩ޮuY}M>ʧe*QrW^ Y= "HAJ]'#(Hl6 $^;<=D62 ߎozN`|B欆US KIAV1=CP }7>'Ejiq%U^/GyҎ]qʯ뜠s_}uטe E,W}v$w6R o6-66!%m{25hԨ? Ƀ ߿?߃75 f:(l ID3-O@ǺFBm_σ W ]o޹^O&ce]"4`JrJO9/=^{8`"_h|S qTI jn]b=$% VtB|2sSNB[;u'KXv374pWޑ1݈@ T_[oyKaIiw<⯸ry=p\NȅZv^!?&$w}ʕ듂E jdkQ]X*`=U!K);PQ>UNgcz{&gT)*U@5dpɔ@(h߬#w,>M S |:igu(!@]6؍eKb';uz=[Dn1du-<ĉaڅj,'*uM܍grnt@\RvWw0O ̽#{ 'p>=d {Y=1 ($6=͌?uړOeQhk| /賈~>~'}NE;(nSj-/H\)l%sHb+wЂ 8a?~SRN m]W+ez&_.^c>.a^#Q/etQ@j""7̥ۤFA7A.C 4.n3'6ZsLG*7A`u1QE̜'.F@s+{Wk"MHe$2g3sA0Om>dq=CUETJ !AWOۻ2}wP{"88H9ܞ~,^V57=~Ct?_eHX[ 3wuGE$C[fN^ +=ҋqǾ$<<1NAV9TG*˘2 Hd^6JkÊJ*< 9b{g{O \e/.uÙ0z £:WX/ʯMG +i#v[Q]J:s0돏>`#5-{&Q'Ú`J@*o]&L*]X=O ۹8vq>gs/ӈ$5 ApD!'D$9oitG8C2rKsqUxFd,OXb`j@Q'2k׏#8Czs.n9e?Zjyq]8+ Ǽ%5\ a 1}.Q&3h /DUfb|2$!LH踤!}O>_sC?6}ӊ)hvМ~Ck?*k7lq뾔BJYzYI#_,~t4lN ɝ事V7yjDwKo`^=WbžFAyώ@d9޽޸3 )R~UoItݝO:^}r&M@݇pL懬o 7~ *a [>"Øc~e0DCBR*Г>>X(Ejz}f-*`̏KqAjƐn@IzT24X72 B UA㩴 '豉Rvg{βs=g #75Ex^ W=$-6>kB۸-+UL(f@ZPu㬶Ulb؛D o*ǽ 8UEc^'nY)LvW}GLatﴹ-G.ݹ[zGG6כ_6Bv-#!WnS *$Îj&Y'E˖ pS,>h\̜,\|Cq\S|xlβ!8#ij[Bz>$ Kn#1Nȫ75gXzj^ 6 ӺwܲoĤ}(DU3 /Z>V].O5 #T@N 9}OrӏE2w/rNDŹ˜{X q-\c3;Pѥ}zE/yz{1]R6Fn29zK7%B F3xTT$-w\ aVo{7{;B ź{79#3 pfif{jAFw:?K2V=ۋT{2]qwGu%hmJt_,|kzcl;cD‰`Jp+F5HтFC$Z̈́S\B$eRՕ5nWI"X%PK{|rg4sL}lpr]ݩmNyW=GA頻\%`9rآOa(wBd 6٬1a@[Ky#pHxI$ 02 ^5Wq_=djȧ25If $՚'2 ÆJąyHNN cAH>n{\[ľqHHn>3(}ZmKSæ T "g&"6=t \Ix'8d~O~Z͒詒%@C&A{deA*C 4%wUj 1^2Dʩ}TQ )'2~~q#c¿x}[Y{RzV|\Щ@OC?> (W3=ꗝd|\|uwEq(jQ7F M= fzkg*lY$$` B4T߳$2_tox~ءrȖK9zqf?~lyq'wW8z}T>#5wUz)3,"'ϼE+VѢܴCr*(Wй[I#dBH&W5F,u*ptUfw`ddT/]U,nKE=nu5=}+/CR˟gpzO8'\]Ũ9%ݔ4S::=Tg3=. RCĂqShJ*5D֍-b%dk.QʢOȤPMX>:9f\!G"VKUQ>^O 2WOFO+}Wy^+mXXEF)VVҁS)C~O6wTItX-X @ RiDua *T4NROp'}2n/oͣuJ=~v:SVB1B@Җ$>? WmL|πILzcz\^/^|sqyȾwJj'tquGoYwIuH-T%[>W0 3m"C/\=E4:F J t$[d=(Jz~`-^sю9o}xv `Ͼ>sM]ן:\ X*.^Ǣz]s\XzRy;Rhx}SOg C9*T=bv#!P I;. G+cp6Wo DdO#h3{YFN>W.(`~<} `^J(˥*[B"]6]R5V)eŖe+ yӵL *N": t^El .)pMdzL z^v7apc>ϴL€N0%T=PVRzK.|1y"||A>AϏ΋>Ny{Ǐ:W{.=C;\W- Q mK1:]|s~~kh*6kOlE;{"a{~ y`rqg *:q=M@l+HdԔ]@}9U] Htl5, abzG!p# .07ң4o]uS=pE[tFrWHͲrJ8 t=ONIn ޫPɶ\Fعu!BUl_1OP^õD/߿{3"Ne⢋*~ .A ֪e21z3OE~USHGGvfWqqG *z>42ચ( G=N}N|XzσM[;UC(=P& p%ׂCP!6@3 1j$^(x岷!/ op9~ R5tx6ۦQJ-n:{5${]#*NsLX@jhe(SJkzF#Hr8X+ x#b/MV9;kŐ@~/Gl4 cV`샋/:d眒inחj=OLUvl%/1ɺ^"m^1[O5 s կ9O kP/q1*8CI9B,C.OUΝU+~y_ VE!+'J@_k~4ځ||[}ӿ{Sץy;UHǾ\x_/W(U}ˏ^שfZj^*d)0WkV\۝7g7ƹtCe)>;f>BM)w\؜vv<+YZ\n:<=K*m=eRS+2>*AW#TbUy+kj&)kۚHHHB^ P WxQr8C+s{$VRVQ+@*k!*o.XrSvѼ=ϩ4b{iݫ23&wj 5I%wrn-uqnC"f=!U{JgK9&'QHʠe^S!R4rE~fk[XDo!`0aYur= ?xbtǬP~1zݶ+Uc8߬MUD+ $ #1o 3C)9"x#GZQS/ yHsьxE*AZxΜ'S QQk!&<|FвQ]5( jbu7ZH/d~%پ32 'pqQ aP*{z_,*DFOz63'7g+>+ȀG9 DҮwaʧT:"jyZu*jA0$,l&wk GAG,//zB4 1뼦n 8AT{^]\%1(gȠ)]/~8ҥ-FtTV*W" v+Xʹksshb }4tK'oyA_EѓC_"/)&8OUIt ˂.Q W= ~T;ؑtQH-SR)L,4be) 7xR+bR( dUysxL9+@KCP %@#&!i%w{>1K :SmTNu/1K'oQH$ 6 OC˯<́EvPXD vn%Q.KZ S{Scߘ<N@>}9( b$zl;@_X..Havzs} K U]4e]|ڹ+dAp7JvK;ϰ`V">0!ToUr|'C?"k Թkޝi^h'=T}񲾅Z0Bz~l47zH@I؛) H*z2\KP Jr(=UD}:<1_{\`rcު:{t髞wEz]^ZZZ/D5{R(_.N@^z~s8 +. cVXKR"3CE~$]XB^dόk*G跐 *LePo;)^0[qE`*XcUKzp8KT{tǝΝR̘G<҇,P0)( AO|U2V7bʊ+# &*BHp'$yY'Fjd79f7S̫ Y@kT7AEFz(}:nʾv_&F<yP;Rx|⻻^}s{>{GOkOzcxrrOVK&bgR+b;)bH!"dHCYʉ30#N p(NvA AmqօOYxw>&;Ww֩;$ߒo T ˜%qet>˺G*}1˯=+ҽHXzN'!$ I?~,^}HscpU|4PPEJ3C9)HVgg'Ň(8P3,>r7i] nJx4sk>ܒ~JXo)uKϾn<;g5^ ٭ &$hF7'9[,,J hŽ6$+;<8=-}q?t{s<^oь Lnݻڧb,NQFS~ G^oCr朘q*0Y]oX|0jKHuS<!{s%NIID@kF>ʣի|0>\M=Ɣ#IUana 65DNBvyܘ5P')]PD[S8,G?vV N, zyHk8~`xE35 V36v BpQA׏mI0C:cԾ#,<^_7ϫȔpDE{X.ALJ0⢊xk\G}xX3S;sn^yȇv-!#ŀRģl!+;G]Li'#{ ~@ DyR;J ;3ajq,& =Qi |-=Rr7nwr|r2 >Y˪ %U>oe ogjRKܱ|:57r>{ra}aЫWG/EWK]}udbX6XOP}_K3H{=HvjнJA(/D ,F4]%ʷs!.'R\3f%۬ރ l <`Gb޺Vzn8i̍6f7+ix`:Unݳ$'- $4£.l0cT9SzfBe_y }EoiGCӨfF2}s/T Bv^ GtCbrÎrϐPI&Of8s"[j]%rYS>rQH(K'Ɇ6: 3! pPFxB:)T4޽5X ^ڞ} Ly>H³ϛl]Ӿd? b/_]y1wϵR~~T"@ "9uz&뺣eU *ǣ]N.mn]Z!۟h'k-s{I^.W#=D#e>C<'^ +}fԜ_?f Rî\ AE-])6qc)$hY W@!uTVgc^z{5>#|W2fyQ 3ݫ$?:DX'j4#' f2JG9>8aő.gW!q{oi@ :YI/܌ F@9c1to@qzFtG+^'./I@^n!u/+ +C W׵O97wFZ ۮ[x뜕|}7[6¿ ?F!|>d{$VmW꯿[/18GC}7{Ïkd ɡn0$UHV+<4(}L ~U?7[wu.S)03)XJ.[<: m soW 7@=dB)IKb۱dJ⺘%za?.;0>*۷g멍[aqo"rs9[^'wkOCjhr|?fjll.}8`AӞk ^KُxPOa7B*6#D`% "zDO=qTWcݤ<0\&T|;SF2)aDsw;L9s|0LaAhcb`*=8qN c" AXWxH1SbH EOG{*)(hUQ-sFe!URV_<=~X,<1}"qduDn.fl'|vq|~;XwΝw{TyC#Uyn>Og{ј=N;""'c+q(lX˔PBH^ w}-̶"͜Alak ^dy|LqFF )FݑLCIKHM;M2ly5YϧuWҬʼnلc`eE.bo88T_CC%=9(ld@ }rAT@=f`鹣D °; 5RYvՌQa!rtT `q}fbQK~F^CgW sz-F0r.8fcQN] jƒ.Z}Cxuywz 'u$ zBGQdgn)Kßwﮮxsd0 aCCBW +iơoׅLU  Ose)h5vE`%ch`TRUw)z/z޼xq>-Ґ ϼב8 օ~_d}vF-ɟ.[V4ULnNXXn^+7~,>~gPVAR9S11` $kijgxF#U"|Ǜ M+p( K29zqx⻮>|>WuN_/\\PS[܇G~@VߪhI$tDzwR:PvʟmBׅ 5ȁ eps!깴N'w s9ur>r5 '?: nL.7wDsQL"st 3_^52Q&u"p;Nu&œ&.L왬hoW߰^lwzuB($;# H/[.V%9uIaVZ6`e}s%g뾽짢eޢ9zbd}[QR>EOjyjn'>ۨ}oԏ#_@usk\\8)ϯ.# jz G僞$=͒DYs@ )j$?}=RFrx2*^${\ze[{:pgf:5sX @Gg99Ű^&. =uqؑGl\rpA ,wF OY. q.T+cb_o#iUg7K7jfccH"3͍?J=(/LtqdXkIuLcq @D{RXmT^*{_mlR%8N;p .|F~X\wQgR ءkӲ a:, ,< W25 y' [hں 4Һ@aViHZ \[T9S6ZNnЕ.5}] -&h+>;Butofٸ-9V(wk;8ߗuMm{ּg9j~9=^)p1E>x@#zv]yo<0F2zNtvn3;c^ͣ3o  x B| KpRy^Q|9]ιz:;\;w㯣u>.f9hZ3}G{zJd'n~x3+{B3Q^ xrvRaFlܻp=3 Dog [P=9w>҇j[MHgmasprv$V>/İg!gl;HUepeZgjƾ 0 ۫E9(vu>{,HmՖzgb]CݎX{D=Z],]ھc(_fOzGF!0<!_=T+Qev]:Rlt-z+-*;n7^#_/H+M A1Di9X{GGG41-B=-!+;V z|3;\ۧ!_u5^:.OGz;0w&z fѹջ:[[^Kn ƂtAڲyn,O1*dʏ,]&.qw%φ$%ϒ]02;^oB qK<NNק5QX&C ; /;v(q9yDvɨPPKj3Avhn;xe`b$% RdEkA)іx_r^BK+n&(E'%TimCw|^|@~|# V7@mj}_idw#~”|NEb)t)LOk^\_w_>#,"Q Svbﰇ4. Qj nbpw72t˅Z7b]Ip2$vqI.VqjQh]?d®ό%e {j1_j XW}eSU*SauSHuϥSB@Cg?+( 13JJG0L7{OG:zsNiE޵\;xd!bZ}^'D?:i4]`eD脂^-<ت!T kS`wlE4~оq_18tlO@EyTnÂ4d1PQS9#Ff=sc J@\ 2!D|{~n(B4]TPbۍRZ<<|:rYO E!j ~U@N :ċQG52 v ˢi$v%#@B mO_!C^knywf(TJ*Hş4|@ZUl) w%F mؖ>sz%8r1 /?l'.S zH'%2(b$ؒ~,zogr &Q%9 PDZ1R\Tv%bH&"u`|`Ohb{</]>Lij(in()?` f `6^eTT]4`a@Xx!;%GD*_Sא;;TW*A(&FܴI 2.ŎSvteU1^PЅG&"Nc\ci_r? 'O/<Ӡ֝cLvYљϴ&MMU?>N.A%ꥡ /T1V> {k>9_`&N@Q萃ůCeV$GA=! ʲ!DԮjj{? qq#Y=|xx}4 ]v47v6!vb)ϧN?4(.0g C@TȐ[H^SRX#UFe4g(\>{n߬x %Q,B_]SlgG.ڥ7wC}:PΡ P1IIfePSh [#eEZ6Y,mB,,B@NC9 ?F~PMBglb9@$hhEFD(ƣpt'uHPgP({ K{ lpQ|#EE格q1(`}6iʱٝ >=!ݑ6?%?!zp)h bPP v݈XYmt’(բ ꁵP\S-'%xJ ^(z\&MN@GS\e²9 lhYg3 }5Tpr7~Od{( \ A$FMCB,+aߣbWnV9iN|U @Iэ¢ +♐ `fQE6wmPw+ל|>.pz<:a}}$ރȡ7eg!ˑ&Dd djoUiKtJҁ.7~L<}' S,Owݨ KdQLEM pLcv:+wJuք5Xwoʼc_ا(*cˆeXԶ dڊQj.ժMi+I/C9vrqR_A b0mx|szr;oo2Q) ?NN7{UW_Nv`}{|C=? /#YϜkY,U3yc"b g7skʿn} ιCT|9dq~XH3rNxCgAp> -B5#B`'jL$|cX}5Y6QB4U#$c>F5S0 oMkjgFy\O⸙e3{4&uyV֮v|3!9"X8uύ>WstTe+ME])p`9&/;z2wX!xR]N!l~~,pHs7jyUݮ1~hzQr7J/ݓ,-ƂZK4F tV$QeX ^RToӓ1q@+^WCudrpּ]+RY^Qz]lY/&[̩p}Hwcα+XzE=`cx9- U%a߬(ᄉҩQBAA"^NACP;er[ף|:h9IxW΃^AH4MC=zvto9/7P|Fu MGL[ז62⸃ûjN,zX2@e%ŸgeFIfI'9n`u>R}P~$nF~BՀm%tKB&aK^^VcǔY~}6{gIWՎŹx +`[ 4Ȅ3܈\eR~x#">afh֒^Pf9Wgv1\+kIƵ:{0I,Պگ# ,i) Yƈ9{$ݼ\$|/Hy쫎g*Rf~M^ŧթmd__Ƴ 5FYJ>X,0zFZoÃy\aRN i'mƏ@1 1A^<5pIel|Ƕ0`#K?'⯩>Ggˏ3;;f|R@FN!f VrgbCֽAkby^cpˮJʠp1l~+%L*% tP)}@$'aAXN{s0X$"|*JS|>N5mY*̘׈7LD%vC7Ft_,u$*z67Qhv[jKYAh D\s b`lB;$IGp9I G@؋QӰN@ȘB;n!$֡&38?V}o"`>aCV!- ;`A"P djtDG*;q{S>P>\:a>{#>]Sj]UOI(KV,jїuE%/qLPNHH9:d%`/QMڡK6*d.HNQPҡÍ)^}=Нs׍QFY,VREN`ni;L pBq4>(wweN~*kW5COB, .xD (/?UfKv:}( z .8uD`ӳ)ٱ7R1 NEQ*GA^_@Hl` >ȴϊ>}A^(f&!hhYa[dfDjSNbXA(LP ef%^*o8'SECN*HC`{["\my_)@odx4Q(^pv .:(8lڬxZ v{F_>C |'F HHu:]ĤqR1(/(x_=^Gx21[ \QߧCػ@JO|HFlҧMRNf$D$$= Ul\c!%eImSbĤO{3>>G{ 4c~5dRHwrc%{-z*dH>DNFDsm$ R;" ̉{||xwONW`hnEXf8GU xSBzl, $bHlBHH$4j\\UT4`!]_/!eA00E"ne](HΕRz}Goیi*OhIr)}.~J09Yp4PPP0L0̱sׇq}{76yxރ~C}!8_<E~Pz$ddz$ ;2_Pw@:9$CWu54_s>sTMJɦGTmP=nZji.^+cH:#Q~>%Ϡ0$}' =TR6mQM)`ݖUmIAYt>u;f#jW~i; _ED+Ԍ= a"l2/y 奋w0/ DUT* xwxG==ꆍyuR}'tʽ]Q= pR |?Br%F>ߕ n?*:?- 1ĥuwZt|S|yySϢJ`Mc&J*fɰV1,A6RXCZKDcQRZHŢbѣ"lXMFڍbHؐmbJFTQmţ%PUDTV6JY2*(( mL0kJXڣdXFj+j-dL0TmTVĆI&ɲbت6dd5cFdŰ"X 4[%cTkEk ɍQchVM&(4kX",l JhTZ4ȴZ,XFƩ*ĥmIX+DYTb,m&ڊM-Xb1ɳ(5*ŶԖ6md-Fحm&- &ьiѴƊKQ-H3)5"!#IhěKb56ƣI lTb4AhTV-cX KcJjY6mIVME5EQd6jFQPFɤRZѨțjeV64Zl4fl"c%ƌihJEi#"ƣhT%5d* TjAj"e 65cQbmcQڍF6MbƣZJEk RjEF1V(5lVŨIhh-jM1TZ&TjƴIf̆m(&3RڕH m EkF+ %6ml UJmF- &lTMJض6mRFj %[H[#`[RĶmMe֢66m20kE!lkb¶[ 6mRVj6("fQ-Z5lm5j62UX l+mĖU[TkhlmFڊŭmĶ*f lV&+jeAVmZ5h#[FkcXV6صF(E,jETl%kI"Rj5-dm)m&ʛCd()j&ʖlmPTؠЛJj[ Mԫj+j[Q[HC`Q6m(lڡ؍l-ڍV(6mKh jTT -@SaRl6[HFқ F[UMړdlU6ll[(+eV!h+a6RT(6[6RڔmI6`6l-M[PBm[J&6Q6SjM*&6iѴ+jm+jHl ڕlQmA[T6D[leTțR[T(l- lmT#bȆ6Mf6dXڨ4cZEV̔ZIbңEFdQTAd +D1cPI J*mMj[U-6lKaEQJjIV6R[!ilVTQbҙ"525!@@)6"*"MQHEQmUb[m ڒCbM6a%4ƨJLhhБe Z)TTlٵ6&3l[F"l-m(QJV dd[)ځ[lU-IٴkUմ[mVֵ[XDlFcXڍEUh&УjJ[ȿdMfyUpA-}> R0"TJEI((@@PRER @jHP J @PR;g> H0+ HHRRUP@R))QJJTAD%$@A)TQI$^M@I(JJF (HD5PPJ*D"iQeJJEH BUBJ"E( TU(AJDR)T@ V۳Ou=z`=[uXs@J IBR)$T**I%*"H $QTURTTIEE IUHJTA(E*%PA HH RP"$JJJ**DUTEHJRPJ DhriT]3*@@EI{׷zTSwgs*SXzzsG:ܢf=QU+:I" 5XkAp>w \72) @ *BU .xw>zՁsz[Ǣ⢄sZN`tܰ:ηB{{] X z@^Y>**>Sx7)$RH:۹nw7WW;`u\=9`R BD(% L}nXX[\]g`s0{ypEB4JAJpl)QQ!RUB޽޸v{}p>}|M7P D7I* *(z+wWup;۽`=n0y>۝{y-X{,: 4 D1%@U (WN.wpwA)}: TCS1R O)'IIb`E'CH )dzEU2鮻+$#NG40LFDlHE-־"EBcWuni\agk&#MwZ$Ql+K6LW_}ԟZyf%E7usewmriXeƌԶ7rX-.뚋FcEѬuQ]ݴZRۛITSf6ƖbeiJfl3U'%K c+V*5)ƺk'''%.nrpkUS,d-9.򜫧Ӵ81jц L55m8qlhkVZ3,cZnQԦ9NS]u95Xэ-h'2cL852ի4Vj9a5jZf6Rj6Rd2ۻu\TY6LfFl7w֓ewCessJsO5N8[ b[UN4*L< qk 1W6Rq8AFJsTrhnPM`ˊlXj.95+eN9sZCme\ljW8s.Lj[J墻dal 4VC.M6Q̧-)ƦR\-kW-ܶ\\K69.i[ -Iۚbjj+%ۺڋTܮƮ*ܔV[%%8Lʹ756 Ǝfm^Xj[sK\74U36ѴUeʊ56kV!e8lYR0`k4 yMna*L8"̪ m8z#.[Ic.:esLBҙLњThٕ{׸8lҕX-{wS1Y(wjJTk9 N0.2Nj h-(md-6mjYNi\˘YdlbUlP樷;;Tl'4*MeiST[@s%-#j!#blsi#w*+eeYR` ;K lV*Ƣ755+ԯbdk]Kv[84&XnRN *"n$nax;o*GKwuws{]sD;,Nd=TpQ%R a*aVjE" ΕήEĻɳv,UƦFVqɤUS$jT\XřvN]w"7$ۻdsױxNiMdM!$ԫC$q r &HTTI J\MlSh§(LZHU)V`LfjZ]!t9r È)9X*$rK'7J!gqr HrLl' %$Y\!YŖ2a̱$CnR>^c@!M1B}(5jƙW{^jH c@NƂm:$ξ-(51E-u`̻4[vbɓ}׎\Dom| nY5'@P7بAvD&αȍsy`tFJcFr,mimX*R-w-$(قQ$"]UfE TE4$ö,]mҍuݫfX%2Eg\m|1ϟ$Q7(]܋y7X4]͍vIF4}+yMQ\I7nnۨ/z=$Qp:]n"]kF[kb4ңLEv,j0Ht;Zh(ז־ɩ,ho>^Ec-ڮVLhtUHCRVsAfT]Wj%ԵsD)(L6)o7֖D[ lU)v{Xء Uukf64ݵ&Dq:ԡ" TBc`E(:ɉF(-mJ# ]4!Fj-%$0FZF1iH4I꼯k]"A(M0!Z]W1-j %EQUCJA4m^^myd& m%n&CDj 1IB>{lb-%/&؍%hEL5b)$0X6Mi A$ń&%26fƌh) NU( ؉65V*+P(Lms-XōQ#&I %EE#Ŋ"2b |Q\h%&cVHڲKj 3#3(!XѨ4UjJHw\ΚɈIHʈ w.̣Ik%Qb6AP%F%)F( FTbz%ṭXأZ0&1DZ`y^24Ĵ4F5Ab,kFƳ M$ VHT6 j KHcQhLDHV6b۔l4Wn1튋W5Db2(cjS QFY4P ɒ#nƆQ#mlDZ m%1j5I$e66Ek$D3`ŪM5 dPa1@`JFb#F4h+2 B#mi$#bkns戰2JhRFIBm*K62Aj4X+)mde$В`ۄ͍!AdhIE;\FΨF)4͊6@ĕ2ɒ!$fEݵͨ5%RX+IIbMF66lQ$[I bb",IOZ *MQDFb4Z25\ѣ32&/5EDmR-Q*"6@X4d2j ZQnjmb؊14A&1Ve5F-Ŋ6#F60h2%LbԛZmm$Ґ`#a-_M#jb0ȱF!44ks5dk!C*( BlȒf"KPbf0h6HLQk6#j4lͱY0IdIiݵb4&wU3%BͶ 50BQlS"+b*)4mpr*"1Lm6($^rزi"EAT!! 4ZodIi,Vf,kFhE$h"&"EE&K!FU:`IE0lQc,"*2BBlJ"Q%D Qm$6@(!J,ZM"0l`HDU1h2(#jCF5bccEjMAQ$;CDXI[Ƭ XQY acTE@IZ43Dk&2DJ(Z* Pj+&emEkIKI$T&2Bjsb@4F*"[VߝY6 $ hb&Ɣ5Z*&j-hMH[dJb1j%FFɢ,06hP- (T$Y0Bf2c*d4$Q(b44lQhl1I5ɥ4d&Y-Z,B$-LbțBD52Ċ7k,WuM "#(TAePHhZD cch [Q%ۿ:(F%%W71d"*Lm&b1J&MFͷaa+hbk2h؊3E3&j-DhfɐMb"HsP Rm\**6 %"Ilk0FP&cT%b TADbBe9ݮ02V#md&6 M_XE M,PX[f()騐õ}QDd5Q[(ĖR+EjEɶcDhkRkIC Ph!}ws{RPDm%FQQbb5FAb-De Ʊ5 lg, V6Vksd$XDEF3 cXPLQWQ*($wq4%؍QF(먌cQ&RVLbm=^S+&Y[%U@JrATQMQ Wpcb+* ( Mb2V)TXdmLQclT3&˱\ۛWf i2|H-4E`!Xf4YwkI4QE.rD2&幩)*,hؔٚM"Ѵ&,nj«t6 k3I$5%SX ܵ@i-wtAl&$0W-t֒ۛk63*ıF6ܱZlIb\6#hIh˺ۑ&MIlcdIݥ"+ͷAEшX`A$5hRXѓD,WwhXU%ryZ(Q0QE((FhJQXF%\m\ʥ˔$#dllP% "ܻ6Hlc*2IE1F ;4k@c'W^#re42IݺQX) H5sW(Є˻آH+-urL[IkNhӻIX( 捺h(o-\iTRh+,TmFGsF%lcf.]9siE"a[fȱWI%cFW1ILj2C,j JߝI4@шHaEcJ?rfnmsl(M^\HWF"4ZsH9Xd:ಀAhChY1\IP0m\kgYh+2Fr DFFэIcU%*4&C(t\sdF5cch*6o "Pۆ(bk (ܴ_׻ ^^dқԉj*1beBb1*KMFDsQLS&${5dZXцbb5bdB#JZ6A])nkܓ:w%m`wlѦi$LhQ ح%sW͓Ҋ݊]nunhn.ήkήn®]$X_zMdѱ{PX`\Bb(먱W(_GϾ2m;m$cgeѨ\5rѪ4E S=\Ɛnx"5=PDHhűr&9t1b76LFsI&* v(5Fۥ,j( ;QclDj] Ec 4h1DTI\Ԛ&Kb#E&j,b_.HTV-i( 5tE%T5.vF,cj6B-BPʮ\0XJ6AQMa QDh)6"6ss3lF (KE cE`3Hd ^эcDEѨ2lcbE@lQZH&"53IhIdAdDHI3ljEFud6#cT\5AA)F$ Z1d ض+%5%R2{現-j(cPѤT(DXƒeQX#QQIJsh1QEB0dЗ.T;W=ł@Cc-͌;:W5A.ۡnݓQ0FHRQ@hĖ]ۖرh5jѡ,b}4hsUUI;  ƣQ IE"PT+h&rufMk(RFQ:sQbˑY"4Z6hQR{kıF;M]8`]8cFE!b(C0*6,QnXƈbFH*M4j 1^Ȋ(U%#@F2RV UTfI;4AsSXlTV4FC^#^[%f`,E5M(l`hXvlZ*55\4QhI4D`ɰwϪ1%FM$EPZ!YDj1 Ӻۦ\j#DbvdfZ)b/{4!cFt,hEcjLنѥhX6Es6hI*(Z LX$Y5F Ѥ(̉l 4TQEF}oaX(ԛ26FJhڃcXmbHƼ Dj,hPbܱPFL[%4,PɄRPR&Mcb#m!I 6Ԕ`)ld&D6,Qm4QQi6-TV,E&ōh̤He&͹hH2hH4Hh ab6$ {h"!Dm"1TQF1X Qi+&cX ƨ&ƈbZEmFD3QEZ#Iض(%d#S"6ƈ1BTi 1 %l#LԊb*j6 *%D^c(,QHb#PR`љI,6M6 5TXɍA4Z X-'٨),b(C``4hSJMb̨̊ 60XƣHFb&"ɱmDlEcIm5 QAcclTJ:E" X(bٙ6D]ޱ"IX1(lF0QXRE!h4#.Rm(hM6%cLFK2"F(ƓF(H4TE\i5(5bXѴlh@j2`A&*2a*1Kdر,mE`j,IbLEK`J cQ %%BY$Gi5jabi*BRD34*h*$櫘Z1AlZUF#QM%IF"EJܠ)(FBɵ% cEd@*fF,EXьY0u-E LP6&Q*$&i6eF1LmdcELQhL6؋#ޫб &Х))ThE63ƱEh-cF ,hKE)m FSIdu2Z#X+Hm9,c%t؃hԔV#I˺PlѢɤS`!P"4 ,!X1,ZbXS@X6dVLfj#ѓZM"b5hIE 60chRX"PRd@髛RTP+ 6%)Q-P[E1AF1155SIF Fƍ4UJ1Pj"ج Hj$lFC s,E2A-n4El`chI%@!ݸTZLm&Rjmk4HQTb,`0bJ) $6&Y6 E&(TAj"#&*"!V(fhj lXcEdѷ-1E &آEIMb#h4%T`Dmi)hPFCD%EfEPj#m*,ImTUdԗ LcP ME"K&%[$,i($(1r*4ZLܷ,Ib(wv1E(hѴQEQTLd3FűIsnmƍ`DTTj4Pjj5"4F6,lj*{v6(h4FآJ6#2SdccA'Q[&24ؓh#D4M1 DQ6eRXɶ65,XBFH&#hcIEAbi i)#l-K61V,XH@H4 dآ1FbJ2`'_@Ri&h1j)0)Eb5IDXDTj6 lb(6-##5QD1I4)! ̂ːb#UDK0H"weѱALc%9>hF6h Xb6Ōb4-#DDh5$@ɣdQ(-h6"614lhI&F(ih,DAr(Ѷcj2#1bh \[\2 ʍm f",& ka(mV#bѨG+r4AF4l 2 fjM` HQ-k X}u|m UssIXr "1Fbj Ω6&cL+&%%6Fŏ}(! ;d 7n H^F,"TΑ@^WEE 4ťqM֗$Ԓhp?kbv 3JW*#Z_d+ )%&ڭ)+f2Uect֑O*#.Y8%˓ArvAufLr b ܪTȞZ & &$J[HQ e5ȣSßH=nK x]w3ponw~ڍw˭Fl3Fd]O(Od☾:˗d qq#`! 醒'I$l df'3l (R#x )!HbnX06zm'??U|MLW}끣`躡KWUAkZGѩBtEZR; Eh*А(VդY "tBhjĀj(V40ZKDA fiq+]ޔjᕷy^-*lT@v^>uF[vk79K\4)KڄҷoS䫲ն]r6u\b͗ٛK؇qjF슭Jy۴.4nm*:^ƨjS 6;rKםc*q[{},؏xwݹN9K8TbRʙZS:5lk/ CIrj&p%=sf;v]B<9ywűP9P]^)]Mޜ7j AjJh79iz!Dru δr6*~VN뉠Ǟ敕Ģ#w5W˃K}g#Z㻤snݢ߄1YmTp4^峤$.kw&BvmOT;=ۊ9XnP5v۔ٕf:m4rP UiwܮvЎ-t7cc؉9nz+"]! \LIyZYHb)Mm-"#n\j!=/6ŲjKqIܥ (\J̑k)ėWY*;-jEkk`\t yPdL۳nVP/5"hÇ>B>F|@W]* eht u]RuV_Xq>y*F*PF&5f\;bh1ɺj=aY\jNg Fqއ^y`noPT[^p-4J}dvlVY =jRD.{An ,2NMPQvx;X]f{} F}{]l922 !|N(UnV]ܲ)eZm)z*[E V&ٮF,ZZB%tvxk? h"hBh=upom7i}N#bRv[wA9&f2;rZv*[M[tb{24n~20ٲ;c[0OXYZxQjK,QJ< X5Lëʶ:Zdt oϹǸe M0bK V@/< ܾg-&H!71llU^$6j,jiY*i=PeNV:#Y%S_dT yst STyCMEyya{C *ftƄ9cIW:OCbmU`ke,´$ᩨB3R>MfƅjlI1՗T{)vuQՒWf̴d26_mL.з#ȡbF3̙Ak۫$ܶALA:GG6th/83C̒HƎZ‚$n A"ZP^* [M"9lPSUHi бYsm!(Zws|Ih櫈A8.LYm)UӸ-{CNʹR\:R#:ޙ-]W.iNg76a;6vkƅݗp@j_qBZ|muWCʝ9v7sbWeJVżh"`;Sj.ze㜫]yWeC*NqXC=!Zs8lz)>3QTpin݉2֘{W1uu֋pX}G.qUTmK385M+^qo]=ᢓ\scO%wT :`SF_FQUC.f;ݏ2xtsjCuv̺ܒic|6Q庖M o3_yh%ݛ2纰GWLtkwUr]8r;,,Jf򵡄m.ZDn[DeT5,s[^)G{I ݊㼭&'mWGj\;rf3CtE͜d+7k_-̝]MvnWrlw;{k! _C1R#t *꥞ Ys:cv`HRjIը^}](r[kҪv#q˹Zw BU+BCszNtO JyC+9CVޣV3ܡmWZh;E+ᇝ-3gTOv6=ջ |oLs% ijscR9I WwyV[*Ve,}˨*lfQk%>pqȼ31\Hi.E8fY0FosyUNyUTPC2)z%5{]r=iTfb#Lۖ=ܨ܉\+*=ew cAʶ7CyeyU-vytsܮ:*uH]4ˮV㮃v!FfۓiIP3)sZ`5w^}SdU}9sݾg[]s{Jˢ 17昁-uƺ[Ꝺr' 4˂%5[Aqңc*g^>ҳqUMpNrHjhUeI T(ue+*i\s ĺdãNfle,=ӍCUqJNBO1u{mߥ9[y8hMsm]ˇlsj:U7 [zJB.'ͲneSrRjlݪuГ7au;xn*/C:p҂z;^Uc{h] ]F [xqVְ U]@ŲĨaNnZ M]>[}zy3EdR[+wk=[}ݒӋ\ڬ%˨T:|/3R@\zw@cLKʻ⁳G/_YiMPnkc˗sҘ7aqi+/:ժ`ZcvP;,䢸tn^bŀRkڮ뤍^B/1o5LMfw+.th 2kj$b[os\ tIO"6ي мz#FjwAԲoRɊ̝EcOfZe˴^g%W$N]2©#3t2oLcs+>.yͪZfevs|]gǴjC-SFIUCӠ|ЬyY\iO:E YLnmxi>L+_6${}`AǬհE'r.YƝV[ݢP#O!O(Dlmm2 nF*ojr;3%JNVgMLکZ\l^UMZN sz^Za̻̺HۅMoeV]n J TwPՄ)Nw *_Gw{u(%Z=AnܾY[N&WJhhGX/RT,ZN;# Y/sJZVUWwy9UlC7/jf,:K``!PGl4UpNbtmr Ǭ] /T,QƓ7Tdu8kh%ȸ=QvdSj86r y%pPYk] U}3ܹ;,7)t;NfuqJ12-7UզVcep]&[xDkT1hxEM*mͷeeHsFuV%ØαWɷr:wΥ۬R{β˳𪹸GKT+;hjN뎓dTS-qzH3Vu͹1AZbܠx5㷛YJl k{n^=YKE"z|4<5Xw!ncWt5i}ɴK\V(|a$>saXIㄞ\?8Jz%ȴOMT]0:"F )Z]\cJ cV뼺!VTvQINhayX+zGXܕV-I7Z x 'n=8 oyw{O7yRWlJ7<9^ Y;dFlcTy|oM;Nւ͋! |Q\cj DH"6;ӌČr9VRLaxSc=}uu>{) \epg= 7ɮ/VQfIWt3PEe@=N0qAV-TMf鏍{k7#2Mtz.Hp/$&OOKm`-7{62t}v Uhz%KwGuz^\T-Yj\JKé*ǧ{0[ }vlwDn1ĕNy8Z7:tx){vEmioRPxՔM5׼0:fk-w(],ŽkT2GvX,<yuMj x%vU"ΕފQ%cVuͭ610IT`Ξi&}Qڹ,:e++@Qꪔ7N͵ң͂,:5/XESfsN8dVN#8+X8JP]YG+7Oe-!{(u+} QE@B <94bwcfV8't 82i5ﮙ0s$G3?v >5"\|ث v0!TeA2Y+%h5s`f5dUmSuY=K <+ Z덙ԥ\p}f޷X#$9TVTR֚Z;Vl]Tk;bJ5gL]}LL$tXe*Qٺ܋ŧUdJj+d/bz#AԶˍyI63SŴ4b೷Cc9-է:,{UJ6|u0I5,;}C3^C]#k=C(sNJ!4t qP*Mid,$IכdckWoS]Z.wYBvy˱GJMۻmJ}4EmcmyUZw+7IK]Q 'VrVU&([)4K}XjQUS2y q,S#*/pp'LGx$Iдxv6.OP{[7H[-.#РEvVӱZ}Ꜷ,&>E 4:Y+.NiMԘժޜPʁzжGl./R6z5]K'F#ImՊOWRr x[tZ@/%hω^A{E1ςA{,͔m Do={sۡlǚ+,'w,8^ݨ& 6KkB Y;i4>"KbZ]xSb.&s{R (IpȲG^Iƹ<:\)n7YL"fɒѧb O]黫Y⫧;+5kƹ㈒ u۠Âޭ֬Ukx[ƟTrU9OZ^x㻸^(S-.ȸ k1uU/Q( kgN<65V5nby=.eZvNl)~r)3[zjB"5uGo[:|*!Gw`imu >Ls.WH+L#o,w]ֆo^|e2Muv1uwLEMn E ,V:cY[N^qkinEշ]2*nxyݽ(AOrrXUjf.A7Y])p'5f$UYSjc]G{y┠ܧXn0bu* }f͜Nv<۬FT=vX]׶ړ+76idNO)tMJIy_W}am4 jgO7}22 X%5Q!+WViw9^mi3+}GDw.46: /ċS ܠ* QB4vZu3dK/1&Pc7ު<ROv)ҏ*va"MRLxuBvqr_NNc dSDv]e,6f9zW*ڱf M=YE1;vr9U7t`" ]Cv v)fYS&1#8LT.[ʄxNbmPv7\{TT+a#rb39;sQٚJ#.@#OsmR]*SJwƙS}ugEJn^nѭ]*rngw\4EފuN'T 9:A"2>\a$OrIۡ)F ohA .M"p8;4٭V|bjf:xj(FHܝkdwʒwƂuHIRэr$bx%,U;*:6ubKs>I&Yz,EҺ@lQWKt^3S"^TR.ɻUejl4Fd:u;U6.ܰ]JwS(λܺOmmN&r]kQڰ42nprFU gjB2ʛ zWUꥍӹ'muɺ 1uYN&w\Otk°-gXwBrӽqfpHTDE]n Og!9GwtΑOJ<DpJVrrS0JJ ȕmDxoЭxupɺbR9sGtΕ/^p=*+]͝q軵+'aJ].{$ɦi7+;u#ɓ2 ǔZEX ͕uzE.+ne9{8)!s|//nb]NvhdM=u׳c{&ԎpRj[kedl&eNAΓ^8cf,wjEgrp\:3G'Uv(K{jodUeR4)37ͩwydn[U.k8sD ޙU=7{t4kssKtX6hX\w>N>V4UP\$ח]FSۚ7ܸF}7] 'r<EYx,\f|lě~Ҷv`dod hJzJI+MȪ TX hn9)a#hCm(M,\XyroxiKq0Wp}Ãs+R'z_f;օUZaAt>gtCkGR{^YEж \5B CvW^܁{7P]&Q횉Ńd=N;k(h>k[v$:Ż8{y~QF3KγԾ f[.kUSe1T#tPM(V7JV9Xӣ7H7MSM go֝rVQGtjtJn66{u:XNSg½4%m^AF V57SO!ReYvN^`/edv:WsUXz2;{F 񽼗Zn{d wBzJ|kr2Ԫ*Geմc79#K,ꂶa vMUg4ΧsWjm3:Ua)i-4͏m-Uϛ{[<̚Tt^r"-DRmj޸R=䴲م7h+|tS5nrK W5jU)],2]L{]n#1ԘmZFUs|c8bmsʇ<Փ8΍Lǂp˷r퇼3f2f䘽*l>F'noBv|\1 #"ݲwwUɂ=\cYY* Ҧe\;i5##.h*`^mҴ]ۼtpiٛ-a}ZcIU+jX .kw Bv.pmĒIU&{`g3 Ńww+3x$UmVmμfT23S=KskԨ]X9;A{(`(O'qhlÚMޜmdں: $ػ*]}Vz5ovˆ\5-m7lǫ>}NkfM=Zβأ%=-6G=]ō$N Wtf*+9y{(bln-URjf,뤕cʽ[5;u…gyjZګt;DtsJBz3:Tʺ(Ԋ]Z"Nv۶0kU8ʺΰ{%ЎaW۸h'\;+=w8^F*A꜉}Uɼa1-nA7rZyu`EVx^æ׏>l^%.#Pf8ͥw)NVUH&e\|6' +yq6Ni m|.k%ӳّoPR9KJeh'VR2'ܳFbۻgb+gk >Vs6)S,ۙyB>H-3Udۥse= WA 2)]PB/b˲سP] YYJ͍ݙ=/ie +&BJ1]NG{_༮md'ںsYkbǢ5fA|T4ͣ!n{}5u6/zWmU }uvSIw!n`ةZvV5q"ܵ,R]5l U(.b_zy^BnaM^ iP,뤕AU Ψ *[^歂U=d 5%42Ge[|/m.cbefۻy:D׻oAtӞ56śN\؟)kwI'I&SX{]ޙHfp\ RrJ10mʉawMqh"`UUi']uNW)p낐AnFrqvLWzh;Ӹ ʁ̢L*:85aN>vzknWFU/sZI ٥ yvE;JtսOhZ]6݉Aޗ5jevayFslT3cBcu-LBw<B`6{zR2OaIyjwV[GU.ja-󬾞e JBK\AA 㷲*mfss4ٹq%ʭ9h)gjL#;l7~Alޏn6(\=>^Yc]%DJ3y[yX(/f_ &5vѻ"dr Uk*`lFSc{̵Cu\ݢ1 Ld/kBpvk%wEmӚoېطTp$aUc嫼YW< u9aU1Dyn ╬OY],.8ǯ*U:m=W;h:n[+-B2\֕'-wy˖T$Tm~w9|92:N̼m'BwuD-ڡc.;B>ǔuH"DV'UmU]3ԭU+HrB^=7qJ l]nkk[f&b9VYK6I-JiȎdtפ xaq_ao޴7pG6RWa:tcDz^f]{ W;9u.u#SFXX|8tzjTޥBa\hL%W}4D6,#lAw]4zYj>ǯRXaޚ7ymF 3V%:)[)=USe뎑Tݻ[M,y;szE2PF(vc ;pH̼9n;^7k[5!=aV>ۗj fμ lglTgRTFtә3[Y;1=OIa+Cmc7\/x^ U:jN GaWNڼ-k)T||]=ֻNm:X]{OwGhRh\kCꚗomXsrNN<}s>Dǣr/S{dÝ&|%]%[Q;u}k6M5خʱpX=wv1]:7#6K#2J4F.;)UC;aŌHQתQ7JH%/qۗ=WNbˤn7kΐݫŶ%c̙v7s5P=憄]zu }쪽 "Ӥ,RѢڧ 3 #o؅aD)(*z彽E+ ;gUwAgc#rUmi;o0UՇ/S8,Rq o Z=[S3׉Ndͫ|VJVn I2u 銜Ē Pv+V9Ұ$ZTkzVX#jBmT)ڻCގmHW]<9XCX 3T}iSY|tQxKz+.r񴍐le)F=;-~j)EdG.au;ݹG6/\x\mH9QڼD|SUіdf6̶/䃿 o-﫝&FBY";xު5gOd4}" ߺ6P94Ip^5bdVVy)n+ܜa4UTyKdԕ-2 vIq*KNm|J2)VqؕtG;ή^R6TTp3l3$Яm@]rZݶ2kM MmZ;ӛ&4e"tNN[m;كPS!L-=sOq[,w œPS. 7U &#X\j;x*bJSDVUyk2eJ{.aleeHUnEx/niyu]V *v'slT%Il]Y:û2ԕKקQU)+{ aMVf&"Эݩ׺N c)P78V,Y/bެ,T,xqHV1E4m:谓u j腋q(Rzj'G!hj{iދ*5[rXU嚦y kCf4oDӂ񵳟 9TyZ=dC0H\٩yNɎP9FtV*EָAeAzNdB)Ax6P2@YfH'4a B޿]g k"z&R `KYLg ;%,\' tD  hhqJ˙8Āw\JBWz('hަ2Ȟvb׭SIC fQKYnTαڧ6'V2CE[۬fp˫6e.aLcv#xxr7xS1nK K1PԎc( ݆IvbBEvͭeM+0ȓ]sYbNVhbj' {.Uְ-fܝccK"MgiE _U_tb!6zt֜;͐׼ªӷ;._4Uvj*mufhvEGBӮt{zI[3ӝ}=v]g-Z[I6þCo)SVwуNag-F[i |]fwa;-سCESXFmQnu|1,`L!sd4 կ2%x4B "0Vr.4, 5bvzlm7Ѐ0h+^fӺ W@6Q]E0.y.9Jd(.u&fe ꭙO54kׄs6ks,h;@i 9c]q<" m(jY:DY(L1OE@Fh$-ڼǵ! kv43BhOqk|2*dņ=wJg)_'^@`ݎsq V֫>HXVH^1_ęo]#dc fkmvuyG]ЉBC'NϖMʢք'FaFȧCCSQpW~߅y[l~w?wCR 8J"iT@ܓpwn' I>:EZ%/Aƙd=za(TP5$r;|aؐs.@GI-z1e#stk|g^Fߦ; [iy~#@T|ǵВC<=+\Ώmq^̇" ;vw9>Y6!3̳ey(1Fę>E'ϼ5"Pv# AGg0G$sڍ~zF41.cơny{z}_NG'8FT 0QB,*ͥxP[h Ā1xjFJC!3H''gݢaà@N){"<E72*rA0I:8!=ONt+%Z*h*,jkW۲CRKZb@nJ Z(6\ X< if :'{t<ԃ:43 M"CCFL Y0ZօV#BFu+% Z%Xƍ(Q7pu(V JjRH8kr *߳=q|r@1T*S輆(c$pÎ+9eCkБ $}^t!t!bBH9; "=ޞ@|텺I WnyQޘB> +y:^7ޅ{̏6GMG1/oy`|s'Nw_Zrs>G`sD8>v qq5"PBnB4khVD#Ykt *VPm- (jjn JU*в4anQ {=9~?dzpH$==a6l)]6r'؜l2Ea ϼ`y!4?[o>ӱu$ߨ~|ͱQg@M%Ev C F|KkGWUP#K/Ћ'CA e=ɈrG"'Nv aצ4. mijQ[&0%\Ќ45KM(FVim C` ,)BMM]B%JBX8{e>4M'GypX-x{g~k$# }20kOȇWUmA\#":ƅ=v>` d9ٙ'Nj>PLϐ88ߟ%Ep9ގfb6%SBТZK@(RSd4 1:C]]\#RwUԫBV0K]^gpγɱ KqT2dUzypba 3<&/0W<$ЈH$b lxEYD kj:$Z>!酳`߀yc2/ rs3G'weH)uq{"^1{HX-)J) f9chؘ˩hvFԁ5-,HRZSwWBд; wc@l*yd}؆`jg8#=c5 MJMB]8Tg}]^D%8Xc=up%߼nbGݰ67[V: ]3di{fy-^}a'D9=;;)_,乷#o!; GH3^Nt0! ]LaZh:`# Um3%(`FJФa5ZaT0CM ^>8yYsUȁS\آy 0$A6;$Ac!#Gc>tGT,!yprA@W ^5"UZ 6kEҝsC\h(+G<?Ky<y|bi+|. @b:'d))އN9ߵu5:PnKe!EqLajn҅Swt(Bkm47GMh"4Mebu:'O|yѰ*>J[Z +O/1TS{ׇĠ׮ȬB=։CZeW'bZrTJ1૪Zvctdnʤ( dN|5h%\P/kZ:tw 'tQGku8ڴڇq`;ֆU2=57m<0׃uQ["SLnPOQQX1JZ/DEa+`R.34gbR!w^uZt)eTgGf݇s1άۄ8,#]գu#)6Л˺Y2N{Ե-FrlKQlBE,hFڮA4+3)33 cJRzOeT7cawoI˱ą{Q8F)Lܩ QUuݷRimvT%|=wr`sb&3uY=EZ+7{wxmu!ɈSmmKljm`I.0X\:AԻQǁaY;%)iM{ݝmJ\tJz=U }5}J0]ԶZӛ$Z뤖%ȸT]UaPTb }bk3OP|? |n*Zq]y:.u`w~՝^*e*"wbU9<'9@gEo+VDнΜï1Y]l3frUͺo4sZ2z^R0I7kʰ16Xrދ]ݥy[Yt$i,!k{--poxs[ &4הb:TP !KkY{W\ih[Uݕ: +UBoNfJλTr b\JՓ{V.zr|8͋+m :7J-a#plQ&XͨOv:pnknUl~޺+2khQ 7UL}sd 5b]g T\hW`,ê9&m\tNւa1 ѯAkog W,THo;T9lCeڝ{C{iCeWP]:6(n7 4INڕHq}T콹nH`#@\o=jd:*'ݙ{Ѩ_rj꺩L/IYnpYU G"$A%+lCoTۜUR=HLWXeŨf ț`O /1d^wMVP8tRZ1H_;̙r)9}xKF&T9 #j̙ڔwlfVެzvxD)UZYw059:ͨYz㾙z7دcnMc\eqN@Hݤ̡'kQvyφg2秳i+JOuvLL[Yʔ86%6밭3Ol(vBKc]`$| 0Z4Də"uEl-doAhKh:^L1S'P[+T;։[y{INl9v*ܞSrWӸۧճ%m]*/SjT(hcygշwu{5 -5}ڮk90˪2Ew.^^[B8#zuՒQ\םԞۚo2|{)GfwVbB;GZ46aP+<%YWei ٛ-"KMβMV !b+U>u՝uf*k8ptE[;[ˬVTX دz=}[ځ} /+R[F]"5c`[Kfn:.ےd׵H:7Mpp`%vByRBnzio/uˤʢND:9Vܙ' h]kYfd $sXvqEӚ9=QXvƮLPZvMp:^[)goev]]iK h۟?YlFL'%QV,*6)TKНΎfُqI%:z&Ư,떇)))Zr[B'1wVZG" L٧vT7֙LWbpRƘ-k թp}/e)-^U⣁RI srBi8-ShJ%hacj7j֤d[twGa'М&U…n.rwQb ]FU}Ÿ1*vWl$R;zz7vo9“KS=sLUsm 7巺6[GfwZM2/xc}wTr]j [Zb]Ğ7Aeqg9d{FUmw5#|^n{5\^+c{>.[JfnfvdLGqkU",P(B)&{Cbg2F9nմ::,;Po <-;bhʁaZt.)e5p^fIa=Ky4tLI%% W^Ftv`"ꂱrX, }s{j/3ڸbT\+6D˝ϰ GVo0fmW{mpKw;(}Z} %Y1q |e7ͷW.bh*̛qo$$}A CqV0泦2GrW^Ytyedb+Bo5CuvǝLW<\scfYd0BՇjz&YSՐ^'{;,ɭRguiC'=k*ԅRȶo(vrYvU[bmw7]ˬU J$&ZS5⮕W(< 2 |zFtq\=Σc73m}Vٴ*b&[7XHEjyw['n: Met]j Vbp_t g,pnc/p;i+#{f,ګVvMijEmVg[ņ4Rpۻœ7VT{N7BfeͫJqzpTl@DשۇpWg+7Ի$ /\ԋ*n7ZnS9++2+7s!ʕ^3ܛPUz$CbAinQKd{XӪ5:k-Y4xJk%5}mv`p겯XiZBєTĢ ^|ڬSVIyAsvWxiZtoCbg[p' Q˶خU31MU!p:CdX)\NOeP5.ʫ&ev1WXR֪wrSl12}%Se|wA;^|ZvEite.=7*5Ërӣv!9J B^ub2 Um7T:hF٠nA8*FSo_ {U*L]Y6 fbͻYgM^k)aIwV݆G#8Ue% o(82 ܫeSIsTvfb G+ f*?=&H#fqkqcp\U7QegMОs5{}Vw_dJp79V)ujf5t(=TMqMK=׭ͼm31MصYBM jiZ%]Zi;w^ؘ:4:Q]\f]\BdD]ܠ5M6敖1 Z+BX2M̴- \#Wt.3BݹޖsŒV9bJ>B% ;y2>ju'>놁gjT(w/76a.9<Р;r=AK"AYY Zi%JjV`htF;kE㾋;w4ȯqeΪm6PhQcmѰeDJDEg5{oIr V˪ W1u}u*sL-V*nvZx{Iji9^&;U!\̡GrU c\1*^f7;:Z$7ژib[-H e2WfgU!:;fu)A՚az7[)mޯelSdw7l(a_1z8 U˕\+ReޤƈW NpT/jSce_wV[6A:sd{>2Zwީū\ *6z)UjmnH& in *ڔbk2RG-.{I+~F-=s;u^@uXWTo-iE/,ފಓtnvk%.QkULmX[]uzAX ֽ w'\1׺Y>4UMﲪK p\9_;j5& Gu3\ŀ{UnUuÙбʵS&;M Q[η0;i=;2ih h^(=ԻԃzTvw<^S"2>-WT#GuA]S5u2B{>)uH*O.pVKz!bwb.©cr[:oG8;؁ʫ'65jbnT$5~NSUDvp]Mt]Ɍ;8*]QrUs5\t7Yݽ+wWiX2<2K^];$+Rwã6o,J7E8+,,չHUVŭ1UZ8XU.vie')nީr_')ݢj7II\:8cPؙk& 1:g&TޚAz:Vpړe*&ܭ&T!Eʷ9iӳh%s Pc:;RNbev~WY`f[+9d]wOg]-ul2ApV,8(*Ϳ >܃j^ԛ6;t+-UnMFr4g1{U x$mpۤ.ˡuB)R U[yrn+XWrz'+8R`% lvFK7[RuF6Δ P"bZٽ9ήwxT{U.oLr2깲8NW[{CUWܗ^:7^9IQNތ;m]F,1Ş1^^m0 դ!g`ŷ9Qܕt{WoKCuٙI怸R>ax}S^ 態"Ky)HNsRUL!ǢI[ ˔£u&ib*(XFQޤl=Ƿ/cU:c jfs]x:>zrԍi͇,Gf7mfJ񋪗iKI26t#,2tnm((݁łu8:neTn&َecRE g:ڛ4p[ׯp>C*NUW uv2/ĺvmSSXht]*Kowm;Qe3Iַx܁!@eGi)o sjTuiķ]M&(Ib5lt&T|\#yyRU3`ڧT\9iqQP7ݩe]i>vx:񊐾 Yں*9;hk#px_Udx&_tl2ÄsAg)9h;om;s:A[t"m4ڧx6j WB1z&ZN>6X]Ӳ2 X޷QYoq(m g\Ju*Ui5J{D]Ʒ=sQ*uh^ko$A*$v7fÉ gwzJոQۖ^ ;EݻAcNcٯr:g8qݛ|me+QkY8Ec(VZ+Q[jS)OKqYEZp$*])-0X]9RzgtRTY8Nɷ)v^V;\$d$)S O[Rtmj˘ժr UDʕFeV*v4 6 bA3ؔ\yo+[HuamxZ2]ꤼX5zڭ93 .9sS<0iPg(=BVc.[׌czNJ:kH7-UUYDuYtQ(H]INو3:M(j\p.xsBU)ya1ǢKei(,vrGr3u2МmTؓ#Ϋ%ܺ˾ BbJX]OulrXX3LTvdr(j!s FI^SG<Ijn|;>ZgI7iT)Bua]IY:+0d< %tiYq w+Vt5u~|%yUkh7ۺz!(B;V@F7*Q (=!YehXT%zE5GsktMȻoZ>;N,A)Y'QPsI^lܣE*fUSIֆetIQcҟqVsN/]'/{&ǐfE-8CnR4v7T =+6]98n41S ɮn.5nםe洪19Wˉ=XmecJ[*g q Ó 嫥T; N;C+6Js7_.J2]{nry+G 6[.Ӡ[wwUfX ^s(q3L6]SS\QPt2^a#&2_e"fj(e6YPT/Tb@.}fYՄ ՜yetx [*uX+ =uxQ]Unmjwlt7>U`*j -߮ZRtH}fnnݖ*;V5f@w ʛ@.҅iJ f4:Exilw^C볭&s]Vs또 plա†2K޿)Qn9uhƬNNSZy\>}b(7fzd9̬um)䂫'']]x˷ΛKu{vΩfCfμRݾMM,;VWuoKvcuV*Udv n B %c$Ҫ:6qNӉ}٦>G5=@@:|H"7rc\ۍ# x/2;ȠmnQEK5oL@WJ3sOGQVS&óWzI[Z"mh\@foX66U"z .,-_\/J:θej0 lJCE}owom|rY*4^v:_^S8B[w|lu3;`viNզNLq >$moW iMUI*}ƲtSv>kY64M7헶8_J-rꌙcl/8S 7-cFXU/Ud]Wvԇhh郣kh[\ki9(Fܺt9y%Zyv+4T۳J*7[dsRn F2vtbӋfGpo*鶳i {wЂ_I,˾^VrIe:3M *݊y:C֩6]B۳4D0jm d{Y Y8[sYSS-އ3l%<.*-Q98yg.MhVZd&Třf˴o(ֻrK!n +-  KQ<*)DРTJx =k;r=.c8SQ+JON i 򫒳:W%U^ݱJyڏnh ΫP-Rb)-͝6䁼jܴάboa̦/q˸ C)V2PU)yUz!A5ѥE vlvs ~fuڃL#++q-.P;z㎷xѕvL./]/{FuaA!T%0B3t윻V t4q$ʯlp33;wlÏ+ҡΔNK w2T,bt+1H ˆQmv!lMGp%-d vXCIHlFԣm2X6]iz2 *(Lܿb.TSpR(RM8fCuAf s0+D.$-zSRh(k]-{7nh̭չ!(wrL\RV&K㯣*RC:ucKbCWQz\rk6rL:Χ^V dm5 Aׄ937VuAWMx{qM \c1q#UI5Sd׍*#T88|CYlȉK2i](a" 8,Shrflv4OuafѓQM c$Y-TDf[WL^ͻ $ܹtʒ*L+ezWoXƮTI]uwv_Fܙ<Ɩ:]/:>Z"g'b+kp;J]UHH2.u[ nK.0YUU_u>.Xx͙Ҭl[0RkH䋃m+,2&yf9-J *AP5n=Dm.d*EgnY_qո/t-!T^# p*Ll4[*,Ҝ-,4ڽ~@qV}Q$n_>$S)Sa.?i>-<\E:yӝI9f6>wl>'#?6Zǧhh~0{|NLac<9Ꜫ{9A >lK ND#0 #aC`f8ڷ@恤!UCsapo_2}j[zM@}:0D!+#pͿ]*oyr]~(``YD#86\;x)f$8Хj±~D42|G!|7lDE).Qn'qF׻osn8`4A4$"| ; c%j!Ֆ 6xE+zz42H/;)/)ocK| 5} U.=d(N$޲uGtQ];']]yFqAmlF"}MgXӡWۑE]6v =HFK+ f ZQt̹hE[ "MT ^+]~!؍ h,]L:g)|"MTyCD2I"6CJT{m"∟Ww}gx~ߒLu 儢8<}t=-尤ﮡ5CÿvTiSl@,Ƈ1=jѫXL:\Q)hRrkWe}hAç\6yE+ZF={VUHmW]@o`zk4+qs[ʡP+;-˲2kt;άsP;G+GBm::Zx)Xj[[@*񉈮e 7Vgƪd9 9l AH($ ge ДGUwXh[7\͹{m&Vt5"nZ2n%^m31eԽa =e;9c.i*I[:%L!zGuzR3&yyq;۲kb|lYj éf&way Xy[d24Y 7Śulp^yRI^fTu^kwGg.]e/f.܌f:ɻ-۱Brb*gUwnܸA7PȌ6<,/^O&[}Lvͦ[{q2. Oy{j矈Ysq]l>NuPJMT@1˕2z|}GM`DÞ6O Meee{JʡŠ4*IHY 77i}m~K909AIV}No^㚗s |jg pi 4 tgfOyKϡfA@hBOեFmU[Fdkr+kAت"c>e ˄P>WlO ؅ZS8OGM9әdd  !N7WHGWN/=\sL㙋y1i N;=9k'yg{{Co8\mQjkPnW-O|>8/*l0\4/D1ܸCG# ->cY)f[~ewy$UzVMb><ωtt͓t /p NuC?"~;٭wcgg=Yzͷʕ+3GeWvh/|pr< `W@+K CCuh֔>^i/f?qmlAN` I_)r }"W:߭ 7i"{<6BMz  pڃ 5(2x ?"3˔.#\_V7w9җ&GVCg}Id#Y섉WА8{z;?r/~t= {z^qO|F_ղEcMp'x$>T̟ O 8$lN%GcC$I9&sxyJP ;\Xa aI;NҖ7\ e* qGH>J}u{O6:&oacAArv ,2글m+頻i q[Pg,,@0A&(ʔ ';4c'96 x$`<^O&<GEPiKu4&PnJLJkn TڀƏ]O}{{ﳥӥ&J*з! xwPz3 <P56"0جAy1 6yw4Æ#!TY౛J>~E Bc A$ψXݷYdqd7}ekD!ǣX3;r޶0:Xd:ONȮ^PS{?w |O<٪oi~i4-[ЌAtD^FڼxNn5*˻Qkt= tMRKC'>vIJB*Sd:{pX~f~v{wgcINu<nGQ(V k{SOo]هa{zI﷫ӡ=z\tӴ잽{:uu.T` o'3 :'bDBGڡyM伬StsOS=rC"7kjrs:qEs: O<oL~ϳbBq=g3"Fp33 #D^(I$U?`2 ia=Àl ̞}}!uO {ӿt_/b@ʞIɲZx"j%K_P=B2O}PFC (VBrw*WXU2C/-1meFe%, u[#RWw ,Y ju bՆ삑0Γb0..D? b ڊMx; EwEβy 4t;KsڷU`LOnFKhr֬KJYa.v]UO6biOFڱ hkUtwjWWW{Z|`N݆ڵ[ `JVɎVBWw2![MAT,m͖ kګcgt=Kv," \ިHdK2_ZOwaK[g;ska$^N'i-1~R{p_PG n|B0|qr 1K2t\%כ沞iݒ0{>s'56wI{N )>[V69 ΫԤAm)!yły-ap#ȕ1^>Bc$Z ZA(> Qt4y|*ĉD 2]mSDžj϶EW6 D GJ~0;>6HFl>&_>Z8oKR}ǖB*}v+wĀry(kdϼ;zq"'n&*d!^6 $thphU ;7LýExt{4:"E Gg>gsvygv;9dM+ 0Hքg QGƩ hq4)nX(PPNA{jѦ)}G>IR4cP-u9e٬fٽgp!Q;Kn![qƭO+V uHvQ;ɉb\WY}]:eMV\+9R(nY]₪Q%.ѕ4[ܮ"]\x HB޻ز%vxB<[*ʾNLDzE'D&ĺclvz`Q<8[%WX0:]: D"2z:fdrw H뷜E"\L&x$_h#ϠaG>T, -Ќ5 ۢEdqVw.yqKbLxtŀ'Z|EWK!Ogu<~Q+K aH 't1Dj-Co[yr#4mǽvT]8Pn#Y& ]t DiHqq6Ca$^&Yhy;MX ѵ%wQn8*_UZglۃ** V']uU\d-UEw14ٽ۫y 63lr x;i @.U4oFeM*Bvm N\S"묱T]ݾd@f.mOCAyZ"ؠFI_"m'Mn[I6u޽6hXOkz\lԦM_^$«uU|&XPћYPKYZHb*Ȃ" Mb֗*)0fwlEב\w,cT1Hz]< rVǺ*;UTELu>;+E)Sg$[J":>g AIw9 vN}:t|J+ClRk@(IycJG&okC*F1 8хAp# ay]v) ##+vR T^  +{*%nGX7dY@%J{N`TBEZ^-_)eC%S *J#6A5n(g3MYR>> > GEbBAĆG ӲIxCHD/65^dDJƗO:>'|l65H`9LqWa]m"8'.҇nϽ!<~6O>2M!!Gث"nH3+1cwÙM.F]C<ܳfz{_'D01"`4mh-g֫:]]CqYZ:d^^ yJ >}0%vC6Q:OL?OߜGdQ#S $J-M&MplU% +$jTh7E+n!t C]uZ  ?9~y|s| ?뽗AFO&#g6 Hr!}>Ǹx>,^+8&gpp LAS@wj)D[T-m8͐bPTExSj75~NzN~Dabh*V``ECuZhM5F&`)tpL)5p%b(]n&j ~6>Ob@`98ȤOtlw[sUݏ̓73"r K`L &8QEk}-e_}oo*/p1@D26D{[9K-=K`0-UB9^ENN{g^I|؝$8D tz޽?"@H~tҔ;kU@55Rw\Vh48b:":]C]i4`MRt A V9 bVA <9gqz|'{swv%ʘKC88~l/B4O$2c|fT(ŗFk<-M)/2 #CۓtNCa54(NS:^CSκU  FH"Ȋn\o3 $ ~D\ͼp>YTxI_??f@& a5yb'ZL݅PtbJo&Dhci"}8&١}eyCBȞǯ wӡ?~0r7F m0d*JnYt KhhnAkl4jq%UBDР(\"6PHw>ȏێ'fě͊=6S=b揲k~rh>`:*Ww&\|p>$yzC4PCJTaOQvn@qKΰw}s@lˀN؇`Y'G8NGO$:[ WV2PRL0aBE.56n&SV[JDV⇊~I?z3!ٰLs`U"RsɆgy)\b}5^rC 1pNgyI)ѻU AcUUX7 I`iǐ*沴(y{PdBdtXNz:$(h5@4-.Q `TJk%JEP*5pLi[tq P%T9(}{xy}cxZȏ۹z.6D&CLF"[B+P}۬C[3cydzAx0ݡ|  19yNn,%_I=}ioE~ak_)]s<=p!s M{}u :*?onl7ȏm!Bi,1}N' x0BfR!keme =zDQoUL\B!Dj@ ˭KY$}i?ik=l)X%o4I$ⅱP@ "5s\4 r")(%ﭦt拻CCF5T0dTlc3ղ PUl:ښn)4dErmޚW %7B;3FŋJ Us-rw9֑y\]:^oJJ2_@Jƹl)mVxD葳Mm2hr؄!r9V3 g/8 u.мC𚟁j[Iٰrph !_@PgO!~J8^0' =n.0vbd<'8prEZ z+>tLQ64)i+>j"m.1A"6-~AT'N&v泟8*Acb 3ic{sNY+-7mQqC4\,zn"㘆O 푍J$bc~6,b954D(HvSu EB6mEiV`"Mo5U]w:n6h[aFd^$&yUCMPkukai&1Nd2[j̈B:疆Y5d |[ډrV<КeAX:J_U2* o"U^SHN &3`TR[˥wAޚێV{/W{5UJ`<]_4&vŞ(:}u8ڳB^L|J귄QIYDk77bǨ|&[8);Bag R oTp[LAjl/,Z|l:,PôJ_:Bd{#6LP\O#/aS4yTvul@^SzuőU5i۪b6,xv(c0nɪ&{$$`pgC u:ޟ~Kբ#]YVBUDw04vbVm*)a% I*,Y9 ,Msm [.Dj6ڋe&Xd]P},W9DYvVvec>'VoS)\wu,pON 4wdFEx(f2)#G:zn*ӕSy6N鑇c)"a(daUulnqe]`}ު(^dQ.F3疸;Y9 mnv2kjs7C!X`вmSpTeSX`.#$o@H@tzXW/7~Ւ嚐(g˜c)EZO87^ LȪٵ0^<-Z'qFxzݛ:܁qwDITSQ6KoCn^mWX0-zԔ*h$;tV˻UiUb;] l蹻0mΥ]AiZo2Iew6w{]njU1#In(wDkY a!IVr%w6rU.ӛ駵ں΋=A];JY$yA#dFg9f]APğX ^RmaZ1)N\DUZYV4WGvnq[t_PxE1Y ҩ=9E;cbɝ~6)^w4%43FD^0_ " Ũ[ý8&%YfmōpxwqYEAֱ=osdՏ::|*Ur֭t(]yZ{JTGۺ׈v:'ikDa ~7~ܹȁ}[ \\U:7 ^"(kwwz]Ypa#|H>'2X;FW";v±Aorz$B%(+2tAvކq@Cơ'N"> N%AJZjR H*ը \ jXBA*"W5Rը@::'^R9wUv~?ǍE$aأ#`-xx{|%Q :kZi:U'G2AMTb]CWcJV;t'bzꛚDdqjFvȡpw^5$<5:37U PU͌N\vOPOǾ>%Ц}8t}zӧ@ Z &ICV-Q7ºA @,tjWimH`ŲWF%lI& Zl@W$<`~>0y[$+4_6G>ܶ ngxr]Li~/lCnط:"B{4 "'DV2ޫ;'ɔ},yg&н0!8%  =Sqw@ӝ?$Ca `Ũ) Zj+@ KJV 6 0PPA)]L6RV!TBNdbQxȯm5nU{Ԏ8 !|?~}!%ҼAÆ0xB 髅 "=! IZYQ= Ϗ<+g"q$>R|Tw"&iA!u2PhG$T-(]tԠʥJQ@*ꛦED(+P?x#`=9m_.W?Ӛ]ȃ9ّ4Ȏ$匿kÇH-E=u2#ʯh|\=!2㒻oRuUR.+7hD$ApsAx/Wn;"tz:Epq-DZn Ԡ+tQ!)t FjD2eBJSjTD ʘ*<<Cyi+mʷ[smW`?C6-C!@2}0! ]fxx|eu @H1<@4h~tBe]ЮȒAo;b[ PUc:s|ǁ$lTS@O㸸4 &EPJ]I B0YKa]MB!B遍]BCwU0LP !GWE~I*qϾ8"[~5Z[;oŭp"rIGN`N:h=@_P|ZJ$@uP7SIVMhn e囖֪wo"DeΨ> S u:?zN}憒|H$Бz~ ס~ DPhh KJRWQSy*:v]@ $ E*6ht:"^tq<7vSäx ӿw^K}O$njĺU&PO{Q:'8>K/i!aq0a!@$GĆG#/dxtr 2Nl i}DIP \N)`u`p_sgJ>::T;vyodG$&eN^I',i0Hm78m LrY>I(|[ c8Xa$6Lsp- I:ƳnN^[$A2܆JC(Qqeؒ#i) CD@,M@XqI͆ZX9d9t*VAҤ99x<Wbc9an\R3p}'+@;YJ"nR5֪ܰ!KWj}QrAT" "I 2݄r#z,QrDqrġrGSvJt"u -:}dHHӳn0 E#l4⅚Gf◬ )xIm?Y X簇<\ i,aUYׄK`-] j4ڧ,w%)^.?sGuݽeMp5'2yNsv0ϸ#4EiQ7h"m'kgl6,1O!#FBۙcU> tM[lX yN OEJQ%$JuxB/,Vmp}M< _W19yu'>i"<*IA/AjaJ0 A2CO1bG1ŌgUTuS̲6)훨KO E)rC:Cq'.ns?NXYI (y$.(:*V.yrVwDX}B!D&im![lnBX""$dv#hsQeV -b&m8ZO5Dk jG0-h q\g4K ogd4e8Y 姂@dg "aFy]W]5n_*jN'5T]Y25p27RPcvHh-,7a{T⍥- An7!o/%B ( '2G[LY4hOA^\sP]Zmڡ[J -a5Y `α2[1ǝT96Czz9Y9Jo86.Vc"U#0g*sꥆ1+yT'T[ 6476%TBuMA# hfl}׼f)lRJh_{iҩ k.fb&;r@m[ӝudN2ۇRe5tWZ$"ޑjeE4|PmWId0B k8UmN-giҰqCJ%mzvb  H sއ'ߟγ](GAUTyiW2Fb7ܞJv@V9JV+uy{J]qʊ܆=ͼmVcaMfnmp8 vݲ]VԹC) 7c &vF}bƷ%D>ۻwFt89&r}Yzr%puM&05peÓn1 , T*.o1C`[%D0.[K\djKĺ'5 ueөZ!jepfL=$ulRpzx*}P`URv3E.{Z괣gu /\oW޾U#5ݐ%5\8=ܛ׽K`B=;k [unPԽV .F;־sffvLKгVAlGث'vCGOAHzJ^mVNj Rv$7]^k9hU1p0ei[-yZS*Ѷ_ Mۭ%B&@h@`D FI=Nxt:~?QT.*4hJtMu4  .B4u ԨPC:+%u5] OL`/~on39٨}U{Nl_M <|kBGg]zz=&U Mʿպ kx@q'DDZ;֪nkC(#e:4;<}̯Z@dJ0$x>Cp9ѢwEWGBwSiUTiJSCIը*B#Aʅ0@BRM MPWz fnyr B*_7ʴLԾٴp_9O##緟XxMTz)$lX A< A ݊uKUӂ^ v>1Y P#I3,XLX@<^HȧDx::KQ㸼9PSD)&4j )T@5`h j(JZX0PhTJ%0S!+ay.o~vxax2!I0O'x~,\*ߔzG~>O_i*)!"I"~CzpȌ9qEGat Ierx##4* 6JjP- @#K)U] Z4C ü l >rHr 30'ݜ'$ϳD8x=_hƏҘT4䇜?w:'cr9ܜh(z1,ڼkF)r#_ӣtA@Hה ޯ4N<8=~?q; |]utK @hTPubp.U@P0 nRը t9d'lh|G6/짍v.7ľ=Ā6 K!}.hݓѰ G6 fD>3P7N/Y#w+,,W~`?z ,sldCgTp>~A 8]Z.WhtqiP+H04tnnE.T, ʵ0h m.nC_!9v*!ɐ6XdSbqyds~'ٱ@ئH@\#oB<4N?nxgÚ\`Y>q~c@@^ CSZ)5bS -|<(T\H^ ˵J4l=`H3Pꓦ@t^DŽVKn:P-uhTT+t jQQZ5ȖBTACMt -E|CpO; ,H?7.ȊP/"X)rLȸfcb&lD]2R@"y[[Ѿѫ@W~ 0@~"B0 .nc68)Yi 'L$z'D!'D:QÄ~u *7#Jjk U4 tjU+PS0QP#m)E J&U*Q??9˴#j^k9|JbG'7Plϗ@ཡ{m*1*z#ߝ(^SgS^([đ]_rWɃ: Y- 9N6H>7Hs2s"$Db=p̑ !zE:P:QwD)uhPCSAv C(EiJSCdRc]T-Ph(N|]oL9e20cf5n܌(!]oo J/:P߉ aV`=GϦ}D 6/Ã! ϡ(dD=L,>sБdpy1 M@4 S>0}TKE"qtYN5[rD1 hg$^"4[@b['GW a&; 2#bᢟ{߽םaRN{<:P( &*Ϻ-=7R5T!4YW\~EH$ABOW^ƁVle܄,sV[3Jb3$FtTzZE:3qT ؘc-u)Y(rqvu!(rV 3qs+\>)=od%1SNGCP]=KANXꕗ $^tU좂beݺOHiqp~ \wq֙WU}C9B$]>8m4V' h7l/]5vP䏼7>!˼;yPK%宎|R>#uj@1@I`BD#~WTi~u[U)EQTYʲtt剣8oap$`L=wD< ' *s \0`".;|0=r?v+sL@AT B+d8}eDr@6þa `X!zOOQs=N8QAqsD 3[`xhݍJ7_/zcc8>zzx7N" aÞ}T\'"1aL&$tn$2[)0eJAB]AFY D-BQB*vG8Ie4 ,F?@HeX0<& ND$|$h8}P67FNrPQ#iSLsVj: wTbYyy溋>Oɧ('R 66!SVІ'E8I8Y0"g)l 9lBP^ŠLz;cM)wgzD,,.TU@ ˢ6[I4sEGR6! 5Q>L QtIY㔠A,jL9 ]N8*=D3P7e˛h&k.݉OO;Kヵ[ U"|0yemY:ݩG2ESw.: 2}Ee!Z9J"s_vȗCZ- ZIUe%ri >X7%uU̪(f58T/]qkSűi=Wc3n]Nj"O3,rxt9hۮ.oJvwvn){nUR`jsf&K_ |JY9HF zr\5RM"`/)is;VMΚcQ}'E }@aukN5I!yxr :M=C~À@1|81ʉcW=VQFK\dY| cuyEy"Wx]łlIoB+kk&Хc XK4stt+SC[:RIJW /x7 766f(MTW+uS/=Tc1՛mbwmMc_Lf2{hc;UpcloNYc%:ۃUtޢNJ3%ej81ADV|Z͚ġ<[ea+ʜ#xoScn`Ëɻ&Ξ.y<./U@jߡ(QmiyUrߒ4ע[&DP6}a!ò4IH TfuQJ^`I;.2u! XyLjm9NDaTȓ][ʒ(:m-rg>O*5M=#cdYfkC%@Em=@1 nFiVWb4ޕLu;uz+( H Լu[۬AP^Z5+ꎔ/m+h*ȉlь"q/v+ѽPUUդHi ^vEl"!]Y+ن*L!!}E{Yllh'oSRDO{w*&Tfn^Ă !^:4UB$NRV[λq!D+eUXkwrX#]ˠyĩKWo_vK:A` pht*-$]tχ^TlV,P~`Đ!t\=ϻP}jAA#//aI9X(('T(ً dym@cd»p^_:<9C tJ ;> 8ᗝ VQ BRܔT`/m饊D(q$K/xq ey8+oş\9 F/" +*??xѲU3]S[$x}Cn_z}v@N*H/2& `"/^b(a@|g'w\>糖 [ؕ|4z$@SzA/T ze ut ͼF U7e(C{- OizzW1tc!8|:dCzp@~ժ% ]2&5 \-4 4T(] S iKM5Ш(n)G/zT$Ox8_/Sm'ijG7˘w3aޜ3~|2|;PnO;z@! PmyGfھ֞V;R:@c۹HW'W C;ӧ^4?jhTF QKM#nCBbSR\ hBSt5-n--CD2U0?r>w[p79>U` ѱQyD9$q;}fPw1n7F:胧^a8qV9EmO̒7MTWB=82;EdaT>O$~|u:=9O'{\:hUMiD ]2@imF\`jꁶM0\ ]QaF5P:ZN'Ca'ۮ2}jm*mv9g4$uv&C 3`~A2),ঁkrC>%g&;G(U(#MK{OH^: (>N{rd1~^dWGtzu:s/~u*.HnE KM] t Bښ:jrHT*!MQ(WEڨbjh;e5riêyPz=ݜ䜙|lU|Eplϵ@=אIv)<șĮ2o)1I$;~,FC ;=e9C/nD 8 y>v\K..Cf9!ӡ1 BQCu&AD5P H*]7jU!46u1DQW? O~O6T 332~0|"s}3ꌒs40ߧ1E4}{}ɖM+M3a`d^Xk_qܪU$-|F) o yr hQ}TzӋҞ~A?=~ڀG Y@C VZ+UʔWp4TTSZR!Z5><<{mCC'@s $"*ˉzC9@gbݬd3h|ϝOC`&p/ /MF*~3VaI5M*ƍ 1) +Sn5HB$:^Ώr:z'St:;ӾUD;ҩV.Ԩ5uЪ%-kQ СPM@-P3=y`~>>&soqsQ/\g͵ %L}dgCl3CAFڞ4GxODq*4L؂Du 㡲]ᗭ r5} c,02=Mws/Q:'G:B~??STjmRօ P*mkj+Z]v15 hBWP*h5kQ4R>b.Nf@]Sh߭nsW56efQ"fOh~c,ݻ75]b_h*AD 4o+ m*NG,VY 1QJ=(H0#E'C>)tgCO*Z*j:.D MSTuJV(j:h4t5TǏ':%Z!@ Z4M4WQ*-kUj:#P=zӟIRZ&J60 8@Fύ/9O根ꪩ;P(DR^ o#j fd='´9qg3I@!CH3#&jf<@>( 3ip&f#4 pŜc ,z#CDcEECwIeE%x0->ܳ^)d?4a:e@EqViidpAZ&նfxl6qТ*5UXB3^*̒sֱcA"$:Qn,d͌ixh:jG.p3@h>A+zM$CuJWC $-aۖ'd:6˪Ofxf3TYSW&30jf K.in7a8YtKy?t7ZvWN3 'Fa@7|YH⵳1Ȉ"R[$BA~)BkF4~ RkzP&f Ď ,*q/wx6U.?{g͏?ƈr|tټu?S﷎ )g^, 7:m~hd_IS܄Owre%|۰H RS OI,e21 N d^ښ)lW#(-\MDDqT"AITn%wMu.Rd!S(J͇w 6OE3K8vMqTyAi"P~:^xo|x͠.l\B'm ,!FIeDi'8bNa ' ! (QԩGԩ%VTt,,{Q曷 [yk$Qe(!v.= VSHmI\D' R/;.chԾMqsRd4݊i!K'0XC >fH#!g;!]'#^"b!Ree74LCtj\vy[uR-KD0fmVlmY^Դf溧N C 05U:qMUw4hPd|8 pѡ4A89ԫ*.b^4* %ְA h ^!xxq;8V=NMtM]JZh:M ; օuu5]nh--P4ZХ lURҭ54M*-iK~?R T1m9YKoEu:ý J(;,bHvhobz)_;w7WVfN ڋ6^].l}5 ]٭57Xhq EԖA(-fRwmi7Lv3%] )k$'XM'BO\)cb+Va`tS9he+z t*̇L3ۂ9(ΖU˔i*'b,6R)ykXá[s$lrö+S!Xp*jl霗sM=%fm8U Ewwvi/7vcШr%\WsaR$8yQ]/ % tSōc}K_#vǷ ݭ鵲Jpsyu-婔9q[PnJ8X5M.^EZl=RjN {+婺.Z&.^ղp ,YrfkrWIur.a[9X ^uuEׅ+79t;!]Ln^`:PϋӄSq-=^n[Pr*D|^lO4]w h"< <C!xRH#Ղ3mʵhgRǦ!KI8BAS 5wFy2nV-d,D,ׄͨw;ۈA$VeT؉49P zàyRF0N8谩DJ8]"FsAxs[j%º6:i>;d"{p t9J7Y9i q)^(<){o_".sDU'.Wwd 8.r.kUGMF ȟQHs"t;gt9|3xڧwIiVBQ2k"@EF"Y0ϕham!K@="ڜ~xou^+0$K˞^3eEi7o^?P|Np$w~a!nxMD7qW]$LNr$J4d[2W~'С*XD#HshB@ aO>D:pON10aTS&sgkY~+zO^PJ`󳪁{P ߛϧ<<]"H=1Mȼ>@|$qr#Dz9@HE,َ=fA'sM0MSS?<>n}zvw~}D%KUVjzcΫw76!h׫TXY.HCǒ/׫@:=ӼCTԠ [j%+K!T()tkD)ZPQ* kPnuMaZjPmu4 Z(|OG8S ̑$@ADV6gZ?o/>>( ;]qwI  Jݗ>%SUX !FVȫkY;뚱9UDQp9璏}t$EY>@:t׿45 #Bۨhj Z:tjF50ZGu֛ D1%]VjGv~9>R|SDCׄ ]fnTd9iO}1͠Ր~y O7yw OgMAn㥱 @.IW+7\l"]=V`d<0(pef$T̫! 3=:BC pzx߳n&/4 +wLZ6RP7]()WD(M 1kjQ[Kՠ$RU{=S~qÁT"2,Q~Zݶ߯kAUcM܊IrWm>O(?(;Z@AKS[b0v'M1b(9DnrɀAc x:zC@ޯs MMj%mLPJCDР MJZЦQ BAw bTt [Jj uQ辢"=N9!S``gک1;/vyl fk绿/.LdgGfDhý{|6h -/!J;,]k1pw`}/1^Ab{vfI(p:|ޟC@4 ֛MRQJ] 4 Tk8 ]t+3 MCZ qVQ @Ѣ-%e߾n̍h}jK`}k#>\>d΄z8@'y4JRp00 tt4uS5 4t R5 @Aֈk:yxxQ@?̯菠/a^npdm}:D0ȿs#iܩ4*tAh0> = dhzfJXT=y!A@++*cphr'S@zt;P (Z-u L U .)TģUt4Һ:] B+ˣiz_mcr9fy $>Usnd~?[7 FHa6ύiR,zQ0՚DɡP@$'v".ESrIdٹҳTZ$#'Ϻ9`ys#uSuSȽ:~MCV:hT]iP V]t "V)hjZjbut [JhDJR@4*Z6=S)= |ܥl\aRc(Da}!,08:$г6:GTLKP !D:Xer *EU%#aVٽk8uɴo%s'rwX:$ӑMSשuyןgz]SQ1jhk]Z iWCWjPTJ[ F.AkZwC<<:V蜎r^iZXyl]߼_c \H/5[v MH${8) 71.C˞bI5Dau.B e`gH"Z o>u\\87y,^We,A-‰vBXIt6e+}hմ&B@mӖ{!,4<u:9ˎp}n/{sluԬ|p{޿!doIo23(Nsx~`, 7eKg^mv=&B+(pPMuOʾƚ8sӼS0\BOAĒ!v*(sXqX24K :SE: A! UbQqFto+vfU U`Ya d#GԫRB N6a^̔d}W,$kkrpWE;);Eyp]aIqˏn=6J'Q5vJvqphPk*\su:嵲,_b񊓭{X 0lb8I8řƳɴR >__c[gWR3r[ TTխˇgfu2jn; l=0a MpbalA!-ԭt8mIpn[cQi#q4Mb%(^>1!Z`U+alqZWC Cy5+,kNCm\ ,6Vď lѲf3vkq:^M)"\~immXh#y_$!kbڊj읊] XPmfUkirnQ@ꕵIڼxo-HNr8sW1Jj@3Hֈt7B,wC(Ԭqjٷ.Ν sd^Q(Ք0RrixSޒ494=AJ|D;b=nށ[w4xN @?GAu*mkhJj-ĭEF #MLZB% wq(hQÝi>vF׷YlVLkH,honcZew=lιɶpH\7GUأO[!MlYXV(43=+^f U9JQșJzƚǻN%j#۲R׹5z]i˭1wHOzCȤ WDnUfbKEDQ0K'Cuub@v2VZ-`9A;,e(gMDY +hҝQlAْG=9am&/Wnڭ[tW[8$$׏ZcE21չGg:Td*` 5SU᩾5[} b˶}25$]T|BKV2TÆy wՒ&ɒcݧoNY(@Q.Jn0{crZnm%6`;Z:\i)巕r:ohIÕjt;V6GFj n{ETq4]Rd;B!&>Ώ K(vJw[{DF-E"GYI&`"Zf EoY aK_.̱pNE`%@' L'ݟwusu;8i\we;ޖ$I TX8y%I7ϐ(H~$6 Ma!B"~OCF˼ R Sb C9}n ar =rl."lj47^l&v+5X DK86Rc'IڂC\Fo>௑4ɿ&sxؘ$u18=Buzσ~ Jnՠ-jt::5, h-ip11hSYU]-)@ܡCh_`!|2!'Ǐ cq ju_Z*claGϹ:EŹRt1eBÇ:L\8Itv+9]Wr8}* 2ӄ:A:;=!:@$ΧI8)?sP)kuѪjUZF:P7jfZnƭ(]00A hut|:%"T @8H.EH!K a`4R&C~Ds۳=CF k 7SJ $RVwIfC$0jS2Є&'t|v+B>UB_,2r vN&DA:HNG::{އt45ֈ4CD(*10ţUK\M jT2u4hm-MFx30c܏&Ød̎EMdO|n[VSWD}x$lv>``1)u0$H;AGΥR{ve>DY]>zzEzFy s쳢ѡ?wޗr009Ȝױ$!6.BD8{]kP7vEi`5( n&5tԦ@*nt V驢h4u(蚆 5t]@!|CM?!yLlɿm'9# B;2b6xljH6&@ |q {{ BjICKG}U8{HtlŻ vvW ZdPjٳmS!}1!~ <ڡ.8udI$u ާ{ʸ~ΎTm+M SV uth(hE`dTMq BbР%JVؐx<(?~GSyAl Idȣȇ0^Gd%#36׿i6+޾0gX$!AX0OhE6h֘xFxy8ntoSn$g^ hD:=Ν C?ֆ&Bښ]V҅01pJG]uCwB::Pu(-i@[qO'~Ood>'Lأ$ {>E lys4__!h<>RtwX,`4o`.EavMRƙsmj|iz@!^ÇJ;qj#;'YNGӱyA~?&.$`qpJb`5*iCWAֈC(ֆ&(-1šA Zbh-R:&PGztpyHA,GM`.ub9g_x@`$Ewsѧ A$Z6e  "}* UJiX+Ee.0 UP՜d|ٳq9 Ç'pst =N'CާW2/^_zwj@4vE4B[d)h.A0WEѢ!Shh.E7]jhTkCCPM4 yx=9OM K,  h5S[g'HS!Ǐ ɯmuz`h)&'dN]FiF.]DuvJ yh2s H0ٛ $\sbvbã+:hVԫt5]j mh:U-)M4]@(R: 5i:NMpq5NY6$Ak`<(' ,tB xcG#,!|c;WaOŵ  b N'0WA Qm\xRAR"sK(ܒ~ҿb3+7E&~,BI>7K'ۨB\M78hMw2"!HS v߈G  (ƍvR5+A4Z2A^K @iBaqD62" Sd];užj^=ΰZ HPJ֨ k&[2檡zR6&tS.頯R':`NMkEڋKzhWq3lXf   WJ⡳U콷g#zWH]Ca £$L3㜳x6A| T*zm,T;tIް um/(s}Sbqx~k9=DϮl#5a]}})R,Gg==kGxa&Bxm([sn'-g3il_6L "QRdt3h0DeZD(|P`q]M, x(>!j7|D/&Z}Tfa p2hY/3P-oPsplh )t5~!-DNHbHY3po~q{̞X}IY{99|wWI4K fEz"v%@(Y Zxi^FQAhu)U3Fcr:Qj#  ,S! m4|PH{ey,$[yA'HBj U ׃gGzVQ;tNax@H<T62$1/P jAt4P^>D!(V8) F qx tEbYEh Hx@vi.o:LX|xrrɿ"PYY4*sn"^9]dPH#n:jQEƈ9LٝRhˆĘ4Sjv:V(*{XУKzU "FG/&rb^l : +ײUU;F<1gU\%gMIhv/9>CKCj\a+=ni`FÖ btIk %"t96=m,T,бʯ"{,gCFʚS{C+%khU@Nf tF LJRSYJBj3gf'eΡVEwy@A0*Ay.eCUPݾ:ԖQ,^VUs1*PT; {z/$lOtGeMyZ[}kq+Ȳ/ 3+>shY Td^abfM>gkUo.JP\CaajQ*frB);H{wumЅ觢w{9yρCJVF%$3#6R*jւ&RKvOv,$ğ a9:;$_zaWtN߅'5SEu%ӫN:O):tֆ!E-m4MPhRP\tV55CVit5T)j<=?yƯ{p>eQ)Qv3nu; @;}qN'^H hEA{{m>Q ۯS[nI몛J-nù(5;}S#Yɿ7֕n t->TJwyj{؏@w殫ѣJVjD l<OQ+#bѾ{,蔶te? K ;!' L,5XX|!yBGQ\|#M2=:^T*<3!4A22Ҷ @pp5TsG*eQ-\e3UjJaHufsYtt4n:, 1*V ۨQOmNʳT&\k9[tQc{vEWUZ j8("JgxhS9y]#UXsr#o9U<;nS\ay;w[d;gMfJU)mCbVZTՙ o]V썹vښ\nܐ Bl9LrtΗ4MT} c:-mtʔI[4rֺR_s2 5g*^AN{scݻ sE]ѐl/z13t)h^rmSt*A,n.?tQ3" b+Ryʳy7e!3j#WT7%0* kP)xԽ"հQTOU[":^ OQImɭ~.'zpZ!d^*l^ĥ;8E[@'1rg6$=-h*s6jS9]:pY~ NV vsҍ:}*~gT}v ΓֲޘuꐘP!2=!Jg̼-*s' E T:du ^Da5T| r%LC؛@a!jWm^Z#]T(BhXkM\OVsa$clk`;V(˄dM2DEe #8:T⮞mBDKI4S`Y{қw|ؼ! 8F`F&xmhEU\@K` *Y/m $;gM VjF""HhA q `xQ K S#djO@|Bh^ dΖC;TnO^过GO#p36#9 //.QxUv:9۬i'Xg-uu)K$;M_~w#۞:t?mORs&I'1 S-yhopҹPT0?t$j/)By`X뫼$$p4{|(T(=./pЗG~=OOɃ ğjK6jl>P \P3$"v[|!p;r3@ءJo;+庥J3/: gʷ̓x׸ Xh`#Y!у l;@ ܁aHa8>;B?)ZCCEѪ7t&Tj]]U(%p+DC@SLJhJZ]MMCRUO$G?Mdߩ} ``|yP05 05o40Π@.yv7ckWPא^ # #Ķtܩ &@oDтTd# tV;!$)u !@=ل "6PzQ t~~h:.&5* m.hh%uj5鸕4Z Rn.jZ+DOO=O0>|r0,zUԠ֗[H*V[#TAn54p CCCP*P ]j߻xG7?'A02 x>2*Avz23$O $ C`)!Ju?R]~ZᢎmD!(Ů ]3b;B֩.c>P'>AS 0! B{ϑ{ xCt:CקzE`a(ZVP[]BL1*Q hiSWh  VnTj LAoǣ?kmqͪZ}/ژz|Ms*9Bjk:Ǧ}iQN+Àᨁ G$"]eQ{h\|qay$aϻW62vGFI 0^1zHd =^:~U׆.'SVpťU54t1jZVb,`TW]*M֕bQׯޱp@'B"ӵj˲i%o8m9̋M}4lVHyrdsvjpLBYA8xVt6}a>oJ'Ɲ$OUه2MZiITXfx!9x`[06u@izGB(|$s F=ޟaduv룡U u0(TRiX։0*P%nU.R^q"=zHlKQ"~U=1xMݺUKZbZ#7wQ itТ441JT2MJ)uwWR=d~BO`s}i8mڇmo_ 9qSW{=^b|v`8ށuGLx}&e[ I Wj$ װhMwØLHzNg`>ov/@CB/ؒ3 ^a${pz~;P‰]]j+t6 @+jb6զjUtAs8h|EH#cDv9icr8O0O_,>; }+55r'9n4:y[(@0^!JtuIG!'$~BsyLI8(ElX,ِ@AHYB.Qi1XO%qE/2q7wt^.t gҕ4`UErNemj]-}jwsN˪hV-!G$*"[ɋ9# ;)ծtxVӪ$I{ eVPUV M.1Sk|b^Nq 'EqY9 >AuWD#`GDRu<4yX®=.IABYDؼvgBȕ](= HE H~$- q[v^("'HN4r\6]d{d Iٔ9pb=rwr>[o#qA֛F=Walwdm- $͇bvfubD][U@674!|I:QGkBPȏ" Y>Z[LʷM9,|brز-%# Orَ1B"R- >'O6@|WD̶.]N3Q/YTL(ae # *xC=.PY0qLkn"](OO:r:֭//ϑ26kPHĦ0 W[9eAQ)i^lTYshOmC$uv  4)Q} <Ք1'9yurB9ϹgGqiᢈFA)x2H:CrQ ֜>ҨU5!<'hbyܛN<0ZD X藻|B}C$BEQDšM;KHZHD\kaxk#E2?@7g~q8:C|0.~󤣏NG̖srH09}I0諁Hij~}pN >c"pdLdKM9= o22H$"0{>;uN8r{?')t7[* EnnB SUXh҂n…}>}T0$rfa ;/GPTĤqLS=\TX!IN#ၘ7'fЎAƎzK^O`A>D׎}d^1]RmuG6ԥ]GU =c!39[ }vɄCN`<HF#HG׽<w!ډiqj`@-p3A(`neEʼnMt5jQ-!珊x/=v/C,%^@HH({0mGF{7O 1 ~~@b"]‚hag-8" @'z{OO@*Ѣw[f%ߜf<~j =Z߈P+ˆz~ =sO_5"a#:rDz׌H4C^ @MSJBčR% T]L)Z1 'C_3 ȧ# EBZ{[}zkҼ<$IB.;DLM9= 4hpgQM%,B1-=X(]*+l}p*|xlwGN❎9V)$N : : TYGNyU44\ :`rDk@ ˜TڦL RCWJ4Jws0][ SYP=Ccn '"l>a~x'* ujh6*^aCSN/OgIU ,C*!zyDOi[L9A'hw,$SxKIr^ P10Ȧw0 Ip\NWΒ9\SB-P5psJ#JiSpiQ4֘( %1 U`):ώ`i'1䄂yM?AD.bw3d5}yϴǐ@*31Se:ϰ~ah0@  7$nP;Oiŕzvuꭙ:Z|nOKgHQt;\}ǠxvA21zdD{4+2ZگָΤ@qǚRJtZu4 !VRTҠ݁\A)Zm03}}y'dO49>qm9_M mGu}{lWBE7G=DžqvDNP_{ FH0:'N'8wnvnM.jnvlp+lTryϓ02ȹ$jl9:dq$^."bNI tSbu8e :T BC]VPq(:4jCUҪV BDRZqqŘ/Ι ~诔r)ȎG򅈜৾"Oc9 Be!:/J:]9_Μz*sq2=x:0Dy #`2αDkڡ(>@EX9w#~ @$# p/~<<sT>^aovra 'E،d=GxND5]JZqpT+(R&@j8#J!mBC]B)JB.Vtt@4O_#A,("+FƊ5A6-EIX֌kIlES#Q4b`+E FcdQl1* E&1EQƤ5EɁF!$j#h-)QAi(-3DIm$  MQQEQh!E+* -bd1hZ*5F-b6,IbŊ65+,-Pm4MhѣPTDbƲTb1m@bh%Bm1k "Xb665hţI&+RZ,+EcHF*KhѲA1%QcTJ6*,ZITb-5F5ETj"5%QE(X6*6KeUl6[ؐE6H6l&l6aV IکMTʩ6mCdHm#jFŰ-6-HU[[B[Q6Ѷرص6U FS`U+dH؛TMڪSh[U@J&ԛQ[%[%laFڋhllhm VƱJSeCiړ`[PmPl B6Hlm!lQmKiFЭ-ja6mM#e-im+ŋb*-m"[EmV6ڡMУhFFRP#`e+e%-C`[Sa m-mfbImVʶm6+jl$ڪmڤBPlFғbdm*m*l[Ѷ6bmmm( mU6i -JFҪlm%IUHډ+hSeUmTF#e&6MډbR6)mMF6Q6EmQVli%6*UlڢUSm6cmhQm[j$liM[ElbŭlVŵkc(6UM-l66ZaQmhضƭXcQlZūEbiSdET M-lh@l m R+jPA(mRT%[ %mEF-llSb6! -liډR*lM[6 mllmQm֨ &[JjRl*4[d*j֍jbLˍ zP @(4 HQQ()@@ۮTT m+Mk URRXEF%Uf( 5kjYE 4JKlD[*@lJ*J+mJM5UIm"QJ"PZPմUQ+Z@6SV56Ҩ (4 `fSQMճ.Kxog9*n}J|wov<UЕk (UCZѪ EMkI CUUdV)"Q FƨU*"Mj#LJ55)(-1J)EUFCZR)D SZkIAYIJ4"!V̖٦+,R2JJ &RA*ZҔPh-4h 5 c(5JScPlYL,֚64*+lRR[id-- aRTHy-QRV٭ZmjѮz泀\^{}]V;xr7w^^v(J)k[wmu*ڲ IVVWnq[=+^9=מx =׽[sWXo+"IEIIF}4ٕ$iMh]phz\y+ogW9w5w.,JRA#c$S5F̄ZkX-Zݸ;ܪ\ ۺV:Ҋ *zQRl։*RbM eW8z8t[vp ==ooxutWuUEUօQX{kH[jR(m]ZMWJpwIg.{{UW{ު=[kuOh Zk[ݷ^6,J*&sN{oxpZ E wj{sFBV<(k$wEvQ=/7!Ix UP"nvUV[J"l&U#Vfv띱w[͕^\(Ty۾fOw۽dUr+!w!P"TTP%  Sb%* @OTS T*S4:pL[ *Pyt4h)rᙊͣTY rk],)$n]ɍ#jlJ'GBJƴ뵹Riږ&\& HIqVB@88 p BBV%BH!H`BR&`RXVYFCPx!/8qeXIIaY%B aN*J ,#+ [R*P, U0,# J  ,+@2,"QVA XTqH%`HXb %XI@!RT`H IQ$eXBAY!d TaSत, J, )(JH!VFR%$! YYH^p $,,)Jq@pYXaI HBI`IXeI$XaZVe5%e6MJU*Veh$ 2$ L!+*jRnk21 -2B!0󮺫ڙjij6JJ+()x@V-3Z^kK*ƦmE꒴Z5kg]Z5ʣbڍbBULV^MZ(K a60Dt[% m.vkr7 ǻ=65wuQF6܌c=h-ʍ͹w%sW1em0hk1WwXXgj#g]ٮIҲ`ɷW2d1 wqF Uǯrh2!ͷv幮,m t)F˓I&1\.rh)^qT+b ^V鍈s]\'whzb n;zDy(uʻ#h场g)i^rEse#;˔k9K]vHnN]ssNYwWwc%׹Iwwsq;q͢.4L570@l"7.t]v3Sr.Lەۏ\ιz}H2n%ێ]rKvG;wn:IM뫻unvfrwfx#n8lrow*9vN뛻u9uuF8uoo1yz 5;ewtvñvݻ\u#swnnut9.Hu,tNޤ&{4h] ṵ0T`"$ ˫IXbPDF MRQLF#RQtml$b c!yp@Qc ưi5B HkYjPO6$KBXfVfXCF11lXIƒ*KccZM5%Kb6,lXɦ[I[KIQ6X4`X(HQcP6cE&J@)5Feh LF!KcX,cE$cQS,m IŻwY5$hMH[%)1hMQ3b%c@ʍEhA1TXس6XTUW*M-rEbH4Y(I&6cݬEh( bdwsDPY5fF٤FiQ̱m@Z E($6L6R5͈Ƥ5 km3Zf#QRTjClk&ŤCf50lQAbьXl!&5cM*X,RQE ѨRTcT!4X7Ei 墤B0%5* *`Qj*&F#dRXɍiLMJ#Qj-ŹnJ$زc&TI#Z-2 dƐj#lFZ*64͓bH]-PRQ6$i4V-%F؍AFɪDA"5 EFƒF+&Ic h(A3X։65cb,IkhEFXb4PY4DJ cPsrc%b&c )HJHũ5Rc)LF*#j2r,bdKQb6%Z5EbLLj"IDFb-#P,mRDHhQc4C+cb1Pd@*151XQR&ci6lPQ(\DEAFEERY0ɈPV1cb-ƣW+h#d0i-JIQQDdɨ"ll,d&T< ͒65TbfKF6fEDdQli,RTcFLF1FJiEvjS4fmFb#hQQE&%QccF*2Y6-d1Pke cFhQE%j"eAlwcR`KFFHэABh  2!FصXbň",A5Dt葴lF J I"(I6,hDF*hQ!chQ%BkƢ`ٖ %lV,T#h(M@BMIh1F#E$#j#cj5V#c"3hc$l@b-RS,Qc EhԑES1i60̚Ō%l`L Rm6VCBAЦBX"j@bƧE4H ZK-h5!Dh62Dhb $T$V62Y*J##5H"M6$53V65jb#FȉhDXL*( PRbĚ 5JRF1*+"b-%EX1a $بFF*dPm hԙ)5F+!5Ki cFKdclaэDb1I&rJ Z FbI(\Q-%3F,%nbB4h؍]4jfHZM@HE4P3-'7eQȔh4lFhE$"уihfDأE216 5DXщ4Y Z52hF6Acd!lbY Bd%L\rC&j66ikMeP"؍HcXQb"*f)4mلE5F1ccmF)5)((QF +Dlml!hJJ I#(#%AbhIֺEbHƋ1d4hɴIc cbFX"h!i" FνzI,&IX2h)QFhVbرd1cTZ4^nmdBѱZ**ʍʼnMI$QFTF Q+%BdZ4)6%i4Ȍl,Y(*I-Ib1F @c%E&6؈MMFmF FUkA,VI lZ1I$KLJ"bjS&Ƀ[+@Lhj(I4TZITi@cX@#Ql)M4AcFFZ1bV(Z2Z(EmblD ͰlQQlTP,j*dX46" XI(5 rF0R(lͣQ( *[Ѣ(آ#Th-جfdJɤl/yzHb (MRHz],%I2RE66(( ѓE#fV QTb1ƍcQA2m@c*H֍&,b 1ڍ&(у"che4DbM&Am4lPIXՐL[FDŊMAE)#RkBQD'I1bYM$LHb6 ٚ"*$4HkE1"m%IlIEj(ɴA6f EjE*bIZ(&,a4lm(&lFƍJ,uZ)*6A&4mb%TThhllb * kƋ`Y"P lIb0!`ՈhƄ1b *((**(Md(جdjHm$4PEIhcQZ($F(TؒĘ)*ɰ5AdQa"50+QF*$i6,j**i"LfIŌm+3lD 2lTIAQM0i$b hłC QE*iJ%mTU%-a6&6 Cb IbAIQb"Ťa3Q1f%E\ bțdRbōbkDL1&,(HHa5Z1"XE5bf,kAE5Z*$،FBXK2H@e4T ,T bMF !ěIc$T5""fm!R[!bhJ"X-4hP`- ^ʹ"( Qlcc&lj1QE@BX ъB % X$cEDi@#FĔbX4`ƍBQDL&`6F(Ѷ6LDE!Ac̴EF&d4QcdIlkEBIDEd؋FE*e3Y0Y#PfM(wmƣ@lfdFMF,&TIFPchva*,h "Q s代w5%89ïWw.v+w ݙu4ݸjY?UU@PQSM00JcK4͔6dd6*-IfT6TZ-,э Eci6+i6meQi4Xlm[ڨF5أZ6Fj+Z-F֋V[hkɊZZ5m&ŬZɶTjEV5ډZiUj"F)Z i@FJDiP((@TZDXbJT(JJTmkF-UUcVƵUID E@@E RZFJ5TUhF*̭leJQIAbUHAiFT(TT(ABhE)(V[IU*+e*mEbUS lmlT&m+mԖ5m#X+BUhFeVhQ(@ E UB)EbDhP(PZPF U BE(UV EiJB$iP)@ PJ @JA)(hRhPF " ZTRJDiRT))QT)fPBh%P P@)JJZiHZ6ՋTjj5R֍XjRkm(5%3QV(dh5MFXڂJԕ@P"D"ZP"ReiR! FbhTVBhR T&Tb"F!#lѶ5cUE(QIEBYai&Bhkdٚ+F$BBJD@ZE DZQHi(QfZJRiH"PYiB$BBF  mPTi56mhִRZ"j6VB))bfUi5VQFŒFQkh֙T(BF$iRQQ+mTX6-hmTm-0,LRKFHbɢJbV(bM%Uj0UdƤm[b&cQTZIkh2XlXT[Z5ɢQHXQf*#E̶Kdɢɳ-ZH-mi43UfaMI34f,ff ɵĦ+,2[4Ԗ&i&Flf[BQJ#S6--,l%%EAJ(bRmV45Ɠ[S D kEhhMm$lҙK L))LEDD)%Fբe&lXamYeIF 4j2If))%`Rcki)IHMڡM%4Q(e L5&MFfѭ+&-jJmIL6e%lR֦L#BX̲SLiULЉaICdɌM6K4̦SUDԉ)JiM$km6HѬm$&mm1Jb̪54m4JMREj-ؒf1L!VD، dسVlIFfMVhJE,hJk)[M2%I[K2f%TVMTd&ZJţS-U-)TV5ck1@JYh`@JԚl4-hXZhɱdSLiFK$lhYmF*2k62V4bѓ-FLi4PTZ*(J%+X)jMlk%jmEXIV3Xeb4hi5&&mK %؈%"5ZlQ%4[l&ԘҪ6ѵcIJQ&F6-֛ Z,̆BL%%6QbhͶ[m-Z%FZ)RE4YjBcdب(MciUk-E)MJ,QPki4Z5ZPDTQ6ѵii+EFm5Qd ڕEFd֛[5IF٭Q%M[ bֆTD15YjJVYA)JYEZR&KQhֲ#[6-VTFKbҭZ,ڡV[iE-)Z  EHZAhI P%JVZP P$R!a)HB BTeiPhR VIQDBD %E P%BDd HXDaQB@a@!RAXDI@AUPUB%BFE!UA%DHVQ%T%D%PT%BE!@a@eHeBB$%@ BPjA XPVT@e$ aIA`BERiBF@FaX TRA TeI@&d@AVHY`IA$YdXA$U` @dD!I!ADFAP !BVdBV@RIFAYdIQ BRYQdeDA* QYRDeD HU VRUZ$EHB I$BVA IT!HdIXDR  F e%D%VAHEIY!aD*daP!!IU! TVTXQRPaXBDYYT$D $ A$XRdYD%D$IRA VDDdQ& D$%j՛6-*e0! @@C  B@0$22 BД-+H 25MiiJI Eh-&fBi5ʢ٥hZKIi+!&LʣREص3mEZ-j5cjh-V5RUXڪ+m5bKj*6jUcUjFVB )D)R[U-5QcjhڨQTjQhֱ֣TUFFբd֢ƪEFhRT D)AkmF-PT5I-IARA芀}=/qr7AMy$0)k/\ʦBIy^Œ&X4UNNo~@/;t:w. =(Cvr%ǝKrޡ q1ps9|t^32C io'pPg=DaL%wMf+gPNRxvݖ%c.0: {i'vG2m5-,kkW9MܐWYLWX7Ow>nky3&_#'t> 4|QC`n#m8Cq pjnk&;j4":7f 0( ׃~mh= W&MxނedmAmN(cpuqnȦ% 8A2?cg) vL$vc?a娒xԆfɻTי8)0NI1\8J?s#i䞆/BA4,t1 %԰Ghc{.&,Fbbb>:Y@F WU2]ay'w)ңuUdRv4JTHFO$.|FELF!AG CX0, )L& kR\t1:G1 =ES`/a50J[c>iJL MG=qbjA;Zi j@ܒ#UTKVqcϖ1<"XFaBpd0>=h,iD=sHN }p.$H0)*3ZrDR2*;pHe?Mc͑hxeaI*K$!܅Ծ-wVaȧ+ x;$Br^-w깜bx!تAafn8 Ǫʺ'"ŭMl=xXcRgJ ;iмv%Mߘ!4Pe12L&y|؆f|f ,R,Es8dULҟ6q0g"DՌŜ@<̄7" ہ4܄nÝV 1v-gg浅At$}3[X{>p+u4" "HR<1X[Cn~ѿo}:/gjq۲\BJE }?[t#Yq˘$ZAzV) ipqX\aTmwꕿ|ll;}-GC!?tj0;/RI$h8]9-E7dRv ^R`8 .\s@jNmꚚ&A)* D2@M P4]8`&eU8`"@RP8 `a10 *00t4 uI-SD4uu5 p?*̮s| KѻmUD8 ;3 䊌9gY(ov,<γaF RF7r+&oS+/lu]V9oxy6)[;mV£vg<Gyd[=}9Pz-ξMbb$PgGxR7srKlH3瘏ԯ}Xn3stvRs :k[!r< YwkCY"jJkepXݲ JlӲL6ݻ>-#ƾ>@w]ע@S+e=qt/P 3U-6p,qqX[v۸]Ϳ>7U3sz#{u,W=Λ+!sehCFe3wgq˲mYnNkףcfw`yJ:$J'md̲gR&W{dd싦fBEY,UқO1#3Jή-+ySP4гn{zU]&RGZ*n)jɣ6n6-s ,L) A7r({r? ՇIJMoNܨDB_*s08 ï fқ.dv6Q/#0Mq ;;ӫ)DM[chxpcNǕ[&JNjapI|b\ 4Qo9s_%2I]r,cu;]"ugwo`SɰWkRPwpV{'t ,cAo+DKoluV6*-jGQoE-noL愛%[u@!ɓEo zuc{Ϸ'~ܝC͊>ѝR8MQZ Yva8l/DV#B{.Br*>ўFi»ЮgGzm {l&`gw1AC}VQSevY n+ZYX۷-5h&muU{f59N`) Vw A]z/I6{.,;[^vq cBR(Z;w-KЦz۔Ъ9 cD)Z{5h8LifI:9]QQSkfQ׻*[дT銏bKwv/+Pu"xOQX>Wl8V.mM]waxP{spAV_Gw돸=D* =2sU UQn=WM+KKW1O80 }@/d殭m"}owId=~=tH}K]img ژ:+>'J]ͬWD&r/>1?y7syK=͸Ǜ3JM΅J!bWլn.N"[+t#m`Y8&'{ȍU3.lZW IBٍA4o*y]`,م*f#Ou;OtYۣi-; {gB@Xf.rU` L5: TEkp>F>ƻeʉ5`8uO]wylNRt;:N0kziS.)+َ\CCˤ/hKВ$mtt-Es=s+03{YPGet6U-RTSW2[ai[2'䵽]m_UQ4Fgˉ+=GWЙ}74/+ձ MSA8J}sӝb~ k#+*ōO,2rҨ}h%V]8FVvH3&JidT/.Fd oS2W\k|9qN-& Fvfw㚿n-Nc= oNȌyGljKzmUЁ ‘I4Uw,1hpm鑢,TrT:۷;4vr:L!Q?<#=, ,,6Y"όw' 5:P{'i;L>*ZiE=cofEPLr.nK#V+dtnコ5KwG*+SSTeЭYhfpf]/E 9SJRɲC^e&m5qg4U/ K&ZI[P8p zU.&SXܺvgvwHd4iEw'qW>ɜ\'>o;(79U! $Z5b-.(DXj$8%A$wvSmP&oPr.AO3汊b^ܹ,}V/599M&ej AݓC^W-=f)pOAؖ[Ӈ.lNYnI,[uMJDxLf'J7LQM;4Sɵ66μ7Wf"RpQBV@IbDV]eо+5ڷJ-߼.ܝWh˙]7 6lpeǏᕷyT/Pyv)68خymuv6#2힠E\tA'c/{A{",bԆ>{[^i;ǴqⒾs`2qlݲVx{3jz{B)B).NxuN¼[1]+P˷j\| &l΃-zgcSifwM MRhB^ff kUNX%0Jwf8n>o2L]Izya.XQNr^w׼ߟ|X'^vLvlҝ9i|󎭑L:ڹWcBNd켛id,u Eo"eRB͙o=IW*DLdGy@{yt8 svFYwdY՗5*0v*1f4v Tɹ'>r]y`Gg F`-Z5Cx$mߚѻ.ڥD`UE="WvN!,ΘΞh7l'HkuKƲVXď+ u]0OV|ef۽/-%xpI{syMJd;;5W<̭ E1Z#is.Ujw[g\) %K=z/۲?ܝUq1ز-SG) wb5˦bFEpV.v4Q<KEdiju}',-5DedJqLؓܓB6rV-InuEKuf1cC'\䫆FyaC޸wDR΍28&}ᜡx̓aS.|V2lTxO6e.Eݯ hu֮ؗ_\ךp us JnP*e,JD<<Ը=q߫8Ȳ_@{:;Sw]WJ˺W Sʗ`2: VytiRYWiJ}}A7f?`3V{j.tngb-rZ/Q;-2,cْ ӧQgs.u5zo4=8ܨ=f6W'^f]{ޓ/X+ەge(szc"=&м8UO8(C:r\/r ]eyE^Jhg8zU%j ʼVqd#7Uj llTx]F07W"{un8 "QoZ7u_="JW* f[}}Z+Z v|yuįNF_>걢zDeqiYsUgXX ldwyBsv5I{U^[|U$NYjdKvM)st5TwbsxFAcPFrJУ1wg,T:[p^=Fyx mCa-VepIV11Zr;\GE[`שr]==wt rq-AYNuF^k}x ׯ(ZkQI!XNJm& IjՋ9 b۲vJm Ml:}*/pC߼5CH^e+n˛-s.XX]V1 "]<2&.qWS8aN^ }#up&-돖rZWމ N+W֓0isَ4RD=p;77ghj})PƼotOAXpzpw/n@M]Xulvtag(~̇Aޭk2ͺ/1U(FjRgl+r^4HX)Lۛ(<%Tj#mƚS8UK5fsqly^Wa7w U, ij4"bҼa.=pl;]1LԳ3^ި!vN(pU; I 5;{yi2e;iXk9:ꮱrh5e݌Ӛ S6f;nr!d>͖NR&gP"Y{[L5G&yJ_فq{LuiEdm,iӱ䱣D9^ޞ 3^F*OX+k"WɧGfA]n4.]I̲v]eӕ:3-7/q88/gBB{v] PexSs&\a{oqg_ `|ەճxU_ N{5]3Q7gR7~\.ɽȂ:G%69pk6IW g'+s.[%-M/r@?rpUYq{W\Ы)/vsvAsh >q95皙#zʒy0R?M3eX;*:逞1oV|2#6tAbv}@.msŕfS[C`tSxV<~㓼 i .GoOO\GRxÁSrSVꙶ-a g+Zt32\xXJt[Npų{ɽF4nkDbܹa*fERfQqvn #J9{T5X5D#j5Gz.yyќ%{{̋!wZkݳо91q%(bJ1fvףO9Hxyz[Vuqtwr{)ǔ٫yJS^s=Sx-Mwn3;_=q2 B&WkGvn>;,}tӷ[75N} QbIf UEqr"Tչ6׎)U-OHSkD9ioMXێp͍xk2jմp }z\-ؤJ<>w Ai;RN.=A,뛇/zʸkEÆ=swrBEyyyVɇYigՏIt,*y{}^A[/s:#D._`];Bv{RXsN,m- !Y|j= [Uyt WzZ TV Cls"DV0.;aӾӷ6-h݃5=E:tJ yﴼy`񇚹#6nC]Gn oEWqW`O&h ǽkTr쬥\0qJBf ʛ4ޣAC},Qcrkᴴͤ<=s{oGmwO;=^W}0:go>O7|cghn| #zP}_PYY5nh`Du$Z-Cy~ }rq{+{nv>Wa֦03;v'a҇J:\]zzQW}ܽ'Q2:tBUrtƫ᠚XR>j[ lO{6f.fے-.4Hwh2syt2x%{L(wx/g^$pt]qGyaMKcA鮑]>̝Fah U7]Qց"UE0G[鰫wixsWV{ 4*^J9Hes;ee*wnHQVVR9\g»^3h5nTkG=F3f8ٻqNRoW[uʶV]d6I8Qi a&KɇME C͏|sgo[bg)8Z[=՟ ws 7ļU޻ý R<Qzr.ָN,MjcnR$ɛ^!,vq [pfk I}m]ZE[o}\|,Oj)x,ƲF[A-Gy/Q6MbPXs[|佉/eU.M*γU~tsJ>{NI擀ܵ໗{h$:L{Z T ڙe M(h/M oIbza栕XP9AΆu_S7r{bHm1w|xUӺ^y*喝.cJKU]Ky!>WQt%Wr  l(lehu9W VmøQ:R9e,ܭ˾qs dlyP1˾|MTbWz &J^)&޹k\{ |{|J,b=Œm]Wסά6+^ИfuY}ܼµg6{Iɏ}Tqpb釩,0M˗kӝUqs뭴--{IeB\ePvw&egO[ sXEk}YS蓬L2:i]$)$KGi35q}[juSmᩆo*& _wsP(&_[1M+9I]vLGf])JUts%-Аׇ`!Cg9V*('R:9RseJڝh+{0T_z Ukwaveٳ%&FNVz:iGLH>u.ui XU>`icuvty\N1;h_\=@d7gw&LS_q2XЙk:\ÊaYJwfi7x8z(}+dvf7hDj} Fz~_oc=oSB{kLE{ 2 '/Oj33=yF . /I:6]rK6_Yԇ0Sq8qYC|JlO`&ꤡ1i ~̑A} yҞC)*VG0F =;] iOϲ> })X*5ǦMXOf/H+QNN7E1&qDkWS}4A#`lԙSona;̓U'=mۺ]5 %`}d֛<ߜhCǹY?D>gnD{WY6%)*U$^Ph {]NIoڂ %`a|{w(Nr>& y$7oVc>$і[yEv>T1]+iFB{|LYEIO {[~cjjoN0!S.yNnӮ6 ^pZzaZv |^EPBrn{NŸ!RPÇ0GO^ l@q"W`٧ڧIMv [ON"ۡ3Ii4o\en&4|>:"+h` *`0[+L5"A\֡h|JuJ7͋Cvv(%e6µϑy<T!bH/Iy<&.jMxU@.,_:]zt*J8Y|, ;NSva ~S$Pjo\3-~ W` $vTYڪn>,caA F11&w&a]/YX?|} =N 稜N{{iJ9 v6T1\lϗ. 7W'{,Qݗ8My-f@,Ϻ') y!r'$"UJ P%ں)r_>JWWx|EO\ e p/9E!}/ C~C cbZ`MPq Drm 3q )6妸0Z&;CAM S47j;AE a0J0"~>s9Zj/?Cі;ʸԿ]]wKL qۜ>{A `F Wo~!OM8^ޑv (NO{݋L0bϮ_s -?tt13?uyaZB@U|봣vYPG_HC%=>#DJC<@܃`) tͥ L-m,010\0100 i44q0-š)1 p`R,1[]7tt U@pd6RI^۠n7s"XL$;K7=Ygf(wۻޘrzN|;5"}bMyM d)K>+p!;b#OgW cDA.%P(I ߟ\)}dRzKܕF^dJ83$BzqpkîrzH]4$0 s0]w]#]\l \1- F6Zn8p&&3Ya#PŢ-0 &Nn|-|_CDCZG (>/9a])vAP02S%OoӪfh_!gxX^'?y:n@xt?0,6 6-A'kE7vnշ ͓X7Y/0bǽuR |"M.tR@Cآ88U $kOeKQrB|LїD?G};+r~zw"'BUP OѴ.faL\\-hn`D&黺JCG4,0x4 u4 u7S\x-6ZX.bh&x́T v  Cp:;?ho^? 7|B&O!/pBYu}@lvwp "XO$Q?L< SxSf%6s/݊:Z?$B|҂>s=|z3xh?b2(z4|\ϞI!IRQ(_x }ߏ*qLc68TLCp5u3 C]]D4uwh4 S] 4t CSpSA0NnsaR}V2_ =9N_ۗ׵;\>2rl3ۅUޣǼ, D JAO4>;5AGf ⲉ*qmJ!RlM36k4ٰ~[Kl^Ϟ3"(;=v|>`oNOqѷ7V?u^rpj=%QT9*@ ڪ>1iceCT֗G@wt 5 MwMWGW@SuMMG]-LCxInji`I``eJbST`9:>|z:fsGRK@2r,çm:9!a=$%r3sW^u./@Paי1߭Ã_u4$Z\td5OOSZa}TȞqhΦW*[z:1iHd =B7^zT/Yr=B$dt$C ]'G!FURTd8CD555MtCAu4p1C*& n.QTh.&.c鉪@jݗLp ٢A4M 9FJPMJP:WծYuĵHMM=Ӕx櫻wcʄQׯ*z;ml#_G-t۫=^aABisEFߜVIZ7(w|rSFdx&0b =cwUʐVNx9dO\jc")}D{WCg} *x>FGrT'I!<ǖȄ1, m- L Ř[UIeU8’ѹ*-[f.Fi鸎88&bwN`"UI8daӒwi6xTgd޾f]4v,QR>7tdjU@_o\utI ,?m(ڃ#2%J>lfSN?$1N5&0@._ `.`ĦQ*H ծT@NHA;w2vs,ᘦ1BF|`&cb..!h8ቚo!s13-SACMMCP4GP3 L5 GA4Mt78+sYyoγV8.+^u1Rw_dVS*Y]˃wMz(NPH^~+,?:%CI9<"鵎3syWMx!RNΓ"zW՚kҰfA[Ga1(]Ҝ:lxΥyӫM^EtL~ޜ Ҝr{+mYܼ1EVåaqz-J5(wDJ4M3{t"j6Z0{|͵ iunA9;~"NQS-͎]!%= AY xHaH=5MGޅW8px Qt(xt=`dsz{66ƹ@1OW'}ZpS閅KI8Ǔv-Y+۲̃Xձ!azQͻ榿cCb`b歬ݓ{2y{=y^"U+ ;8~z BjG&Rg;\ouI M^}Ul"cVj^y/vk3w}7Әi L&|j^}+;ڍ 7M ŤgxmڔGtry|ޮy׮3t~ZDuW\-Z҉DŽYk0ǥs1bK${g4ߊ;&Ы4w,;}ֻg=WW#\ٻod^FžVA)7;&oZrTo]9ZN)e,V;&©%ܥpo_dh9n5lym{{-2@z#w[ y 303!ƅ SyGe m/{~}+EjiyȶMy=f_G.Lp[,%vکy|s[f80?sEc5qaRy=<ysZ](߶t!mڭeW-ciܗ)Z(,9lN3žZ6k'J8qδ(MT`Su̻7RZ~yi}#flY3?& ]#oٞC(,Cf!)rM܉jn!iCke͑-JÛ#>OMuʉǰ#^'3R)6eFKEY2k!&%nKVil:Ѥ'_Wr%BTIz7_! [/xtߜ)OSkgnU`#iue#䯷ǚJ[s=A&+gWrxS:KΆ]4̓huiH<3@nrZV*#/eb'P7>S*W{tYyBG'87ȧ*4X-kfbZN̤Ucv/=ئ90-r ޝ{;q%^hbTZ_wgOߟG"`}];jvnF"8'=8?M{M@DꥃDR(WhWbڽZ9"&]gڸ3-؎ir90Og IPa`i~:;ڡ2֯z"2y9*7c+roFii a!%ԬW9٪6=B⠝C*UݶE*y3zQvnڳ yf4F/ywLc}C\Η={yMo]ŝl) :f)&ת)Z`)\N[1[^5Y.=LWN`̙֮r' UKl.(INR3vE6bV赂 uNw Lj^9ywk0kbH%Ipf)7uEGN[G.zf@ftnv7{KzPB33h%7+YTthybgSy΄#1Ե\_Wu(La~bHQavvƞ-묩N;(+}WHAjY). Bհ' yؖpң^#g|؎v+%Ӹ:vMWٴpqGE\&M^miQO<7VN#0+g'))[ˈPe}W{Bv%#}F[F}XGsC]=vKYYOm:0`RayE|nص}*ވtHMĊNڸt$k! ɭoNp;hѺv=ҀX1 $fWHT.#wUԴ4e{\58JΝ[I.wKFuݦ񷹭tFy9f9QbNLUbL={{ .л=y\ruwAd9iU,B1q{~JS %vsnrZr0m't#d?#VFe{Wjtݟ*?G{dcuq\sl8NhN4W"dUqrߕ^Y1¾ )N'Yq,FE=yvcЏJv7̩bo^tOK:srqdbQUicjxefrD#x-ܼnU;z)!=_Įo 9zG:>O".޸*|)/Kyӳf&mitm a,}}9zHOŕ;g]γ#` dӋWhzϛYo+Q'gs⢦^鷢뀇+byz7+Ș Y޺ ҫanQ.^Tz;UZz8{Ҿ}ap#@hȼ-! Yhiu;1 Q\dGr5Zf> TYw$^5j8FI7QԾ i,6>Jkwu@̗ZJ{Qc5Wf"x^h]#)=CYdQ^iv/z=ZkٺT"ܽk>'ys9oU3h3{x3wSn w:gSuj]gwO^0N[7f1?&=6%ltg5vg0c/bʺb0mBcާH n3h3TQoR 3o/;+{;/M#|ݧh6}/.frnY͜6[Ro(e'q5ӳOe4Ն!ƅ+704hK4Qs.=vEq((x) nr!Ŋ~XX*|Vu/.vFeг~ ,vjk켨;Dn&V y5mP{"#u{U`V\l3Zoc$>,у]^P6ʃ/q4 B]ӝ1t!,GweW)fX2=ʽv qr\qTstޞA/҄S^=W;yG_+W{:jy >'|45,Q[ry8J%MgVlF鹙eʩ8PmѺ%':XAlZ3#^.]6oWW4Vzṫy?xz㹙C?(s$A?e=wNc_bw)#s9²Qf dY%*3tKܽN,^vMitˡ SGcbCk'YP%i0X{ Xu}#낍Y?^rOZ{-MqNktT=h]K,cR?e@IԒ w KVanlήJW }@(1J[Q7Niy\mܙ {%]Yk]p%=˃_5a8[gnlo.(uI7g([$_%Yu-oyu5]ViWb}kF^&iLo>_F=S}]`妶;F_Q9ڏȓ͒5V,6ok%PYPg] a^k^:+Z#+NUuPP)rf{/6Ճ`㞺J$Fv"Qf:> 6ptj}Útw2sK4fxnF ܺmͅt /z&ĝe)wۛOg.Z;GBK~)BգbMݭzs ѨYuN6mols\rǩ<ةNe뵧^},3QH2g`AdwTOD('sJKvGY~?\Є,9jS]w5%^us{ܨ{CO܁C9!z)K&[܊ Ja8ufi}J_uÏ:OS_UcBt'Cuenno8+1=3&_y1oΙ=ȠjvV4N4)3{)>SH|q˹UHձ_~xsWq7ugc |VV\{D6*R+BUn۪T')6 \PRjVіgw!zx+^=Yg(qm&((o+t,O.5LN,'_W&;w4{dY-soYbkbvvs38p%K1Qu ,㱍I,jb)7vgBMNG,¸PYU6*˴k;M^anC®=][)"rء4K)^ >ѦZG:"@Z<K~$zvgJA-q] xH{uX;I6"WŃez"޶u;Zwa:i=UfѾvU'L}5E(dޱwSw\Dc9٩{Jӏ7DIekͩs$qګ}:^ lU8Z;r&gHgQ ~H#t%]UZp8Mz{ 2R9:*YsW!(اt2=zvFô'DPn\YQs!uVM%ζo |.obngKKHJ*f%\pZffRn$0`wm2) K<.Hۭ[f!+Y0[@8Gu-԰qi{F4S8f价hxݸV7eFׁk76X =19ȴdqǃ._iYͫӛ:'ͧ׸fnjW 0ɅnSbb– 4Ur/ Y._iHh}aE6,̓ mMV-b#7S`o |k$'6mj,2o r[Z-U)<ݞ盅;hTݒvޘ3Fhetݹwn[\۫IW oI$0{'G}ٲes[qW5?Uصc3Z3uFeh`W&(+ݶotWB yZo.=<ۅɐUҶ;:J 2ȫ/5h8?Ws2#xxI9.Xndž4r?XU{S6H{B.nޮTlc`AT_{wcBgAo۽S¥eG,Gz؞j#U z19.=dgVȭ̿PdBJTVfױn*uBu tPL]nBy7|%jNK[ b6xArW;4ti݅>x^γgT!ig54n=s.bĞ\LgWv}6m.)5]0rSZ[8V+"L F{bSDkrm,nJ؟Q'U:.w|tDZs7!;>'w8^"<$M8zdžv!}Q;_h!Ʋ&V>eݩ wܻ/5Ud>=(]J.×m7[ԖᖃKJQYbdwJ ;PsHinShW9p圧_N53(zu_-c;s=󹾉L8Hl:LurA8ձJwgMWŲKDždl*Ne+2Ǻv uCFwE~cEf.`;.k*4~ بihp\4\ivx(/dC̎V{̈7Г| ə.y^$:̊i6j)>j6΅iMY0a k<._8ʽz 54s4+<=mPrt4oTvPmezXreqyZs\𛞾Ա6W`k.&{ÄSbZDz Iݓy-]:Y"jb]w> o)gaѲq[QT0}z֋Z/΃C׼dG1x^Q6`SkomSq ]K6OkX=N5+۪DK8S]DIշųl>^utPnws1gĸWu}_ w˲߽7bwj%G3ޓqRL9ˆfrS(]LnlPSF@غNN4 oy_svL(_YgBK5)|ɘG)[bPp5 .qx櫏{:]BDq~|L2GGL|4&vWۘ= ycoR-YzV*7$|RÓ[UovCoS|w\(?qߏ[/ cKdysnpN9ZyOUڵjr3|8]E=/pח1/Իϋl_cfr} koUWiPˋ).-]xcP57(ã]G!=sɌpj}v-"Lufr85jԙ}]6 ݞimeffz쫬4vw\ך <>)u/>.O^ĕJe\rmIݶx6n#Zзv}0:d)Nκ_}{fSɿ]٥GGop6MNo^xkey`gsUt2R- 'ً usDT'y9o79Sfʽӈ2^md#p?xN]{{RgI.Cӂ2mek^"veH*L۹OvIխ<{ 5e[!޷,;}u1.y'Lyn.牽٣=ݾצfw=ԝS9mü3-\uu,J55HJ0.t jV<OV\sS% 뺐J_MU ngˊi葆C"x}\ŵ.c/YJr]pV`֮Q냮jb-+]Kf}c =U7CxzbKmŚ;EZPě#Ҫ-rON199 MSVR+̓^lw㼆;w;r2JFG^cxj&tX륑nSsZs;nuΐ[VsU3Hx0Fyq(^]~F{WE#6{v=S5-ht iFF Yto4`s>Z^yaDž̽8NJwR<)H9˵Y|.:)XmDܮ`ͽJ:q Rˈʛwx\=Q0`o2mU:d?~6@em1yϨ|\̷;)cA{2rGGno W˜\]7Tz" q89@՚j\zo354%=U 9ɹCoLe,V7>o&== B=y014ʝėF_D\"vVB4I[w*F+X#=fFk&]Swzsg4YYѹuj7_ؕ2L-ve.r3)w5*+D(lj;4d4rtEGwpcM3c)X:7vxMe$9Ačvk/Ujukݗ{Vv\ʕnZ巋ݘ <68M(kEx ywQs="JF67z,ծA3!JA'T"w{m[GӭCfoXYt8\W {B^PUx5݋`>Nr>aow'ݧs8'Y-RWNpbjvN5i'HhͱWջWQ n3>~+9?Ws_n99R;'g{͎+`[ĘsY}=.C=n'"*U]Vij WH㷈ޓg tíɣ,TWm1ao0'].Ry2,d$O͖&]-]f)6ʬ1Zˮ4HRƒ\bkurGmL ސv9SG;)|Ħ%-o+zgTI- x:o<|mUcMKbƫWU`[Ib=4-};6fEf{>?Yԟk nLjGӟ^xgfuDX'(uvv)FR.g1w֌rMxeYfnpwkV뾂ebI-S.,GDMS;Ѷ %xJKpJ!k57bq2͎RNaНlga+s_%7ò)E{LoV=!6&Z«rZ{Qj-aehx̕=Ω %`Ʈ3qLd}u6+7hYd7!]Dx!o] Tsr.9P}6s7JPfu+uH79&^w˻:p/kce.ҠG#EaGi[;{!){lx_y Ȝ7GRH—S{|glk9jb+8x&Μ+%,uA`wASt3UoVN,m٥KxZ_^CE2_2Oo=w2=hL׸50ξ{Wx^o o`؁z(nAl+w[ǵ*aa*G{̇o+칙WKXa޾-|/shU>V=TV .E7h=KoWsp&+f/{t1ҬWIvY9#ꡛޣ1Z.e"DHRJTYa8^ڶQp͵6_tcO'0.٧_u×8{<[Fθg_U2e*f?Z0NB/ +:g)˓]0CF'ƷXO9p][]f՝6ڛNV=xVmK~TWWWnzR|uݷ.,qU  7qO5Tyq26 6;7zQ;47QlkNN]CPYIW}o#JJCr=-G->MsО:sw3`s}IWΩI`pr" WNUr*$KQG8ݨcË 8|q \֫A4(!\5lA s/aʼ*rBfʒ4jƒӘ7rar Z7y"4K}\ Sw |iat[b؃]TK%ڮ+1eM"39,B{[m,r Ѝ.j:ED2r$"%:76Ъro: V1 VGw[x5sziyK.yLKJ*-$gYUbm"[U,ޚ"Sgz{רGGhdn]skY9Ũ9wIc[kn7f sk jq "1GnώoRᷨ?Hи3,Tf/2`&nkE>zF)"- |svX@'61sBgl\>ޒծ[|rWrW+ږlL)m%U;%w$o+MQ,agt2g7 Yb[&TwK=Mtw4mo8׋k5ei]s1wbڢ"<,"W>}K3:zlITlG٩2lsgm&x~B{Dse}U[Simi#n2Irx%vY9\/f؃ޓ-Tn]ԩR owfSyekZZYn7;ԶvY=if`ahh{ >n}\n/A:+ r9k;$1z6MIU{DvK*}sneTox(IH0wV7#9Z.1|▛FFfP&)EnZ3.#(OooxJ*ّy2nm3㠜cS0* 5^¢~cw|!.CM`kv:uďL]/ݶ4+w]4էeUrʧcXúʦH7]ġyipjύ8^tq^ytfEt}nb u>Y2, };u_*.CR:-̹y\ ,6;FPHܾͭG;!f *RmpogsպsvqkB!Ϝgfl_dd`xR̜O-g0z cdRtw+!KSq/ZHwFrڵM4<KIl]ك:/_ZR=}jVTTB$'>{=ƹ/N^#"Tl-!oK{~S'0$̜WEdA]NWQQ>F5i"L@˺Ɋ[!3IvꘄYOu}cGB6YUJ Cx, 'm(, z6.zU١쑞6̜8]SX}9iwe.vPV!sj$ 9v'd=3Osyў- Evۛ#fE:q^[RMhgJq-7GAx$R@OcK;D 5Huy1Å\C.r܌k#iN pjJ ]R)ԽL(meJNGГj gu2ft$E8לަ%7Scχ:k]Cy"ۗ ݹx7NRf.OAg6>.Zc1-^m)ްba϶رaKƺ/9h8/No\׬l] q[Z::h!T:=`=YA6kk圖_)x0E#L W.ǎ˳P]K..*{˗1de3)({{&k^ʍuv]WX܎v;D99||Os/Q#62wMɷmWUdg]y3!|A^h/Nh) v꫖GzML>i|F`꽥깣|"C2i,VnYD8?/=K;-7ʴ'[r5݃_D"2ddH_aMyN˼\Q^DX&.ɖ/[tU.4p{u:wTkK~)xR«{v͚Ώz°і۔^gQab׮|oշG+\%YkXE,+Q- ew?f-hvF;۞8֞"կpn'äK)L {yxQ:;n5HU Xfy[yu1nʍ3anU .i+r g1Y6k6]߯[o/{"feNRe :Iݱy9I佞-Co\Oo^u1<T7{&7vc93]HC)`wvt+[\].*;.ۚV#vR`sS֨akuwt +%gj~ Ub?NΦE^͔wo^O)%*v~{O ٿb[O:SYMt-"BkJL<^\~tͳf{("{t\f b>3e\\[+q,fD;EeyMr p]Scfc,I0^D_zܵ.+Cӏ1pwqUfQ 2cp6 ܁F[vsq#v6SzY׻³u,x:t5% p0cٽ=1 C4ju֎چޙN/J^T}im|ޭk2ۓuʲQv!o PͲ= m|X^D=z_}+Z\a/:g7Vqgs9߰3_\e7;5r7S4aZz;61nfK5x1{2zfadwkk{MԖs·=d]V`,ꏃ^wh^.m ۝ZoWYZ >Mɓ妚[k{&aY.P>H1(O]ԣpE:>'XZRֻxqXRy[)+7c*7amUx;R^b@1tn}8(LI_?^麳֥B-jCUjU!3rn 35y[fN p:޻pl@eK\+PaPns6퓙vhK5@`5޻!` 1du\,=(AfB$h;#jN~wۯ9ِ̩wne0Ħnb7C:EŽ|G?N/ҫZFOռ;PvYʨ`|Ku,rh|鬍[X]YLE.=&NOQU)鋚v I,v{.v ՂԏN4#1GRo:b;)Ro<NluAu ^dV3&p X;o핚rIڵ;IIb 8. \bpI]{1΄ v19E]AbGiZՈiWd}tM>rjdinNkpgy꽤8ݎfbX _**((c T FgrDZvbk7+WESgI{{fusbm\*SRZO8Dcrq\moP]-O^˞Cla =\sVGcb?3t;LW+wMV4Mwj5$ƾїٴj?zpr{zUdstnAqW~ή05It{Yll230Mz=qp@nU{l^W[J2/z4s ^<o8Br.* ђ糃p]2_+9,d]އ}%K„rçUnw &)3}J|:m׬l.E1MR-v S]+vhMv$4Ơyqȡ{E>s .Aܛ ӰWWjwbʬ#py~C:erM8wºپWw!UY6\2ET`쌕otdUaC@x1E띂^)\c7jR#ڣݪ< MW.˼ȶSfG]0nkθW{ssu0Э̩~J(=cMUoUnd35Ef" zg_!ԹW;h"q}zi̧,7 xh˧Zm$\*\dIgwrT&[Cc /vB1{r_8x]иyPD.3 19Jnv]bP싁g~Br`Wb:>H^us9Xͩj4@Qu/۱po[:;~ Ϟe* 4_4l0zނnø{i"w6eڣ𾣼ߌK8I{.w[fU +JIp}vi3 @wÕ`fIْ8^nIrB=5{h_VՕYf{;`0 5E^n DX<бmx)y'8סV3q\bg谚sö]u# H`q /y'}=vqw9o=o_` f^>yuLy[ MߑyNBИ^DA(NO-6yӁ Mѳy5eo a쩛+XރBd{z37 PȦbt|T#5ٝ7sKז` `,=47,EbG=>evҩ=伭ha[۱]ַO/ysvһaM gXtu0XeUoNMYpI^ }2X0MWǞ)|.3-ь#WZv̸2$QiNWڒ|0bC[* .I.bEG{k)d|:UhVvvsmLpe3Osg (ܳFsNZ M{k,)f\Vl{2QPҰK }l+H}$jE灡8EFMLYg7.\y1̑_ p{![y=so1ܟz+{o0<駩l!E^ty73V*n{%FL[~߷չyF W sg~dxDr-)O_!'wsޟA'F،t:#yDwUNb9e>7MB};ƪls N)}lSS ekS?i/!Ɩ `Nmd-?3+Hdq2M":ډhՏtc܇дǘ .zգk:ʆwǝb`U܆t.OUg Ȝ:t`ubf#7b95ڮ 4awu?]xhҟ2PqO!Cvr}%(63 4*.l IPD_,G3lS2Ut T|)5"JM1"2U?S@5֛imm[ƣu ʃAދ\̹&'gf*yc!!ra(FRRFiyN.LEtgrMcc쮊A&\rn)T9"n'S R,bAܱQ&"N|K B1 i:ܩئWmXŁX4&ۦ6r K»THq )oJ>s0̤ \O?Rzs:͕,:\3>/LJf1)LZA8\`T*dST򉿪jyuSJS.3*%wOqFs̲`xs=I ~rO ^-Q .2bhza EI.#Vxr$T6[aO ̻n0z8FN*A|3Ptؾ°c%Tޜ3\ʍ&ľg8R%^C1{1\rMC@ȫw5Ç9 [ѵ֙})uOWs\B:W.#͜#׻d;` Aoۊef)̭e5FUؽ{2?û ڨvj1zl:x!ׅzj.]r!Mz3@ex {j{ +8GG GloshJl:qm׾{ѧ1YCUlܷc$ͰLDslT>;T¶˹׵R%W8e/'"Td)R" QzKA snwpQN"vB`i!3A;J%)j 8!` n *&#j黅0MMtL$\ \]E5\5@a`ASM- 4MU 5x=.MCUaa ]!/9&W=W8nJ \RPqW>Ǜ| Γ<H2r}2h.rz5.ɾ"U=Tl)^}=(-X[{.iqk;1d''BO;fT(Yte/ω]£\c^ ǓyNu;ډdk5P툂X7XױL=oMֵƩ6M,Ys{)_x)G_T&/޻]}2+x״t>=hWaY#=01[܊%G bfXt%ZY a +PK}8_m羜55J_Gw&q`ǃꮩ3%[o,Z$c6鞇&Ԫ9CF5>g28-3f맜hP݀wlCUo{덛NSO^g+2aDZXZyJ9l3Au/]G0RW">ngrO,GÁe&iǏXWw;gE;7t._dږmrwܰtDX'TvkA;ȏ-Sy<^P07|} DIo'sv̺ޣC>8DU/!ڿ#>RN%l>hnF^7@g%$<}# f]*uT=^c>SVd~Py-9ȣ K5XDk/t|INd?8fڽ0Êrn$ekx+wi޴*ڶ$Fu復#gC[FbB?ag[}_-8p]g Zj@'.M7[`eUO H|#SfYfC[e߶I<ȏfwW3CaSLJnQ-3vp"Mz9,t!So&Ml嵍RdѶozR@pu@Tu|- F_gy#:gREg.[Jh9' My>8z9U2U{ qxp)8:f, V]@S]7LC.t"٠bj(-Zjjn; QC t0p Lq3Dcmi n膆g2H")j)_$wډӜk"I;8_۱l8r$pęSZ`, =QZXz>ڨX"jcd>TN(#|fz@0g,U̩*(u 8Ay1;,?N'<}= !##{{`6H!顦%f:bjH*0q 0 v@&8&ejn&.&41pwpq LC@ W@߿}hd섉"! m:dC}p}"y:oEv8:W߃3tBfx %Ȇ#RVwio/õO]QSL p,:jP4u@\2GL],44pt]1̴A GT $I`hn4%: b`Y!chרSNC,Ckw"ɷJN)^cQ0 )%[g3s08٬ y^f'%y {V vWz xY ٜ9ßS*eSp"@ BgJjCY&2t3JBI %4jgv$:~鿀O>p \4P\p5q iD5E],Vj 8X j"릆b☰p\CTQ7CLGb8h(|!|S}q`_2S'k&}gy$qǣ`@\Ca$/.䭍_.0}p9P,}Uܾ~u >|vJY*O˅BMq1s髪&$O0v:nPQYJeʧ}dorBDUx :z$:^9R>ސ"Ctz46?HXj黸) \CAA]tªATRn&n30 E r԰4 EG] 534DM \CPtuWSUQWD8Ô7߃㦭h]KC<*K׬ҽXJBȨiF 8uD`O={ o ly7=9I8D5^cNDMtm8sjYOWzmOqTywm&5*{=~@@ʄ!C(ENoG0Rp8& i鸆`: X6\\EDtp0LCQTMq1q@LhPյ5]Su&&!&55Ř8&X&# '#, ,ӜpM'aH+lZQtwZi:#`E]06'}*G}yA1\,l`pߛ "^6v FO/i ړ,,^}^e:Uqm[Da2yiฦX{riʪ3br⾐TzXI >{0Ĉ<~A|󃋕U&P0 Tq1ll CAR:bbXj88) q ML\SD`hia04UM\LQ7t54LSʃ&)5֧UBәjpj>qw#fanwT_c6`6OVx q3.r849vvn{?sc oEd<~8پu ]YU#;wySS>*<{II#P=pGy.9uh ` *뙻\x` wh ~D~$:>@tum]1S\P<*(R˭m[<>m HI<isƕI-?PZP gu;<ѾeYj!.|刦)HƓq6ΪWXtqjmI`#[Q`k`oaD9"UwWgw6;^D-r'NvU:Fnd -g&nfsO$r \GN*Tt) DAsOy(`JYZ`4M/>B9]E] T:;>1Kiĥ?DNULXShkM[=Һt֫tȆ>:/Qn n+&?WaHT#mY1ݼR#UdjM4[Vq ;U"=c@4d6e-<81wsEܓDC٘4X^n7'We(Y-=ڦ(WH+r6)z|U4}T>^njB%ϽT],1a `}SU 5-Nf66B3V۪>д5WbKT/ٽHDVW^Sw&N 1W3ƒ7X>G8, ٗh๞ۍbll*76R&{x_ZTRC)*Fn-6"sxn"4;>k͓-< T؋>S {*_k 4=;W̃T3ŅMx.1">U/K?HB4p<(vlKZ8qAxraьجfUksߦKS4xl2gNl}^ #ހL@˜UCu6ĺi9n VPEW>+Јԁ3M9}٠i"}G9Uv}[6\n4SMjڻ[;`7A M|}|>U'}$jtgd^sV%0܏E,z%ڕ'">;#RP~MG@œ1DDA G0q AM :kci\]]``(h8T PSwSC1\D &ih0]wlKX6++_}촢֧1_3#nqcF])WSaқG]෋y)%vۓ8mC5ǧUH<-]y60K~}d`l|9cͺԩ{yΆ%)}EGWw7o{nmeS>hN.6"+6zYtCxxv!5زR*p;tHQGU%0}4'uuuD͚=N]ǪE[]Iݖ*A=Dɲ[ԂkWNCq.+锲Sx +3rݽ$~b)^*QnJtn|4WϪxG ;{Z"J & Mh#Fa^A݊&5Dv2,}kyw#n-H ފndz_PJt6坫g<:Ocgk7 rf,;FPe[AtRjiU1;1'gk g2wztП(HNͼ7i[OhZ Lbۺ!}x}͜B=Suss:W=D}(sQך&>}o;sm/.jvo9o!۾"jqiG\!Il]O>W>܂Nq3I cgfp3ջHxX9U# .Qܛxy(s7ˉmY7s-֪gfZǎd8:7URzwLL8QUVAڇ검M,! |╉D8֩lZ9]h_ ݣTgWܼ'3ݠʇb$M!UyX8LB(;%ׅ^0i+r֮d>5i=Ar"$\GM~)q> Zw27BJU痰z.UGj:A^~e{Θoӂp3aLjkF> iE19ep02|mޟWfE{$y 8^لTn3KfvqgaP8Fyf/ |ck!xaʪ2.PtG#@ G>n/!#MO߃/qb#FC586t z|;Db|H7=TI Uv saa!vvq\#~ODi}*]`|HnC}{ea.M3E#~:IFzO/%'_o_\0/ mߟ)1MG L2`&c) 0tTC5DMن!`CS4Lwu01@qt酁hֺPb8DMPP4$4=<9` )Bp;Gb\C0O'モw1>6ߎմwe04oFĤ@)y TnJ5 KVεB\ -ׂ.oܻezq ܏rǦˁ=q(F!}zEu܈|( 7CRиE C\0 0MPuw&81HmDMCETp,j耘ijXjf. ]4L7Mt0 ԷQCT~9m ~.TP?/"IԨU/S TԝbXX;9dIqY3w k <  YO sCQ0M?~o-٘2]lJ]x1GA;`2IrsR;uy߂85 hcW'^]펬ͳ,&~ w׏S{$Pp'<96~ sO#b`hb:"LLiB05D M Rjjn(hn .& ijXnZڗ"Xj!ZI HD=^?sY"<0@zQOJC {33wJ6úc<ްϞATgפ9'V8`?#MB(iթhIԛS̼޸fW̮Пڝv3ZW:㧩8SL. 0CC~>G@^@*T~KQ>8L|{ιTrU#o܁()\V-I4'jZu`\s4-#RU#fم}0&K%]m+ԺR!YmYqDO,3lECfH`E9>MgEM =_ #kn02)u=8@Wsʱu ڶ4HA2 T8Y^̼E9Q`梍3fͧl\df@?Z 0Y`8?250?(#c% b =i ?q54i|'2ߠlq4 ëԞl-86^TVYURQeDA!ǚC9`N &0Gq9RJ"R]|8>i#^nj4t}e7I0>:Uf+ЧcRAr q"Cg3Pp3şq -PoF!-Epj[̫T;(2Cޝұ<(٬&#% N1C/}}%X"QͿS6<1x(̧bMҎ2-QTy"hMÃw5qEE*@UTW&}~q^@ި"#-3r/Jti-yHF-Nx5ܮnĵ3IlNn1RKx I0X3_Q3 {AιB\SrK:BJ#]J7U[ʨŁTO:䈉|B5 %03zX"昱q Ek݆73 _3Ud0B=G;_h[@mRQXxxIj\,vRWjϾ|[*DdSK'HDNheIr3ow5H&U_jv#h#;^0̥%n ݳ֡ubtĥ"QM39 D3@n'dZպ:6s=NBʻgLsiE'*ֳ WA^j5 1&_]0#4,"Oq~ޟwv|ׄ'L _jZN."=*{fS"{QzC%S5GGw]<r>'3ɶr~8!`i`jbh4jXhX: X%&+6ڛZ#bjضhj]Һ$Pܙ?_w eߴ VveW vW+zr-cǍܣr׺ B 2qԫޟK| bo@ɳ9duOz^4V{/ .:rIg]74 \D{ic9ۥ^ m[Qd^s"裃zk说.Yʙ]vLC6|}xy!<-tzO]Ŏ$FB;H(Ğe/¯7N1Y8jF4TPuܗۀˑ5da?ؙX*GsqȩvCJ0~}q7a99} J6fyT_P!+y^us 3Ϯr"Ys؏ !NhxG^꽱E$z$w2}r73F_+^ܹLW>ݝ wvqYIUT96!x2$n.z[VV\m_Z&VӲl?ZUj;oR])<33a`}r [HKYIvb;&Rn/-F! =lX|N4y'<#m5qw[5WuCO K;:p$bCnƹAv-,ukP m [v[ѐlWcM܅:+^B2Q֫/3M]pӐk'e]/ag@1gQЊ1]lHޗƄ(>eۼјlŧ6s^.2-?aQL|uA-!yg%{rJgg45ǔ篥TJS;e\C7eS@uɣ(36zNRRIY]PzlQ~)\)^쫦sGRYn>n`Ь*+~>Xx)_Hp#XFC^ΥMTWD8c(ۏO z.w.7/oi0w'⏹<P?mSt!KpUz9R$y$C">D-Y]t xE5M_ [>[⁓7")AyPf_N'BGJ@IVmq'G. F]0 U0J >}v=l낍لZtmrS1j8{#3ҝjʼJ4ݖi6]72 O  8v'tVL :|_pۻğ_ =TwNE^^qxLvדv,_s?I7yقׯ[yFNџ0s}&sH>=SڗR桞շ~c! Ir]9Kt|= |;BPU0+?\15 L2֓M\w0tbjnR KG] 1)4t5Ett6)(2V,MuufRj!sD8po~8Ns bJT\Xʃ7۹p}^Ϗwڟ M4յCttu5PTlt0 Q0h]¨5U(R[]5w\(R@SC)5TWW )[]uQA>s0D$)@=TJgyIХ Ie٦kEzQ۵:Ը] v (%*$3Lu>CۯbFK5QtgS; ḡ93ƾcr\5NWt?k~DFP&,5)'COCv+(:Z\PL ,IS3P\GGVA quI`[fmav:j l7DLM؉hY cږX#`:0rA>t~zvyv%BR=TeEWKN!؞~[)?Apo_7ǎ ˄d% T"J.L56*F7zm9X+v)Yzo 74i#C xI>h=D۽:=/*`WS6_ɔpDƄ)MM3 SV]-K-  FL\d7PM5 ,- Ap Zj"in:\TGEBbT W:C/:>P?o i!#, =vHzIs;36;2W_.΋ʁ:eVU.oG=ա PF_?0= ^ϫђo|{g|m!n@UFer8j7JI62Dа@SL0(V]U 7K@GCwqG3 E] w@TAuO|z!$A: Sm/dI]twsu~?r]ߣgo(]@@|=FW.#HTwy=W&*J-aϹ\+hZ{ղRb_]Îü q$,"쀎><;@u/¼zmŏ~ޏW-ŋrBSTGPCE]+KpE0300L4ttmm--t M\- 00sUC]4\SLL\5Tt57Dt715QuKZhwC!o`wR(\ ]U#h )JN_  t j298W'o NF2 T_@Ar~'d}89QK*p<@dD>A:,wI]>† wI'=uRHVwYsNN^:z1Sa.vM%JHk~c \QJ IS[{j& R)o-%VIG]Wb9$r=II"h?*``.)&Z;. hh"``.&.(8Z"8.k G@5 ,BD1@1LP`f*`:G SD)8gI]{߽>\ܮWesP3PH+t$rKS%LVU鈘&NV5\ě?{ IԱX6g)oP: > T*I`u.`Dk+>R1p)F2X[#dbD$TR!bk*X:B!K"M,Kby |^ -] 퐬p"ضҊׅJ׶ܒju'rbb'w)Z5w0Cy.] %P1d"? WR͞bvlEl%wD-5N'.nJrkE">nD`4"J WMR(Aed>=44B DkM4QE!uJ2w#j.z IW{b`.6}D}"idQUId 7SJ[0d҇fw! ]u({hh}h(Lͤ2*qє7ykmsv ۡl"|g3-MjFM SkqKr29na u,ջr5U2B6^4ϩ-.% Ld$F\qדq )| # ̉ ijf%BS Ĕ%[w$UC`WRHZϪ iDBWHխR̎,(9p! Yc3;`9g\ǚtD$aq\vp򏎜Fez"jv,}GUeι12䉒H'yY{x1#:Ov뙌@_^cו 17zxx& [i5ĶidyŹRzinO.{( B|F~2xeןq{RI{c}l 3B#Zsok$Ѥ4nfHj>WTl7tMx` ZټZ.[C}bspkd~kyޕu=c1px0w`+XC\_o'+w!(b飢Z6j nej멦`ꨚn`6 vB%`&&JPDWM0pm 0T2N׻nԽz_W9!T3wu+A3jP5֯*|ʳOJW$UCT6FRfeQyQvfu};&'jB6c:tΰ>; f5`^A J/c,T0Nk8 8Za1fK=+IFBo5b#Pb ?Ms-D'@Zbf.pq{R'Iȩ89hr"KG;w];ZB$+Hy on`l4 g;<_T6T+ 7^;66#˹愙o1M0ːL o#^h<t/}dq=2k6 vd ui*˭9ш>NVY3B|~DH˯Í)7pgݾ 2^[Iy]>v*"1{Ժh]Oa5T;7,va . è\\wUnK~IUǪxۥCRG(wj&W>8hUn,IسjTrg`}V;bH)o/uЕ+ vSO. Ngep\i.?Eվ[ ^dРؓѬW0UM,oBuPM}K':˳S[7tzr1gCmue]r0]ޤtqi}I7ag5ܝ'aѦq{F&o3cj爂d2ִ1ُ1eQնFĤ{r.mڧnR-Z8v8.?LTպ%mfFyy7{zAN)l+#w[דDStjԍ>rٸRH/2eVVyv W9vM7&Zw.2"6rꃙ]op4Sܿcuj&sHp!R5i}\/^c}?7#AI!iN|I[GicQ5}6쮨YR!eˋԯ+瞸9lĦ79ǚj4Si"o>Pٻێ,kt-:F<_?4XB5o~(_GMȏAZרU'S$d|1BЯ&ZʝE+ZۉN$īԯZ6o tdB`fK9@~7`|Ǧ{d`1t;:QZK+7gs,Э8*֚M~@}L:q.aUCFhncg y5A pgF"ߣ!1?Q}ެUiHR\0;aa!b#F o-[BjEiڂ}4mO<b+oJpNMJqW#B-onʢ5Hqj?yu{Ax1:ɔC6d}vg|^qojڍ(}ҾRDZ,sHqOˊ5`(&tK\a:0வ|vpܡ,* >W{pv{$^P}uc%ϵI70 O]J|S (թGFop,P$(U{3ȥ`LI"+Fj$gCmٓC_a3 ۱<>OJ3g($5S߹s_JO->Fw] - 1ɋPWjdx<=Gj'my5D|ĚLGEjgRZC.N{~{Fн5vΝ9bX| '=\,pQp), 2]R4l%(!Y!0- 4Et6(@4GW /mVQV)-CY1E~'6H!Ux"u~󜎧:9~!#C{knmaB Ĝ=$W#эo5Oӓj9dpے.,;N$b!Zrmg\+c v:CR(|vYxBSaJ8& aP$0Kq Oƪ)4j!aK,h0Q10Q 1h4UCGwR-wE݃&07O_HEnyЦT3c:!mGR}[UU)1yB@?sCOpCQ A#jp(] @{?]k\Гuכ:WM3ig'wGx2vzIdvby[z}I!.am+F i K!&k8Z٦ tI&n&&%"am PpD~(qA_o}j_](Tu~ ^Lp 'ߐ 8ģf vA'{ ==ӵE\4|i6L=gۦ<#N}KbS+e}'SI3*u}TR2qeY`9bVyzJE{'PˋzSNc@'!}Qqs¦iq2͵ cP]IXn*+`P%II"@qjjYekei-n4$}炿;2h)SزI`*C!9ל3tHv߻8gp2n  |˯u^'?]!rmGS~sÝ 'Hc.6b#)q"#݋?W>6hsǏ<^7Hx2d`8 y TzUz$;߁t ҁ(?%"jXXi ea.j ipvGl @54"]@ )D))L U V*:8j  )NABD")6D\* G_+^'~v|F?TkPםIL#] y) ah$ڹC1}*>cjѽo6:^=Cet~dN8g{mOWĀN%CǢ ߀fCO~4@ l ٺ4-&;h%i !@wh H[@::`x<8UH S(W,; Kz}y@-D?]d2| *uwxA7IǏQd"ƾ+TuHR!6f2 ) X]vtelO-cWһ(VYS<ڒyM22M|S@GC$2wBH*_phf(+efm\n&9m8R& .e륈ijnZ:8h:bX& /*g~x-'bk{WYgDbLg$N;NB ?_ >|.t9tJ=;հWŠCsuB|z輥 nM^p 3"6$%dꊚl>oR̞;S<,v`tttiZT#QDFMSIcqm9^TNJ< >}rx-3!Nx59R'{aSLB:91/wB-nV(5:)àxk)<ޣp̵_(@;῾Z>9݋">w٭Z#f}27085Jcs/Y+ fqDB9!k Mƥ-JFSnl@pR|&vI1-j0s>gQR2 UUoYWMƕAUCiB>uQJjMfE@-4-x+h t1#*]ժG\%\SEaq'x OѲu[O6tW,$5KR}XԀLjNkYf4y]h\KlR4P/H'b_Vψ"SeSrP:W "P\R6ԧݗYPڸKx6[M{7Iy)Ue&?0Io[F[5[7D6,-B|;(k+20] o?@[ƞ5{TGXkqf's{J.G5)Ci60A=:+f.,k]Kn- u&0 z);{m&[r_n+ ,RZr罞^EV`AMWJ^:~T4$]+4g6Cc[57Q2-}<N$}غYW4Qën¼*gycu1dWD"vÌ:f[=NLb/ٳC%\n)\/.Nu -IfΜ'"N߰2yf]گI=s{u,dj:r7iXgX!toK4DǃLBOs}lcI#$nyuFet9R~piru/ھNž=JCy}U^ghh:еpT Ktu h&дXc@4& 6AIJ4uTp 51QכNϪfhcsjQˆ~;qy='&eຩ >ٕװ9.ZwxնV=Rq{*nwo#ՉmY$컙p CB Dr')p!N9ðI- (,S8ۏg^zYHu׸~t)'՗#;%Mdp-fEziư㜐$IíCʌ&?BHK ;]Y:wQbȻ-]Y|gc}vFFvW\9Fid;umd20'Y R>QW@4Hm+jqZ)S"ߜ (BG/(jܦp2T.uכC*kE7\r TM6WO9AJ  l-[')Mœ|Ob߭1el =d:7T\5%)Yq݊~\fcիZ[#7ݪ搄[!æLjf};oJ~}2+9nGQV=^So)팥3+y]H̱Iw@&퓛w>lEPqqН0=}}1hsvFuVX-w]45tNE=Wɔn:71cݥP-47(mdgU_[yZfja=⒋%ytx} /Z,3fѪRA]mt1 &uk63vM׽/,?x> ərZKJALE1 " +:H`s*}$ҴNDu'lWm-v#{*:Ԥ\uUT'Ϧ-TrۚSsݺwe P-CYzak.ZGs^pX3棄y̞{*Raֹ4vyyY-,WϒH?$Sr>iE |XÛF60>D3<-&f neI$Y˕z -i,! yNpUHOz72~>4t} mc~f6(K4$)3WQ6B.?=ϼD[!U&FBV"\.n^UsfgLwDG j>hvvւ ?*O3lzÆWy߉;5b|x!Ʊܹjӄ]K 3b=rڶл2 eu  r*5~ͣδS" |̫(LsAqY>, is^pzUGHH</\ ^$''NoV8'44д -MAղM40 DL b Ѕ&&YJ%:@uumP30@@tD]L̰ ]Eh:"A")Nt;N@}։(<h{U~{cWo4(J޷NaW?1=%\ƆQƨQ;֧S[Y#i p\i *IӠ>>iKv Wɴz,BzK*'_\jO¶f%.6(fLL4At7hJKSGM\WxBc`n+Cc'hO\_JZCRo=:geB<(nfSS;h| D$&!!1缴=eS]ʕϾB8-=Jѐ^!ERth&m$\a[#*! J<SeP?}8Ǽu4,K[m \p5Dɋid(UB&ۺF:jbc!nj#(.Ap1ppQ8 @'Q1JGhއJJz[(I< $Ƃ+^[װvKxhHƿ,Uہ wgΛg4H@OS-H,j=:m-xE e-j7D `W ]` #;LCDGxR\{ 0ll::鶥ZjXXX6EpS&9`k:e#v`6܍("Yb>C_?*)R ~{ i4=B M'fŗ^?xJ*T;P)k1/Bt1qM@.] `A0q00F GuC]ݵ,-t]]•cpaxSQ?~ V b7\W~.Ϩzt+$,; $w{ V]S$i;C($BPx6@D l@׹y[YtDU"F GT3ϫY^Q\LH=]iG9e;|\d8}_M{+FHZ⸶YJek L@Ŭ7@wCpp @.(`tD]z8 &55O~OOzZ 9:Bt9,ma+n{R">V_5AsL:ǙA_6^cin&W4x5G;~ǟ}b>Ry?+ "eƮ$t4u-ASnCDp1-RZX 03&XTPZE&3~CICIzi,>m`! 2Uw:Q/s37UG 9ȕ.oNng<_W>E?{&]&6Rq ݼR8#9\g=֜_\^^U8t}GO{0 ު?!aV4[Shjn%AlB喻nce!hjn  mh`lZ۪[p1($pKPL,1- ApLɎ{'B_CГ V1l [eزc@PzD]Ÿ2jA e˒,;DCT}q=q5b;8@5x<>|'/wR8fbڶ2bh%Ȗ`*c i" ;&h`h:b6b!ceJauT-;馺)h\X6x+w7~턹͹WB %rNF5Vr9T✺] C*S*s_niKum!PD鐰Η*KAd} 4&MoJsf~͗02Dp\-wیEŰO(Xx0`4[!iWҷuܗwWiJFN+zf lj=7J0tm]h]wLaB"SjTVp5fkM}ΫMˎR^zvέ>3<ЙbX'%jbTYl|7z6YyB8ji)gL]=85NDTq5=t5IY$:,Q[s䄟>wxkJ'8Zњpz7A((d%_o SKVWƠ % DO1\#ǍsH"8Ӕ)2(2,^09-##V&]f?urtG+7P>,~zvkO Va}| D!6I:Ƣ:PtK<nj }Qoo[2"I =΋s#_0nF${w//;Xgr2{_b}VN]TT]f2 vX(;6<|Pmyx}'+$5KTl[A 4Fl  W sSi6RCTO 440S   B t7MBŲ衡,W1-KqKl( D7Be-w;_mnW' RlRdfi's黠4Mykq#7,pV: 2d3oi ]-' ɽx:{9U|v,/xٕk*yZ^c&=LM Z ݺI޹'[{ #DxնRTFQI疎hFoɿ0iy.p^ϮZ_ٜ0wM$]›_,;;=~K*D|w43{zx8/fd;T'ofd+\J0 P6 #Ʒ0@}ܨ?&'R$Hj5,-!ʼ}Έ|: 0Z!`>X..RQnkWwF+~ˏu 7}Dm\7ω=s稇aqcOAozŏْZb\S1JGcm9a:9̖.CVŋAkӪߦunZ6,sZ#wl>E/w"jMmfpʝ[ce=F/ ED[܁#jj\t*{۞g4wgŐkJ/u {:gqG:H12otlz)HU:VѮj|ZuJfMZMMUXqc/o38IڎlݩNk.,ܷGb:[\׉Ru>S&5S;nnSধ9:%C)z*񮫻rOn9xoe_n,bq3\dvu:˩G:Ȋ>*+OW;g,c,}v8! I!4g["Ѐ8Xpyƭ>7t4u`P^1 -a2mUu֒Jxbt ^_sLrz{'z= Fw_SLVza:^e c ?n!< }_OC8>ݒ\8´7U?K&D`*\pbvuicZфmΐػshbMޅ%Qz{1C<{&;ޙ\E}}P\?av;!9+`}n~EO60ظ^MŃzb&9"c{US⨻򱵊{Gxv`ƣ1P^eקדC "06sjpRϴ?S* ˽k+rY)|u pjw}G2]*qIi L*3kɣɉFafO 1 y^wyi#&9z/ćWbԻ٪bClMXwgRs3.cE8J [܁tզy)[05XMHG4D5{b9,_KQDn/'QDc-ϋYicYf2.m};+ W'"A M⬉JG 5;?u0\i?EB x瑾I^<;]tcrb[LM jm߉Wra ,$Y!쾼s/o #|K@/L>>2:4_&zpp8~-iK1m%%cJQ cb`څ`!Ba`:.&"h!,6/D4l iJL[>MGc|ҧQ9*x?  m~+9L:OquCsbh~j[e}fGnE 4 1G;uyʮsU[*v`TQklٞTtp$/˽.ӓO֖"lE.'У1T֒be!n6]b'"Qu)8 6~kz(Ԃ!l> ى@؝аn@inog9{#\5޸aDƅ4x(⿌_'Cu!~#=bu>pqXc^=/*`(9r^ Oy* RwORT/ΘP46M `Zfaca,-qp7Mr1MSe SK, !A2[pGT49^˝Dz(Q>QG"~KWʗXk(kU G08үA+:w$O/aϸ9%de{꽮|˕+}$BX+]qwIU89h+N.{Dh|=&z<\ty;%G:2,q5Mtwatq5 M0 MC;aF!hf$<>_!=üP8j:n8&Jjt G.LmK\lr.e#]@7d!t ((q膨j?WOs@sˊGCN+:q;>~g>(pHAs/צͰ[ @jݩw\Mu{nf6ۡjd&8|pCrO+I,G+@Y${FHc8  5O?Gi3?P}><'~G2в™] 05N& 3 1,KEݥPutf!k 7+L6b!!@eQ;WzBu~{԰$,,[ '!x2eAPЄ^VK7iF4]J]%Q>ZSؾƣHMza}NN#czUٔgRx~ͣ}򤛑y*OTꏡTT' 񷄀XtM/-AB`[MfZ .룈멀8eZچP)9!`|͕]B9}[Ms˸}K΃:٦a?K B|bu{J];%  l1+CCH(@Z%`nj0)($ʏ>0%(لɅ(fz`#̐Usvb1k{F\[&aXu( E'amܑ VX#/Mz+L@E:=3&gp#F󼯑"͞O]L#e uzjuU&pR%)^F^q RӼyn7@팚ٸ}vEm SpU g,f Y̲Ka=41[5/W!أ(F9'1ݝ1V/;L}ĉΖg5c~UZU0;%tzA5}Mu 麽gʝ]tM7%>5tr*FK*J1K()S#şf\R1YW;Uejpv}^N*EOK[/'C+Zw #ϝص,ȍx(FW'12wciNnhsMNEAymf>K>vTx/JWh~&`!&Y4k@iw[~EC{;&U˜qDͦ"t3N  }с Q:N#b'GXF5SMiSgv1F{5/|XҎ›]vLKJvf[Y˷qzm٥2 Qf_ ;Ⱥuh)q,qrރqS轢{d*쒶ˡ:pn酇T#5V鲑x/Jjt$9 t:8M 9vlYc3:uus?Bp>j|#VI> 2sjM}vsf-NǓ,f9 P/ةWf(Ì1t}N1]2>̝Cׇu:Yx )A l:*\dj'H*!yY^W CnW9&~]* V9wD[xVǂT4.ok=2ǵZ,xQ2r]@MӇPɸH^iqg96 G#KS0vx#(P'-Eq9}d|ѥQYq&9K/0]ޫ~wuPJ6\јd窺{7t_'n|}I*_9V )`1{;ޢ4E7&WXbU D!M~%>ϡ,9y+}vUt m+RX rŞTe6z.YL֍fT0 JŝB*eA,@_ 8Fgyuqe8X@a5/1׈!M r 6h Mm#"əLR׻Q'S#EK|/5wSmvdSi=9J 2\zuaq F|=j7m=A#>ޟOh^l4ju*D~e>ؼ mVOmi.4B0Z Ma &Y>,妚u``4ֻC=u/lXӽ1u|=6#ΌO[.|cKt9y{,<N ήB*(kS_ U =jPp+L~ z0Z jL/X޳}rQk$=4b{53+yb7 ?r)^#eezuE- upO,vY B.df>T+4 x!ھ&\J}sd/*d)dN:z`@9Jjwog'[9rb%9ADh(7XР:FSpg'1RT|$kH=&J|iEpK4@*RlE  >T};y0>Lj}C"h$2JrD,L fD3 LL3(Jpp 0&8fZ888b`jjlOA"#P I?wb]8:ctf4NK>M =ܹU 5($J]Ӵ@ڙwk ? VvQߣd9 Pq?|=rxAd/;jXZZ,]{8_7=L<}#km:j:^vԇۤs] \"GfSQb#u ybq8|Wڠ{wRO#<Ry ܹ}>"wߓ\€в2֓$d,,L 0eaJje)Ac%1 Ct1L.W&}O +x%ǁ?KN򅠡2@pȂ;M,PFC<3#ᔟ(^cC(TРĎ*bRsAo;)zWgܣMOXwVA ]6}q0ך5^-'e\wm\Y~՛$ gޒ4"*K}T͔+'箳B6KӖe=rb ּ`=G<<|\?% `chq@47]L\5 5p4MCL@0AM (0C4 5LS GSuMͤOߎ~BECaQꒁGO'j%,[ ϻڼ;?e܌wybhn3$@묺[yjoGl'?WMNiк-ʴzȨiqY1i{JP5+=mT^b\ =i}&<{zXxgf?v}3_xmлfC^Ǐ`k-QC7Awv AaAޔڻ5-Sqƪæ>ꖝM! Ǿy롛)@yy׍υ_lHۑt2: ;MM}gmhg3hbQ4D J q:XɆ*:S73 p>t1dIaVVH{'urEtyA>/4 cqn-6V h Wh9~BESi':i5x#<yCqԔChm!=zsq"=a8hUA\v|PH2EI#P /xt>XHd k Knc6 J>1DDhYSBc$[>^e* XY['!ǪH駕׵x!imyރ/J:7۴6p۞eZR9w#Vſ6VSq}$jv4,:GbDT,D6A'o Ze}>wkZ\o%5^XzuΕߵ)]P&`B\ "Bs5^d r8db$@;lj;nmӦG01c+񰔄Þ<nC`g/Cmg(q<~L>P/Ӹ!eRsb]9WNfA3}n푂rI/#/]D?>Υ)G:yV7cE'"|#\|(}Mj4̻.9ghsQF*-H *N(cS( ׮ѱjy<$F w-4Z 90zW0{;6-^Cܩ^- OHxa3W0@SC0uMp\MM urMMLLiqWM0 2p F0s ĹmL,)0 5:H5T }sKfٱZIُ<\to 2{ʷf0T箑0ZZ.oaoh˵]59uE\Mh-Iwnochz=EK\ oP7j,bj4YDrUg1Js1WZ=sFq!W3L'S/^=DfB0IvV/:f5W}yڌ:7o޲B JF]9hEd(MRg"OojiVbOٔjx>Ѻz Iq0 6R~ck2R[Alk}4v&M8s'9|k85taQuޤwZ]NNlZqp/nǽSšc&QK-D eHe73 YY][Ftq,N=֑?+{zj22M!x^Y6]8*ҵKYNѩnv cp՝ZjJ\e#kVH@q{33rq?9Ï:ѼF w'7a_3N `rӺ`v :&@?q?IS([CH6d<WjF OGmp4wkޜoد-ktޣL Efyљr5!H8*G4Gm"WF::ܚ׎.{$;v{oNW&#*A; g`Ӑaz^>lj:ܗVJȲMM%PbYU\ 񫽎GÉLt}X¢Aܫ  g2z#C_g/QT/>wv2-W+>:-x ۮ" /rx$_/LYw`yLY+zZwiTwr/Õsc!0)SU ׂ uHl vy٘]lOYSh*#Q*!ݧz[xRlӗ<WeLpgL{UPcDheR 3m*ymM7{*]Jܟe=FB \rVHYtT 0K; Nn3J"&ÊۊCa2lu&K;Sj#0mݟB_ð]qk;B@|$> o"}X%fH8b88&Qhce#ibb6ij``eLN&akcc`baBPИ8eR& b::ǺF{>UQ.p?eJWc w}01AwApIPzy`6h >XҦ42=>c=6=kP܋#g}ֆ*uҜ3n>\f )B9Ir92BWiN{xx46 $MuqD h)C3 DS )t WKlp\ #f)eb ``ؕGǿ$?NOHP!ل:R&DGON.֒s2?M``P]NsHʆI ? p>.ϵSn* "I퀸܅=}La#ph?}^;T!a>9TH9U)Y%ːZ8Aq K.:.SgLpttl.3-l-0 1L 0pqwY#?J'hU+"y)utӧNږ]>wc`=oTqf;ø=쐌gli x}!Oȏ0GOL|#8[t0~%wæ{zSeʚ;s#Qg8Cpws?MQAݸ5 H4b%YKI!a.)iMMWu5>7Mt-mKp, yH?ٝR)E ҁ:27 ض3gB ~BB@"'͂6@~ xp~Wŵi萳]< Mb{@3)ONVW53Ǚ({.GEHtoǠ$;e{;&\C1!8n~Sp?f39&>Nq 7]Xl+Mu>ME˘bC;A+ރ$K2^¢\*0;ܹ_Y d|?O^eZsuq7]t u sp405CMCCGS3a &&i.&X6ZO~o+/zHBEB@|4=:}d=sf.!]]tLM44G4Mt 4]u47̄WWtS5Mt4-m =s6_t{ߧo8Y>MU8!A>4:|o.hI\kxͭ=qFA=Q_\IlV!F`Mcd5N$ 9}8SCII$UWY:4C)AZv!ԨHv)0InTi$))dfž=GN,30s_.v8&/1bVXiy0iGnA ngVPͤ9W1L%Xdb3Ȍ>u¬تM}u;Y(k O2=X#f?MyۏĬ[Hk]G>,` 盃5qlP,Łly,9kM("eJ Hǚ#<\" r x=e?1ț*u$n*!|[QY 0M>ojoBe+ϟee:|ڂXBl(DJX͐Z*[pmb:-< ͦևy?=&8אy& <3}s'1Jd':Q|੫[)Z,;#:T@414R=U0R.c^ItV3"-1AkMsW?oKZ]Q!llڤsFɊ`s+IN!M,w歯FK1cg@MĽY:%HP@5j_> P TɝiiF6\Onb+dA`kw Y!{a Qjo _R39g9bEh +X B5`I*EϽFߡ"O g#a(+şjsq\y{=pXǛ&&ڢ89V Rq,j)YrKn" 3$#wiP鼝@t:"8Ow'wVvEv ;# ޓ~"rr(|KOrN )(\dNb兦2 tC&zWUͣr[psCZ{h(<}7(T$V)u]2μ61b'IPމDFJKPjEMHA"'iGK׉{㇇F4E Cn\bGFv\Y<׽q_}O9{93 eіAUA*ha52&1]=L͍Q;vZy]H3אn#i+ql0cY^coKsRt6_1Frx5K(OOe=١{2ZGY{YQdy#Yeefu=uJB3O6RMJԲ9/M}X/;kI>={u>y}BLܤd."u+K}"oac%lL-;X}H?_ L⒫s!0 UkzGM3X_`=옱َ`'a滽p#vSZ]5LxUV)ZryT ѵ2 ̞ mjw'8EzʓߑYhq!uJy8)& yRg1$}$)+ܾȺ2shvSW T;>Mb:{?G0<\v!ϴZG~eWA!~^ >bɗF3:;K(z@&$Yܸ쯧vn裛7ZF'.UH`ƸqD7jIv{EkAEb&g! `ȯb ˛ͿM^9,>+;Ә㘸2Ϡ2=/I.^)JZ:WpXϥݐh]O:adӛ~:w딳Ų_SXܑl4ۦiI5myƓvsՖ2e;[>l45s%}kGr-wFP~d~ӟ{co~@?Pڂb>dTG?G ӽj'wEmyRL"nk}2k.6@oqvt*>g PDT?pg ?ʩͪ4^r췵uěM53&E[; )cTW] TBLSzlP;\_KUe}rnQB(,<3*=IԆ68]iiP PƵqL9#0Мp0L.012 `; 8<qP؈| ?NQ,(tqUg'>>Ǿ!'Wxޏz[ϠQ9U T^|k`|F Mt+0x2狋d#-ь ݫm\YKP<$Is <ԇ ~BIS>&'G%CH?fY9^yp=+P(GA0Hc9يf]IYiK+hjP`8ahXX[%b8?>~*(!_ ܹtN|=#=[BvXxy~6$xxC"sH@92Rs̨I ڣoG=MUV_s.NrHM1a֝nU7uVȦ7<%>utl Udy؇xTG 8~(ӝ,W.D\N-=PV1˒<5A &@}@`^. `b)``h9S?7>_)[ 0D&׸^<'¾'˛W# Cމx.ʟ4gajWwڑ-Oݿb?usD*'g aZZXbw@e En bhi()LG@bb `nZ@ ?g@NHtTJtOĴskiAZhu\AupDs /F&DDbsek"az*N+x3;g„!"Aۤ;ʒ2A{\=7+] ^R4m7S[9K'o}(Y#z/(5}T^e~L ?6)`YiȖ:鮸!:CMCH]CSW]0 Ca!Q q1h( KLP1k{Jʐԡ>A$ _PRUrk~ ,cmY,^Ayqˇ&|xj)@A9f4 b(af&Zb\ 588Tn18:a]MD}\@䀜C9%)9M'SyEC(S-`Yu T;cf&i zT@~A/|ϹUv!~r^>|vFnx"c>M~o,;G5UUsQ5pu(x^~RyC=߃E>˽ K F(}A#RbԒ?z"eSxh0IFq<BA4(zZVа(փ3000q M2ux0]]w( W0010 GMLB,, GpZph=PM9R dG'C˗ӁgW İT rU9W!zlw<|M8EuN<>Ay{䇹w]{S.L4eTUO;”ZnU.ttܺY/}/l¡ӒQbSgsٞPKNNª[*K}Oޙ9׫#ÙcdE3 (UFrG҃ p$&%=xABR !SBzMhiLB40MGC]  MwCLC Cu tqPCSG1LWGM55qL@ SC `aih b/UM /CWI ?D^P+ScݖRд-B/*rr^ڡ(KZy).Os끊"O=}HhzEHgqzջ3a'c >g>71j8|ݿosh%1n2t 9Td#eorx\ԅ9GiHuEP'A=2"CĒ(CJ'OJ/!?14wP02qStM4t5L\L"CpTtt C)pSCt4t p\E 5 \Cqu44 1A4p\P,I@M!k5EKD`QLԉ,cF E,$SQ!c&ƬmEb* 4jmHXj+bֵjXڋEF(bUUUc[M@4(!H!H*(* R4 * KJHP(ЀRJJ+V4UZ5hCBP+J TUkZ-5mFbX4h-QQlV[cZ,Z؋cXEbmj65b*ъVѵj+FV@ @*4H*4 !JP B@!J()BHэXmjƣUX+liF(h)iiQEQ5Z)QT)UEFZRZhը5ZZ5TJZ(((Q[EmU(R"% QZZ*V-V0-*((@PR PāCJ( PRҡBP(P @ШִVUլVڊ PJBB1*&+mj+Q`U4 H"R R J%(  H,M R-)@HPЃEDi$FJARP @TTJ@QQhQ AE@FPEFRTi()EAiBBQA(mZ4b5Fb5ZUh5(RP!NkQjUk,j#m%66b1 -561FH`ڍ,+bU@)@ AJ]ثo1AY&SYL7`@ bPE {*FRTAJ$PP@J"I P@H(QJ("$*Px`4( R(ABBU"UTTQUUUJRHQQET"TE @"BDQ)  BI)RJUH$JRBITIєU Iӻ%d;c׽c>x;>{xK_>^f^/@*D@%@DE) JD)@$A )R%EBJAR)DQ@* RIRT%ITUUH"JI**UI UEBTE@"J(!B@D*J*PP!!BD@J@E$JIJ *Q@(6`9 !6qyJ[ol&ڃCH펻6v﯂}>k9 mg onx! 3z{ 缻^#&DHil͎ < ש8'W3={:k w}p9R9V%mwT$(TVkFF6kes<{`v<.GMV!R;oxt(:h"  ݋v מ!onx_}sxX4(*l燜*%PJ$P=hٮugwYz wh㎾^ۗ;yt`uLުhUTPٟw*L"PU];n0i.};/n}|z g| wl P*DHBJ'@T&JLJyI IP$MU B%MFJQ :ms:#"lݐv(m\ tZ 'nDB ##(ѻ(ȻI۬k5V.Mʎb[5զ/:#pml6kkǭ{-.v6mWC%A@Ҥ`SAZ(XF\ZئjZ4U-5d ԌR.4 (BK*Ha3CBJ&@0u !@AW!!$0CZJK++(@Jˬ$e Y$dH%h@HJHk$0p%% dHXYe%%HX e0P !I$ !!tFRXs0u `HB``+ 21MbZ@J@@$0JI! Bb@HHC   Ë $ bJ@biIS*RƦV*T`1 D0ěciS],&̫%dW[N26̨[3b,FF-3[kGjj6"eqdPpI1i   Iib@Qh*uܶbp(D%FE-IJ$ H$ JT%`@B% L4ieL `IP %Y b&(㈘4 š! J I$e2RD%XB :CddVa5`@+ARMij[-sW%TTWi4 mۊ.+v45Rk*W*G{ݤv{PһZDEcWL +J.CLtQM$p!; 86QMyuww^{|WwWfTGݻ[#u93ܚen+a\EU+('!Hn U)TdJ@- deP(B(RJ*f -BRd" a#aU5BP9(Hd&-Zܭc[Ʊsh#cbŬVMJ@ iԫMH]5jZƱQ4rDbCpIHP%i7rG%2 GPkh-[Rhh79kb7WMD1ˎ" 6ԩDILRIsw]]ft"9$&QQUGlQ ɘAMe<\%()R)HęJUhZ$w\MqNv⻣ :p78=rw.#JƁdʣ53DAiņIw\ztsb\,:Wzh]eʙr)\VpUJbRHE1\L7-w ;&JVVsR2rmr"STl=ȅ;t\S˜%0U3ll @ nƸBEC`EpW($LQ'l[&QqئXfFIdqEMC59ܹc;̸b@t9ݸKsrЂ7#;\āE͎ݍ27eLMY+T4TƧ]\6_>4LsPDH"Y9Hq+$RKĚm%&2NrnkDr;H9D՘I2H4NT^fN\[-\nү ,HK$w;wv^c6R1劸X cN8伾䜫FK;܋q6W.{=sn;"a ]$\4Jr;خfˈgIdKTlkhJ 7.[c=݈r65N.W1\WƣQhLr36DnpnU(wFW5AQFs^y]&).W]+fCh.\9p9]I%67.kJmsw.W-]"1dn,7N d&]Qع\ckvXpL9k۩2lb)*$ 1&LKB]U)%@&4Rfs]MܺhشE!s\[y^'w1wvw"RrqD F\1FŠ`5ywz*MmhƊQg{Q40ɢJ \L4*r˕rEn(TA,%W9WKcr1cHQi FPE`Qb+srM,TPwx&ܮƊshAkyhvE&NmK\4h5J[4o;ň4;(&M]V4 ˦ۑPAIgqphV2$mJ9AguʝۈKniB-X[)1"*yX F6E[&#$#NwIj6usbb[ (nc%XW51# `Ƣ-EU%hL2Izb4d7h1%ub*Lhך&VHHb(30kr($CޭA5Bd,j &n_wdFh1Q`¾ܦm&(\6,l@QZ.[Ԉ @&gẒ@Ɖ^cFWڹBcRW8+sA۾mo%6B i,RR-6u6a)c ֋f4͍Ic\j:Y- 6J$K$bv+e5TRUM4"65]mX֍FfA5yu弤cE׷\ȴflb؎sp6 66enKF(K%.3]%}TdFbR}c E1cM1guV {FJ,n{x% ![&+RHlIfS$RkrjhX-'QQ].]ݓcj$"K4 D"(5vZwt5ōŷZ$b+ȈFDX[Uržk 7[%ӗ$6#d^[ʒ hVHѨM;Z]#HJ,޵|Mf&H6MQi)" EIklh:ܶ4X5]"KDXtXH4h2u:lI5EF.h !rAآ4Rh[wUS5EIcFjJH{^Qb^r@ɲBDb{-2),j1Ti$`{[$k \ I!F:hѴEѱBh6tAlb>ۘJ`+DTX꼷Љw]cIF#XX.Ay+E H4bۚ1*7޷Eh֒tZ &Pj,XMS4ֻ6MNTV(0kFubdz܊lcY6i64k(ưE-FFhEXƱF5F"ݫ$ыuZT(X i=$ALQ^d`ŤPy (ѯnXi3 XƋr+)W4mMUbS*=j$fr1ll,P7[r!Qw4ZfM"&[P b65 cu3yEERY6չEAj戍1 &0DkV(LlEW4IBR:TQ(&,cɤ/U(( \b) V F'k0b6gWMƄiJ-E]Б2X ѷZQ !cDȃ(FZ6f]"ш,b%VM.4cEgѬQ ][*7Z4F!hrѣr=I4F (AK@l٬b0h J9٨ѿQDfȑk̑YMWI@," * E[7mlnIlk.D1:HdBL*nfɊHgQEcQv0b$؈ `hnPdƌ;L,QEջ5pQE|QtM- h5v&TЌAivF,pQQ]W 1d,M3%]U(4h(Ik<6#%;W6*]hd* un4RZ]1 tThֽ%{ncFƽ2I]!d&'Z4Vn"Fn[đLmQչS1n!ةb( sQkj "z 5E{nDhVRhb5v̘Ff"dCQ5"&Ih]\FIʽ[5;%DTE:QIY1tƨӬEcvX LKQA&/bnRI% 颋EsŻnCbB%lHݪ (\֛"vU&WH;i4(r mKZ*+2"#Eu]ݶJnܢŷVIF+z( QζmrФd ]1ksQ+&͊QP$+̚ ^ךbt]$E  \5܎ bF1LѧjvLbU]QFA'[ ]B$2b urmtjf37Vw(f=F4{WdlT{W"̊MkWUsLmt Z.hvۥDG[V4E%bv0Q"3^l[ֻ4 D1zkQQpmxc&RJ+)Ok@hmQW)Ս@EuRlw :$ѻRۦD&n܋b7zìbI"γ Y^ɨ=Ih@M KڻUhtbhһ10FMDuI"Fv/M[$Wъk$,u (Eu\޶唰\ƍvы$lW[k5͎RjF]#b6Qc}+\6vZ0M0\ƍuI;pѣ1 أIv|`wuшP $XHkGmr̍ZLhvq,EոbmFbTv Rhݥ\l01 $BjDl 7\۽ba \"'d IڹHLnuQbDhk W]y+Ԣ`gUۖ"B2DWUs#%F(؂utąc;i Uȷi\M\W#ޥŰmԵ̔Pjh)JW\F{lhM{mزic0B"sdf4ŽE]f卌kʹRNvh6DH|/U$ mp+QnDXk&QܻnlbΧmFI:0F̳rF=IQ),cb4cV ME%Gb rرA4{'*$QF׶ƸbCD%y]($lFE"XsF6]B-b43cDA11Fa"5 FzbwWM ",lVME,D+cݕ ,IkhJfAڤb%]5& RX# ZJ,Z-F깨dj#Ad1Qbdvۨbd#Y,L4h4lmW6 3$INrŃ@l!nw\ B0Tb-vI9b˛" Ѯe"E$TiΈIUuE\ыV5=9hxX Io+QTDZ"ƹgu&:W7s\Z1lUtj,_vs&"dӝt1l4PY9nDo9nt.˕tnT\MDmwn)-&jsnnBL:vfЄ{S7#Sb(6(R\ԝ#XNr 4EQA;rX#wuPbۗLK\)ݑ:G9E!nHEԑFY+ QT\(Sd e##{ͧwr+,w]d8v[رJDɔ,,8]خrƢtW5t&Qb\/}%2.sY366XE|UdYEęLtsXI%ȊlWΡOJ#\jS@SaH]9Z`n&eB 993"s硙h*1+](ލ,Uw!:ܻLcnMr$u۔˔'-;5]cXĢVm8C A"૕a"! Pʱ(fHb뻎HzD\n:幱n.IC2-IH5 ȣ*@Jе')ewWMN\W9qDbpi) &hqs'$ʳ$)" L 1M(fqFVX7j)Rp%ܖrp\W4\\AieXTQ!;9wlu#XZH₋ђ$,&T QnDM.NYV4*BQPb J($dAh#mM"M#05(-4Xή#L# T1c1dȫb3,JCS4O-a+ 8duǑ fkj #scᩎ(ʓH )9"N0lDQvD4V|.4-.kUrm6n-G יE&R\\9rpNX8NP\ IqWs^sMxkERiܨě\bfcDXH(]g5howUQ\ {iؒn[:qwv}Ȋ}h*,U ā݆QuP7m& $nGlQ"We_kLt2dY+:؆*DfHBSmnѓTSYN&n98  bY:w"`1r.Y&O8g $7\W&ىCDADa3sF݌ܹEo.wO08X`n鋂\Ʒ&7*Nkˎ\snE\ƘQQRd(EΌk6"1ƆFL*1An"1I͈Eb/^w (ѩ*,RbX6Q[4bKb6Uu24ͺQ +gw5Kl0آa(ƣidl`$Q/]FwsJF,PFr6nk16 wQkQbm\EAأ ѨBd.F0jN\SDhXEQbFƀ&61lcFAow9ovV$ɍAjfHPlEBkEXԔRFtF %̈ MLXiݷKڃS"шi*%m%DcdĚ4RF1!b E^[1FSPlmȍcQDhZ0 C,FIŴZ0X;] b*6j0dhMZ(PlmDԕ"ʼṉљcR[lhƨj(hF$dƈQ2j&cW7"R*J4FM#(6{6ѴأlhPhh!F݂(%cQEAFѨ- Fɂ %d1t\ b#HhTRV4͔IhFRl& mcm&LDmcj5%hJ2FKLF(Kb ,+)6ѤV$E*3-3Eh**L!If% ahL[McI[&*4d,lE$Dm kAXɢD4±`*+H@lDmmʍ357;")"#UX In[`QEЛF6cMTdHmF% LQLk cfb m2M1Gwk-IQ H؄11F(cF cTFKVQ& $iTIfZ) m%QDb*QFѢ"Hэ-4E2b,0,P+AQ (EcF(KH%knVFZ L4lQV+A52K1FXƳ6M&Ũa6LmDZHRlkIjDdlFŌX b1dhXIM Pl$dLClC6lh6"fbE+,V1 F(bRbѰS3+%yU*2h \E 0b"Jh鱓Th*"ƢMԑh1jK&EEhB۹*4lRbjZ66 V(lQLɌdFRY*hѲlZ@f4Xk$D bFeb$4Y(jhrPD%DPFcl`QDDQ'uhj1E,Q%F&1X4̩6-"!RTmAlY0Th2Z+آXbѤIVd,d&10$DY4hj1YFRXaj)id!h"#"JHBFfBF4RIƢTlFcDTDiE%hDV 0,4,b#QRYj6ЦPV6sj#d%PQhŊȢDm%ABQ\MTXM%2#PDi6dHbh HJ(ؠa1dƢъL;* !HlZ@vX1Eb* ƍ`@V)(̋c00ƲTcF(XDnF4`ĘMDfY%F%j-&D`رaHQHbQI a(I]mbjcE*64QCiѱ-Ai*0[HjB XIZ!lcQck#JU&-cFHb`(V$C%cE&XƨiY6DѓZɱ&e5-!U)c"J#^۲I"9 JR@4IHY4h؍XXYLL`)QI4E%b6LERb1QDX-QQ)шŴĮ#EMI1]Qk"4dE3b%CbE$-Ѥ6K`$1Y bi[+!2dIHm5dQcAb#cF,IblhZ4IRbQ&I LXMAc@lTC+,LFa4QQX`$Y2@`Z)X-5wDFHmƤdXMVFb-EQIɴ͒1clTAFъFd1"aZ4mmDTTTQEchhlQĕj, b`dlDQ$l6DIPmD` &1jLUPMFFF+2FX҆$lTFbB@%#mfEّce&lHHQѳ2A&IDbj`%d)$d6-% cEjH 1DTP DDbY1M&#m%, FlX&b 5(э&D hPRPRRbb*1rrbe MF!CF Qi$%BIɴ&6J3 #-jPe1Ili5cYK1F-Ab j F4RF[fhETh65X#IH+i$$(F Q5Ai$A EEbCDjȍdKPDX*"Hm4DVLHmHPhe "J5FXfhMJShBEY4[ɋ3cXFQRh!(RcIQcEF@(,QdبEbK`ыBTV`ѐhѦQAfh6ƊH!dRDTe)^U̚+3-,B T%dŊa)4l-JIIFHŴlF)by֯LmeXiChЛEQ&,FFcYl4XFرTh$S+ `ѱbJS̍ IImYMI&( 1,Xi#lhK% (-Fh6AD !)cQhQJ%%Q1I2EDc$hd#Ib0AL͓IE4(0i4bcb"$X4UF*MEE RRmBk"b#mjf 4mbB6D!KQR!ŐB#Q(Ĕd4BQ($BlQXa4fF$VcBPIC4EZB62&[Z,ELcZ̠d,QF0XI!ɋJPh%!AjIB6,Si@UыF%#"!Pl[F T@AFE̐)06ƢEQPQb#Z1jP̄Z2 EVMEFbBU%PQd1cEB`Ō ŤX؊bVHKE--ZLTV6,Q66`1m&*X(ɴF53% Y,k>lTF[X͊61IQ` h.)Tbѧ1cF wm TDj$E$FLcZ-1L4mL(lY4`JJ!b T6 blXB X2ѪJ(2hcId"*"LAQdфd!F-DE65*1RQZJhbi4hMFS`"Q@Eld )ł Fƣ3!CECIF4QZCbFI*( A1 h . NTY3&"dQ ฬYnhN+0QĴUw:7r(7g DaE̲"N[NZnIpsT)8;heVI6U\Q1MlC&#*Jnjs#lmؒAuDҳ$f\%MxSIsWs\9DI@HD8TVȸ*ɓL5*(dR*̖ZEbYF_* EZmIPF¢ 5[Y4k3i$R#QlI&+m+&(XŚ[,,hiMk)FY&SDk(YeckQfjH3I,U4m[Eh*Th5Eѩ6ƓTmڠTMi RHē"jشűZlRIIƴmXZTm%EED@+BBB#ImFZUJ5jUElj!iEhQmEU5mkm&Z Z5jdI[k44% B %(.j5ZMF֊j-RV*j6j+-i*EV65IX5mTTFڣjэ-l( (P@J!@BBRJJJ- 4JP*P@2XFԚhKjjڊdՋckIiZT V(JiX(B)VB JiiEڊZ UFbjQ&Y4TZMFٕm[hAi)-EmIeFjhP "4, 3R&6-)f*BijJejI LTZYfبM)jK1I&ѩ5b*RmMXبԖf664TmEQh[dTmmj*cklmjIVhF Q()V!)ZFBaZj+&EŤ*-dTV6j5QkL6bLUEEFljƵb!IYDb%)Th5lUQlV,[h5XIh6kEj-Z-XE*TU5V6! )U )FhHR)IP)$i@Kj5&LfR5jMƨ%ʍiKcYKFѤ`ɒfY)S** JQZbɵ&ɤmRҶŬ[&ʖQEEZMTEV ZMFT[45ZUkY4$*ҢP#2HQjeVm6*̨H"̊JٖՒ+TVѠlV[ՒSZ*H ZE)iB)D P P)DbEb)B(TDYʛFEcj*V6mŭmmjjMUZ5ZVDZҕ5hm$k@ABBDR4TjՋV"̶5XƋ[hڱjVk-k%Imcj5hآ ZֱVhՒƭcj-UY6UQP%"5i-Tmmm1F&Q )Z)(hF* l[`!FHֳ0µ#4IUT-%J($E&ڋjd+T@mBj jD-Zf# T[hڠ VCRmImjIdZ$Am! e ̭@D-mL#)Amj"ej 2FacdYRYXVƦ)#ZakBMm5XmP2Jh*Tj"(%Y"դEmEʲ+Ȩʹ5Y-llV5TͬJE-jȱ2eXBZT$XbimJ2ڡZ@ Ih VF$Y%YE$Q!RhVA RE`XF)TeIiAR!@%HBD ! )RTed @hiBbE!e@a@$`V`ePBZhU FQ$AIBD$@a)U E!FIBU%MVQTijY@ʐ,4%"@) B ( B #$ "!( H!Bʬ+*0$ RH2@)@!($,"*H (RH(Ȑʃ@J(@H0BA+HJ H H *$@Bʀ *@# B!$" 0J@##@$ @)J)( jUmTVH!HUQ `YHYAa$@!eQaddA$b"!a`IUd$EVXXIBTAT!eP&"FT X@FBEBFXPPP@%!E`IRTB! DBB@!A$a%eQ%HHXI@@QRDb@@B@F@@R IP$` @!FVDHZ DB`a`BiXa aYFDBB!d%$ %H`j*ږɴlmDXHXHXBXP&)352M&BfجKj͙*fF٨m6b-T[,d"ڍel((DH0Q,бEfV5Q6lZ"[Z+2Y5i4mS1kb*Z6ڱkX2Tj-X E)iFX$FجkV$QmdHB%YQD(H5ZfX6أm5mEQi6TkEmƢM6+Ebmi*+ ĊRJ P2Ulj5Z Z*m,[Tk%cQ5X6Q*ZJH*дTV6E[IUZmTlb-mj6 `١()ZRF%MX%[TZ4kcmتITdMhEk@YiXhdڋk%Tm@ZT[bڴV*-VljZEImETj,[$"`fFX$fI 1Ce554UcR-hKL`ىf+&e(جT,JKfm"F: @~2Ë0Ul! nsj>[6ڒn0 4pq0#TZ 8[a2&Y&}>l ԳUP6\"ND(OTd $THM̈́}cws{,,_ +Ԑwy}k:)N" A$j* 1됋gPF6{\|T>S߸i\b\swC 5ܜFoq_K4Y!xE41޴i{xxxU/s}=ߝw+2i@Z}]S1٘ޣ65o=%3[M ,-]ǁZrN{ԞN#c]4PK7Zv.'gЈopK0_p67^Pz>턛3DxlHC)Gӣ4w]xSh˹s4t@i`aGfv_gK[6(q) m34rVOucDwn=737g-|#Pm24.5J#c $t#oIlƂŝ}{wߖM62jat/9382qa̖qy$XyǘBw5y{>Gr/"H9rЧ% /b1|l,8wNNcФݸ$n)ԭjʋ^:e%DޮgN ܡ3yYܓ+I v=Ŗ(ǒ]iGtػt4논nϙNOD)7~dub]\U/]fxpV8ʵa,FM/nN ;47ׅYS b $ەvsћ%a<)]iV=عes5yv佯^_sQZ87)'A E;ʝ1:$Wq}΃;{7k (F<oa"Fwag{89tF,/֝5IEE-=E)Qj f$!M(4N-ٱoFޯ<0de\ƕ;u4r]fg# tk.Y;3j'Lq-/t'GwC6u{^ciG:4M xV>\;FXVn3kV8繇.x]ou7vS AM^GÉkm̘nܸgekG;YzJZIYĜ!'2ͫp>\?qL{A'- :ne3KU*yYvϻ>9z xtⓣJ`Zh$.w^gǹ 6nnr̙2L&ływ M-$(2:"nB+Q.o&*6λwqƶÇr}XA#)K uTPn32ZҤ}7l?ao>/,c's:8 vP_Td;Hq_Z23sK+lqde LPRBŐΌ9Ms- <89N1s NvTrzq h3DZߵDFn]m9UP^#3Jti,Y$a9>U+O$9ObzςNF6يņ7~]?,kD¤C\0TIM,KJ ayd+s^rq.jAocd'qςm`  =A3 Rҁ$J %[D20)9.MC'nDM&G8fyv\E݂'v:MSjpw0H@-ā#[ԢB=a@~3}R?fꝶthś&=\5鶽ȵ]zp# 6|.tdϵfncB`ECL/,<_r!ͪBHeH f=JpxĄ6๲Kf*v"cxF8,c HgecnNę!"BHXxiܘۣ}d]Ea0ܘKh c.)hÃbi*Ǜuu'׺-tg+Ē)GzVn\fFr<8S Oj\/l>0Wތ yFl)1xZt)h1w$';7&ISzo3ùU\[dկzd3-o C^;9}폾Q[u!-gl]«4nqbqݝR47srL՗n>]0f'kK&e8_+_FkQeTq̷~GOlؒ\X3pӆx\/ ;7d; :Ny'.;׶^Fz}F8EesKU=W\;Ϭ7l~6a:i[< u5J>*.2Hc72e>"}Ӷ0z9ܟbr)yoRKǨ;dwmfwfQgY_gusJUʝ{tl <܉ȍ1j$4wshŠ w29/i]PhɎ#};;g}˫&ur5(E}{乻wnhdvy;ʼ|A*չ9l$Bz{,r0[wN1 |{Bt9xyp'6}#f青Gb }[ox8[3d=>2<\#77fNŽ:Od9dF!̼n  `Fǽ}z:'exwy0˞zM[n>]y{I׫2jF%׬Jj}oO Y"tc@ױhaXŋ|=3d"$zynl2qO}.~s|QsR:b5yCuggԣ/0<>~e_f5);/h]rڳ,s^[wyM/m~k()m;f_NM wpk a^{6H]0[nX]7×rmh{7ʳL(Q鷴{X>{/z)y`n Q7(vLj9f矲K v3ԫ]xqnt>h1s =gcRW471=d >8QSja)O%Oh3:it2tիd[5Nfk2\#x͹J$ -)eE/ 'nu g 7GLħ"֌|Z;p!gyWԙYLdcA{_}}k}ۜo$Ny%])!5TV(|e6QŮV{GzwN{[׻d{J=*ǩlt[v*wlv"6 uJ4P@4xWvb80qM'߬X3 ,OWyŞ-<}A|BEyYiC{;j9'OW^/u-omuM}9Ѧ:8ujt>'Ir>S1YX}åWXZ Kו˳7zMi<j8%'2z|S:#]:"}77r9{dz_K9;ܭw=j\ÞVQ[5o[^tgio?Cvs٧)>#Q)'s:>~ ǫ':#wݞFWqy |iHt lpֆ;Vݍψׅ&&nv̒=}/N!jZx3]yr~=oCvI{,n̏s)nx7*pVپ:Y)M5:/ geeܺ ds;cnwEb~Jއ H'aeveÂ?0P Y{uC2p푫݈97XuT=_U{ޱd2EoL󏲵sngEz1SwC޴qN/@TNԷ'i%t޹'S &tf/+;=T a}ٻ%;uթۇc -}7HMmkͺ2tN˘-*=_Uү`Nʞۛ}y]TQA,nz]pf >{72u5\3|{2fo ]gғ)W z0՘ Yi|$:e؊3r Cv*>rBٿcX?I>\T hQC>dz%Ck4Б&2kOzw+9ex矼A6xr۽{}=h<]&h)kY ="e 硣3_Jy.=i62S=K*h ZZ#hտ.sw?vc uCyW=ʄ6{ҲejUbCjF2vDK={4u mXؔۉu<\NWN[|ͅV7|0y{v1)Dw_?9|xcWyfB}u'w,I2;j\2ՖE^n E;{ψ(l^=82uzܡSγQyů%c"O.v4=e6x3GwQ|n2MŶC5}m⑙|DP|sfGxz*)˳=t!RXwS(|/OxQ6^74zӴՍvOYmE :Ԣ)|v:Y q)NԜO;='ny,bѾB뫃+r&=1޺-*6')Gtnrq)C02z ЖGJ\sNyz9<2lV9ޞw-<+wĴٛR8 ˦]x4_tF|̳ ؇SMְ3vߥgG4!&)#SHu"N8#.1hI{THu!IQP=n_i==\#7ݕf_EՏvd7G}2^+cȸOmcÌ wG`x]Wi7M }}uY{7zN{˂x3=;3тlewyHۆ}<վf-:ŏ Os=ےm;*}[\ы]f{z|[OOO6zgIm{ϻ6,)WUjn#TKIl{_,~#oMR=[X\Ԯᅳphb:$j#F^nk1>MQj;FzF>ޱmՊԮ&3HZru9kx|<Iyo=;Z'nu`31^Ζ7=3tBn40sE]BrL=|VWH"{q,yV!iվ,<mAj0O|ASr}f1n1hCu$(B#C{M|rLWe{ړǪ6We>4暧zݛ%g [ ccnv;[Hخ `&5 e~<{oWTq=uB fڲeۡ!ټ{NOwU/%l^}qPWGfMuL3|p0l#h7 whl܂%Gz4e9})wd42蝹vyoױvY7=:_r,a\;=qɶE<<,>.l'Z?fR̜=tu^=7GC Lĸs uOׄx$Ng'(U3'e#']rXŃED8Y̗Cǎ{m#hȽnS57ja='}3]z&d3'5=;|\X,I`aCh2z'^!=;x{6{3`s)[\ڪj:ӛGエ=/j ̥#ǬKnT=3!أ_tA7^ ۏw,*=0nj:.? (~b!_α{nmK8rAnKQߡxC)z1g˵ 5I,0邊CFe>Xfe^ tog܋Ro;勼-I <#-Om%4/zÉ}vg}^:=ӳsL}T{f-Z^^%z^6dAGǖpGgR;4c`ќ&{"O2;qk(Uل[܆<|hT:~ιв8*hbgv^;$Ѫ Zf9uBtȻjR?zZ=eQot㷡0՚&q mr{by׻k%R7^YF(uf . ]{ (j¯oc">gogYۏg`۠>f[4!|xk}Rƒ#pa[l,":hNé1=.OVbX-. vnӚ;&)$dt[=yjyv0ϼl_v(6׏fu"h}ұ9ww..')ϵ?%Ys[O?6auOAN Iq}wWd~X+gu#'74fKy#7ōE@yЌue%w4,a1L[~l 70C)i %#Wgw1'8GpO3-> f093Gf&5Z|9{-n:7*QDs7I&=W}$>ėHg-^yH"9fsqfsÍx<~$RbӇu9UME90h4Qoe$8CAgW$>8L}Ȋ=Od~x+׵O1 8 =4!]㋻l仠[]̽hx|ަ<9nM=pl3Nǹb󳽣bK'g~{c^-ֱ}ossB8{'{'xٓwQ ]S;/}tu]J`.[QW'/veGKn$5hwhd ${nMs{k&>3rgi+z[Y2^= };؅bA'r}Tنoia&Y]/>`ΐ 5ak>2F0( F3]i_yE}sL0FAihs@8Ό@'(gn>ڔ{4H5 w9 @B\ JwC9 a"[͇5p[t%g<,ݬ=GxF1쵙Y}c}k: g|OnB`uDߺޠ`jjGQ_o\𤚼4('0s]CH(;uv_f|:c.&pg,}M?Y|)֗R^_qd?L԰佊Pi-6i 3\dk/&rF>۫NÔV{WyS^>V_ib\8Oyϸa>>Nw{OR>(#Y`<ЧO13YTPcD:{MǕ/\_ ƑB+I!/{$0O>-׬@OlD瓦{fblT]>DwcjEՄT-eX3(Ԉb$2}^gx=qPg*YG5:~B/jwȂRFh? {r=7{=d6Hv,dV%KT轼ob3`M;a>w1IA|߹7k8s?nh|5*7usr|9UOԽ^x(7du U;6a6()xV?f1 C}4hǎho3hlG5l?Z <ռMO} J>2O~)Gx'btJ58#&fyD_yo)~ݨ8wy^z^jfզڽ7 2>SvՆi1ObH_ΝTy~{f  u(Pkf ])ydzu.tj(RѿL ,ht!&[s_w_{h<xP˩h">0&hzHigZFՉ$ 4NP8ם~vLIIԝ%- <ٲNP2N,$u1Q~Bcv' M>yp8i5fgO`Ɛ`/Nb;0'7kX u F%BF,H/ٝpѠ-ACcYPD? &鄎7?f]o<3OĤY9D}~mu63ɀ(x">IG# Q<\(X0 O'4x8K4>[Motg^5|n7f^>#fe3~ϴ~c|ɴ>O_>jYLdg$wGzo[׳kxA@Q{*@ѩIĞysMTa!.=9ܸb: z~{i/|:nE;lFg>/|AA"c߅R& OJfaQ-rd{s({uxv=Ď|!h>=ѕZϐeΚh!~0(cNK<~kKs&Xi>4mdolǽzj L|1/4Z xjh(9rZ( 'ϒr|]c hRQ͚bw s[p~x5w]{`R?4%xCXV"DS yu)`T0 23}B?q/((> AgBX\ 3NI~T&ʵSb?e'<|&tZ0Ǜjf&_22y`ɔkFMֶFn12a,L³vhb?q8rk;ȑ+y+Eo˞uO/-QW>8=.xaO2p gTy _aEfJu)2٫\U5̎^w1_G4<†}3֬ByvAH-C٘P'pO 3 yzCJ5F6uh>8 !>&hh3}鵞ѷ>b1_6>e txv/Za#ʾ r(f00=N_"&&*!856 \S=J ߇ʃA+JO{ÏN'[*w,dbWH\ I-QF<(^嚲ɠ R%)v\ʴLSܝsv(ߙ  /O_Rnٴ30پ<߷uf7ǣɾ|Ͼ[ÜгAZAd8ܬ7C[S=N;Pʔ22C%OèNYSn*rP+Fݩ{g7o>9"C ՞~iA($J|E|xy[3ZS}a)y0|2~Y<<5>ʁft?SvtЏ3!D]=&9FYE* /ՌB1x&8n:naYeb76^nkkfkڞ>XfXo}Vxh}AO_[w!~L{@SO'Y/:{ylyҟ6m@ 6xdK_nqA3zᙕֵy{I׻ ⟓w|/ԋ5!ǀ7 j鼤ꎳTLĥNefۭC'[y:;)ƌ5R}dT[@Wޛm9.=: &|}(Gws5_/MyoV}ofS9qpO[V7]U ݜ-1L~+ӢV6W>oq~k^w:)娨Dz)͙3{:o܈>Ú×[м˧Ã9w;DgggEhXfty-yRaÃR̗h{W!yu|7/9l=ޜ5a\si9?ݱv[2l7iiݺIk dǥ{]7y97;qfs73>xSpf8&vB+V JU5]Wx}ũ#o]G+ s/5r˓В'g,̝zYݏܽ/ ɖrݼ%֮vX8o.,]C3w)Ggx>~3j<ւYDe7Movm9eܾt6%;1xFV{n{8noӯUOmIܓ4IHojZv%ǟxh3gxzyގ7P{I {(c]󄧻6s n=ރF:}e &&ZE6t,ygvG}E]{ݜ>7onj]snZ|?rqzTW{E!޺]v5wYޔ,znkaZ9!wk/`$um( Hz<̃o!>3M{]ν艩}4Pɐ齞vݽ5\,س/=ljF9:t7)J޹֡W8y.pTsEG O&E%}͚Ο-h!xCAU!v p7_6;34TVwz=3ڈf9|- 软׻.Nn.Ͱ [^|{xZ_ /7QwiIzn(ow=w.:n\}l#</33E>v菰+oru%/aL3=33)kf})ZMbSs8t`}wy׵9fTx[1eO/jo7EuxqeCQb ɄXw ȁ/f_^lӍ&X> c!έUڭǘն[s,x _gh~8 nC7;w9]>+k<aT ڠNz}FPNa_%7l K}:F^Qi;kzO-y|N޹2\!\^ԃfvgr q{ow?kK6X|o3-= sg0D!#PvVs(GrEt Bͳ;wcw* 7Xa#.2i`L/OO}:L<ǻ- 7Ijf uV$#)NЈX u~'fO}/WS?xz_'>V/fve {ޯx^7fs {bM 7fckWpf >ql&0N&p;:2}Q|zq.xmw3籛}{e'$4'Sq"AAn136|e=O$;+xQ:vH/Gs4w]Iz`y}p%ZKt6KpwO앂 sҿnyҟ^?Cq%Ɲ vܽ*bg_Sֵs(o5 X;f5.DIt<4N ~mgeQlr- qaznL:38.o@^!H=ޞ<ͩ 8r}>A0#Ru>'R$$)>N}7(rḧ&9x{K|:>%DXIctYd.rq/}wh|gV^(6tv:g{Co95rSs׽ڊig{(P0/M2B0y=.yR~G/+<ȓz5c`$63ٻF,r^mu72؋6wQ'J8WӋ' HnDԟٯsw1PzO[}V 1-9MFLTsi{ XAXn9gVI&C)<7{շ}ڤ(f27Vp?2؂=;r]sCge^j \0{厐M0FіAqong-zlFfG&Cz͜c]NhCW9swzؚ9gV q'Ж2oOR[к7Op);^I*sa #DA6y\KhLqa|fb».9 ,H|Ƅi_m.°1i){sɖ`9D=^nVf!2O> NzuIsݭXފ6ם% iG@Q+Ӌ-k8bvzOF[ ^"b[z 3<^ ]kK#~̰')Ŏnvls7F̒Hyz=l.{׶:hcf\_^̫™ގ҇&cnߢbuwG/Dt +\ulu[Hoj;f;{;iM M4G<˵'k(:'7Xe }HiķɩB28{YTSvS_u9{{Ûڇ9ycݱ]Ft^w.S'a͜Xg3P'e N( 3Ǻ{Fˇ;kme'Cػ›L /LMsMQ9fn0d*}o0{x2x3$sÝaYϧI}o-5PVjl؅/Oa?zomz&`ˊzCݐ0w 6oBۏ锨"׸}iuV5-mJ́VcLF`dғݔ%e"o(,n$stᒝgUČ*ԍw2pgDpg׬6 ̥ܼhvWlY4{V^[ַ=FLGxs=<c7=ֆ;嫠%Ǽq=Z`QÎfH%jtӹ[ྭzd9Ԇ>셉we⭪U^}q9~3|OG!1d'܋A6jMZ79lYNqkt5{z[B;XB"מ'캶0Vh~~x:G'N-p[$ոz&{r~o7}ۢ zkU&ٗ'\sSW NfB'9}|,bVCFYR,ڇ{щ3|ޓAvɯ(}mf{ݸ_[}ifjktbF^֘q5BeX f=t.ݜ-zf쳐(}֩O.u;!>=A_ZT6kkBwcLc-vK+>K9H:^J#f,3WKlZ{ 50NL^v/[qӳL'ݧՉSm|ڗ0f{WxesrAÆWãq]ѳQULmٝ6Ls>PyCċK.seNԼN[3fK#YU+@it>7Y^oNm7ڒx/!nը)Ebȣ|aܢ߲\ޥ ݼMN9O{ v&Ml\|,~rŖg i{nsj)_pOs7}nY^bW9s>fw6\3^˽ū } G:pK Ƭ;nMxĆÕ\;[n鼷lj! (xBGJGkɀ׵ WJP!.[쳠g5$0z,fd[]szhM9ɬA7+T{\G8gs| /06X7Sf#*~_z }K_7N\m&C#0u]o5 +foio}ݚ:D ] oA b;*f{wbd-DlEg\~{qrN‰X1^Յune,vwtw盒S-}'Ow=?{,>p8n qo[w5"0.<Rd.FD.7(wYtkq}+ϊAߤKq$,/}=c=x_dnJ8(G!&3=>]ل˸$ܜ4*">'q{]em6=o \0ɚ-y˴݈fuֲA}3Uهsnne۹; oL{r5 xs<'d{|QypuR!,ײܷޞY/{^j4_\.~5cǰi㫻O52lzvywk- 0,mG\_xOq0ӛw&^e2=ݽn!F&Giu#wof&}=v|}F5t ~>.{kv^N%2Th@jޫCl=Er0Rofdi~Z~t$: ŷۄ؇,%zwgr#ŗKGz%{_x&4~G\S=n]}';1obvRSciz33aidÛ3:dR<=}]t:`nf+zm.ݓ7 ׹[)΋=%/Jy cTd*( 7cG8uM.L?^^ vهû|3pǾ݊ۑK{K^[[[JyX+$@#p#k,W3L .V,&hӨ^olOc5LG8xRK!qnv<(v{.p نs8燽NaLgǿR.l|KZ|z{#4@ns>A~_g,olHtzA=Sn!QLHDrǎW a]I@B|Y<=EN>MssEaDL©gs~ Sx@=3nf/ s/Hiι9ktƒM9JWѣ-y&`\f}2 W0vNOtmjJc|Ӟ,T֙J ]jλ&ihc|XhɊ^* toaZO|1i&2yi7OնޡsۍFOVn;t+W}ל`Is=b=a3 ѭG]>/cf2Y2*NuScNT xsϞ/* VX&luvbucI6f7l襔~0Oh:{!/`yYlBDksP%rh%C"٪$Ŋ4˳\c6{IA\33Ap"_A{D4ȣci`E=?-ALbkr(4oFQ&eyRžڼ_fkuSo^Yw^bٿ9=&<7I;_ v3|}UY&$Ӻ`h$%o]ݷmg7{ZZ\O+9P&89=T$囊Zf=Mʅ*5gB宋K;]gsC{vw'KO6 gMf@ֈȹ^V<w_oɘ"U= N#qvxpQi& >( Af3`>≬ncY&H#EDq&.<0n&&Y&+~9 uC!.-4_Ԁ>j/(|=Kc҆NQ[0+[(up :K>Bbqx[T=|7r~]^P y})jo1*Bkkco`tV}[|DxȪg\j ;ϱ;]Ms"~jp;ÁQ[H-GTQXچñmQx Aû愚(r|=R6Xը{Lionww}\JwO\ /x,9^D.ou 6M)ot/-#K}%>냆״<}35Hgw]'Tޛw|i{SqRa !xYefÀ$р`\2|l"d2JsOӖ!"S,H]Y^=܂z6^fyZ4v"b}cnOG܄(ӚO/]yxEj,,xffK ϕ˝oIח')C<\Pgy[AwB3'4*#w:2~n)bh4^E$&̫Q|UWʷRIɑ<5氘pM:*|=Ƨ6C(t3" 9=^[vo9y'׊ .G|T>{׫ײm:xA3(;ŭmdgD9q^o%>\Hf^/ <.0oM=kb3{D7YwD}e{ޖ37ݽ|ެ/x!ԪXN\\uto*vqD]4\z{7yj瞋d4{iѝܹrmqE@Zx.ҋ4Aj/ aӻ-Q ґ{A$i^Ӟ/=whk8wM.^46ex1`!-<z^lrg VZ}Ȗ{Y7Bh3e)\3}ogu(z ;};ﷱO}VۢX47gm^٘\Z{mݴ ;8mc 49im=1eLYǞwo޵d:p|oA_XP緰Ɣ6{[)0>!a e:iUnKkgGdzG.o iRKuF thD9uff wgz6~^viSn]/vzm&/{US쉞xguUI">9wYoBOj{ITE釮Q:uQqXSM;l]dzc- ȱM+[ !]ƙujeu^꾭D߷ 8vgR=N}\7+:>~பW}Hb9ǧv=rMܷ|b ӈ4M ؆bjؖz' vz4{ վ0{ Myz|:qrG6*-2ܳ<ߏfӆn~)n>\\Q5(+2_ eo}kوGNg:V_vj1c^D~>m|0a`h6yi^s 0 ua H5Gs5;⺇_W'z|(%|7 ~agͥEh)ԿnTɐ籡cͽP}#ĩMWmO,'V̺|m8ap`ŏLݳA %+o+!=ܾOZ1YV!A'ɽa$W&`KG'ީDp{l.ӝJD,;,68w8 3&v=O*#Gbs=pN ug3 cy? (=$qNf (cB+ WS/utx8А%Q K2䆔8y|/J/l1sznQZ ~f&3]# Q16(ݑ zHl-#z8 /Mq$vۂ}%KٟGo\?j}R-32f#Q}Y8 ~VrLBl\3M)rO1ˣ{A_留$#A/ 0>5 Ro3mfHQ9b!xzC8 $ze4̓ŹdB[*r*5O4||⇸Iݓ'sDiWNWHsj9Y&ЌkA a݄8"]vfwvv!1dcT<)+840\f"UǴO=(qof,/r&,؎fUCC\X/NK`>fXM>CYwv aD>@<5/j}2LW0o.]3c[zyj{ ;z s~θl-ߜ85׿ce\ݵlXG..eӱMLJܴ$îx.yn|3WCݗs+D8[BQR5^<\.Y^4zb #qڴ#Fs};] QvwƜ=%M3} Ӧg&m.\K&Qپ1UNдy-e#hx]8oxZl{l3;wiNGwrLzs קMif'O ay BTyjkMP)j\£ ͊k{0h1OLS2='&˂|!A9[CcVpۡ>3ݘcJZ-!pS4>fd\;@5>Bdad%k sl P[:{4iCʁ8urn $\5C$q/HZL;/‘xKqzǘǚړ=祏nEo0-ĻJz9Ŵ%س`ꚲ䚍dS:1=wɦ_w [տ!=vn徜nYv(ZBbZϽRR5UNYۥ.{zU{>-]k<9[Ӿ`ET gs7&iowSQTW6:W+Iz/Ю}σJBItC?2=ב #vR+Y[@zbsN9{ۖ ¤-436C8,줃%ɞrnվ>yq#<l8sSMwwin],*ՆCX81S';s.'+Axtb:VwMnX@P#s"#=:FW5'MI.wz z Ǧv#gGoO߽yc[0HSE#HK!3W7">B_VW^g֩&QӺ!LkҢj>ffmk JU3)fz/Plk)}PmAwPeF6ٞ#犺^xyImYMw1 {zP?19) Nh}s,jAIz>0M̈VI 5ѨxiϷ2G9ާI=yfBl @"g9 $˔!zϏ{0PƚA9㐠aE(:84o]X/6M*Qqxlv͘XʫRI D@3q6FKRJ3X(d'dm82b@F& !|VmٞK yWMRקnQ[.m09 5> a&^ZKH-؋r/-n <9ˀ~wOƌʤ`E!G? gΫIF<=!Hί6NSZdaq~6NEPp ʑ)|/{8H6 :U¨Rǒe(2*>Kn?#!ve2ժ*,<6slݚo7fSx"'6LhUM-)6O//){٠6{s}>z sv*4$pԅ'Q]ݛ^S›nˑ2=:9V;UG\6̇M9!ڑUMx uI~u9٨E63͐?2C_bqDM gR~,3U||4[!.  L5n0pN: }tr-x:yH̳/nYة#n@Ϻ A8[͙vچF%I佟wի*x}4HNp[;u2'n} ~e[c ~dAy 3;i}~yf\w.󯳾6W"{R%}8:rᇈQzJ^k/f5Gf*&2]ht8Ȼ/~Q{ *k)ހz`{]ބ"ƨC98l=¾v^oP""ybf7= ۾c OnmҎgy^`:c2>2Jˊ^ndVp\5+/W{EݓGga=ə[r 2rd-gẏTxvn]o޲p9tXO8zqfz3}nT$Fv^.+6oDn_o uPu [pڷW^ȭG0zN|'^R>=3ޞ0Q]-O EJ^3?w7O wvf`:}Ecwg% nȽ70Hu»<ӧ~gRI`JQI܂tGfx! t^9~WD-Fz5uαzpjB$ GZ6GZu0>s"$om"BoV?/ =y0r'?Oъq""Q3lHao&i2}ՈLyZ9|͋NbHqC9n|> ?X7df,xğ`W a=MNNb%a+Pye:]xO l˃xJ!Giؐ6B"TG@٧dL5 hw\K|03&_ːWӛ5!ʝ}쪊ò熞ߦկ\Kھ(rUad?7?W ~=O>gC~$T)i~FOv_`}$샨4dFD_Pұ/)0yiikqwk#+Uy.L{<qn=HaT  Px8M!<\F)e'%xr}9k}˅|Jin/{gв!\gU4^~'"opV DKt+C #s Xҿ>@BFa|1w;5s~!?-|Oz}w&;l() :X^ .ms}nzoyDsU$OױxbfgŽPܸ(} rgOy9TxIw%GDQ;2abeAUspYcI#$1L* nsOyjCd[箖3~ܯe梩!nN0?v,O?/?}Zrߙbj)|ʉ羌}ڜTm&.TǟW>n񳽶2wۯN|/N3)Rſ|q{:䧶 {"E{AN-;ASۗ3 f&iO~Yw' ]QafzWA~[idGDN^=eV<~eD,i} ʒx_gيEy_I?s3󙆲v p 0 |4,?K0*ŷ{J.>ͮ iϵYs0w٫}ﵷjE'H]<帝m 9aE; ;5CҴfz=M; #Xq8tq<<|ߢÇCB>Ma!U6A†y 2mņy 2/<G<[Jy=GS3k2#QL:~,oxRW) b.c2On3m:B>w6ey9lqE8aSrǝђ⩹ɋ6"]^cS;/'+QOvzluIe||C#YHǶ4CvIkyu_=1 paϰ$oOJ'…=\Z/+$0D GԂOjtx|}) }لYՠkE T>GW8p=ٱ∛٤ĸ]lD2]r], ݲw68wf+&,[*n6۶ W^6pk:dy @@4+ӱo  '~zoS+ݵì6>輪](pzdv/G#*$1c=sۺ{Wn0-Xo#w T,kzq|H taB>>Bl}D#**>N=ǫ9Zx:Wï~:2m\N;(@ybyWGsQznQe>vKrwwݟ.|G_ho1_5|.Ak~f][9g€ 5>Z 5|k0}}歌,JVֆFuǪhTR1(G $ĽMvu!XOG;U)]گL]jP2OFeRl#{Ve0`"kA>|:k GIE_^m'&y)6wx(FC'xuͣDžgmx=!{O:͇(;vR1LOF#R>ZiCDJ l"$†i.'G,)bTv57iGgs4xn䛉y9BmXgXƲ8y瑷_@ȻNe@gp{)9.Hv$;M'{]7c3y补w63߭UkߪrFR$ō6ߞ>G9ﶆt}W!Jy2{I1Ode|E6ߝw j繸fAR+}gxJRmt]OxLݎ)wDEk-WcUhmgHe$zN1W.:-ޝ=}S h!Z 2"CZ}Iڄ04{$7ZRDޭo~XE܌h84;MQ!d~Ceg˚ӆin gL"l) 'z:ǼqXeFPS|.X1ܼfs\Vo]=l̾{P͇|r^"DM-o%އav=T3.1\s\r7BD 帙f@޳qq^yr|a eB֟ zJ>}w/03l>9X9齢b8~\w:X*mud. <Zۛ &]t[Ӥ?o߶|OS63?`t9&C~O/æp?a~2#J|vQtUٕz]l.y.Or؎HuSkj"v`ᶍ%Nvµh`0VMKFͻ8(k\½n~k?fXofY+*d sw[eg^N-~Y~2r][=YƳeKOpYpMFERv!y_\ݜ,Mşuaw;xq-&K`[\o<ߢg܁iAi4U`<8 !Х9 Q$rAߔlæPd)Ci $Z{~Goo/ Y>=]R41"qG|0"e- K\;HW8$id/\3BuN}'alyn3j hsw7qoW{w`̽n'y|/g94oeםǵ7zc^`^' _A +ݯI|^=P>r^2u!O2|Y}6H`,ֻwdpvh8]ɳQfuX!Ӽ,rny]e.7ݜ"O|V2L=8\ 'fӣ}K{}re91LXw`7,~;׽hݯ,#s%FA7EX|Ò{=[$C3`#~ݰ3~浪Cqw4y+GR~o1h5WI v8ٞrYʹPӞXx➸}3ם<'T*cf9mrE$[sjl{oăUbTŷ e1~A?~%ac2a<=79(&8<|twd\pe #҇%Ή; `nU{ݷAxhҋ |Wy=o8wΕ}z{f]xrwFG&{0U KD@y̾AS{kqnp֏Bu=%Sc0G_ßb^Nzޞ&̛͍%.vUz}$,c#ɦY#Due0k`r}E-Ykri:գwڶQe=O[ai,Ed~'~}Q`/u"T̋08}KNr}U4joSxjxo=x.C3+w:+Fa}Q@A}td=y*wmrd2@.b]奢)aƈB7Χ|aSyjCT9dDd?jȧxx~MWZשb1d:s5ҍu2w}+[n L=MLaN1dj&7ZagW`$uWT CV#od*=Uɓ܁ĺKп:M~qoϿ_!Ǹj!Ӻgkt@4&RҥAP{crb#}@w'1_`*icR'20}U|t cm\R˵`ɪMտfFcnsٌQ4ّ26)M]*u=j͈lhhuF;SqcٮHnR2mWj<#Pg0di䛍Frt|w͚$2= />?r ߭/|F!Qއn^q<>c홙=tV~-ws5f͸GB"g|݆wQUѨuIu} f՟bʴص~um8cYM!`*k,٥6:ڜ?~]^ʧ;nWV bE1rrz/saQ<ߧk;vhr$w3=t_ӧt1Єˣv voa{Mxy}VeF6Cݻҭ;͎E2x16;vN[dlںPt<|~t߮BD; )J=2,\:jn>en ǦzO߆+4 ?s^w{y|\9}מz>9,w{ HQ! kH$1?$L>evE;\E#% jb?P !/E0Sо%:_ԯx?WKvÖ#;5d:Ug0,Zœ쌦3Y}ڶϾcV2y޽GU6GO2;s ۑ9.H;9>ٙCRE-$kP>Ȳ 51uzT͛S>Gq}~qZ? z(֏ _xn~?}APfN<58`W$= e|'SJ~Wsjf&T-j84ٔ}lm.R5[ү[)vagoF.0bWeqg𨢞_ԯT*GCYK7槛϶5ڂ ~/ 1&vqO[l=pΡ!viSP 06ǖS)}>|MBI +ɹ}F%S$ i1%8$8V)B!L?tq99$߸o{[CѴ*ֹ:/DR()quۧg]~{ ۩z;5H)Sy/jOtru9CF]|Cw+r;+VqחVyh̙xsc#Q'w1#cx!Β8.]w: >O^էF f\>3׹;Dk狂a7XW45C NOc\fnVSoo#yEǜ׿a6D~md[jC3T$xA 6oxDT]3P>C2exÕtHE} jC`8'ynOw|nor&%,-,(54[훘wݻO>j_{>l'd{;=@zZ }lBeydëXRg[2T,}'j*V iy!5x5*6oܻndy,"e_.Nnp'mP-+Q7+Eq}Q0&-0H{"ǖ}m[bv YI2S+.kz ={=w{sxjvU] ,闸1ya/+ᚫW=3i8'nKvn}Gon;S4cMmNB#Vu}7²ش%\/q{jNO6`i#BLa*!7fJAX对m',-Ipz%-+NB8jݶ\Ń?lutd<;g"KLƳ<= u8`Pgٻ_bY4ErQnu eWR?FNW< ҫyv0&N {Ƿ:w"zýèC٬>=:`Q'&+,CIc2abf& KUxsUq)mSw>doeTu۶eݭ.뛹SA|3fd_6/ռtpf;-n9giMUx,s\վ#w<-NoL[.ޓǥs{ro>wmw]ONx]~%sX9iXop9pkμN?#O883|RNih)w5ҏ4m9 " ?6\ %̌~އ x};붏 cN? g$OxQvm;ѓ2S^`C)b/j+W\> o>]8o7^VI$"04[bKn#:LTuh'thUed7zr7R;< v{؍ _vkwԮՓɽϝFi ̬kW-crbvFބyO=8L2 lXA{n*da)Z[K缮Aj-#pU:6> 65L=nuw^Bhg!X.{zU;&EnO p}􏴖F`R{WYwaR3^vZ }s?\04g X^;ݑ̰YӡL-a}U٘Ki-/i){O_vmO/sP}Y{~pƺu|cA{{1 qý,aPvVhG7=G t%>EZ<@<_Aqf І%X;8{ 6U-Gc]Of&_>I}WvX R Dۉsd( rňU>\߯{z 7ɻu71pC0u2^o#?}aܾǁAÖu.P>4}hIacCj"psk{_R+&Щe|O>o1p/R:MvjA_3)71_ײ=̞$a^]< gx)='axtze=x 7R(?ptPC`G ؜9^99Qu|sa>sc|¡ K}gdw} 8ȐkɘaYABФB~ȱd}N7h#Tn<&Ӱ̧ "g#gS.k~]L?X A9~Bw, o`)"H@rSi|*}aTNeK^J:~$i#e.+&& i Ҟ]f EAH#&yW|~<'5 ~`T!se9ygZ"XQ0؟^I?g ?x]l~a".̕?a`'֮o&sOKu\dxW%5Fn8' 漵>"RE;9=t˛|G~O~up {'c)bB{k}5r6ӝ û\}7wo1`BonB&{~8ji h03kـ7Q^lRƟEc|dN xDHŇ~g8~Wm<|:_pnM/OO¼=4:Ol9X0Yf=6c)1aέNJp0kzMaY+uڲ1)Zۻ#1qy0@j@D JdT,d+ ^}wt[,ߴA ?G8M$𦂁Ğӛ1FMǩcsmtN/M퍧 Lő1=|+ƭr/ =ea޻| h>WLXLg .(x#5~.D5 8H3}"ElYx{ϟ)_ݾ_|NP篘=\_"yE|.6V-Yc. n1j7ui2wm1aʳwg.͍[0WLTҍ8y߇X^;7!AJv]AQTZ <Yg|>^wi 8_l}g/f~+`ϻn&@~rȀڨ=j ceԮ>Ю}ϻiC gW+ YWӼ>ot{ݲ3wOS'2Uo7ﭗBxmbٓ۶lG;[ae4CǓFSJ3ShqUqxp8d{>/Q{*rjQf4o%$qչkwGr<=>7~*?~!{yR4_,:?/}G LL@w2vhXGIhןf s_>ē|wI0z~ *|aC]Swᕟiu+][pɕm+mq~ڛGIfLϾV".1Z:jlC0nLdeRVy5ݱ܇=}{wj@9)N*;dc#W`* .>wϽwp߻|6C~?n==|p~~Ϙ@ 8WXGhOsI'D5;5zoQՓQv5>{{/fxo0"~`"xmv9}MU; Nd-SzjNݲY6Fm+2zﲙ YY^wSCͧ?.F|@N{&5 )_vpރS!zk9dwZ|<S֎]~ʂg~l{k}hw@N's?~A޾Ͻmʰ,9?'S؝K|lKC~kWvM9w6%g6ّvrVWmV/KvetV:ʜSXvRhhj45COϟz_۩J9 HuCwQFP:ƭdw؛@xZҨ|lgMs]f|tn+XFyO2b8Wo9C~O,:p޼=Ak\I[~Z}-Rp[ +L㘆(UٲsJ.wtq&}TڪV0W}ڪVujl10Q[OVMQN"**"bwuk˙.g7llnyIxCjq9((M1)Q 6ZI!ASs'H8r,kvm7]k[Aw9Dͬq m*9w~7|na[wwS!Hv81Qa|ْ ZgB"v|}8@$x2Lb5HҧwC8t &$H5~`"LKsSJ"ӿgp,wNs>qp~K׆O}~2y4k@k#4v-1zpӵHʮ=T7wvq4þӈ3i{ ѻg_YټAUf\zu@9xgfJO O:!)5'96BiiщB| @YfcM &Z_͢vzgvQvOTQ<"X*} :B8;se> Wx&a5Ãowɟ# %mr؆ 2XcYRY[sk?HyBX {͋l[=iߑm_o>U|CLC߭.J~j: ˍڗJSlfG_kI]P2^}M>] 9=9Һ+ln~|!3?/"I0}u%#Fr6ׯ_o ͦq,BB1͞\gx˰rW/TO q!D~E2>(:7.m%{ap2geBkV>{|7XP-}3GHgj $ Rrc!1i$l|^LWseцLx> "A? >?V!{\J3I ( ~)!68N4 Y@FW8~03u||y߾Ǭ{.Ace;4֘`QqB"ȓOQSl6qhQЁGƚq׳hn0Ӽ vĶu=݂9M4cWK>ֻ-"[%Dˏ˼;e9 vf{_\ +pT}(e޹ǘ<<{]e#fLіyew<^$\K47 [B;j:ĺ^ ^N62QzVz"lK9ŀcL5޵m3|w{kqs3\40#9ωUO4`aξsh^I^'.z}cb{{;8u7v/l׻y X`Wof' CªwM_\$\/|}[LCٳfD!t^ސnMz~gXX[msZ8ərdb ;ę}^V gmf Q좆]퇼!{UA =G:u?}]G9K=_d9Ic^D ?-xEcgJ?^P3P"t LgJ ?#& 'I?!0s,W}0B؅)%1KW'Z/%xQNoqi^ zڡXFJxZeC||PFQ1 k5goT &n ~>f_뒧aYGJvnlCǛAft4==Mbw^s:#nt0 ~T2>bm] m)eú.us O\Nd=^Ux!ow 쀺y0~~T3n>e6tA~\ t>G[IѨLe{>EWvbsw:OH_n~H3Z3_j Gꟺ|eMh.r;'c8܌u횸޲ipj̬o>7dmtX.mJx'>t0˱dS`ndR!UQGnuLJ=4?z\>\~?Z(tg}h9#]]rtfGwa9H~\4k5}h?'ԟS_L:T^wƮc˻utueinel2Vh @;}*=L,zoe&+yÜw9Blѣ 8/}=?:{hL]A" kYgaL@|*x[߻?&=߾p)j "HG`D;9")Y)*< i zy+ ܲzwKMן me4m[9ǣn@w8P]9r~fgC71{໷GO7y{3wcF燺简P@ly|7Nz_N4N>Džy+}9OB@H]+}/,ci$aFg%49'S#ְ104D^9{Mr&ᆪZE9zscGR8*s,WT[nޮxԖwn(|b'¼o~1@HR7\$;{)xKB 76Pzs^M<5Q9~0>K8 *I^Qʘ?dii0dp$/B% Vϰd>o(¹ II<5Cf#fʍm`W)Zz릝Eu<2U_ ; wmuoؙ9T:%>-Zsj$1=.~ߵ:.a֭}+r\h\PS:S<><Χ9S*~ƈ2Rcg\> q6po'ŬaZ:ZmOsߧ xe3:Et9O2޾ K!9w՛>TщhxrJVsӎq]v6%M..Αswr֚9*r\0s~>8^9-HGFW%p)NYު^5vF^ku4I}xjֽ N;?IQyfu %XN~A?4C DFrƷ]W"4O}lI M呈ztr2?xӇ 6)kMf<),sɇJ[2ǖFV,j)7vSd,ɞ\e£Ni]B߳4{vW̧!eg6I: 4,͍VMDYsN3RrgK'67|爙;XY(]e;^{!_a]Ib_PͣD]rrr kϣ$D#QE|ΛH3cV S9ܜ$.G n\|55$uƶRv*mݟS愞'pKS_}zA{{{j=A5-E:U'NBq+u$]5G^%:s@>@Q?<}l3c#l6+3ܗ:5Mjf"{Fxޭ%'~b]> Io8ooT3CwdH7 ܯޒыUMZ~{ωIphz7l X6pS$Zg\&ԠAOxõaͯ}W)c9%z p36M7IطY>p*:kPcJy0f".-Xb~ե(TtuսLS%,S;|4osc33\L!v7c5Zy=xQ{~$HOH#t4{Q~?r}k7dqH># |>1!ι#Kd-_wŠOX}5= F1 :``ԃmkӎ*lŇ 5<\ņY^W1}aَ:}þ8hy/N&FQ>#7<%YocDqIfg;C:F~RL)K>,~c $cì>귱/~)p´:j[۞'6MxKgU>O^g[{Ɥ(;Z!wy˂}є 6{/]{/m>VôjČ~;MU-qFA~ig֋[}t-@eTPuVP߹`F$2VgL:P"~+/^fd4ʐ$|* 8Wؾ&Lǽ/o g*owacA)/JHS4>wl}gunn,#}Q=>򳠝ӵwPW2wgڡc }Z+7Ay$ȽżӉ^},j;w;f|(|޶R5t;-N|~Hdܛwd͏^s]}g"joNMGaܗIIs_v:O{}qB_50r < AQ{U^\%Ac<770uzG\V$ Hps>|bg>.&zOJuߪbv#LZ0#mF.z~/d ʻmi1sP3qlqtB oۅ'cx20Fֳu-i;w=|\Gdƅ#@-}O=Ftu>Gĝ~Bbڮgap%'@CZC8/ +{&Z=Hw>$N#X6穝7~\wyKZ[`p 3c!}(gG#;[` E^]CYy^8j^I+E3k}ۊ)0kPܹ#*w @4I 9POkCi-`uN'gHFSD?gKpi;.(ﰬA3/$>n{FHAHgng(n_xA0A=i gLH\*~_fdS$,.&+9EBEb!!qI$q_͔9'qioӱ4Lѻg,{{=ĭv 7EॎtFO5s22}=D꽘ÒOLUN`G~ܻ72])8^y9P}'av"^##~#0 H{e.0`u"AC*c;X)h0$%H|'_ jC'#?*9Ͻuwz*g˾ֵ[gˮk2놮gs:EǫâSl\u<*y5!Gt2RN/ب{A@^yΟxO D΄pNRb8~qFz!E(3LX:$:{w`A[s5$?})v2MOMSx{fC(>yD]&BG;k&;|{cR<&]gd&Z/z>x歾[t0ͥ=mPW`sIÇ_5 $rNu^'](=fqÌzM߳LA?8pr=mzy~>4@Z>9#F{Fj$n.P1`"4~^ E#sDR^X #I9x)~e [߱ b}V8'4!0=?r&;>ݍuDyg56UO,}(Ykmq)uk,}4A?xd>&̀d)e L`t x>S s4(!<\QQ,Pzzs0"eljw(7^{#t9/s4>,:'Re] }H~d?/#漓MSc`kG_&s LiWG@)2+&|>q(GNvhLY>vuU[ds]۹>-}S&Faֵjtw|ZnskWPϣsQuv:Ǚ|c32@;E"UP{;XOqC;a2.z~n{-hcwу çn27S/ 6)EĂ\j }O`e=k5$h;j2Nğh=N{[5V3=[4qwͣ vpvϲ3\qY#[-#T4xuP9^Ao4'61 iQjMo~>~uLzHQ`#C{ց2wA{}qᏟ~^K<xlU\K L1>gi儠 @n_KG kY3ճkY,[v_ϗ2ߣڌu! L" ZBA)3wrtkKP~|{{?EVfgE;q2#D.#Ϩ9JHOykʹ2I S׾ZzXGq/Mmm(כEgJBNx鬃u&PuNṔ0?-+Tz9em'yk#LۻSV2Rq; ڍ mY;ZڗTi[,,Y%#]:V,2dq;TMbvxs W,qF}ie@.o "Oy"'6!s0ʃ2rqsws^`r[Ꙩ֠)L0 >Yÿnr29BJ8VHQEdRC X{d4WQ7gvے}sunDFFdj}ע5#|s &kZ&4=)?!k r쓰ݝlf]\/tI%hRɗOs~sӟnee'^MJ}%}?? l0*VmtV$n4Fu2+cwcp&Tͭs洍NV1]Mde6-#>qm?w֞6Q'!qt$nO1~>ҫa=])ͻ%Nb}7={Pϙ}Υd/fAFʱI{nǔc>3KGgh/Ĝ\^_ntڗ<~dmFjAxvܻny5n@D_u8e?7!=( |A8s {ٺQI}U6 ໎(f,;n/"琣rWNt3o`Y4{kMn>}9ow<9܎4k74f|8ㄤAhb0_/vקO9C[R}}ďsaxќbk,rg,>1R|N І5ṣ+ٝ1n:; y{W\n&{Gnʟ=G8u m{vQb(sv'_{/{|w͈` xEifnR {<'q98۷Au-6<̠ʝBU-%yy=K]Af", w]cK$B gܽ2jPNF1|2t:cGtD}}Y;o=u9vT5 ҽ]>4l;_Jp-=} !QR [ w{/#p}k"k  Cc0Gy LYڽpFu`)Hyp.ΊY̏?\_|Un W7ߟ68xrpM:eܸ+EgsK8+gH( I. X'ERf4ؾ H N7hC&`Z"IB" q͇<ɾybW\F"[Yksim U؃8D.@}>>g2/;# oaH?<{>OBƑ=?Dp*ע"[vٰv;_ 5 ]Vi p{cޞ6t j =OZ/MsL&kC808[;{qSBG=I +?9'ޠwBxǼcٚ7'{iP4y9IޠݰT+$AM%}A(HAV2a} ȴ^.]6S3`u|W{AY->y_<Bh]UW}i*`]ͫkw'.sq׽2tvuSvq m #iߋ[2zv) }$j2Nyk9kru{unӲ]V\>99Oaѹ[~' /Oz R Hg RL~ T eTW绕F{i rDF@a` _iI\ů*#bNjA!Îosg5nY=wyS7[+N|})]nNFTLJyI .~pww(4Dr0$=#S?oG{߮/˴Qoxqa@DH|0IN_VrLf56EOَqi>>g9q .W\̠ڰJ}=|?\S6[ӼllNqsWzi۸9v|Ո[-kF ;6:C(9G2sq<|hJċ2ʤ;ivvNPd]ʗ:| {h#'}GǾa20gO,*"u>ˆ@g {z}sa]e}I}E/$(>Op#ߗ`?vŞ?] Ὃ}]y:U^mZs8vo`<}}ߢ{ Hl)( Cg퇷 O9:b.o[ߥ7~#\^{E C@F@JXBtRXNX"~q;qp(4ɳ7]tod~=8 q?CӶ~z_6/@ͶyK6) XCp'=WrIa7ݟUX}~xᯐϥ]?3<׭?'POAQIK`}b}Z5Lxޙ 3&ZOi׾>UǷ#swf[Qe4m>o]C.4g{"*FAR}\~rѳE5)iΟ4qdtE~T { e4>ÍLg7dza(:A:WR|m5~%Yr ˪{:R#C xx=֫p6eYۖ޶}1c#aw~Ə3wK.`e@_>xyg{|֞wSeXhrټs8ِjVez0 ?7$vupQGþAjʋ$(L$ axO|yx}%ٛo$Pl_.!!9K0uy]7w& b;7c+ee1ܽf[*!~Íō4!0 DHr掱,kӪOxQADuhD5C1̞q&FxnbYǒ|KDgX(긩7q=V5TuS55ԳDuf6giM}3e4²>fa,|t)G!y"!*̤1dJ2p!0xf,bo+}>H>'"̶31ϝ?)7i?@p}zƂ`~ iʲOn\6=Şj!9cPF`쉢79{n,d"GmI䌠W,gt#Ea>i6ۗ,^(9ИH@(2:Ӱ==yQ9ΐĉ;dd<32kDVaͣ.dc.{!i;zG*Evчt"hq܅ ץOI;w~kӃﲑDph97',794PZ=nBo-2m.mǎL>>4/ͱ7FzAtFv?b [,׸syDlڽCkYߞkើ `M=}gftmZj9MޗQzS"3'ya++j3cs<_fޔ}.SgbQ|#e׽;\Mz+<Ύs`Kwvѧr䫕帐 N{vQpŒAo}?g4|pnk]P'˳Z7V)x|C&EOvk|4=+挐DOyZzۧK,ïcխaj=VTmy5;]M>BCg㻾E>W3ݏ;f.GNe0{yZTo؇L{rdȪN=i+R:aTg[]i>ԡﶿ_g4%;[Bu9ۗX6c8 p}sTSު_{ lËMBzw,8ônHD *qu7s 2`iń'd-Hl@k,/ģ H1m$1ę9rf%K#'ܗ zDާ#wTi79#~<=\>EY>)}_`s|s ),PbE>&c2Lӻ_4)OorȐHs٤kеqt<+,Ζq-3{[=^TA9 V: xAۂUsקxs۷Knx;7 Ywbtɼb>GɺF,y㧺V-ɜFfiXl7GhaoyݳHQU˗Zo{ՙfi7=;4:1*X^}US/}$#GcAii>8ݓKWy(/#})Tm }V9 Rv؆yd%VnJɌ}=qak!k`=V.ib<܂w-Z;~gѨ=dI"=^"ʗS%,\O6ںXtO " ($zvX7x+,ԁOS}!S>/Z̙4U:Ҹ&{۾@篣{K%ȵ\4Jѓ|)[hLX3/Ku`ϴs3wy%)kR@@RDAmf7n$K7J*Ё&+%ѽk(4KL/ ٚ5ga1P&7ˇna&+mCr f$Er7lu s:LjH{*Jo9ˁV{oNftp ?~mLHvnnHj[d8Rw{wK~vzua;}?iOpPP04Տ.=h$aahA5X9vs~t;<{gPq$$"?]L8Qā$tF `cJ8prSko!7tByŎ{C_)R6qL*>I [-}jUû'x?zѬ٫R1LW}yp<9'jz9Ӕԛ>k_翄Gƕ꿼zzMj=[1}Xz6wv&ǚqp GȟzNDGe 9QCJ@~8kë|̋3+^=l҈(<M$RQ7aO_f2y'W@^S&N}#R/w5EKJ0__Q͗I7u.vKO}͋+.rm7QvY\{&Gft9\8le5WjK&&:'j rݭdJ2pDNY@> b14g]aR~|H\> LB 7#/"ﱉ > >d3y εߏ5@ȚOљ|+\ї# 25Lyxz};K,,&oշ8tiVu|==:f@P,\+s$Y>vD~/Y2Fi 4+;>ހϪ ;~B}u|wOԈxh8#WI;WS\O>[,.x:{f}JvpYuPԶ O{çdx<3̖?Yjc3վ2z}Uhz^'zY)~mm:wwsfKr^Jhj7S(xEyPtqKpv׺;{tbBv>:FcCB .N eqnqCƐIH#֌H)8*܎<}g~@ apMAQ}ħu;rQ/ٞ[os/9T>Ͻh{jHC+:lMդ;!!uc=bHI χ\FT ;PڴM!ˣ6 cϛn94_{k9N@HMc(l_#ᑐ? edžhس1;}[uz7<ɴgVz\GK^|g 񥇇>GJ>{vG-nwfti'rL<g7̗N6|k;9by\XR߼-6(sg?|XLy}5;ns8 +z=}٣sdc46=v;oSެFF}]WVݼ;џwM4eTt^>߱] u7tGޮHTLlwMCΗϸH)ooxe| ץ=NˏcQsaP62(A Aa8Jki@p/}OI qP뿥͐Lbr 2,ύE KcNs+;Vk/y7U6gFk59֏S un$m~}ÿ ;Xӹ5T҇Bv0o_t́~#q)xg8m>o Xe' O(\^g?9aÚu9W<#w=P!sEu1Ҟ7N4f=M/Qr*I0?_ W^1WunG|*.JnbY)zWeXI帰CX<5JlQ>f}=s37GXC u65rm8.wrgwMZ6.wSqs=P7o^W=Sݞȩ./"7$_ܨJ)T_ia+eDi"|9#5Sٝ\?\(6Q!a[撆@Q(,AibŕeTV'΢BUs- \u߾P;t\=8Tj,~}r%2N6kFN=:u74wǍ|G| ?oqeN>᫖ĢCZ`%q"$w:)dQ ,D`~%U !5f|ASZ%c*À3uDOaq%Vb:Y]Wy3ZT+\R4n1GT>!"3O ܃9r>"4="} E+6!=,}-{{am6yԺ.#3ct{v 9脚ѵ9K 7: ہݳ}.ghtǫhT%\y*y^/s^ͭAZ6ET8ozGE!cJnbЗO-Hje̴ ;>}P׊m:gʄl):[{̨`Do&&nf<6k<|]7nT3=vq:l]RlU·3wЅr]R"Ce.8F;0Ϭ;ezPSx6J$Nxt љ4{9֞(Y+Xyj*,I=tgӈHpt6+*v\gb\`LJ_w!x~1Xh+Gw}7s}\|l|aw0> ᙭IR?C_iыI ,fOGeV؋K&d&Oml-0NwrbyjcFvi.M#\|y-|#R:EBO}Ӄ LŢ]w K=Km|ow}s=wՑ,ᒛWz'yoUeЋISӽ`%G_PxCO>0w .!{Ry,Խ Z y]#x Z!vfÄg,L*]=!!ӣg<㻦e y} @yyCw^O8A9kRa 1\;wu-wdZ=^bgtSD1 بtX^ oF c:y!sdmØ/3V!c9y ]hACEyZS:)In\=YrK=;)3:FV/݈dž`PjhGrgZM do>6Gj[Q[d<|ڻwr' >6ooc#/2pH| Ң|Ÿb] J5wIDa0(8k;6$_0𾜻n/QpF #B~yi4b8j 3A=%=䎰gh3C?tE>AY':RBa~+l+~_XgrPwww=?3Pg$K 2 4۲m[8|A*~nϯ379/$b}<|BϸH QI *3[{k'aZ^Ai̫2{cg&Ick\z߳+}zN-ۥOS!:g5L6LD0,*.}gcAnH dcxZB< `Pdg<׹wxr7{{{t9!E/Pd9!<ְ!5Q9.7ox ?B@0%J;Hgnn4_]>Sdbw縑a)~83\E`_`@.q 1胉&_s ڃR9g>+7%X&ЧH-W_7!H>aԯ,LudQ0.fjqI%qgfP!0@tor;.;q{K#iNWq^@7> үd daE?cYǼ5M3 |+r%r :l,>ec $^ytM q!=$g&}sFG

PT2|xsjYДɄ W3⸅ȱ?$$[bVǹ(-_ 5MmF ӉuIYJ %%2㐿_Ŋ<>&A YwgS^-/4muN.WqHF ~6vIH+E(m_C/Nbqb~@إAbTaC<]+Pi%=1cwgxIaCNeMћ1tF(qh$߷ &D|n[`‘eO,&C}f\`y&A8{Bg.oNܞၓm 2ym^ת&3qDA8WSBLSz68//QI<Ml-U{y°mkgLӢ6rv-s순~eK18:Bk̽(! cdq(CtY ‘lt"lx.kevhdoh_2FO47".Ug;AQx;›soHJk#WY/56OX'U :x_\0er)R`kvπYP! 5] 1?'o”c|wb6{ϝc=쉚wӌsIO־MV0K<'q,vԦCnIXI+?\Ӳ$Y jtc3 > dRJEK7<;Ր&uo`T 7[FWN? \9öǓd6q%bN6RBrdz1يQ/"QR#&ȇ_ԙQm`[~j.h?jd۬%`~i+2Qk)Q/&&Al7 ߌTuwzݿO)eS&IB?Jt^9_);3psg ޟ܄r.cn4O]{dMF2ѷϋ Ձׂi3-;^^,Du %])AJ/:_;,լn{֔6Jf!yT`8#kx?֢}؅`o.?a A^++cÀ O1T2FZ㘷L?h9ﰀ7Y_,5 *ʏ#뜍B(m̨zĞzxlT}ڸg3;r{+.5ρ4l|$3't%dX6$fFA 6gɂ%9h}eTz^b>MO3:"=aݢQ&}آխѷ17UU[L9ګK90opMmK6B#0e+G!40׺(5 nGؽrIݏVg 0CyEp@I%c_}$&$eUni n[X5\`z?Fl?(IHzm˖#vA,0ЄD'mg 7hpx1/Q˰LUŀKT/Pn2SM(>*/=;Xv **_%բk(? gpi,ΐEc`7W&?TVXܗ,[En2Q&s zNlaƞNmK݃8||KmrT?.#X:QB%8tKFPg7V8E*.] gZJ{ܹntY)0' z9Ѻ`+=l;gHqJ;2HHcu]Gad}t4[8#:`qFSOv蔢 ƄEt0JqK2m~7C:qzmS^6<:9S(q[M   n܀Z&QJeEӇ>33Sΐ K2|fȏM.gQ+Q[fB})RIE64 E wo [/S.-cKix:՗KXՒ(iNْ (eg\}#8Q)ԩs0ps*{;h<0(>kV4dVM;7dRCpq,dbWjEI ld\ɜ9Nx#-'D@&,}Eǁ29P Ѿ v1>NYޅG2bR[.8kRGL( 1c0ʍ`wۡԀdx9@/ՁrsAdYDܬYhR{,dWXUTFrw*/5wNi͛ /Ë^YLJB2TjS-,[\ )jfxLŝqF2X| ٩>FY Bߧig#xͺF^sJ09OM/2knX}*+^Rܐ`ƤRD3Y|O&QE-O;qa!91ssÿ~䫣Vw7R? -'3W>}ʼ@jz}:GFFMve<$uUgٛf1jeMuYgBͮL!<~omU-E.6ER?{,[~P $wǩĒwR4AH!("Y9o;x$%3(T̲ {c[ޗ:~X9E N#wαi6)!JH">d]T*#&z6Dʬ363oÁsQBFƋoe損ZҒ;R!j>U ]A@Z \oܨtK0pC1:Maa)>~SAHn]TTZ rѿqM:%xg.Hg1,a-0?)>K+ay,ci*p Y:IϔfPauTE'C RSmz:¡.܁4ZKYڼ)9 %Y6lmQv^ܚ$6`~mYq..qǙSeMgU1[XܶLƸ*s|YhY0H͢ʟW9R&60܋G{R=M'!$f/bAмmL|#4p[mt6{6-QE"W{Db7DX]u'f,M}ģ2~8}#ٖC:R\V<͠P{-ƐDa^s*a~!FZ!{CmcgNP%(]>sֲXbkI,\]Dtd{KzgR_zzs;,b س$C;ZM>rU&,X!n0â¡|;1cE 0&&% wlZM`P0*>$~ʆ %P:+P\azsv7Z5բۏy+% #BD-];D`F=o~ER<2 >zS5O߻U'&ő`/lVBãˤM MzR}:/ܩ EPi)zXEz:A vGR ١E.HB[1{Q a=)kIn2W7嬂a_E_d Lmҡ]}|A[=⧊ut7C%Z}RO+5ǢEq ;n̕@$_-\qO`1s#:$X]y+w iMMD&a fFЪe\ķqߙ ~= .¥`RWR|)z8j`k_Vf{Da!OI?nw#Y˂5XiM<76ck4:nS DL+J+ aLPВigkRZ&2)I(Iލ c1Nqn~^zEJӂ;BUrX]5Uf?b^&)r} ]<|Nb>>M| ӎF D:S3=k ]T[$҉C-6TM{r֚UlBT?5ĵ3zKz 1tdTo>5_c ,hwD1 %iwPsǚ7y5k"c] )IFsN_Q@KQ@4M.t+9jq,qn&L~tv=;aMmˠOM3I>WE2YNCI>8e"-:DBYfr, [f*X]RZS_#-~&@e+\>w–n~Ȏ,YGzۂ8$CAr8aB.(r9o4x4p./g()~r1 2%\(_)*YuAa׭v#r;GU㘑;'4ݬ5Xeo4QIB K)Y%b06;M9//YÛe |4%p1ǡkO(am jڅ AE F/DJŤZFX0iKnN$f1CԌwA (FCP/QCXr~4\;TLwr'JhA'o%i܃-nX+H~IxDg!%./wIGY{YҖz֟eHb ow2 bJMrԱiҪ$jĈ9[ε[XD,|"E/32ɣb9d(@9bV}TPZ3o1ItNZ6 ԙ8xUJmQ7AɁ>Ou6]$'mJ@I }^b\.(ÁeW/S!%w+8VcT<k^_vĆL$)tKqVL vVy,uM/(+wTKXG_v}C k}Lހg܀蹪^~ˈsb~A~ŃQzV)Ջ4b֫E<0k&4Hl ^K)bZ}ϑv ?v1*O%#?5w +an::|@YxKDԶ)s|".f!ݞobN- #1\G=GD`4;.‘ҙ7å%%*amx϶(֬hF01kdK=II?갖wI^}mVAڤ0QG&e4˭e1w1Ty~V!]Z^5fs Q8 *Ni ǂQQLKL<1-x<$2`9F6WrFP܃&MvEN#(a$(&3 <|=` {oZݚ#A|mGIz@nCðߪ䋋Asb\LX8'vB|( ې%eV ''В`{x~K~' e+u2Lҍ /=;ߖ3;tvpބF?iP]JTg5M/1e,YVکz{w$?ėJ?4p2]ZZ݇F$r?(y>s `n=8H#Aȶ<$ b9 f.?jEB K6ن3)5 섂Ϭ4 5Fk1tv1l;IU\5-.VMJ $eٿ4c0W=RrAm/DQzZɣ0yWoti`\Jgu* 4bIcȋq$/0a%7*L`{V(jN\t8? ѿ~Rړgh3ոD]$EU[cYЋOD'MDogOQ&W$LXbi93=l'p-\fOŏ,5˗GՆ<8tKGD KG޻s8+̤⧬ }E~;}ޜ0[o]Їcd2鍢%q<˧1_k'QB(-g'S.?r?>DUYLq7`+\!zCBqHR cti0^lyuWsJ39mW#x߬'j Ld)l*m ^ ?3a,,;ݪcJ,VBThېBC_ WqM~1v~틁quNG+l<_5pGT٧bc w,0"}Z[T[lKaH%+ކ<2KE)s{txZG ;cxd7t(g_ , _m| גQ3I)>R&T5KTq>Ӏ>AC}\ٵخ!lXZ(dz~ gO#VsDc0diͭa vd'L+V}9e>(EG&i$7gT p:l>Mt/W@A0xs$_ D@2Gi%igz OfCCDjR^Co5)۩#6`/RG7lieo8~ 5A^i$z,*Mla%qwjpcJ:Krl^';RJ5o)#J/V0 RJ]x$啪Y^85H_K7G kZxJknowoמ &$l6 Ew^UǴkfXt~i#1%I446Knk2PC0_Rr)@)%з~ sy0vlVtm{_'2Ԯm^N g :/r/Q˝"5WiQ3jom(h kjg_ FhHJVK~oAq~ob=xܩ3XnHzii/nA'\H)0,KrV*G@S6jHx!"l MۺWr֨ |&ve;Nɭq5*c;mSccUǞK %p`LW gl~oz%^~441&O#Kqb'CGۣ9azKMÚs 2[ Q3j:%Ψ"g..7S74#Q'8B~<]`@ i=G׃*S6}s!kk$/'w&O~r`  K {maf{!OUgp&.[Rp).Vw 7ş֖}!@* `[΁aN>#Py L{H2eMN7R!|_~[d NbNookO&%x΃$@,Vɀ6xtE<Cf)P{,B%7'?f`.[<bq'+N;Ls&i:Ա01>gI}[ 0}%3;2_~$a_Í#F&yZ.TÜ^LOKنb|k ?Ļ8ک߄ɭ[Y_ }9RzƩ|Ï)7`~5}P [ʑEow,2)+h9z8bR~zܜ&qm;)4^)߳pἇK@X3E*B\Y@&{;_Ҏ.F9Dv8԰{ v+! {T;C 54^v~f-8?*~?ؓ1BO7c͠E"o"llo]t:G_,gr5I/ɴ\l4?b]Mϧ|>x,/wQ+ ]U&Pdr'pbޔ*9}Fw(SQ+Z`=̼?yD3>Dg?*lM>%Q/oR%3+ާzs)+%x5#y~ykXݔޓ\(4; wxX8JUkyW?z?BPհ1hֈ]B) !XªM?y^DMϸ ^h)߭/4ЕɃC{XkQ m`4t].n[[o]DO_K(i4Rtsbg_yygixʈܵME,/`]\$p">M)3)Ă7˪CHxŶv&ޝHPb ?uDֺD03Vd{ s3MUɯάZ;M@VeAǤQ]" f51˟n2: n(V򩝂*ywj) T^C%TwSD=RtŢׅT'rCՎc=gjG74[?y /Zۺ%1#6P@N aTԪpIWfose '7G)%%zֵ|=O`cJMO{4Ja^qZE ba'U,QXQ|n >ª1Cqxcfad뿊oZL81%<5H-YΉ# lGwyFվ+J&yܜXdfrn6g֋ߣ9uU RlfMs橛1vh:32ԐE5&X+Emw=ɶ#ޫ[Gǽ;~ !^գrw@щ"I`̸/c 3mY:6'(Rpٟ˕ꇌ;bc^T O*,:awjVMEa] HmpWM>*Bty>jK2:%h矓 O6/W_j7EUUlx_7YQ+exp!8ioؾΫ[:wƮ9xp2#4ҿ!#U~.3p:a+s Z (P k; bV( `7T6'0ᆅL%s+iVt+0V5'ˏVoޭ8tz 7i PNWr~ڥlZO$V=$'[(bEDNJReJZ~Q tSR}]n]C~Elu I'P1ӕ }ߗ'p+U52TM DFY{HG* $'\^1<=@kM^1؃ͦ䢤Lcۊvg1K(5uWP9]^fĉWwk{nLibJx:'Ua\=Ӕџɼ{S(fcjn<[Kr %Az-U\G<j ^i9AOsǑ8…P*g׫b.%{¥vЗZ䯅lp<9(KFw' L$k̓s&zn~u}rMˡdTnm;ٞ(9=PiLlpkmpW<ڟ9iN W03mJ+9ԋ_}1uo˶,Leq )}T>kuˆ]^WuuC񻤮 g;ZNvBP_q6s3vkQtES Nm1\p&P$,[A7T9E8F(R[vEk?]` zGݦ4Iռܪzk^ 3o ^r_->q={*޷ŬԾwNua\oy5(뛑9"$8=#JgyJ*L'tڃ77R6i`+-Uv$B˅1)nu4L,]dŚ`Klh(c6!E]ΒQIfjL!"BBT% N{-<|Ԭe^1r'OheOZL> ,eph9AŪ)Rf  9s.`ghaW_$<)ͺ[}@0XkV{j=fv[U9S V>qrԁ^MB~IL> m2lzYvimx`GE®9Mˉ^j;c8iɎ6Q~5CH7VlҎpԞZxnW0yᣘt|מ;+XŲ+.-] k{#kҭL3r\4*[&r\&W sҿm4,ƿY 0i?@'/ǟ#QqD?#~LD-`"g1r&?\aU,&ȫQy|̈́f= r'E)ՁՄ}| ;)cV"Ёӡcs PwN`rF3,/ې7P>ТW]8*Sg=B%"bLNdCXwñz$K*2%¯Hdة<YbOܤpŶr-:=_WiL4`Zo[-~dCߣA5|P67L^QvG *n+ʞC^L 2Jm\C5--Һ.\dR-p`Z&Z 3eISN㛡jx;^:rU'G?P I(}d_YS"PЏ$~^x ) ]et|$F+:D B_ig#9##FCV4G69Q^APCujEST@n*϶3!fHhMoJB5D2dU#6kon1=Rz¸dc8(Fp$},L. LkP˴($b=Ѐ^ ך+vEi S8Cȧkz?(*QzQ'0근h45aHzi/^} ~#TBt" zg=r Cp-2k1KN`.MOMKa35P+{?r_]YGgJOF`p1$FaL\ft?.tyL;WrFzD)ɾY&DADEf?񇄡\ptlI "!>y@G\׍2}-A:s%h\9$2 /&{֐:O/OMQ͎v C T1AeTs t;urkT||b3giQ|H)sLkeb]xLg΍d9} ^Wu(/,44,el* ]S^0wTQvqGpx3jfzToTp\x/HXIڹTf.ss,adF G&9K霟W&ڹWv\e`^D `ޢ&-}TJbOY:T~C@IgdrD}w:`/N 5+I6%26:fbȺ6HxX0FeG.&3t(.thQ,we:얝=G> oEzqɇNuIGޅiU|zG&=Ӟ욿QWG\B6Oj5Wc$Kupi'E_ոPh5B[o5> cJ#HV` _v>(f;{8ڏBuhC+1#0Vi |=MW/& m=(#NS6I| wu 9ܖ+AtfxtDXzG"oG >Vvx2}qJ(TW~tֿqHP}/^H5>\La?$l~#S$ܡ; 0WlXˆuoPH1=aW|ԃH{gt-g W_SN9V k026j <-^?.?rPRb2xl~r ݾ`б,^?rq+E!ݢb˛ j7RsVNn;u{"a8=Xu +dI^lL* Ir^(yK]ºD ,5 k\uv05~Sk2|zUXbg>S$SQnaoFikҢwG1 vbM_$ $N{v~o{μ tM9Ҳ#,P;CwU^JmmܚDgcfc{a cWK<6̱£wOpP0C*2@~e8{rx @U<9XY3Ún;žwz15nO[F`;m X_"_4|c90R}xf]2&ҐEp͎iDrS2F2t/,Fㇹ?lq AM_EDcnG / y&-`O$xãF.--C% )/XLߑFg_{Hqԉ]*=O[ GcXevg8n8וU9m&N)g^<+ %14Þ4Y?83 }%N[ŕ5ŗsD/oɽm q+$YLJb2VGs.HOv,0IjtۈBGMLY;ŘZGX%%;#][:Җ}պf5e&s|=t:̎(fk;Mk3u~[^:hi_읞s!0e*i&f!C4,IEPȾW;7ږ/xGS`lY2,WPӽ[>E-.!TmB$rg#BB=AC>fdn2pRp'}J ds7Sxm>r> XR &)a^p6%ti;7ȇ˔hk3[aY\'7}}ZBIzpw),/ZsQ![yaGny] o}CveKbITNL 2 e%}%,f0pT Z; (T،f_&[n>mՌXo1/ao~Fm8TXF8e֔[ 2?$#:<%(^XM[TRǠZE4 FHOLh0EQ S_(z19l*Ƭy}S4iCWq)kGX8P_t5`cL}]tWǵ3J)!Pȉl#7LYɖ)3w78Skl>tt#MxӦQ&m'$0盋-Glu_c#ܕ ZKۡ(#0h4XчVӏHh>뛏,{kd5xPLơH{X3[ZbVz-Iz3:=g%*%xbðBwe&q nGVQw2]Sb{czCA%IQDwx|7gJ_pYd_w2hWv::/>?;# By穜'V["a&S@ċ.7c"`Łq;fZ4sc]b<s?呎XZ7Y9tNKB1u&1&GKyc' 4/r×}"Je>5DFV jX[J> !XzyT2(!xzork\򃱘O仺<C!gak6(TM\p4݀şwf.N7Nё,H$ G,˸iNNq|GfYݦ0Q,(ݩ~lV|292{n^ݸA<_EfV33Χ$ae;s j$qp@p7J Jaӽrm^U1{2q7k}eɂ .ޘq~-'g(Ư,ݹPYx+r̚y".# iE6?pIsϥzhµ=,.kwLCI%;ƃ|"[~DRT԰5U:8gD^=P`3B*zB~1+_Dߑd\}xW)\m?DCj|&eQ  qMHvs`[5%d^klj̰PfddႣ^t7Ǽf#uiQȾ\t S*h2 ~]2T ]v,Sgqi$;[7GDLt7|]jވb')A-*r;^_#WT6ZO0\*ۍ}Q`_)K`VAʡ:qp:6U&_UKMPRxόO~D.ʛQ| A[nf}1ͻ3 dDV,vz&DOGƴ0 +zA * N¨jWN07aa\Y) uc] RR )Nҍ*0t6GRxLQҨRg-M] U [b{P aF/E.-N:+q$'ٜhcbtMD!9Vy})MfMaV\dAZ7rm諛P2g\]'qܮsR B;q GN/CUnX8^#s1x\ȟƊ‚AvpZ)[Nppn%Fز| Ex33W<-lqKW/ <LzR:̗pv;9]? ^&Ƃ b7[%-c'WUjӕ *[sn=KJGMߪY胦&V d+XyȶI! F((J8~`lP8llQiM1MroIDar cK#IbsIe arhn #>Y730nfL(=IJ'CXfQ/q4W1L[ЈlG98eX!C{_ClY/%BУg ; #g8Wdi^4<}`3ykk1 w6TAӊ!al!oJh!-8W&m|0ܲOkm#y:t)_Snܣ]=Ɲ8ڣغL'>/Qɖ3''8m̰zz.Ƨ1!IlV& SS JjG:]_3a97-@j6.U?)_>=K,=SV|yz_Nĵ>Eȩ3=k3.Rv">vv$ `?<&x(]sx)t0(e" nU'&!Rc~ ۱az>Ϯ"XF(͉ 3^e qj+WH% şNNajz6۹młN? A#&"gNyΧA"fTF iy$hKAv$.?Τ^'lqN'a v 0 ]+8A\i|Td Oɹė2M"(q.^zwp XZ'.->Rh.yXE*+X-R(~h=DEjlx@uP8_QAd>lH;,wma(#EXm,^Rq2]6ac0)@>VA7fi )L}S<њKoѵXcט%[Ag{xiܟl`%?%3AsBG&޾BvuR9r1ў 6*"7ReWÒaMbEnb!8'=>( O|laA E֖5:ep%5i 2WӒHhH30T2's^IgywI, Ǝj~~:2 :T13~tJ/sl: \biZd,\6W뚟DEe>Y $+ z.DyxS?VBK{6K-~C{.jZiC4O;*~ԮkXsQ{!8p]nF6VKOd Ѓr#bȹcGŗV^t;TM< wwa虈7 $Ӊ~~"dۣziF/|O)96<$~_I-Oy8 ۂVZ"EںccUt)X(c,Ӱ!1/:q ;4a!qߐ+}9G&,qvr2gn&c"}۴%]P!s?o\ lv t+mw6͉}=1u[qC^1-E }W1#ϩV9 A0]jTXP~ƎzOh>Zr)_Bȇkǰ¢grɛ,dhߟT߈]qdlFZHuJF)iibO VVPN8<(xi`|I'tn]p`3dEp´(d zUBf0~']T @쪸/tJ~1" B{-@h/ʫms,ak3gbcעD$AuRPHS(Q/}B 2&q(88acSO{sıWt!U{jY|V 9ɛU*B2yvLXki8}M7 YF%(aʌѬ>se~D)z?(tSdwE; r$zP\Tߺ(cgOfgGX#|7r\6xrM[s(DpDs#jN(@,eE3q {SVcDJWujc/#k/L?/qb-DaU%> W+VNuz$+{/QRԂ`'.ԲPxlRvA@Xk5um/ȗ`5뵖;nȴŹP$Ev=FԵXDƫ[m9 m<u\JuoS4lDHqp#}j'J9Ve;eQ3ru,M3CM|rU ؂UQ:/~ 1Y]\[:i+ғ1p? <_J Yn|L(>2j?ψv > =29 t΢2 FtY;UrinQpQ#+ -ĿTDu(|FU+bUdi*>(#b~(g&[[ȶw҂ۘ<_Lxt/Q']Y5-8nB%YuZ)X6d08gǒ2Y.VitG;_u"Fʜ+C&Zf>UF Hlc֔}'绊VU,5j%KM ģyhʯ`܌P}y][ج 4v8>0ԍ qhܟX<*+j+WZ1e 8x Sp}F~ DOXҠ>ZGL]FjЄ5;hai&T;]WyyO3))...$輱ifV?eQԫYL؜'N`z^?1T4 =\ojk/<8X9S{+Fg?DG_pe` `8;j]1JE˼rU̷twKcSUCu6~")%DS%!!_("|7, ńݞü+@`]im`XΔ%`-7~j"CA܅^6 ֬7's?d*gVFg=ήW2/y^sI1"cxjax0Fj)d-?Җkf(.7g_ЎnXFEDA_ >`J}+ψO #TD}G̙)$h>3˺_\d4)>>ɹ`pVrз?f"p ,w7;>I)gG8{3*O`{0I݈F16;RN&@̋+Ntw3@nC7}Om؎X)ox5W"5P#gH=)IUu$|ϭ * BeusLE[ݟZE!k!As1ӕ5>]UВ.~m[\BlWs6??'05iZysS&h0m'oⲖ_PKb9ʉ7b& v7-l2锏n }$ #tG:cLL >h э8f/9W?:%:.ӦΕF>E}[h7e͋lT?&{, ]De5r0k Y8~ CplHJkPxHzFPCH4f[{-/۱FC :YO/.9.~k/HD݊FuBjܩ[_Ď k۵ ^QB#`iSʀzpj1Z7@IyXRnE= n#& T`ze |*4kޔ ln&k`GFeGբn-< /M[oOoV ,+$\3 ;9L |{2lWY\F#A`g~.W,~F(iTn_ yJT4Gfo/.u%e&~Z}5̢OV&Eou~@s$aꞀPg A&:0pF' O11/6K`aVH`^}\aV4[h۲֢vTy,zVOuԳxT;b|ztGʋ檈B7?c;BEd@Y鱺4*=S?+$<4niK&ToC]YAj5$/<_G&ԐZPS P%g[) 1TbS!nYEf>w!0:QHnjp;')l:&> Mz 1s1_%#똒*N|V(Wv\ʒ] ٝќ04p +)W{0x!5oOؒCaSZ-iqJ~F8",]C⠴{{ԄpŲ8"8/ħΛp9Y |6:h_}[tE{Hn" .x!w$/,~0biuA=n)(PjPhH NgpB~aLV&U"azIm&F){ R:Flk Bq5E/W<#s0֒!{$~ץHaXqW\%k|kt]f>fF"gAeW|cPZMq(@Rcinc.nqOŅ]ClUOPmkB2x+V[6N>C:_ֈnW_ lm]OGKQ9VQ9\5G$RijLimH`*z}mObE¾OSD [ĚeE;Ko6(y\R鑅cX^0(]Tvԯ2-Lgw[q!D%Kؾ%x;eFvr.#x/a(A޶t&j ZJ˔ 'l|_8-N'HJ  ¼+mIThtBMrMJrXIծ9k6 8q<`4ZJ*{Dfrwk_*#jx %Át W*A\ $=N8l?Sn24tmC:TkpK.DD$8q{O+Μ@.J|h;yCUZL%ь~rJ)jhoV6MuTcyr8w[S ̍$_uhKqۯl]/}"T\9S.B'5U#? ;7(+o&Z gvO%STë8!87iLUC g\*e+ {إ4 /ծH{ePbQw32 *_uo]w|w}{0e5:a}?%9k8'E!* 8iǝ@#LM-8*ӽ1hϩ#ܒ# 7K)IҚHx*FU>30; ϐN2A_wϴXn>Y4p~t *dj6F돉9Vj_ltp^ӄRVOuoo qOqy Yl g=gmbBKڶĊ3_+P=g2}yrM#4rQ'MctИ=FvT>%8H 1ݩZ?4Ӷ/EzJfV sttES~}WK-{E xD dBc.5:,d?ݲAݙ"Q ȴjAo4o}!3偊6qipv1`v5^S99"ְX9C~(t"2OvKN׶˵5'SWIPMi_Sk)/7‚빚ᆱdPZxNf4aT}isgB_ӄR4.̀Si80SI:i.qW[X|G8LX/Y P?N'j5,zsNF8q`q*ٝ1̡̮\Iު`؏g:OT)\.|`{Kh1fq Y>&VP" #=SN/m>W=7r6 ^w}b8;h W+* R<0CˍHLuMxzT׃S`Uy;DU(OߣTl K]ń#.fo{IP߿# ru"fq3?5Txx19Adxs.pHWEYFS@=MOze(nRfÅ3iX,e<'0X>9Dȃvm@"MCj>Rbsc+T)Q&jNj۶cam; )-1F6¶Xc۰\R7YQ9tBeFؽ:9ASNd^Q$\6tMTrS8] )gd@9NLX56g\\Y,VP gX*]d?T)KhkS E<1}:0볏gRlM- ~n?掓xA%p4PUT"R4%X㐁^#)icb:Nq943%5#)^G;M޳!E{0u5. Q}ŒGH- 81ƅK7p[hD;V\2ޱL9ݭ㧄;Z D9C{8 -9֭W*iOPnsDrhIZYêR?[^-CmeѢY5$\T(W}wn18ёz9f k5L=eWA&CW3QKd'[82#~$<+n$M>Ǯ5c+y0VOI73ìaܙxNbGXlCxS6ƮoJ4~Z\ RyBXʦF 0jUh9q?ٺ*~"Wu(NjLtDQ6_ 2ӜE6µ=*B/-- M@D]D!\#7UtE9202?)l,c݈4V[y~zl!kע:KQJ1{gP 7VZ? Ft(2,v?z V40jl#|Cn RЄӎ[x3.\wcN^]2WG*rU>$7O )qڿ5+Z|)7"3g9=Vb4h\CΙIaԙUQU.rgGEQ5;zGOvͰ.jsӺ1)-Ξ#Ԫ'wy3mzbn 7<#mjs.AWΦ6- vϕ$D:*1]3"4T!E '/df<,0&'E#_wm6`1LIJHI՞J8uCzz Yӄ :l sPn/˅|' i2 9Ώ(3[b% H1왺ɺF4|zQcUsfȗ p51ݍ~$N՚撻y흷% RK=Qq/Gcʎ.A#Sgt;-:H,攝vNFY"UU̷P=̑z bW楿Rk5ȅDz*Gwd/J[9f2Vy rm,5_Ka4iEm*RVIL[d{>6vy C|K61ɧ\ gc )?!Ps`V9ZvqaUd-<~*IAryzq84pa'swkvWW$ i٭4@GI+&P>CZ6AԀ:OkNSMzCO3<+wh^: t.g[N^R+X"-E<ݏuD5Նi;ND=KЅXh4fX:s32+1.|ņBu4-Է;G2QX BbpwŅpvtw ZS{Ӊqئ|XґUV*^ 52Ol݂ͨK$F7 r@ÏFaa6X\&,͟Me{k1mmFbAw9Y7A86(dy3OV8UfU2A ٚMUMLV?pPoid=M9WhUMU@f ?jОrĹʠvԿi+LŸXadIcfB7¿„[r:aQ棃jEV:φp2!—ǐa؟rf‹ s<ڨ݋8Im8X6{t~Wkm.GKֶj˃V)~D qٞ~ -1EROי?ڧ ༬D^i򐫾c‡\nz TaҖNzLΤ`1v S@_ihBU M-JK d7ĦY,?gZFKA&h`b8tAxv n*c, 7s,&#0=.y/bN=K]YɡIG4ec[L!B _C;GONMn ?s&-$@(^v #' }iƿۦ*5kɼz~o[PF]y!ka1 WoKW VcSvsuUe#U^K? Z!ۅ X7IjӍB0Ol^^V cRifCh5.ƾNh5_x! JOo7i|!(YG7A="L(F6[FVOP;ٌp%!Z?0V5x4CEA=Q|h{fl̷+ؕQWJXx]sۊMaDDeח`opR!XSN`^1뇋Xz&%}-nhII%PemNAv'vpiiXz<Z;9 F"3 #p }0W ռꀰ}z8v-\LW9ǘ@w$uR F 1/CU;Ǵ5 U{{@^ҙP ݗfeƏ6Gr"7/?iGGؿgaԽBbND?!~tw_4Э-((Ic3a!O 7;) GSbA#;]|ѦH툛Z';M?fۂOy5Rj|#89?E!R7tc{0$pAl38&@. dqrO|aX G4!yp35746DRn{_Vמ[u#[F'6eBl$8ZJYwB@ΰ޽V>A-'pmG*DK:*L@\{.1si*MCWxb_Fy  jQH&0h%{|kQ!۰[}Yzs+;,JL|Up3`RSOUGK_T0\yNzwui5Yݏ2 J~.x`oH~?QƆ"b?D^Ra: 2aˌv yN :\2ʿFVpEEq1!H Zcgjdzö@Bȫd[y3n.LG>?,݈bφw*]c%TWI2#SZvJ/sM%>z ̻Qbh7%XXPx]7B0p8{UJ0 ntx8Xm.\Pt=_'G ![rĠ=gWfYܘVGS"B9ګOŚsϯFCOQuP. BO$v@+D`߿*UM\{7Iyo&9Z,'IMg7-rzA\OT*E  zn뫥ʆ.RK߱^[Ir7'kM ]6Gz/o\:(>dxR+5nVy\c/aml}AM P|AFs?)[fiW-P+]"]8U?K F^BiV<8G(-#|vx;q(zԱz"1(`4S\Xоؔמ&$?6Gh.i˴%ϐVP"a$ -ƻ̖:B6rZX^`zz1/&KWu]|'=_sr,} 3^d[]90rx/u^M:(C{1W/D;~́ )bDRE+Y"zAj 6k"1ܺGI֟4]r[feѥU5<v{lh&!ӵL7c'|uD}=XA6,kʳϻ/ͮt{g8;+E\'#e/Gϛy)}_V Ϸ[b9$1'ݺAgvGΰiS1ͱ1}n#ҜYDS *ښmٺс#℄AHo^F/鄠Gɖ`XaxuE^0/sBN|=Ɨe_LL۠ZШqwd_X9bW;' W0M-~JwD)څI~*E ZCx$:wJ@A;Aŭ ^}<҃+06 >F4Bu>ϛTq0PSriαR3Y]IOI2Y^U8ĸw u7/HRDzT,\RG5[*KyH0H >bΕTX@/~\rק !.ѝM``˼?L,U{ B7)D^ mtUBӘH^(-̯L78gPD>ƮKrp黺He ?%i_%7e2{I֛238{ClOlơ*o zC&57!$=8], RXS.-BhHw~Fgөy縕Jd{r6dq>/+v2+wq'86#z Ff3KI<!VwX x|)L65O8;f+_?(1'E\Y@dz\_(צzq<)dj++/ߊtfKtD }WpEwok3INp^ZDMg)ƈÝ/R" tr!. oXɛ-qBbbBe/| /Dw<9v$k*ne-YIcf0{gG1|?Y7Z|٬(NFnX{ߪNøQBW:'"ӻQ+vBb:Ga_G$(V1kSN  ~NS qcl闎K3FobWc, [.)ð 4oLs'9db=9ȕk;ӏT!4y|9!Z;8klpŨ>J_d,iRQ&C&6(p50IcA^2tJw2:,q]]w4B 9a`.ӯs࿿`zZv,wJ>6BNѺ(EJ-#Y/#9OJk !.J_L]s, ZگG1:RQ xBEH`hb-}R"q~ab{+#k}{3ۥ~o6;R\ :K [ GU3+s,}̔HGD5 rio;pfjP(?u[VO"j~-,Sg½[X$Pp8%P^]gbyjV.MY#߽E:'9%h|-MAGV)MY$5ǬFzfy5qI:ca:5[p=qTwmYs.dCm]~XV7P0 }43 R yYt<6> 2nJSp+$orhSs掩l9E$e SBn#T$ZԽ[xJ7O茴wz6Փ%E9e،z+1JԞ,bThmq,L׸ҳ_D;R%xv|4wOlgx8=fɻKBO@c I/%LnY)\%ho&1 ;)DQg!C_|DJq[oqs4W49g΁ SԑE63{EO͸HWtX\q#fm*f6sKBivkF6CF fFRP:Kk:~x7Y0{zY'D{qHȼSzK +e{&yގ'`m6+~|vM]Lt#zRI?0vGyJN'uypgnf#RV#=DkⴛK_ki| 2jbo71%WugԛQN?f%g/x@`2]5nT:m'ڛruğCm6Un=Rت#7YVϯJ@CUaUAXBa4)" G⾺r])99ZBT&TWu_KIhJhi]K؊ ޿ܚdOm\YdڛlcwwɑjPIָo! v($Xc2MdL7jY5}NK0d2!t٫JZ|*-Ʌ<ҭ21cJV|@{;|YwA\flaP!?LCT}|n<5/Ù\7m^|Xv-Sy=bI Xǂ}xR$#NAJ̦󎻅m#\oU:V%hܳ?IҀ2~`8fA1W8Wޝ+Br[Um8"OSRc.ƀDk9@~Df Q$Aa#1J8 b! ZUJYWRpGvKW}m5"  FWrCe:6M$4* n`lt}]t^BP@y9F5pPR]f"hv@9M-m*o~+ND1G'I55+zVlL IfbD+"+^ qˢDo69$+6˖$^ڜ8lbmѕǗlz,@[1$6w_Z>hjl}g|twz0MڐG|)my >4/ Spmjx5(/uؾFy"ԈߨS_'C`!3qSZ10Y<֮YY* W_fsUeMXĐ8jmFU`JpEtT2ŇHKܶՔ=dgc>o"ap@goiY d+S;:#Ѻz'tZR wJٗ<)zG5f`Ʒ3V䂊La .n*8f8 3 dJ1֋.DnFcɁdmFP,c+Ay Rdg/w|:л/ 06qe/*9y X``R&9@kŲ>'LA٨ 4l} 5"B߅A:{!6BYΈ|?o+K0Nj O^/ Ŝ&+U)Qle"^rcH^l a b F.{WbO{uQ쓶}:lDIPҷ̰4MRPq}4O []p}Ky\DR{iHCأciHήP\|Zz `?28Taqkf6Qu?u2}֭{B]le.F"Xkl,v`Ldx"wޭjns0X`+\x≭ʷ!׳d*۹7fdגУ5~N˃R*nCpakEktY_oa;] XpI`׀-S^jE?{ + gr?Q1 ٷzI)(FspGn4q#ƨ΍PN qONЎ ^E (/GV5cpO`̣\e9[VN (CzwPd|3-G{I߯WnD'// ᦆdu=)xz?^T33޴$Nاb H<0#/iI-Q6e4 pMF\n6XE`K{"q~C;R>ڍ(c ˖'t6ud uFzɚnVnPSY ԨRYEPƗkqKYMKjwk^9%/C?6JsCc4Lh#hql6x/@x+Y|sLsXQL\'qrsB]鉉_σWHN (JB)g;oS{1iz2d\`$]kA+7H"w;Mk&Zn6!~_FYkH ^|"6S؛ap!? f$SVrJ'ޥCcO^3.<ܽ-_4r'6k[{%CK m~(gx-v_zdu rttaF@; }+\˳f\߅stz(\H'e[ h*\  QN5pZ0IԂFHi$.;rF6ȂQKw`xAV^ s $vPj"ݛ_37.2#nWcU X&prZ^z6eR±Kˣ؅96ha" ߚip9j4;A#oǰ!dj)j}ZvY[ͱyc}ߺ˯TC<fD>w>먡0ᴩ) -wAǀ\CUzE-0b<3#2oϢiT hS B9'bt0PiYt0Q7͒ij% W9[0WTU$W{ 7(^ud[Svd="~CKc)yfGj HӒHG+]#ZkEO|QJWo;蛥U'NxFt'YA%0 sτQsZ*Z$UA^Zè/+>R';1 u=ċʖ*֨c@$(OFFL ܒKh\:̈́ I ,&lv(w[Lmڹ4F4>R\_ߤW`VKCI966:f\/(ԈρQuGyƤ_^#ԃK`\fe /YAϖ?o*-i>g[V 4+֌-Tq]iWIV8#2e:,L|DV5=0ҥ`CI5fCsIP!7S5m]Q\[bkig%u`̟ j.n1#)ʯL =U[{b-%+=sLjGeT$f%dYXdh) %&А;O\1[C7FSqVLK˜TfH(eAt/y0|"=ye-'?T*" lNZBGE/6vzqo> O i@89Cg/5}X2ȏqB/*R̭hk}]+knw)E Ph.;%H:DqBbQJ cʋe9aPd;\Đzv5dI-^/o"%^mel[gJne,t<{*nOwcɤ]K#OuȻ)Ě.`bQo("3I :;b,c6D+85܂y鐮UeZዻ5~V X`N*V*q/4N9lk_ ͻbp5]:5 up dxR_,2>x%G@3bR?wSd9:E8)hA@icnѻ܎F/r\8ixry:'CkȅXSU@߉L8UQÊM=;>C4.ju2{`51.W>\¢=X8JP;FZs$aka;~ʒ0*[p cl˶^+k3)\(0*N!d<Ơveyl&hL(\->l`ޚoHj ;IR,^!pk4Š 3nJ.HioGvGQA7CDFTɵa 3(!mrn}R`AWrF$r#.(DGM4{z=]?"ۧ]Fm ۘtc z 9":q:?HST `scZgI* 5jB$>b.YGVO)%?yIK1 ,TGv+[#9{)s|d$LJKv)J!"SSsF' ͧO$~̖ Go5ff$=m8(2Crn6$ 礔;鮟HN}gVAW5y t?'ge2A`#g/4,{SuECk^7ugm.<$Pꖮׅ|hĸYg%̭NDF]a? *f g Ȱ"dVw! kW)XiDeb1\ *VYiCity4.K(5_gv?`ȆHڅc&"Mr\f##D_(-^Qo\.n(d 6gSF|@h))x D s 'o$] @K x9<$.2L3s (1MG4s/F S o#W˔zwdƺ\O 3iv _m1~5-z-гH%S qv+pgQ6ŶuH!>tԓO%dB\sED6cE{Q nULuB& 7iҾS+D=J1n[pR'Q4PmRo6ZZQrpsڟyD5С`Ro.m\"<"gx6)5L1ѫgsz~nW"4'Kw-_?|znKnH>#42^نj蛋 4.\cSRV,CnWc @[|0C\3JI~sLY9?MR2? ͯt4)H[>:Ky$pxRVo͘Gߙ5ٷp8OpRl)`ɽl e^/(5Ey;sžiNoGH[ǣ{۴pTF[g?Cq!oH2uNC\ݘ' |Z,2A=>W (B\Naۧa!Jc{1< #f$?Lruf,N6R(@NCDK(h2}ۅhƒoxt;ķD-7#r6-ҌȨi=霮=d4'X=vլLiΑd-_5ZS :c>-/T1 (vF@\\%ru>֍w~9[+O>nep+Evd j(#''))Y?s:B^SR%d Qҟ֭[&] m9w[ hh&[m+nQGz5C/`2P` gIml .Cyfi\,.!&m99By WiI]9T_rJXpρ]Ʉ->EXZY} N$+OZ*S/ZD.[|Z_3J6E 0~&tU5ԚQ)*34~ =H's؝Pv"`ˏC>vHlZ -gɜf u{VS%C`;Ry_0 ۱˟ʸmPW93&K|ìA_|΀Pp:`|'c,]Ø橔jH8,넡c2$Qve'Wjgu/"(>n_P6ˈmSEdW=8j '8$D A({p^돾_՜O4g{TpW#pg9n+).orgGͰu`N趦9Κђ@ ۺ9K7m3m#'ih"?N-MZK2Q]qcg*zLׅiyd_S8☱zsƺ_"\pƠb f GvL~nJC0Z\ݽ" [Ө3' UKL."|jB] |gW{3o:E 5O>GYVm Is$b=sh5JnBxtfJB#3#~=d75k)u=‚S!WNZ#2MZ' 0;jmT vdU[O4ǿ^`,1^4;DgaM> pm;SwE8X >5,?LRlSL5ٗB òu㛅&Z ֬lg ow0Q)9U1ݑmRYE<_>/ʽUX]G2>2Vy{+JSfYBHa$69&u 6~;(r)t?Ģbh!_ )V&l;%bZ{Sw%3frhy YԀgOk.LpFW ]z^%0ڍlV份eH 1CF ٚ:yzTLw%4F)̢'f=Mpl&?j,M4Wl ͎^-#/ ֏'ֶ2A0NV9ze57E9_~FnXC*+I&M!"HAr`!Sn9p EzV~*\E`w>:?b2?-uQ[IrzÈO/LԀ9`a1`D.5Tz `܅̙"M*Q Z|~LUo/6 3,H+6GJD|^ι ?oۤ]s *"ugw٤p2qv[ֿ#B-lyI>,őfcN\DPM[}gECT>2͎U3n}U ԔEZN.DbFkNˮشAտCƣZz*=ߐ[ί+t̑{_BbжCR)p~q͉Yoo)"J/`&ol !, 31)Wk+adxQ,<hK 'GE"w҅ԞӆzY{L>"gS!ʀ@QHF%ֻQRs;(!A\%,^ H&Z7jY JQږW1iX?zP)^nR UN`;~?۵DkQq*A Ǚ#9nX&Z$'1"(HkItAf|~{OS85*U. fXq6*ik;rO aKeXJNM/:oZ?$~IyJ . D Otֿ߭Xzo{F8@hh%D"ݡ{T&鉹qŇ"0j?.0t@#A3lx#i#\8B/]#i"9nMG(T瀟y|imXC0q~q{(r6.].PVkKn|Wڰ츑:)t=c\7~ ̠CBCce=<:e{P6 Oӷb^XDyd,̧9$[/HZ, ""Q6 6t.݂CrXT^:#oojET6je { 'hqepmE$g 4÷{:1EX@0*R9E}fblnqD{|&>aī{CӟtxwyήXVc1㽒샞|iMTnH衈e$jƳo#h.BޭKe$p»1AiQxͲ<^*Vg ҿj@{SWgT`Ds/7-fv]OŅl~0.i~ކ֝YkeVF4Lu犬L󧟸"XTh)79=elbV|C-ϐ/&3;4H`P;Ꙏ'o*O΅U+Q%oSsT P1dkþ~_n*N[q.5q]z=ekb1ru#$f_(ܲ'@ Ӣ/46s #H.>p=9un|9(oTzb0p1Ŗo#=x az:Ae56K:Venλ\s!|(c7qmAsdUygn{%[.4n;:u,㻙9 %]\bXvy)6Su=X[//q_bN>L&XΫM-׸Š~0;?/ Հ4D\fu;+]ݗm2taKƕHٹ|Wia,#Wco-:ЁZƂm>j68wNN_ ѩ|b {:Bhnt. oR/6Sټ)$|7$mNމɴ-CUlDաX߭BCkO%\W2~&a N~|\I/B`eD͋zQ\JЊ+ZbȎ*3CY7ܫPӅ W'ha@ɌL,\>Wb<͎0'/9&)(:ӊ֒9p_wޑ씞/Z%FN1b+ʩO͵o0Fqa)[˃?5qK 4UU7<"P õĀDN8>ϻ 6y<8= :76~ّ۳KUd/ǻhm/h-?aOYl?PkpY8?67E%PiAf[H;Pa¥-:/Zb7l[-ΟyC)xҏ8ܙuOh~j*JlPK2{;YIJ+Q9q!Ϛ͘K.v]&^ ,$$s{6^PS~2椀"rw6oe3x|[b.₩l_bYԵZ$[/:LOW::B+M :7Wj I7Ch-noGĶIJ$>PX ښ@Q Vֹ] L9f0+|? #íajG27 S!+((js:Z{]M7ռjJʭ@t&˾"_݊7Rjmh0~%Q+k~bEol4Iȍl4C9ދO{0{F\ߧ$ʹ60 >o~!s ݃-UNnepXAf14>x$O GARo 򚌤r0,p,Ӯg4yo7kxni'cUS'!iGX_R%nχ绫2Kk?Syã~VsF,P%hzc>wl,Qm8ph4v;<pz@œq*?SEIGu-]I^~.^Tm7r/9^Cdx#AJS׃u'g+w:|GP%b_$FR+cաT֨!*MwS].9nU-fF#p`dޛa0ÞȎynƝ9#x:;8_Vf"E7kIڛ\& (F-8Ɉw VpdBgj.u%l*c6+~a*fD] {5KqQOGsqRsb^Lm9/k\j@׾~>SD9\vm!YPD +u<Rp)2َ6/{xպ#fk[}6OIF(qj^MۡޯwGk|&S"xLYW(X#g% </\ͭ?s/IBG[OP]G~f}VKFp~(?_8#jV) ED?Th/I$<aE?=?'Y0Yjs$Eq0Mz@vHgX..prOJ>Kf#BELH+O0'h^eMy O܉%ہ{K J؊$BxVJdy%f+S˰<ߔZEARhɨH*zjg'KR3hp< N[ՕYJB"u[,=,Nw7xظ1Fm GU(d33t⋰놰Sm|UZXg0RaLȺ0=GVT8 ov[i)+{hn} (8Iy_sYjC0~* r`A{4Eq._1>ɶZTE>R^CD, uj W~2EHMkj9#pA50OL0Mc x QIu_X"q Rj98%r4ඍPf|;׮ʡJ AY @x\KT55G![&Eث3Х}eP7N?;ҖKqշ|Pw/HI.4Itq ߪd{t{pSyQ*S}FgΡoՕ@GdgRB8X#!|s= l#S?j*T( /F ="sk~y &=k8%Ogɦ@O9?LB( X| ^ȥc7SuN@Kj4ұmj=`y;EM;wt!iNFacr(ZĿh Z8NοE7Z2 =΅?=HV:f[PW - )PxGxt9>贈svEȣ7k%4?e?=2FX񆡹N͛jHVaW(hKxUia [ ЉY:тnmUl~MO~EYɳɯ@Ui\a5+&mLů3L&iL_~S̅HfSsqճě'F0/[ 0FwM8HJ8~]T- *5 Z}܃߽Nc'9W)'2_C NG42tÚvg %='V6~jBέeFFE51fr*ğcqY{Rv?̕LDai=T? 0߂S$(,jc~޸\w$Ӱ"1ѪrE-H $"UQYtD{HO<[>ٺD׸UuEcYC+ra5o]/7le %4k܉?sAP8'+ʭ>/ 7CGY*2p>ʙ+1؄jbz`R V~OjTҁ21$Mup#IleCG%KI,2V9dC'{ o`)AIa:;h\Pwєi&_}G 3YU^F=FGPPvBn4r^+~{q "2Hodl- cXXYJ˥+>f%Edx UvPk,C!پ.c$-Ơ;[\NpHΫX<[%1΢̷gь79'Y>wi W̔mƈz݄ye hihG"^[mW8`8%/*Xkؾ<+"IbTޟ :#k]KYyUxd@x+kѯmxֶAۦ2/հ=`E] 3d}cI0j M_</1/Vc4 Q)Ir; &謼im~_$Aը}` C_`(tn }HDS{U#>˘g YkFQѼZ}KxT_0s3F|U +O =(Rf9s gA~R$4{?"7EZz!{= MM$&k;` 56-(R%Bx+b$Mu{Fi$yc沾Kp R8>Q9M"61_:>zcO)oSe׿o{hC?"iH4UetH@&^0J+p0-<" J?%n 1iZYI)L^ Z+@\<;/19!&#WQw &#[}m+ w ذereؤX{4S}ϛ#u` ߹uIP2LR054{O^Yvڦd1=1>g˰*5|e{f9F$,iϴc(I|KЙsL]^Y4qxt1}%m%ϱ!~4I#{u*=7yn}0&%aXg+doAߞ6ۼ *% q7-.˱^hmgaiyʒ=u9dz2$43[qڐ@f19,,cۻ]ϊ6O/"xmS[c-*P?H^F'JL~$_'oqyI\0BTh;ųu%t! 錎y|M6@VB|t z~[f\-|܏[ri ›@~[.i;ңXES-r ]ax>-uQְq[Jt9p.o9RMf*蟁Eekɀb^#%vqNZ5ITrLZSo漎u?oZD.aäscL,o~ľF|\npխX9R9S#iDڨUu71E^?{"<2Dug8uNWFlP~] T {l퉣{qOaN%m*{}:0`i(+t_|;7ֈ| 6 T? ;ɝV=@ ^`v?o** e[HLΫ ጞlXK=9 Hv}prSk$9 R͉*8[|ԬQ: ~ =՗8{FYL*s^MfeO;D1h߈0Yݏ[̚n4,bn>c7F97E1cI3d)FW?g7+*jcx0Mㅾ֑o绶d4uE #|lQ["v{^Hfz<ٌź.pғS{Z_-H[PkQ`>6WD?g}-E蛅upDa0}3F_Dbp! *SQ c(ǹ$(%HyJq(Ȗ천ci6g&bfl` o!FR`7>]`|+0y> H"F!!:*8$&~K7~'UW?g52P=ˀy~4MZC6>Ed#_Z(J(#FBB|"~b;se'>7H)bpDz4qx{fַ{dq{vCaie*WA?ou;EYKo\E"9f\3EB^6F~n1xVϜ8MKҊ4D|kk[_ _K&K$mʣ;z$^tk=+aufLO7-`y%Nk#M#%W-4.S PJ UNl ^ѭF?kt-+ܹQY)DIj[*j(ERY4E8=3 5K)͏77_ &<.3ʗo*bE"#֙RK,\TC䙁}j鐮F'nB!t%)g'K% jP;F//LxXZKziC<Ԓe$Iy«(g z)ɘsprjhVp ?$6 #ӃO[XR'`slcTTIz"$cִf#,$o5=LAN_Ù!O)eD!] j __eC*)֛ԾU7ǐqXÙb:+{$C|?.ۜ\"B68CIIu]6"glCu<4@{³ǰ˖Z!W8xmìЄ8$ADV:3V  }8f3H,b-hP +sL4a bq]~[qq_,7(~nІIu&=}Y@ۃL,a>~S]-FXp MtWKXruZ¥Ok!aR@ NYN1cA7{zQ_˒"͔⏌ei1)JU#4_҈oZӠY}74cx*K-ug¶tqNH, uTSm!W3Qcq/ZJuɀ$ll8@ Vmp ݎZ#g=uaUxݰ*qT*/dOU3rv8?'|:Md{dZV':(x|k*J_uZJc˅q t@қ9 j3~}E}*/ۊ Bm@_``4 9On$懠#R{x#cgrOD#˳^^3]Py%2Ŋ1 ^_$vR NܴME6 S6M6|[ r肑tj@|tfMq2-v HlO>UE1aҺZq(lp\fF"+yV(G:"mWZϭϹ67: G96Eye5(T9?7_P[voEQxw1h&wՊN_t(bo)d,E]h)qs룊<ߛqjyJ9P`+r%ޫ!LőR:sٱuC{4"` +jA,K -'buNͩ䓼ˆI$mdrp}Sl@)Ʊ _OzˑY.cC^2'xYzn`*[\1DTK߭CSF󹕝EVG*\/P{ ɟ I'{e ƠjL0C?ZG' Dұ{/5TСEgΣ'3wRN/0eʏ%U &wi%>&FqbQA\җ!dSAB0Ty28O H (ch 3됑tW̪:̝odv_:0/'J^oVmG ŞSS%QXϤquFxƐjz/BNT+!8aձn VMDW Bl#G$+>ݪvs*;|'" |y Z\ TÛUe#EFڍ}|߇0e)52Wt[vhhT/Ekt2iWٵ[]SfrFzA-2pz=YQ5}es׀m'#h@:`T?T=4/"X:Z51Dк9f/<ֆ'JYok}m0~=̂nƏgVjwN-]3&fdzo}VYZ΁Doo6qOS0.2auxђGUִsaUNe;gUH= ]qX6lΐմny `j"˿jJ`էu刜`wV;!JfTh:yi'(2>.N"P6ݕ<%Zs{`uXĕ <2ֽ؍} ֆ\JU-d6gnrz}ҬYO{F>Pfz")I+Ht4_`)nMl>YY2 %j6Y{Z]8}ܻ?ްʯ0Skċr@bN4Q [Lrp@E/n@@}" 39]u%I2OG=%܊ZtK-Q`SR [0J$D$Q,9Hފ9@+r/7š5ƗDB􏻯8zh=v9 (Z<8rEaE I?1($5`5M3Y98eTDAA a^ rjt*܊[ҕH:2rfB eGIHu_`tMcʋ4>+:^j޲2GMS7ZDAh0q£hL! ^x]貳ׯ/O攺WSa`F U vH]xUIj%4WS_ ;qZ+@tm7*AZLl@, #4{QOIڀX~^!D'nku!ٌ/` ,—3}ݷO=tX;t3R[x9y w@{SC5@@4qvhV$ciBT}N8?aU Nn q_\AVR5u)xwxsـ,>Q.  kSO mQ:V(4iR\YbyaZ]SJ$bCr~j!H%*ӎj~wŒ NUPɛD;噕s}]IW$m!sVص_6dGUgǚ'hٯ 8Fp$Lϳ} Y,HHMPMMbq}ܽvc)Ԣj:`Ŀi$C$\=}^ &*ъN%/!Xa"+\D $ab"n,y2tp1zݚz hҊnLWX6Fct.Lk.߱W|s!:`w"  @¿y*QcЎOq`BfhR_9v#[Օs x2%,06YY'M~"k 6@% b|ރJzk<B[͂aqC^wxSKi {Y"E|.hc̋Ş:K cw=1R,wG9K*F}Hҙ€ª]e5.@= _w@@B@,qPkEηM@TUQv`^||ouڧITu޽ݼ۽l{޻ocA&EޝOE^Twb@J/fsA2twXya776lxOކw5v.>|{ kQjh>DR%Ǭ)eYNېoc]*-գv3}{3{Wl_}>}i}Ηfo}+x:w;<V-lbmC@p!}ێbmGg{Cgb}{+-{|:i;==^g'fpwS{x`xMifR֩wG3*>}aサc횧b1jOlzw^^>n{k(i5]kNVn3cۛ|z>T,>]vssXTtz;績{}M;p6|#fMwy{w7V\뾵u,y4j4^]{I3f݌ptFtV&ulF;턥^j {>N-Ԍ{S&{M=${}ZpEPSzW9wGM^t^HP/.sUuۇ}{g*>;B-7ml}8U;vtzyC}b[jz돭zК*^s{^׷I7kQ}Vӣ`wS7.9'd|jnZ1jmKݽe[jtL^ԙ}(fyd/-E \T{ziݮUosJCΩ{uJ+ҍۣrnI0ѻWӠ%U}ƾ og<{wi땻+[}wyۏ{qލ&cTSԲ}92ySMVv^}(G|*u!k1y\D@ had*zTOz)OCjC4$MA&LLi"HZ}Y$|~3Om㹳5ˌbm.N0SS>ڼw~4QUU(.aPW B!* H(" H%lb)"iUvWUdQB-1a *% OLM%hwtINEc$MCpzb)-{b^FSlSk&Ye!B5JE,,-ĔkڼkP,1'4R#@b7:SwUO4guQum9cn[s뻻dhnnhɱIb+kRB `J/rjhi6_IFzk-m}٦̲|ˑZؤM^GvdpuFCzfۆyWfţPY*\zmyTUZV+J湍㩭IT4` ߽@?u;m2hg@^^ rfUUVYT p]H]8H @z.p; 0p>{  8spsw8}}wJHMEY c)+LDQEB~b?>Eݹ`?"QOW_+ 4K~dKg2ʦots#G_gO_Wa2j@hflA"}Q2A9O\Ӷ̿> Ma91&4"(+HsVP5{̣7Tң48vg2 83KF{5(#+pީjᑾ<,9וּsevү.ٱ_V39ח'9olf#5Ng m#ݎ3oz-02o %Su 6P"s| BuJn$Ea;C: 0Qh]3K.ʻP?b (O^}3춿F֝ܟ7cnp{HɄbK%FR=+lc5z$uȡn0&$!g\Zi!%KBa44HA* ICii2Qr2C$4AY9 %Fmhe4eYN  jE f_%odMݩ1PVmHҳFfM3n}ٷZM;Dv&buYii}Ք_;㗭1KBhlg-M}nvBWgnѡ32RE@A|efْi%%_t&a p2)\C(V3xr4`DLKBũP2WIK_vj@A,rbuM_˖ӐHkyX5_VX ё0$>2Tbd &hBlTp@({{ HCTRCRHm h u.B=[W]\-t~[RÚIliB,Mb84r`% v d10ZD܎i8ަsĉ!6JDE=9F5!{sַᴮ{$swv\G5Sq۔Hwstj,XV[cSn !@)KoHc_\pq#.2&&ոƜG<$Q "GN֔b+aҴHs#k-FHš*$İ04mb'%L2XY DUQtX%EK4\evCp& ,:l*mY& ȝd1*b -F0~/hԒCIwP\ۑUj [*+R*Ef%ư"شmՎkM"PeJԽ>`޵!Fؑ kC1Tt 8 e9ZA$R*5k- wߡw )vĢ]g ah212 Al9lbR$\NjRMsXkBf Q̙5P08'AbЖvS3JBPS I.k  nWnF:Bc:`n$2I'ٗ/ZY-v!Eq~Cyw}>}g/}w<ץrN۔UX*Ų[A9 .JXԃ,7-GCrՉ6+쮚BK>h@#/zAFMI"2 VQ+ER5J PF[a;Upvtx;k$bDIE..A44~cX{8Ck)@/~]sy^{;>w5ǻ/:i#:A6exS;\f(UTm;l;9+bp:6,7luW @ZszSVMD[(jP2ާPm.CDښ幛fuӆvPМat0% M6Xj狑8sR= o2cd(_wۮmDJc$]CVLm RVHR8ea9 $ 5jSx0g,h?ԸZw%-P;%تT͡Lh2lq:hBҵ!kPhR@CT⺏RKMuK_G>]^e)цn("1cD.IV7mZ2l@w'ͿZ'=BمjÉތ ]SldǴMZDWnep`mrU,EFd4!_ƏVqX|j,46#mtz5V:єMC54)cuۯF]^"ʋMҋVKz"-`dzŬE);G&ނQi^WHv)c:cn( vGWUK )q K0e\@Jt6芁S:YT_eME-!J4㈍#!_ʻ!AGh4Fn"PmkPyG0[bIe5cYAyUE6x^%=nXUn{kuM0]3 TEu#4ei=+V_=ܭ S]ʊӣcgR􈊵Y}_V(/Vu¬du3}ue5X[t4W 4-1˃JS +_3N#Н1]mӆ1=#mTg;+`说= z*USry1fUx6l/KoKMn^g =H`X;=K9v v{h3xL Ln,o1 bPd.po ৚ S1ZcťL Cڦq:ɓ'D yűf`H3"E *U9rUiS<ѣJ[Ͷ<JN^1thpiݳ^cÕ:$l0 Yrƃ XHou"-^}-`>O'ܲB'+ "*d0 ";r}dX+R>|`í~I.??'z};_(yGN:p5 IQiQ݅?AfeZJZKT-zyW$6J-“du/p)|3=oR=+UW]Zu{ߋr"4ԾGN0RD ֲZVrjJE*w%SOק4p>@OGH- R!؆W2}՛ȉt8yݏ>@@ \)A A1ʅWb"_S6q{ (wA{~@PSI7 S1Ry,aCjʪd12Z\apqB*Q%D&P BRjnTF$J߲U%|o6{NmVj R#KP;%N %!RPT ! @!Z`W"( >XT@#QȻ{TX[S11TT)PB+(C P*D-*a &f" [$L2Ht:դn9;QA*jgZD$2r@RBX+1$&QK!MeURb’R}J&LU;Yp;`p À;$CK ؛ƈDlnDxz]w00 .˔Ͳ$'`)k8 dC"$"CYu/aI!i5P5SX<Upm(iCA: -QSjfʪF**Ys)rZA⇑mRh\IC` Z=r(eEPv DDcU$,$@Pa|%8ӈH*=$'d0'J&똢kC1 ()Ӎ7n8i-a.BAQ%wAsFiؓN2Y8ITީm`30?D. RT@D`tHUBҝI\!MG>?&>`)Uy'tB BkxnR+]8)*F,6UI=` 6dk1Ry3}fwPg@16X9HZfCe;AcD A19N0F"hGmhѦe00d0h&Xq*p92jIsS}7vS0,%-3YcmN8CK^U됱}V:t,[T)Lɋ}nnɷ3$,Q2Lh)gsDxz12bd1Iy.+!DYRѦ:48,+kL,iCW!z8)SD*CU6 bbFRL7kF'Kh?zRH{RAy2t \@KL9XL < LwwaPRzvy#e8\)zMt/QOra3!dd#XIzaT옽 4zKbw:;nHT1-L `$aXU~? 4-HBs,sR@>{񐇠Ֆ$dЪ`|0ب= zby&'P:ͥk@q(H{yȯ87m@B!rE30 r3U$-5 ݒ,QrLKQ{ء‡npW`:&.@|9xdrW!5nrkn"23MUrS5XA5$C5C͘;m{/!# m( nXbbzDt;hGGnԇfw03!%b`=4_^7)lb `\mӦGzX"*0!H $j|d5fL]qۗD}j$=$ {7>t| ѿEEJ'9,wa?rIm^rw*.1p1,i< !HDB!bsK?jfF0FMeiS1hD9 ƄPߛ~.o~?}|Xz3{M_S6ypje|_OE*@C|mPJ%;]1d\xlii99;J„JG^^~=~1yyp74qc?.ȎO+{:C%[ʑbEeH8JIǞ&Y26l!Vw xyxVmBp|7|*ۿxu.uBUQK+Fj4nWFp䛜72_mvYY^ 7qM''F #snX6E[V%'sƸ޲f_GI}^n8,w.JE61u3$ny)DTצ<_c۔ZipmuU}d!pTM~h!;8 T|Y+ G>N`Q*nAԺau䴴QGĄ2Zĵ*ؔuf80 mP%ؔW\mb"tJB XmtT0g&Z$*o &nJăɯ,}Yʇ {h;j9,4_=(u=nW^j)(2M~YobS,@@JTJXi!5`Y78Ps3`Kˁ"@?4:;>06\xMrl:.$Mlp pYw[`C{Uo4) Q>mWvDuU:?N-ڰ1đC!M,!nfbUUU['J) Ĝ03p;J`ˑqi:oUȜUKW/h-WDk"$3znKvQ5^kd5bwb# L=aoU`u Yӂ4k06N> SG0SӅ6`ТR9 Ϝ,G {v.v D1O2G>ڱ>^hDFMQ4cBLFLFZ%aFSJѤTcZRiSJĭ0RLV+bR$^J%$ʒҒYJ$QE1JڔUȪiƕM1 uI$+ҒJo[ITe-mUadI(!FQb6 ?HyN{VE`=8ܤq9@( @0bLFT %L&0  i.@+5AX+{`$qAbc qF#Ջ [Φ854f*c4cmFh"$zCqIH RBn\CR!~U @z/,}P0KII<𪪪AHg M@U&S;w)Y L?׃ЏU-xOt0H)Vh]82 Jn*8ac6E%kee[UiАꙎ>-n̙6F6R j7kvc"0ͷCs!HYĦ GfcRQkAGr(|~048~% `ι*& B Em 7H |B6v{j@nVN%̺",`5$A)!,;Dxi=+nE]FzMb%d\%Ͻ,9pL LsI$.;'߾M\FTdj)K'I=ulmH0~+ ,aN7v)C]bEG_F:ZVa<1'm1O=~;vTcpNRu~QR( \ZE|'sc2 Iv070G%U.gܨ!a l K&R g a!h!Ħ s{WLf% A".//X$<36X ж-$,r“V+hhIs}rW)e[(3!꫇V$S$Ͳ8 K BE!$UTgel"# ш#:f%N]R`$rS&ha0 ؤ )??ȀI Ff6ٵ+DLR[(!.ָlN@p&ǧiu9Xlmp$gC|e&E$T& ]ta:.u<*C'}D.Aӣ`jr .(*C2/ 4R4+K#JI4 M)g H0$wE;]alA#VxQh_Hh|i^V5\2bP3@r bi( zJT%Jf i$H EvcP-$S|(l\n $VS_NeHF c=ՉhCZ7͠<~@<1I}Xй@z 3dž|l%ݍZ0ʪ$JPLp-ReOܷ꾺r,-BGgjRI-7 9p6ݩgIޗw>WҍB"&+lr(1*m]i^m)$1HyPFId. h4ׄa$Ȣ 4f BQQXU6MjYT&CQ)(,Pcl[hZDD UZg^'GGUQ0h0jOXRS^FH{7YCz = z8)̘$It h[넠oAtrqH{I}Uu3+.>yq\żM1!7~6#ʞ،)0pKR}Y)IZ@]lc$s#d4xIkCkV$#D} ]0$'ŋs8Lc}ow)JͳZubdauDA@q{a=D \!epgdƛ$gv4|^JPEl[WRWS7 a58GPYC4Vǝ8d$*$U%,Q!H# $i  zD$ˆ' i#DP*Ju(CI 8?<*R  z28M= 4 nQ װ#D h}Q,{>F("Y b=Ԕ< s,h fF~1QɂOf )YH,UUc0{Bg~ےD H]ƗZ(fb2t'nth9.-z/Z Q֝tWYJi,I ^hDys(0!mQBk@ڻ>4Yp;L:vh,t,I& kq8;%k1^Bfy*A@̉7$" I]b85( a83ȤF*PX6eCI]4%)4&h` ࠩ e. $t;'y:ͱԼ\&$*qUTxH#%ަHi2ejCHMRoTٱ"%V.^$\7k֗itq"Քfp]Y[u2fʕxNOl1y_VOZՀJ# s9> hIw6d>LOo1= &4-H3+m`^&9DNcSR3ʃ25A3Cr0xTdI8TO\4;ϓn68;~F  ,f(>լmuw.4$spTyJB]$&ka DXd V6 v@2}5*Me5oojae7 j1m{> jKg'OVs8R=hG#~+Xʴ+V:U֪'3yP/frKDE(`K`H=[^h9BPOp {=8ewZ ((\!0g ˯>Jx M#Qz-gӜ D9ráh&WR] RK`i%T08㍗=8. e5<`))tyHpo瑱0[O^BB9|V`o)4=Hg]E:D8" gQc%GbC&1a"Q̼`a. |jՇdPkqlWcug $ ՚VJ\e{\""E @rkD(bmT Va|㽳ph#/bJ0`0\i6NJZ^ORN牌`>;VЛgQm xa۠ | DyGjQȃ\zX>Eܥ]Է*ժx?3HDDb! R#D dHLPi0VwZѤb0/2IH!F?2ZԲ[~ccX[k젤XFl̾]Y&(_o< vyM}-n-3)C]Ze =?A=XQs$Tȋ~ E:scv5yThcjW|mk.w[i O}rۡY' o=j(}/'f@c((F"1Uch%͡';ROgO'yB "FAc"LJ5&i mH$Tg9}xmO"Q4ى͠^Kmez * rÆ_daƐ viapo(CUy0`Ǝa 2b.N}HUvT7$=By lΦDA@X\EDٜ5kyI ;zoֵNGGL{"5ye;+/*p~iTZz9&Z?mmMs"Қ::R)Z֊Yص"庎|"łT55E~iW*5L#qX2NG1}]Dm!m:1AJe<:T&;/+}<⊲$E:YQLKJw#Bu&AkJҶjaFC='x <9):!8{{s95#4齥ody'9RLRT_ 2q]xh;m0 a"Gz$Ń~1AD92¹ oDIbbLk'1$43RPOqeK5 ʌI*S/! D2y *q!0X])Ycc(t$f$I04&$l1M&DgђdQj)$b&.e,`l=*My$ r y-ܙ8$GٚOb'A U*HL% Ī vlREmKVMeآ5JME6jX&"%6K"*Ji+^4C_Vߧ[k.+].>=?}ovUI$]/\ߥ{s3<o=9;{:..ffff.UI$K{Lyww$34W'뼤?@T׷"8s-Q~(jmS}u`^/Q^ۗ+[ַ!J["}VBTEM~MArjšX}g['@P`aOBrCJVaI @=ƿzt68A3+ofi*7c0'_5vQCF́o38bT&R}p|q(dv)t?o?v}0GBDq]-Yaj'1bbő*)\0 (zC3>{Leciu˯J]c6 X|sy p;}#dPdla+3,,i}Xmg“~zZN%}0ȳZ־Qq=#i<%X*yʥ5%J{LѵiZSiYkFҕ hͫiUB֥ yKfڇ}FmdŒfH€>yq& &BSF/? Z-5BW$e։1.:j^O=]e/U MG/sǔBxV5>!) 47"nH4|\*BY L8) IY%$^\rw0a`){20@ 3OrIWMv[LbdDx\;Z ۷͸3}I}& H$F1QFewb $jDL+/_Gr[>%\]M@Է#M#>b&L>OO O>ceTH:@]OD !80'QMyFsp/FV4Now8SF3hÚI k-#ٿGٵc~)~7\ ,98,1g8Q9fh9ү;aõӯsFzQ:H^BSŗw3k[w^XonH.ϓ[rfaUHU"%+`wqk֎ Rʛ-&I9!}|^{!獃 H0BeQAK]چb1'1210Ef&?h0'Xun7S}Xx {$yHy*W}›͇fy0h|V1.x]V*(LL'd{MϷ[i305*Y*Yyp !D/x.+S[pY8X &"b|NٲM!S((Ѷp(yb o :/"ď I}bKۂ]F^u<]xbホ%`ݷ*5k6AE%BBq0(“hy)q2V3$ڞF#Q] (QV2z/b0yxz~ ߲" F㿤8oHٚ>z(>mAxɤ#b[6cn%,(oqT09誣Y(z7ue';/EdE}4)=|MCFJ)XBO/e Ջ M`zwI=w)ȝxڄJ9}d|;:ao6aEx`O4>sYdA 1mpcώ㍌3<E"6h2/2Tcp$@7,j*C'=u[-R#7_ӷn)r Ieʘ( ÊlIT- `nv6[6ܚ֥ӬKn2*1ҵ ,ow;7 rR^뒽7wvrc kuqӔFK.mY1Hաp;!MEmN[fy3m#j NsK?8zy^R$"LwJnBV3#Ͷ)in"q9(Ht<S3)6fRo{1לVY WKkWgA%cw$% GEs%yTװnjDda<( +[f-C򙄫^EW @yWi)62K05eZT:Ye9sqcҰJRHQWYuiǐPϒ60ɚ.7 zF-DžVs| nI&fUp2Uf?di`vW!buMqI;!ed $P7K+5TgXLAlr[-nYg;3.Ëi>l)Oz2BD f2r[g%ԁa(RrY;ptX8|{Ip0DSDr`^:]e!=HA i7V hh>͇P}@! k;$),6r=A0SM#TskghivS(;Egz@WBFS VtSDH*u1"vyզ=2Q9t)G٦3zuoV'fĪj\7ҘUNE ' BW5\JꙆVOF۝K)-+&],x=q—bR6vM\`` ꤔ(!Ӽ摵f pX[[Ux b=DAϧB؜C /Ja2 {ǰLҼdwH<%}̛*X#53S#*o #z R3}3g)\%:H JPA si`0ǷYa(:OO vf Fy҆DE _Yfk.-4y9X wƼJgZǕ`6# X᦮[[7q,.-G|fWݗsLFp:j%n\6\W~rQ0A#T'h u1.¶|F ?;)1v<1d&'h5e {Y fu ;$I%=, iu.;8H?U6i+*QJ1ȮLaU)XV*i*ʴJrpVUUJ1XÆ\8m8ci 8V6EL`U+m*`TTUUmSU1.$8PB1[TbU&6LQ)\*mDETU;(xPVԕ$M*U<読6pڪi*+)Uݵ*ֵ4)UiS#v ?C0X$'/kMTbJMeeUx:D똝%̂+3 Y,-H5RsԣJTFܕ3hn8nn]O&6ŶF,Y$ESWMU&F&4}T,SH'Ck( b'}wo:e 7D2We(j&D(]ߋJTԋ)2 D@+8B1?dԜY!"Ƞ$D5 dU 5%"0T:]_-x)eD$6yFEDPhQ8L4gUK= L> ;} *T*KlMC⊄ډ >I*cF9N\o$q&塊({nR66fM^㷕׵q|Woo$2KmG9 8snX nh?C- A-RƙlVSjՑ64mDjƢLVl%RRZ&Il,sB1xB'Uf P!;^R **d@H!%B[)}n2T*ΘJkl|Ơ}os:CЯ#[ yBü{l`LxHՎ ikmBQ/=N+ޚYᾝK?:$QΧw[њnz)V^F!ۧo=SuB<W}lk|p5B if1# `2|aOXZ`A`zbi^=RYa H6~_]S  fL +|}gC-4z'bbn'2jveU6Q"Y5pk9j=nH09c1-F:,%*2e)'07cEi2jpqt_0(8zn\Ӣ^,#chaUQTO3bfgy} HcuRiCg]CM=9y[vp᪾<܎ܲʪeegOM6f[6m2 9(QUH%Ӹa7<9}'^6ygYk|UX)6L, hҚ<]Ԅң3~$9o^ ɧ6m,v/PW:;Y|0{=gSxK%ݤ ЅCc4ru A0HZf?EfTPSoû eQFr Μ5Ku&*=< &%l5j4l%K2ET6QMKc$KlB,xn#G_o+I aRɆLL1xx0Kn= cQQcEJ״ `9Wja``ħ%2 647f́"[w,1@f9BCPR]#Ql>p2xBa# MJMEq1=lr ^"YQH~e DBq\LĆ&l1X",~!j%G1a{YdCtT6_t09Y-#! vIQX5[YO"­!@js X%3\6&i LB70^h\Hh[S knl"hEaTN,2amFsHʀ@m/zdV&fĮFA߇ !-_n)Q8>pުwgLBPHt/EZb.B(͇PK\,C4]SPHjѠЃi 6Bqܦc8Θe*$s_UNftSja)Ln;C݌hŀ*PW Y"A_)RJy^[x5`z2z%NJ{P쬣m$Yr1"Դia}!Aܒi h'𯪐*D)6ITa=VB9Ƃ25as@Ѕu`XӜəLFCDMz$da}'] , .K&x[EûknJJir@b.$1#;&Rz~]׶ToSRj('͡?ߛrx}z67*ZRJf*M9DJJR? |bܙŐg }?g?OAv?!z/ O˦0l{;42=;F) ]x"5"7"5"4H |ʊ^~f)c ,"b[& K-M`䗈ė 4 K%"bQ*D(,Bی̍ 6/%E?~%y%We6#ϵ}($+ &+؍F_@ks?rꭥ7 B3Ndv Cd0bNď /aDMzp+l nʒ(%WM~6n" d%$H{4C t0Wsx(;?N&zQBrE@B1ZշڞOwQz-oczR83Hc%ԟCSfcI&FWQoj{{6b7"QR T¦ 3S${/r@ \ryEKmO)Ci AH8BA *cČDNi;Y$N&!T~g@qh N/G[@KA 61-?^CGlL㒒RЉ g㈴by-|_kTöGJY]P[y@G1Y{-Wr]_ѻHL` ggnzC=!aaVM)Ńe,B{``1) >h򒃸vs=rlAG# %OrWp;RI4]wg`Q^So?I$A6!zNJY#DZ?D)JRA| 80-Ϗ$I']]~ wwwUw*_43ܪm/z3*vB |*z!pl EO$ ݦБ,R wLݓ5V=_Q8Ima$DE C!`cѽHx4HI-1\dFCQFN %XK#hsP:gw*ӄؑ"Ii[18rwQiRS!$NEn$(@Oې$Q DVu}G-qR̈aB153Qpnu9j[cT(Sʍʌc _{hS6gm /qzw|~;xc=~m.gǷ=KURضszK\Rc,2̝MiKhw"jI6kG=Y L7eg l󎃕#8w *f$1!zw¥n2|ΔqrB R -h^d ݶ]mH uN=~{4(Х4*H44c.~9)4#ڸ*r#C<\@TxЍq#0֎&n9TtF=Yӟe8?ZLW&0/0N])JXex7"-`D7rHǤr\t˨+= \RꚥuctsĂi1,ӌLdœ,FèHʡQ7%aB~-O|'Hub@HG\`O.'**כTHaI-EQH5(0hGbE!o!2ڼw. (F=0K2#ҏōM,*UeWo =j8G(~hM!e:;:7B˯4:hT,,>!gLg=6]HӖ/ZbD`y_ILr 2z3c+q,QE/hV[2P`:׫]#zHw^Ѧ[ծ6V{_ɦ)XB.}y9ȷvo!X)-'eN)uvUWAlaIԏ[G X݆^$AV`AE"OMM"~ΘЇ1Y(v"a♍9~ t0$}& ~1|@`B3HhcXd{缎%Dk$6S/Sie⎾ x}7>nK x.zIAxIz>H;˥/*UR/(jhuR Wk ;m썤6 ƌ6ms% ji*zc(iKh_e툛l'e> !"^bTUL\< _Kȡ!dQ(JCaT]mts {ﻓ <$:(z Cr6aF jqA~o  yIw!m(2PT"3=0Y&Iؒ:vkP6&p=b`'[w NdKWÐ0DƐ4O:PChWj&"mCܮ{pnb]}vSb9upͯL)" "߻ӷ:,)'a$b: rx:{8bRR4%~M`)s ed? È uG82sG@Z_JCK[zrqhR~V#4ۦޱVj1jŧY,*JVt㯯]zkHccsF}TS{bV3yn;&E3ݘjhFL}zmYs&pe-ZDMòPtIuB9_xڡywBC bB!5D_iZ&ciAW _NI05 PD-}'my|-N;07-U:Rh\0jIċIx톐AEzߊuΏGN} V'0 v?+x~JR_firIJr\9DaǍxxݯ ۺw" #x$Kv>1*gTI$RI$^n^.I3=\l3%TIiiY%O2IU)DH bUoyUYeeN5[E(sU?D?GhC䰮B$!JHK /dE  d (zALR7bU*PEY0QJQ6S "鍐,"jտûj6&y,))(!\A*ۼn_UQ&R!L"jlv&S,iSKQ%M6U5[L M)-SUS R6CjJ(@\s1GU/a 23Nɸ۠xθEA33)8;TI!rRGX ꬙ʇ?|$!KYcy{~CHI#aAKy YD~n&2~տ! d*P'a#I G.i΃״;D"3!|:j`iKփa3$DEHHRaflj]n $,1"HinKd o6|-z^'Rگ$NT@<{a9*L$ސ=สOybiQ~Q@@0Tff""i32 J) "(m"$VzBgtm=Zf7ߙӜ,6̾ޗ-oMo8hmisU;z9uo~\`ܦ̡52E BQ$77:2W-u)j]cj%L(ʬKDKlRbXu|wc`4JXas+J\H[jK[*suF N .Nw76۹7z\mFVS7Snܺ3I&z63 (j] m1x`@݇Pti(" @&fkb.r.r+v\  80EՅZٜLiLlq}8{~М#$Qe^Sϗ䪦CLG66)RDi@ P:0@v".(;tELSIWʭ5P> g̐6},]O78?` #|SQY' OޒjXǗG5ÔZ1"9!Vu Z`5! ?m?j{I 9B]!/-mL^DڞH$s<\arK l6NgR DF@§|Bˇ]R̤-!G34c?OTd>qyeU/qNަ2-20*"q HП\Vʪj%؈lv#$x=D 7)<HhXnҪ›M>1܇uvmmmTߥp :'Ht @r<~o]DG 88"m6sM~$<f}mmosP _ty6Ԩ,F'WG9u:ԭ+Fix:{R_"zRxȞDG9=F9'G``X{K!<; ;ZUi7$rE!E_HČ%' &8Y&'^ʼ5~Jsヿ)Sw(, v )zT" @4()G"POor/E1 xth4RIX k}[ ] )DR-X#/m.Qͥ1V `JP,L[ #@L W&jW:d 2M4v$1Ii@~kĭZǁD$dLyЃlqYV&ClTUK4^$E +4Vfq,JhP+I-wo,V9G L qɥרfM6!TOmDpZEp! CCU(fӱxs P9R;t&DDJl*bXmUQW.ǃJƍ|Qd&iiiiEQpp`D"bm2tk5K D M  TM7;9?nnVv̥,.=$H5LnR`H;i2X/V% j2 fȗ 6:y,55:Nn9qZT+YWqi0?(%A!`{ BTjUiC?Ձ/}kiͰXfhZИ ˜JHcOH8BbxXnTὰ!wWMoǴ :ұhd_MatuP}ޞailbt'cvUY"!AEA 0\+H+ \M40m1-ڵ**Z4"; si)[ )_7II:%6cV#l~TjbFTҔiMMM1hzק&ch4QHO'b>8ͯIn?z+̐ 'JQU{GRbi,b5q4%{SN'yӗ*ͣ=Gc?MCiY#D'ij-seo*?UmmWk`a C={w=2rr>'zV6(.D>Ո)"=Ԁ?wf:´r=1=4땯3M?Oj`΂iT&J"KDRIQ%bHKoͪozrDu4ВDDb%xX ccmQUJE+ E*VJJRQP4*h$Lbbcp4`ܭlc aZ4J)p)¦*mSU~5LV8bnJpJTҊxw%ğ$mYSMI?-q#XP7&4sN2I%= bX1\)64ەѦb$åZ2D~r,t\uX &B#jʢL"U#kB#5DU}]\&@B JORC$j"k hق{be[]HV?R{{n"""(""""""""""""""Ȉ""""""""""""""""""""""""""""""""""""(""""""""""""$""""""""""""""""""""",DDDDDDDDDDDDDDDDDDDDDDD$DDDDDDDEDDDDEDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDZ Wc ǸR;CgtZ?LlGC!)cƜ E22C  HIj)MG0 AhK3 "I"EQcIb;yÏI$J<3KkaĹ{B|7ʉ}јo‘$m$NP1AOCD'M`B{~jw]0QDةM!5XBFæqg@`+̞]c:[$]$L;xq7~6 :\԰Rbmcx3 *w%\QvQdRKTG qH#m:@h8pp 5[8>YŨaI$]:lQh9H\`)?\SLLڤ6tJv+s; t(D'CafFPSG!?eˠ_fI`ރAc'_0TAI&2\u\6=ac&c#k Un 0FЋͣxl7AB#Kڐ(m-3DWnKb5)4$k@Ƃ-fA)Ahņ ҹѣAk F8փ;Ś"-?>"v.2{rClR%%{O3W|1C||csĽGPň jBՅjI]$b؟NΒ<^/jF% +o J8GOD+ҲpuoǥA/V X4,#RK7CZ0ŤCh51 _oq>_޾aU ?XkYBg.LSY0 Gg$P.F?;ﺇe^C!Ƿc: S 2+Ql}FdZ^`Mey4P%W-S}YC?z4A"0xTSE{%ۺ:OR"<>{f0b_~׆jk+-,eJC3LHW,,+Z-Flx$IVjB#LmGל"Zu REJGZ저.{;%QHu Ubb2JU?(H &*s?`OdTPP:~s-DD۬IMId'4&ƍ&-ВgrZ7mFfa%:ǃ:@ !$+ PхTF⊉#i|J#MNYq=Pd>o<+"SvBvNm@-UH.uצnFr(KN '(HӠk]f I$#0]Z>?syD̖Dpf"UQ_'𱿤glD H?)d{ILIAx"P7mʒ#)$7a{'|皕8'-7bI0yN9rs7KI7H&#d` k!h"4<(6Ў_,RF#1 11Q;URIRlpD4$s=; ?+c&|Wݝy-3|ouؖF[E‚Zjdb&X5 y:(((((M$s˥ٿߞJÂCakP1x/Z0E;wGy uJԼ#&`w`YGItgnrB⬸΅P.hG1.OqT~LF$O9%#BnJ t;xdGwn:<,Ѫ:45ٹ$XV!;0e2z$sj* 'Y``nN7.*kx&Ж & sSb!D-.pLUL]lUQA||_W Z|oZĵw cjO%ݗf21Llr/.D\.D\r#)~^oh$l"ԂJJ?{c,#s]79n-ٙ~Ac$?~{UmH`} ?3Q3E4Q3E*]i>R \p UQ c*c؉A\Zֵ+䁖e f3x7urgu[4[?(;JBB;V=ZFH \e~@ :`; J&@r_bw.jjSn[2S"2*G" }263'4keZh" 1pfϬRAk4Y.@)𓾭$ҘMH ClWkQd& 1/Àm]P&K@w8 0PHmCz8<1B_֏M-]%MUW~Oߣviyv\B$-w fkq|ZBԤ2zby{{ Ʒv&bNzW{U{|7o)8Vϕy쇌t8pyxeThJ'Rlʩ4V-4ѨQeRU),4ÕLTG]A4fNu:~i0 ||M@L;QP)W(6Q_Vq!RNSkRvn?4dJF4}?O[s՟D}OcܝN~O?q~ iWN,$ GM_c0c2O 92}琇ߌ6| ,*X[C1X22hKsBN0fz @.TbՁ$m':ZbK]B_܈\,i=v;L""(quT:Eƹq4s9\n*[[[[[[[[M5IPMuE5pX+rڪ1xtuUu t0ְcS&7,˜ m:G7f1i2M/X cY?.@tZzP>Lܤ4]S3|//컻˻\\!,oDX=nv Br,6硍Svo:-+YkJ̋"F7+1d;^oa;SWt G:yI!$"0ēd2=:i--{qtYmTږ1` gN.o?t&9UUEUUUOm0 {W JHZ4H[Vxu$HI!+G?V{}!W_,O4mt[X[m{3صk5kѭ&e:eα"@xɇLRLRYg$bbX )h]xw:1Q`?y!7AثgL r`a٘ffbC!C]qfd-ʃ8=wZ(vUs)C5MPh9 ^pj-fcҝMQ:N\i}}W~'wET bKqe29D]aШ[Ub`,ٓ8Qe̬Y {mGt(fqʋ{]WAoɫ9sN] 픶ކ‚gy5umiv")2y)$4R !7kZϱk&fI><_[{}{6m)jQ`rh]\]݅݅ݣbl ޕ|Eq2#T'ngqխF)ʞgG9q+GɇNC*3MZ*Z˿<9N\ $.1Η(%sb"˞جA÷-)JDtk^v9. 2XuZk@ Ϲ$\ 8.%!4qrnAԜB KIyO#KV*"@`T"~pX @!p%& QXU$qSA "UHHI E(Q=8Q>a?>!-WX$JII .bVE :`#Pd$ %QzyM, M#QsZz]!fYkYA{*VbLIj$Zyq͠u:z1LR^M$Mzj[#p"|vyɨҧZ6~_.~~2Ba! JĽX6co>;hp69AĆDEqC*vuFWӿCKPChc~+III&n}zk8LJ6IUo~L{Zd S}c!JI5DGN>4n/ %qX0HpĿ(vL-Yid u{$AkFbdUC :a}RwgTO[9eTe!+r '3̏61aH332vOgSCހ ,3" 33( 0L$"ʯJy1,EDTU G %z@U}m*?3?ke: pX2 ~ثtknj,8QKYe:47lIsz]wr.,AAAICF&dFt yd.VQL2&zTO[bʨ0ڨh2YX\) Sj4f-(mT0b0$!7ĺv0ވ2Rh 4:c\r`;(LqQLիz]o#K#e"fc EkZwс1xCPiЛjYgKw D6j۸/дQp"Q4T*I@G){D5ӛdKNި QTd o9t)ië*L*bɃWc\\S@T{Hm44پh(aP(ޭSmiZ*XT `WlCd`E PfƗ`Z8h 4m bX Eb(%\ $6dj3Dt 3c,G,-{#e .#j$vt!h,ш:IzO'J̀cBUB*O#ad0%`PX07x 9c>Pt|wұZ̵V4ѨahkAsSԧxކUWxጔaqx@*(RW'tg9KiتWw%J,c %rosDUQ^~z ̷=53 EM%;dwCqӢCy0~IڰKҔ;O$%veU^yN;UP? BbԵAIlM Z )J4SQZ&ZCJ(AIO3+ɑC4E 7faУ/R# 5 t'׮X/3{Lr&10}cN(kΧNfm&P6=D[mb&4=﷽:TAE^8;i^6@)%ja@h6#=^øTWRя&d*A#^̭M16vۑ;7  ʠyÁaZF]gT V:I2m: 浤Wszq^hjEj&=c:H8[2Es&Tg"¦epBZe0X\2 -Z]yxfeҍg*b&9uƊt^fب藎#(o  L9CEͷ7^.m*TDbQ ,G/AFK٘Nb8@іQ"+"¥etbgwv\>pY#sF==1ǂڷ4ѦVɴe1|Gc[\tcO湙41ncy&|tjʮŎޢΑ%6F Ԇ1%., lҧ^d-q( 7B^\"qp\1 'ON4Q/eApGP(Ld L3&BPb}tʷlOS}ئ2{AIҐA24%;] LapF)iSjQPa@6 GOYy@ipuHC2x ZI^lj;v4lI,GesM2̘o4<g 0Ņq;%< \'ͭ+),֚G%$qZ qXYR ,EDJwS`Mf+PbhFqM‡/wl=0%ָmئ0/i2 Fd,6'C]鯟 ŒΧ@܎"L'VYl}2=&{eIAabyS]stmV\4D*@K 8pffʻ)4% {I6.k'~w+"CrǒY 5Mud#[9WdZtL1Y6qc E%X\c,d&Mtx"i4cԜM|"a&X9Z4׊2p ,ıi#0!61lfd E f!dRZFY//LB @ T?@# ETz?s/ɲR4U]0G Gm}{dcBD  aUbH/dNB$eU4+1auO8CᰍJ6$q#> cœpDjAAc'"%Y a"Ҭ/˫nFy]I)jV!@DҚAeNJ`GC`b 25nZISp* L C7PfR%S ;m?py:<ŦU>M>? w?hWGXLxB`sESa>xPmE1$G]ʎ5JͱlXmi%ZiFQFҘ%iX6$Z J֍_ ilaA:LZե\V4)6,f 6Hfض?:q]t0ɱB>q]dK,a OlFQ~׾ZpSPylvps;/@c nS%(iII Jz>xoP? \Y$s"j9G($DB "eVj%Z`_}(QdPhI!I` !e2U13J6fiڤf6,!TұYKQIm)IҚmj%djUU%V(mQY$ԕDSYS!ȅ;I0ZEMa#ODēʇ 9}UF$q#t#JMBTdBl?7#%XU(HxF[ܡBu/x5;>o{x510e߸ Hqq34{ =4  bN$` WJ5c!QNO[ִ?^hEdEoqv6[QG#,0J3}hEmԹeQS ٥6tle6ciim1J[KGnU>|?7ПBL(CI!$ "M}C44UL:ɲpr +Z mbbu{( .L,h",S6hKZkIO~t!Oc(y d^^A4~+0GD9 G;OXm swdR?Gh 3I!9\0:F ӊ`jOSM&y*{QTFa퀚_ YD e($ JK"+?Yj$ ) E' "tuj!U(T]61 hë_{5bԑܺimJJYMd5RUTA#IK1Č.*Ȉ A%>Sį`'A?pLz.$%ђTOtn0Njj #D}H V d$ N%8G6HO`T`;!ʿr~7_𐒏[*0g6C,>a& SI>WUY|/rސ!S!S,"B=1~>xk$P>餑%A*LRA#Acʰ[)RsEX3dK2DSJKt fKF3LȇRGHӖAyD!DK%g!azU)ƷM;F2B=HO#N;F n%)'bn&Wr#D>?8}){EOp0==}=>KPA'!gG*E" B!=FܪA*$E@1b "wC].<5AKm _Ţ8Q|_DBZfa=\"Bbp3ztSKEG"HNݻgTb/=Ԏ ؠLc Pǻ֑д_~>TaLqVAHBbIU(ɬ6rb\:K$ic(;GNqv{U]lGGDž PiSmÆ2`+CL`-W?%pR eIT 4t1d2ynLA>"O/'I?Hx;ʇ=6L,y1cq{awwz8A7g6& iGLZHf`%@dzM~=XO{SA='ڏjByI,GT0 3 %**ICOmooa6>|?[QUīݴoTm;vt48SXL%F:13zw+["!J0[E-) (1X2`0 ږE$R "،AIS",FBȂIه_r&!ۂ4C ϒ9ĄD9!~IS Tp=($_t*M?) PĿiLl[ga^שR .\K ut-4 'հHx+ori/-#R^T^ S %1(.|?#xy"R*Ou ኘ~emY!~ ϳN:kTNk0uv ӳF%K#,:ǭRY9I]:W*K8dX`}ArGmV7T $Sy 4ί;hGG!)ggXR%s{+Z/2e53Ylϭd _ol^ VG̓ ʧ$Z01Ǽ:ϕ>t /Ti`P<#(+ z< RDMwY!N?^<ȥM)GtHvO}swL [f.`T0`f1/OX i<5+Vh4H-IÌH 50L _HPgKjj !Q%Q]bq mR ;q1-ԂCFzMC K Ո0"%SDma"j/0*`N!kZij"z@7 d,/6jc~l %Ni Fvkp.y F[`m.!LALDnBdB KH`7tH%Da(( 8tWxA@o]ŖReE7DDAPh@ihE(tBhUC*yGtBI6Es 30!CI2c `‚msCKh?S-ʦ&G:y `- FmJ  8΃IQ$[ [jAlsa̐{~Osڳw1_ 9%#A{WM "y( '4$MjB jK!.GbUU9Ffڦ5M]kwLN#Q.gZ,1,LRF&(8BZ[V+et,ӤlbbYc&*qD&z^7I#MbSn~'>^1D22kY_HyS̤0! D1EQ0H `8S]:ujjDsdzgA>%BrO߭Bϙ?QD]ٶ'[{}n=ѹ[dOO*|Mo(0ĉQ!}bӘ}~8|?RlUU?$$@'&6}-Mŵi`.FHG 2HڨքK0ۣ˟EǓ20`"kj4!|Zr-f/qn!Z8S2Ur:N;4 `]rO/ 7~!bQ%1D,JOd) .-pGX$lĹq^jDUMX& />CnQ8?9n4_%t]X\rlխayy!Q@I0ʹHx {ZwHD hdhc#lZQv-+|cU{Kbct#ԃ͉%#VICvvqt1G҉ 2AJ) R"I$JpGWWG>dw?)WZ\SbgʳD|U 2WJ xIy4|!$2x_g=mw-WR6*&d*>#:8tacÆ3r*Jګx]^Nx1ЮBpvpr]:4i6ǓoSgR;m*s+֯z5{+ή "xy2J9Pf\P 萆@`A˸yj)ĨQ,HZZ}ļLum%Ǝ=nqeqwWq)ug3oVC]u\|?uCԇ=w:9]!jmS)jp2JvXȤXzwL%\!d(m9 u&:WDvl1i@f 8Wpb0˪ĎYF;Aƕч0PBy Ɗ %B=vYU;P R[ \hLy +!FGb3k $ka8(O8r4YEHכ~Ve wH +)Z!}^teB'u`[X徆bOKnK!jE%ILH-c=ܡgpQdA}s YY _hG4MP,c@^G}ǵ_{IaVI .<0*r0`eR.&p Vkֵ  їX9 0a"YKmV%B9T[а e(9Q Q, (cIa!ƈ Xt a. ,8k* (km|1:x"(c(rS h0 R;.ع OVi<9tpEgdu:$물oɹVIO &K|6uxX*DwEg m&ux(TT Q-Id]RáaaT=-.E1% f7e:kxRK^'3p,4.RbM()|x2n8].SeH%MMjiipp8ܼp1iJ"t܅y HNL5A7"KG ke)5e!ˢSJhe"NOPSdM,PDta1 FG JB-e:IL4a89nԜ-If\0 f,eL0$+V_,.;UbF&0ـ>T-KӆoچT$vl8w䎜9)_irpruIVW-Fis31c!$5t{(i7\aoP<-Ƃٶ uap=hoz*Ǫ!Zp4],i ެ + yW}wrepۻobvC]<*l8L ˢь5: vv/Tr0vF.:iPNA%B%'X8CIDj5{m׽AGx:vHXX"jHo"xF㘈#4@  WV T* 16FrIKn; @mf $p8h#]gGtAcWj<c8"9\gJ y؆xTUܪ2$`iM4TأبZ8v ijIkdhc1%q%f u{Gy(Lu:t7446QwRDY$u̬adu9UfZ\ZS@W )mj-"F [Z`‰H #GNS% Qum ;SQliɕ):!!tԦ%f0i2aJ)Ţ*ũJtIޞ.E, LvJ"GF RDEI~ОmHTBNGCIy+QABr<g z37*"{c/zznL~0I}j"9y~a]vC^].Ƕ`&[YREPV! oJ>`Ο gh J$[}wr=^-f#I[!,Me"?PZH@ H$#$X%;A{RH*gI%ER@*z$Ptbe IEP02IOS<0&t#߈v4 |~W.( N߼s$UӾ~OCDr?:oT>%sPwM]F65 2K1A0# U MtÈ3``(b߇p5lpJ r&RHu5C0E]uuU&ɦMZFX`U4EQRR F⠣ ~e=Dd% [mD`4Ik"s2o!$oa͡^9ðf6+P07+ MaJ:cAV.!6MOP B+QhMڻGlg܂ê aO f&vW,VY+2DwK"M4FT$r($Dʖ\g*`ԳQ0 6kh,U$D <`]2#8IqU'B^oqSC>hzIt1dSwsφ6`mVPh|mUH#*L PԦVZޯdX8/+>tc pLv֭YƷ{۫&ߟpf`kt1{H# q0 ^6)WЮ8//ü0:LK T' QhDr!HܞCHTnr^sq!X" /{&%g0rWY"KDJ,@#++ I ̲Qa?"`??>~ƹ»JSAO J"ZU#aS~dw,WZ=A jZBPOSS%G \Pb PrTp3`0Ā)It[Z4$ T @j XZ "#Z!Ё Jl$%l6К!ЖZ `!5BP hHM ,LɦFcdŲIILld 3U,Hm&QUm1M#IHHH4i!&2e ,mjLRI5F-1Fbkk-i!LbBEҍ-Wlnmfi +WZmt5IDʳMk&2IIJBBe3Bڤ5@Te͚]RE!'ADr8M@.d"+ Hb?uAAq%P&@y$;[rN4H/@0=D))PzH}8KdDH#߰ 4ҘfzZbƳIl7lߦS튘h>A$xkT4K0cN~꩏Owy=P3+80Ԣ:eЇ Vqi@ ZUq&iтA?RY,ZAlHE2 T(s(N8̅Ia%VU) fV(F)h$$>=U'bv8ka]B*&㑊. 0&"D!֕7*"Y@2\i UD!qA$S'*H "q[u {;P_)C~]\nY33G]XS]˫Xdafcz i;Dj Io1od%OZ{yP~ʐdAI 1`Bv CH;!Ҳ1>TΟSw їܠ pg (0JvCJ( y0aXeɉՙVI?<ׇdƚh;/9}B.O0FK A?)eL$07Y`D ?ƱV3i!4Β=AlM%?{5Ag 5(uQ?Ïkm0iЌ$)dJJ%TjwIئ5"  yA^=.pKB-G/H S$%/C>gw]#:)"pnk?ΎOH=3ՓH@F$H AWܿ;94WUNm~/(`K9`>Jz~QJa"0R Bj`H?ㆂYf m(EfH\A$@Z"?eDj$&EI1ʫn4i\+⵹owkT[Klm,d "8ޣ$yLLHI5A ]D0f( TN"/Owxt,0 29 :W;SAA);+9h1 z睑 aZ~-䆳*GL$WPaL">U'ϞfjO'91F$瞝eֵk4Fff8^fH>ŴtTF- Z^61Eµ"Cϊָ32v{4)2G1z‹!ASbaN|:fkZzNN6k03vLӻk4 i-M<P9.T&&j#cj#Fi[L&N PÓ$,|)1_Ә>ؐPG 4A\}kUGAU ibO<~Ϩ/JkOצMS)JUU(@JR92I?e2hCSBF(`'U %LiA20!5J!Q2eg0=kVW;tc;bRҭRI6V[O["6;$J8B[vm &TM14NaS^hpQp*E\ݿ\$Dk20x8/.[ BB1 Sp"A\{wc-G[$TzN%oM7aPefEg^ ~:>ml;6VnJ*72qww$wwq[]h[9K39Uw37zbo1BO&Y7~nl萃 }vgxCPLzԉ &*A6 U` "0;}t:OO/?Ͽ߯Oկր{'AO @hD VD&D)Uo> Sfii߻?cGO!j'HUZ5nZ-XKrRńXڞ; I4@(DS?2xA#E{Q{B?gb"~S3(55Zv)A-)#LmJ&YF \TPKN{߳Jm),m]vO ?' h2ďK* a"e$ad `J#tZwz.o5f˨(B ۆO?bO$NB(U,cI)Pz$Cwp$': ɡ_w6 +ҁTb Tyr֧qf$?ݝ%(nfdyg7Ѱc f:돟d&NX/!$?H* 1= ȦW$?~(LdC`!)~U_QY`14 '|b~;;iƑ%Ç'y8[hS\vؒHT99b(ғ K<'W$Qa[ eUdATg]ӽmH "Ni6^R)B4)!u :64`EMs2KA݆$ìƉI JmEP*Hܦ*'lA[PԁMeEBrºʦ8n֯LmT B\e8 " %grmhĠB .X%=X.h>RQ(YZNfd*l):2M27 sEq)eЌYKِ5rYhU b^5jIaYƍEN -*0'8M2hE{UؙC53Uf[D䬢,q mƅ8=z4{Q;å_HIbj)rCSIjCJMaz,-ݡ#MDɞ_APY<83$O=2*OTU,$ر¿'Wtbklg.w)᧑I/!C&4\ iRXпN$AK&S$UXv~Zƙm:H5J uab "Dbk2j ) -oxcLoFmuiap  mKrfXn1V6#CFnF8 ( (!K)hc FPD(َ B1T2(D)03^7G-X2AʡDt.#m6JɚѬi:oH-% ]던"i:rfB@М3\8b9kG&bpy&798M m4up4+ $ERwRa):htXwFAgDa 0%fz{(m+94p֌ Vl$`ӆ]6,IXFe^f;GG=d{د'欋%l/@(B!VD~`O]zp'h(~*G#1*~@=BCK/J L J$Q2; v&~~rA tA`%?%>W*c*\[%jEgĕUXpB}"#_>$vxfL&7?>H.u ?~Z~GH.Ϗ|j0]h3?l1cgIsb=QwjN77&ٙpYW 5V[B#M' 3''5}1"ɆI#gti' T4v́Zqގ[K2f#-3 ôɋwQī>jR͜j;fVMa+ U6j̘B۪Ir5P~YSԕRNLp>F`LHh}B5-! eى34&1eH)4Hl##(Jc+;֞!bTcdZ4K?˼!Fa4̈́9)Q'\dCН,e>SQ@__F:֋YX6c֟n9JjdԦQ4bmrH;ԩ-*O:,|564~*O^YDrA1KUh-Z^q˺jEUkm¦p| NQ*8K ue7˅q#]l2l)pֆ4Č Y(&(ۦĩPӂ.#N \ @V`@5g_ZQ][ A0+!}n[2a<4$C9r >W,xcv;J\9<{tv?qn Cyb@f% C%0v’|BC3$g,KcH_.Ae3q9N& >L4?{Wo.$3b+ZĀ^}/o? 3 3%(L RhRJJR`_1dL(H$i ䷣.LiuucL!a >e> @a!tt<&O_OZ!dCQ  h1'cZ[jjˈ>=^q?s eC} 1b]IaŤH'ȒHS44L:d(RPqR nS40r^ C|~JJ|찖gq"24 l?Ű?2*o h&;r92$4#0 b0rBQ?4-Rb&"&bL$zRG&7,L*b J99*`B (R@ J ilJlq D݈HRŨMaJU46KQPMX݁,Y)/B΀nH}>O>* J'blR_+P:|{#QSjUͱ[U^㙹R˄͞MIm(2 u($:DTiJq=M$Cb bZ_$hk0&M V5b?Vn(!5EG@.%v!8cYΞrY"TMϒɠV#ID?M10tFAHCAtiL  4K )lRԆF$T$ IL@ <r8"b&" Ȕ a,:nke*%0LaJf864)&kF &1:N& J05/@c+-mvon`hYə@ eg+)ڵh%о^PAH1v֋[|*@]M q_spqqg1LL:CH0ˌ8(!+1 7e)7ɗ]iR0G`U>Ft_x*^4 CD@U @b~IOlo7P H("" RRKpG L␒9|"0&IlVQRP*K6dy8S 2 @$؆Sb:j$b&b2n<>=j>2QӧCp}?8J*xt`qWt Ae}Rgeo?*dXJbbGᄆѹ76ԋDܔ+!,zHSBvdI9YP(KK9 ԏ05EuV5ϙ>2I\L&stm-7vs)0ɡK9o } 0ABy|CXxcC[Jg7a>%R(کԕR$H`HBQ*"D)0HE*RUK %>H?;Z dO_6*R=S DiH)*j+ly\C!  4y9x>eI R4/H"IzMze.WIۡRԨMj@֥MU321h0sK@#*$C$qĞhw;qu۳M4)=w<׍~g 'Hgp|ӄv5jxMQfH7Z rA/n,H/FB$r# ;{{/3Dh,*P bCrFH4+5>0~NOCdMz. <t+UI}䳅Ҵq FG6#VQD&͍eEAvf4 Y lGN:HuhXō(H6jR8ަڙ31)+ud[e2`Jһ@ISIdU`p[1#y\m$fFd9 "RbˠH݉B SaPX326*Yଫcұm5cٲṪS/HAm "0d,3rSchUY1$HƷ2Nm#1Tz1B!%0xg[?Ŕ{;t '2l(؊fa,5AQ)+&dk%{d$C!32 \1\X\LClʤDhV$pG5(4e`f46WwxWt|ɒqv4`@5MBٸh0S?}JUJ_SfKwh@Ѣ~38*BE;c:ϸd9P[-8үѭ'i6T3C$GgvGIB'D" kY 1RHPDHI*e`-"4DdD \z]UtHmHbö4R@B*գkW="T x  tfݒWݗMsb+j6Kn[%Vk]A ;"p4Q Tem;+G Xre*bhȚ e"XQ2lfldŶRZIdfR,$Eеb_BA-᝜mL*Zh*"/׈<'B_.efHT!Azۆr IY0U10UW@L$F$DFG PtS' |0؅$5>/#8<+u K&x8}H٤;9Td')i}po  I9laz01yG"HWɉ2pCArO1bbѐ 42N4MRCQ? U:~/Ύ}lM*umde- 'HiI~B}d!1|8bFDE/>9J<4}5 2a+L, Y:tN췼0޶! dX?x*$|:HJOނQ$7` @+:y(E $Tw+ "A&T;OSa fwțmv -%b f#c"A4{#? D "K"':$|3D'H}rNh&CMC}tzHOC Hfe KK@UV Dl0~%ie} j!ѣ<(' !>ya!H@X J,&v#":%{d0ܒrTN_oKX๠1^?:CF&+5Bhhf #:_>W300yy| 6 QGٓ]L±1oeD$&_:O\=?!PR=ҔVN%@A"T`AH= H %8#0Ɗq3S xI!8K!|[i/J*mq5#ZGZ i6=c;Xt&89i Gv٥4lcZa 2 %_o:j*mMIĄ;_͎ A>Y`eh RBaH_qW}oCnF o3FzH"`0*[*@`\}9)Sn~`])!XX Xz||4=ɒU%Y%1܄O B|}=yZ^Gc~1_1=o*"S,">nTB U\9@b>"Ҧ @lXYeE!(! R0Mj$j$|HG &EmUJ dg8H=S/y^F!dvMI)h1 ɑs_X>WF44aFCdϨt@I'Oh _յ)Oi:#,[/B>3afgzW0OťbfH>[iT?;D@4l= *hT:bŔ 29B+ `W~N~htu8JAF9jd2JьdanUsV12dZC%,m)Dh*$ p'z}a ?._=WJ؇}oN@ ԏAdS$H$+ϧ}}{{&=NR'M™()pQ p IpV$,~OCAGǨ=!tCBD dd ł堔XD m΄f+I{a4,JMJl`4'{}>,8PA9!HBBFȒpIǢ&Ve*/5I$fA0/K=!.SJAU>LдPHdάr0j7۴6N!er8CRȻmlBщSf0JWeA4 hv,2h %6HɚjX$0,rF84cQ),$Kr016ۭDs20dQ$BB\%H&Muwd`h$,Pf@";| (B!6s"Lg4eIvp"C@)Ha[Ls/52c%X2C1Do o!Tg Yn䉐L-Ͷ5]h aS;訒牣XA]!!eQE#-yZWݨY`е,DiR@a  ǦSĭ0399aW6"j"GHS * )"Ȥ*G,mdj M9VZM*M)UYTP #,JJ&LÄ1Vn2MqP5h qAdE§ k<յCI;K!QHl|B}~=GqZj^{l{l 808' iZPG!N|b,l}~P|!R&*R 4RG3>hm'@_ՈOyC0b#H Y* <;VF2>ڻ,YiFh/Fa}тUOLJ(/@|>alwMЉ!WWI $r_Lx٥ivaSN M#'vHI_fKIdp?ž ڐ D ⯀SJwG$/pʴ+ NCA#0eR)55Kf&0xDJGݟ!P&>\ d?W60k\Ub'M.JUziQf5I>XBI<6.''N3ȕqZ0Zv:7'R)k텉BޘX\qzb"C,iXs*b΅C qvH)9"v_ gGր9,b\%W{GN E76 s,DOSF~Ѭl"24o M(((m϶d)m %%-:5e$c緛ɼ=Bn$4ML59|KNn;om# CTAO+~@c~-ײP "P(5o`6t0_h:@EԅG@D{D83ghulC  Q"+H.@ JJHF(ذĝ[R(N߰I! ԇ*lmCz:|S㶴~AHJpR:rr 9zG:4 0hAYE) XIKJX'#Z$q4NAUC?T=_7dxU{P)!;/@+nwb@EHcY0RA >De Y"`5J++i5lVe, bRe&)մS+e4mJ $I_@ HTR%Mɝ"$t.!`hQ(D,ćHTGb"pɜ сL, ++0a8(TRLEЃ"aM5511c51X`4iYH, S!W ư$d$f @-Ϸ_2wXGPdO2!~v7|m;i"U^ ϒ -w8LefU}V]_h9:0OV1M+x1F4ݷ'  3&@A3"?T3ŜrA79G//wBli XħA'㭃[*@JH{o}N["V7TK&LӉۼ4Gi1D!n cQHTb44c. \Mm3 @P))FLLs& taR!6ݰxxl`O=Y0CdM߱1H&ϣUDZ`lT40L $u_:rx8:%@x:%sC * BGvc&ѭKAbr`8ы}&c 6EʍN҃f-[,i ck/XƮ~Ч"B> "|MzҤdgN1084n+$:$WS;dMWu J) Ћ47"t G!`0FR@!'HuHB BI;{-)hR l?-N Y)Ha/Hxw%LbFѢ+J.轻{WK33^ ?0|〆aW|Lȓќ*YdEAzO3Hy ): {0*wGx$(I=!saݘ0awNUa=OHdR; XRF `^ I$˥ 0Qu.b6|P&F|y1:V_9ZM6hRwCNz"7|>ۤdS+"NcL$'pRϷ8NXaݏظq"yhSB0|?*UKc%9B4!`+zNKr{Cx=36pX޳.$>Lj@R§T+q;O-!ӽC08Ĵd5)pdp5f~aur]O5hcv#joUo6*aC*"gt;VbN1r؋@@,(\"LHEPRR `+Bre"HG(ܩ+7O;BKC/ʎ,4QfJE4`VE&N>M=ٹz AbIWҕ^RD.C|Ov5&EZ.QP @gY yQnش!^eOM@ʪ˸ Y2Lf5D2^RhR3˷Fqf|&"rÐt쮝8C -wϟa?&~>ZjwBeat6xb'_|}=VZfgkG G"ehwQ2Ay&ra^Q.;MP;; ֠ Y"gنKKBֿ|iYN0ئ34kw߅i˸sAfbPȃ-ஐ4 >hU&dQ/}W k}JŠ-.'_y0dI1:CSxxۢY>| _Vdemq}u#n] h=ihLOe6M/iM ŧ1&T5ՎfZqk!1t)g*)-?h>ORuHf8T`LMܡZ0$_k=C~J6dT%5vÔ(x㲮tQh88(Ym*0TҸW:uN8V19+ʱÜ9S%dªGX45Hima2h+2\10lU֜JiM5 fki5$47u_{%(iJZ¨+bH6tv06̴RF)g2THzyr;Ҝ:wtʗj! :|tH#0 D9,P0D0$‰(.w 8 I+;Br$ٵkIͿ4h Aj2$$F2hQ6xwΠ2 Lk͐4e ou T#ъM! Ueg>NgW Uۜf<7@;9W F3Ϧ;|i ,3$u`,22Y2fK;pL Md\s~wxSFCg PS$ixBF%hhH`"aWD&ǃi6ՂTRZ5Y\~tpmQi1@2);RlтX#Bw$c{AS %Ȯk .꒪@' =eoVd,xƈnhM!1-+S*:tz5z۩R. CBRIT1(Ϯ 5{;IcsRJUatf- I%pmwekB+"#42mn]ҁm3R e˖GHqf֨Trd1P5qƘ~0MK-.d!ڒŲX*U(*P"D[ԚU"zXR%!20(JX,Zȶe=,FWküg*ŧzN0 1^Z3l (axm3ws4Nyy r#yPIh%|uoua2Vai(LCAy gFXmUY (hff2.\V%2hF*PDK8ջ*Z 9hhR0*]l ) qgѭ mY]IK%E%$N0dnaԭȚcJ5FKJok..ʫRVM|wrM)_mR9HUUVԭ B)8E$%Sb6I!fΑl.aŋ$c9H,<sm:vXi6mRI4P+U7%Q(! 'ڕjXjBAL3va 08Ȟ7W[^Z f4;m i¬!w@5U6a[ ]MBK %*^;k)Ii,$$i 0*<IhHdXWQ%v%RA % kh1uu\]YnZih։5FiX K,)ɣed P0ಊiV Z$dH M,- Jm7$@bhC(v'QUI!;U #Ql&(Tёi v! 20`BQB+%0%l%?T&|߻Y|.xHDc֊AԑjQV4!ª%StvDcдY~OCֈ'h{{V;H\X9*S ΋mY\7eM Č7xc#d* @e!kJRMea[EVf#4lbGGrb8c[]!MP[*JB,,)bhv  efadm)"a*$!,TZkz72ZPXT%R}Iz mf%yc$0 x^^_>'|F;2)!P㉡Tfޅ1N'saLj"&ex]Hl0!"%I>I!ܑCI!;wz(_Բxc2#h[41 EOkޢ{ tVN.d?DŊAԁ% A0~&~/#nx< &M[XD9dQWẬCb%@&DPSֿ~#[r(R|ʙ)^/M4=)JRqB}~# )$$$0 "&1NhjKXa#D!vd/b`2Q>@>ϼ6֟}ԋH0dHEdM?apXjawv $ $ $*xK?B He?3^l6x}n"Ȫ. Jq׭xd5~]>=H$2@fM0@\ @ UQUvh֎b+E$iYb Xdw̪Z樷66)$M,2BKA4`H@B({ǽNR]Rtw#~NHC 8+̑f! ZjUM-+fͤB*(PJDQ~©Mk꘴[JeD|@! eXN Vm+ed~rkvl8 JAD6ֶ}|A#WTIva),GA: u`kAY- 2lT1B(CHqlZ\' Fڨw H`ꡡ)(_ҡؽLz Ҋ5$'$y2Wb!$àD"^0){`'bɒKG`cIT#(3啲"܁Z4 ьCHkǠorh' VA2>+(~Rt_ hb٤9(35XٵmpBPؓ m 8M,@~c`ׁN@)c{iE>[3\O؛e>*|&d DT"D~ D_"1 (,LJ 2,!J'9STT|몜*@t^*G2J@ v<ģB -#x'xE15$+j?i=`|mCth~jҌ~Aa>yk3#Ƕ%gbd OI8b>~"1 +*HI>w$=dGIaBX d4ஔ"-Z*|dh|3 S !0AOx)˵*AgDY"~H';'Q#b< C~ $;,"bIC|qEjE1Vd u?,nDS$9bx!QY >Ԟ>ب&FCژbsI& V(Œ\rx0–c%z*ʸy U?K& SB D)`R)4T*T7l; 9 ؑ0$>eT%nilLzo#'# I8.+wNզ.2@O?i}Q5Q37߽}X@ň~5^ gh"w2vUߏzH"D/\:ScBuvN(eTB )FfQ!TCTnRhIr,&:@&KW36(6\ H@ ^Н#E W>ecaf)11")uݐ[QRX614Y, &ؘQ1a_(5P "Bk뤵Un'/BVbAB EN8)0+MihE4SGPSqV7 DHp͉͊" ~#傎O9SrV1WDfmgw3}33,hxiSz v7)ȝDQM]7PFQԑ1$G !)(p2B˸ȦC 99N!ctۑ" 7ҏ%  »(6meMi6APVC33L Aw ]@4B-*I!kKmP`Pѐ"c+(UPrUWE,&%dX$13Uqt:wrF1O'uI$wȒ~*TVԡV)ZlEP>G\`' @7O/bPdIU  ê~gڂ x{/W4 A*P*3 JĪ D++H X!jԶX $!,PVe$dA]DNj@š!f'ڿ?,r@CJ̙Q#c<åzJI#QDiT'J&L>JB y!xsח-"-*^@Fbfzg5@}V S"6OJzgϏhdߍ$CbeƺӁ# igVZJҴr@]k$В4l K 4$HGBA H'sYv*&CbxKst\Ia τ>_-am_<#rЏ!BYsnB CL<^ x PVI^1QD 1jW$8e<>Vx8`^tS@a蠊֟]IϷWA.Ѯ-3MEPp@6; `k`[O2-U3>an|n{.wwSO55}q^o݃Te/z҃֌}9ݻp,wW;;wIfuoHVmAӶ&w@!{mjMP;3`1IEAAATPD  :ЪW]R໵tAJ.F*M*D 4(d**Hi:((3o|@Ke0z}}7}et7BA.GOFCu6<}[0}MP^vrTZ5;Vmdzy&f n7v{k!mt=ޙ2gǫ+\ =֧]ywvYup[xp[ܩ;]ǽ5(kjnøkmv˶[B{w,^ѭs]jV|34mr+|}{g5nUkv\}m5Tںjw"N+kt눺c`h7^Q׻uɃy:4"_]^dt=Sf[sdCvnew5gs=v|>{|`zWd;^phqoJb}>V._ޕ{}P}ٛ7o]ѸM=ZV/[}zǪe{}y= Ƕkc޵L:׭ͭeOY=z   V+ȡA_Y+;4 hQ)Zd}[zhN} Z7`RD`6֋';.::%2{gҷ=˯Uӹ•Qm{8='}3glnn|rRv({{uK5Ig\>᨞g\ޝyn4o=ּiU/}))5k׎C=m{jb'UowמA뢽eh;ec lAw7 }5voWwnۮ"J!EPOninVfҮƔ^o+܍ݛn{UE%ڝ5u=l]h}vH@oRcՍfE;q@ F>}̫_}W g}޾!=TH뢽:=k/w:j{9uYRW ݔ 0uHg*֏ZJ{Ci)Sw]f\/pKmw]=qiO<UVZD@2i jyO)4 ЏPHAOe= SؤbGM2iMhb %""%<5=S4G7z= 10M4b`&IISȚzODL!422 2M2@Sy ii?Jzz=G4h@d&&h 45I=51="2P?$~73u7 #E9T 8ܔ4L^*lEmA # vD >FS6q*XyQS2+2 0&Ӈ3HD- 3(+ -P*ҔJDa $Nx>I\$qՁdb1I/ZCDW/W\vt%@MzDHw!{_;?3.\Mn9Ď2[\APsu1=j JGJG<_<='8;k$K.+Sg9KCfݑ7 n%[&t0iB?>Iu,2HJ0 fD-VibdՑj*(j%)A2P)PEA P|K&_37o:Ԅcԥ)Hd p0"4)($%P"ЁQ0Dst6!!^bvѽ!$Vմ +Mm )(s8+B(|Ff@.D{'O?N * @$0M֤ u8EFПBbd0?`n$eX Mj_'}f8DHfOT[kVoz?[])'&g{y/* Ū"V׫?}T!3>u/cVo{oᶻ#[A$я?/S'P,61K6NsrjifjwU_u7Mg*Dχ?W[yuwzC]\\},YegsQdy`BIJo+jux~S^$^81E\zAXֲ]VgqvOg1lanmeg./h$17lsˏ[7Z d _vRf" 0EO]T槬 ВRA 0M [\tΟߏ5ݶ|,XY mܯ<a%pʻ n^^F4;f7gtyqU1z<0:;GOHU fKR$;:gٲuk5ݹu#C Ql#6B*ǍC2`狿M*@q2d H}"twwk}uvʱGZajz) Y^-2eZR?Y: 5c%FPeGav$"v1}3F6l^^[%KXI32>&>6>0Kaw| ?Ga>*)dɆ8azHʦn/mx z#ԻB/%\O8[ߺ \>e>!G :ifz8dut)i]RE~ϯV:FPiݖc8b*!"-Yb)<$u}K|j6eCL( [O]f-qWa5yJD,lVMECI%|}M%Ys:DWNL vsW㶌fL2RK&>z#3> Ag˴My3_ܱov"w@9 b2 y_c<Añ+,d #/ E;˞&B}AL$8*,66;8rvmjڶ<^R2C"7G\C[< L`ּ7O)ƽm@@4]F}t4sփgwTE|NagASYsi: ؅C/"cI0m e5(FIM3"H&ASFҔI$Snm1!  3&fD3""F2 A i*˶xu {?a_jiH 4IH4XKhi3( ѫ,YE@RchAbR[2E*j&Q"ѩLAPGӗBE93(Ŋ[躽=׾\G9A WDc[PNG&󩛇Ý7')tuvW3. kmV7'Lngoq.}娺,Qo_~K͂\{uvQU :R ;2*8lHu3EA~j'CU1pjC e-nUH8 ?5Ʃٜ 43g:M1gIp8L0rA%@YAN|W2o瑜r^/ tp`xF!źq?YwhuCnPtB`KqlZ4 V66dEEFʂ_DTґ ϳv7d{d̈ }{-ʂA+ݏ?߉31#$ (&,b&,s,):oz7X`r?!h3qmԥc/zKCCW#!&@#m)D[*2kP-@kĉdϭť$LIIlkMKL#DWfh>~3p(q2ߎ0jfR咪|O>ҽ%c5fL9D4ùOKfTPՋw~csǙ!!ªG#nh].SG=\OW=QhlĂ#fi'̻U%ۥۂk%R6b(Ԗ&i(O4p:۞5 !tPap<~M}8a6㵟LwkldFџބY"NDbLz-e+)-ɱCq7KY>D ̨$> ZQѢ L%+ &OR{JCh1EOC -()tm$)du6}^]6&n/_멧SBe5Fg!itJҪQ"Kz)3}%VQO􈯬?)Eze>xZɶ5qYt߳bA@IbSdUMzzav~>}z8ԾB"aBb#q_^7&c~|(%u֍dY = IUWmO7+¿V ^O$`;QiϬvtH~> .ۺǙ ,'_-Dznh#b8='/=Q d>fa NԆA?:l( ƅ- KXN[/ 1~LO0jȊ RC *D%r"\;iB +0eڪ()S!fdHPC Jrb5Z"ݚ,(4X{0^h Me bfYF瀀RYR)᥊YsҎPdOtԐ9ꭖdhgDsu;7͛Ţ5Wrw_D{˯@E(Y'{rp?q@㔍*PƍI`29CL6 ?gFp2,2\ `l 1YG EhgTlud}dU^0. (jsLc5[Xs45^ehc'U3ԎY) #D S{TOB2u"DƫY}$gD Zq݆|Bh[:;; ňk {(5Ȃ~,ph]V[)FEQ5+q>G a9[(Em&.M!8,Hp$`:$?vuc<\Ic!v"+pr?DԧGX<{zo{B4-KZ6Jc &XOX,ЂH.h*9 l\Ui{kZ*ŕH,Ԣ)!46~:͙)"&2Xh?WPAh0B=߭$ t{0ײ&wE $ڭU@֫4hGI"BtiO=dY;LYmGT^ˣ ͝B#P>z7M%:fCAJ O9a/tM XILCJ\f.BQ9XAE*nDD(*b"ʰ<.̄1, t.q4-dt&na% GOz;8tVpd r~/Q]~ q(| DJdP~ K |4BL|UG0#LkPLjJ|ˆ7;i:.2s}9CbQuRcyq?K&Zq*1sO7Hcv57wYc~_88woֳ3,zoXnpMfs0H35S.:wQxVy70f&_;׵h|u\gl1x>j]Uc917N|{7?Վ]~zk=|{;׎33MM:OMzηZx.=DS#gV1nUf F"gCXQe}+`kfzo%/t &]&^~dG8? vUQI`f&eR]ac7.G'jL1J;<|6i}39TxA_(‘-Mm 0:4ɇ4xzlٛGDp2Ir}?Brwe } Ff`=A@Q8uRD`P4(?+,ZjM"ZζL +`7diÂ󮐩3&eOZJh(a ʑ3A%}zSCPOlbgɍH Kc|$&#:ÍFNbmXSYQM8E;O7?1wxqfFEeEf1=jM3^X_' j'Hr:)B:30Ȫ= ez`7V6p }qߒ3Ri>CP#便yWst|2&pf qAi2 +)`~k*" D,D-z"A5pͭ>o,9ب2>Ɓ@Yk|1XS ПK1aI}SFlGlH˘(_Ep6fql%BV+1(SHm&ƚBk|H[^!,x,'4%z<2@z$– ǎF#! JJa\O*iu$Ԅ%܌;R}((_L8 N ͡Ӗ5ԦT;bFBeklKh"M(1C@C6@d+ٛAC>EC;N3 RpX``Β)@̋V0$ z|$ԐC̨O '˥Q@=BB E rI!QTi$ zkWѭz2rsiu @R(Ԑ@Dj$7mxf"!6l٩)i!$% ႈyE)i$^[ Kx'iKܪJe,M,[E4xV퉲IJ$ѳ0S#2J[s1kjUUD<;"ȋZWI{^U̫S37%8ab8V)lxTYN"BiREn\Mzg'K/wl4H1D#2EsD1rW0ѥ h(ɾ=󌂙# 8rx |2?!X3v;<%pMI>RH'%i$s'Vw(q@SQ$OMmZ)̕Ǣ'(lU`N6œ%Dr捊Uf*9Z]rJHRG% !y¡ j"*DG/Oǃ%bd"$( ^hL(cBlM_]hwE\:jlYfjhvBRLݿMێ VXOSfe*uRAFߟSa hjE6PҠP5B T R"A"B @((CULZPN BR'a T @)cClvi5y7*) 9fֵޭ[Ν{053Iz1N', mJJ-U-sn}_op]+&9z6mbG|7QLң5E]x@΋Κãޫޫܰ{ gs&LHH}iH i Բ᭩lf5-meYVeb@&jpKcӲs9zCk.J{>2d$J2v`Az l=\ r<\$䝕tR4œCA# G-%Px mL7x#)41T\Q?7dvI)$S4 1@c4Ϙa}jf.iB, 3!Fq9\&a<ӻ,CzfD  IA#~$?(ډ jND` ~C@]7*75Ȓ~]k#Z֖&C$uo ƞhOy V./ 6>8I Y6lXZ, -Y{'-<2)'VHjXzcLv@\Edpl5oz#b)"I0-1Y"2MQ,R#PD+N*̍5 O" ]SO& Addc9hc;@NGxY#"_[*VD2T MJE ˚REb = $B &N^@Cp"f {eEYLJ"ZǰX.?XFO!PDW["3ZPG< tXgu&1mG7^"t:$+xrY%714=|QL%w:(B`Ш3 F'H.3(n kl9<;R  p!ZdbIũ3n !(̠܁1T|b팟Lh\bi#0 q!+p{$t$5^^}`_Ҿ/y;=2f?Q…bo?9j|-e+Y"'^<@B~=kjč k"ZAg:NjeN1e^rT-@V|6uǘ:A̓ 0 h!w0UdsŨ֋E9Z֑ 2%Y$/i &n4eHp[ӮOȳ˻upnا$P!UFQaK𿖷 OH|W˄LOya`XD#XuB=Vt. wfGRu \8Ѡ묀]&n" >rgϡ K& D%&/E@h\@P bD"-"yo$^x>8D*Dkb'yt@856Zt{h%vQQPf@ C섒3p +wdM=??l;koche ,-g)K;!#?gy[7zbU & A 4afİ]xR|?[Բvvȣ4tw= LISܸY:1:?rcenrnҹ1NYlf&^}1{*Ƭ.d)EbyK&p{-KE$$ )RQ:־>#撊&I$厠V(kxPA.饆5 n6s/'4ݱrNv(YDpi WŦ16EBt{:C8PQ5$3|nsd*|Od:D\HIx6YWtɖ :WLWt ?,t"GsAp3e hOh.!W^(Rp",@M}M?IL†B&ޫXOeOb,?*)+1&XOӪO*_Q*yzi'(rZ4Y={O?'K߿Bk*5aa(& |B%E 3n3ĵM\kk؛ܧ)^3a!r-8[5Iu\F1Xho|f v\iK5HqN',NM# ;(o7CJ{3@~5cye dx!Bs">Fmr9ӆἫƖAKbiʵcVr+\RDP5Vwxw{}=7d#2kAgdr@4Bm@wi H 4]Dj8%i<(gj< 4Y, ;{M&&c5%Bu|υdﶎӲNrid6Qr]U+ !P“ 2l N`s ٍft2?/Pj !چo&[>~F8ͫ^8^vz?8}ƢTgh [fDoQu19O$ 0*2/?O蘴uh ZXjy4=]3b]2ĴޗjȥM,Qw ^|V߶,[_r/j}7|\n+."5!Ts 2[ݙSyGF,¹WgG߷ X]ngfgt܀/ 8 3w?wG؋3."zŚY"$ ;_xW(7ofpSةPpDрɁq!e1Py_'ީsg-z> ;w]*9fKFA4TLuŷi5Itk3t[_d"SY=Sj\-Ɩ#aHªw Uۃmlnb3.3e8)@LdU} ޑp$M0ԶUe _ HއE꠹}h]q? Z`\MC0\4L )tx.h&}DD  ?-tuF0(Bh_BEݰ1,: U:aP2r ?#S[ulڽ?[f0.ROHAwE/c|87R8FEsO3یDfNr~TM *^L#rxTi8J+DRHP欲HY 8DI|']I={dvhnIaYM/on琂Ax;J@Ph,"`f:ZկpV,),HXi+;e|؀Y 1@}։sH [(!n1i^F%Df1̜&9Q}&6Gx]f3{Mk-n x"v(@ "5{ۆA R25aH_,Hh"au8 xBͨx0T%EUj*~n!>2,bIjQK`b'̨El +.r笟Pcɤ0qDo,M2׳ %R7O?]}n$`WC~6crc& mǹ!0 8Zt陜guH/}%VVV}HKt𩜮=c|5[=w+w笷z(vzґo42{h2ldyd tbW6B10%.BTSHDSnዬL &otT j+uECD(v[dHcFVKDnR_ kЭ%&KӦs*:WA+ L@I$?~ۧxzbh޸ZA I}6t5mfJIIQ)5탙R KHvl}r>hyIwІf266=p8?]$4%أ 38* F:[P@~8PgT%ؾ /*j \̩ YWz_(+)~+DH!k7V o鈫<>̗AMX܎ؓD<9%NZ%u6z Ad}#,mjWfa@xp 4)%MF)$ilrȊӟEAu''@4t)ea)dmiŸ^DAF 2둡;Ԝ3**********************************HďØ8!{ Br fuC03-{Qhfڶ~J118CnwR2w9Sc=N$ݦ:oW Em<#"'RG?X[ "B&UH$kA>li~ p},Ơ43/Dz8HRmx WTJttrDhqDD@sk2%rJ,*n4tg2F{:lHO1~usڙч2"i| @&1 $M-$j*o`o3$!`|1TP"\XLzht3gU1֔Li*g>1ݧ 279}aZd@.%3ḃD9d_#VFְՏ;yLE%QHxAvs5՘|ZB*e'..&vq=_8mJ:Q}U@&MC.LJܝ%"N,D'XK4,mH+8ڟ՚|QۙUu!Ȫ(&d6z+qr R3Ld.Чn$̙غڥIh٘faZ0_J^ټ"\ U<)0*N"HYPhhau(}B;D/qE˴gUG*)2Ig@ Ir0;GJ٫ũ2a{Y%e>&-h ]NWCtٺgh "dA "xBvy`p˳`UtBSՊG8P 2 7u ,@d`H+(?V8"!k2dxaKd4Ԅ%" ]s6HVC[!%6(++63 ]Dg:g'g:ȡp.;!Da8($wD2_kkAz@NQEDa"Y.y#d ɘai9PK;(W\T i(Ji50a1i`_o|I?b|{lvʵejT鈋3iRdBG顂2fBn<`<u8rs~܎̽>Ohp!'we,J9;c$nC!:C0(2K @3Kv;KqLWO>5tIBp7I ' RWK)6**nYJ5o?-e;~nO(eLY?Ԩ8AMŞnIDGr_+AQMJR0&bD,͵Vc=qD.'Ĵ|2*5xZ.68qF!"G*5d[6v+Q:sVDBd%$*#b*zqD nzBN -#v[®gmLˋxH)glB L|]ǐ\ Ȟa;`@ 4SjUCNś=*#!E=cHQhE_4Y ȐoA%5vЌr p;#\Ozˋ+FCfd1;wyr/t33r>۪Vͯd2 ;C$7*n> tfQM3'3᧖䞒rG;F\(y3~ \wAC9!:NA?)@`ϑTQ7'uѣoc}ExaxtH¤v[tdХa+2"c4 R-#LVqbɈ~|z1㏒ `$\!~FKG^ A,`,cS~O#}E@EU h J |1*#܃{yIs0?%t!ۊ*pK"8KDS+{ Ac5wrPpvNN&JdBG,G%OCrW%Ȝ_zQG͛dAJ?kqd+WQ.efo|d~jEu.Ԇn2Fk5!: %кY"&&H[ u0u)(~hvPem00YͲg,TWyJO(R=Ś x!ÃQ #lW?8?Do]{}IJ{Q~/wpN)hP!Jtu/yO+7(`} ˔c˶`K&$Q5i֚}bHw/}x yCx4SPU-[Uby~6Wu5s})Hn/uUwFh0k"gfJбXmPlӆ5fS&:Շ QF̟uWLư]U5cx9FYMYL`> t,U E%EpTuL`!鳐3)O`l8ƥ BPaFvp`]fNY25,PCڽw۠\:ܝA!2D3="xY2ɄiSi)D{?^Ք:漬vurJ]SZ ,L'v}A Š@+-8zrsp˄gM49zJ$`M5 14M~ze鑮1 1Հؽ zfվ{udvRHk+P.J> QZ`Gr' tbDa_ :axܣLϠ "+$.$KZy Oml$QkS:cS4 37a'H:h @Q@'Ml< M{N 6O+CS P鬧#gcyɔI dJ$N<*Cpy@DFDw?x9F,j4q}:[>,}>uXEߜD}N#=&K $7)<5@$$RLBAD̷2:3;Ab0jZ@었+fTش4x'xwxo`5$֌$AGRObV;Ǥ7A ˏTM}MǹH&;T45@hD0ydzC#<&C{<|{42 &!pn&O䴉<x(rHLIZ}g,%B DzƉdvTU!k 1kkci zPuC: z'܏(D`#J a0?m p-e|)\ =evSЕ\ZE"¿.F>; b?3&}{w,vR E9=}@NA+^36r/Q̌2fRsBO9ȴ\J'_l-ZJH@ݢ„cqR(?!B6\#ܞ.G*b.L5y|ޜGR#nQEJpCte|PPSVh* XF")(\\z]NiF2q-+JFBP,Gb+Z f.%1_qs7 ~ z w aMVA yFh q_ejל/&#mRd0 ](f.g8o |sG7Qx] $,٬\a**dP%1߄ސjxeKcE dL݂O+ZB`mvB 1 Fr?3N:s9VԹ#)ג2P(#,s E e2 \'K0,%#:s0v3.@ Q9j([CV%9ةOF1~PGfCZHܒފU !aSk\i+ yAP.тl߶.TpLƙ$csVygEiҡ26H qd;ßB 3,"=`j; 'UG$4e*Zeu$JҬw @и `r=Cab8Sx9" <]g*G*HwMr=9 D_cG&Wq5$v DL|%Gƃ`v3Zp_MP;cNCh? )G<>ubF|ZuJnx,LՅd*z d#рl2P(w?2!3 dy 8w%&֍92TӐhKf){hK_j0ܢo+`5wF èZɘJ4ȝg34#:h5UEM3T.:9i\Pl>yւJ(3Aѕ76gT%_SDnS7JHTR(Xw.xD[H1djF ~Ihḧ/hr6@'8Ԍn Xl& U3*䲨M9&i禽N/B)>v1fsv|7캯cmPS<9ȴy8 ސX) D(AyVcH''{ f -I9gl)7NSU.6VuݍScO|zG1c.[$@Z ĺ1mntЋ`4\v&c-%Ոu ɵ蓖Ȼ),zHB6Źֿ:sW8OE B<߈x=hI\֐]dYdN)bTiY[p~NmL ! fL-%:(PIAglP^#FF~?S1WabG-Ih0RYy=::͸GB1„iwIdKdgɏT'DAVx{λ"͕=γadBP=UJGB]]1;6JViE9(sP&fffm1cpQ z󱖗6~`5P;7 A0r3_)%pͨl'Xr ¨T ^ idr %LP-'E s]bJqPO6` G YYGE0@&~NqOst(PşnwZ(1,^'Aв|#-+\( 0j9!Ba+q3@66yBD`H(=>?<'$5E??Ϩ{A2<OmhƎ{0t@G.ܥ.C Ta" Okbd!tO_d>dOc 22ID˃5s)+l"Iӑ^+1 *ZtWt4VQ"$kT/+%avnZbʈRs,;#1iɓGdf p]@(ῧ0v`up{>/ao(Id:?$12LIęy=QmRp!ۚʤ]%k5mFFbj %\>šDVsƴhb$X.|Y̐ѪuPGE_)hdMEI =:+j܂w VC`&@ellgx;/'}6ӝ s<먍K 5cX\C Ӹqxӏz6/7Z׊k]؎ l2DU&`]LT@wФA'dFJeL"H盔ۖo R J+n?!,5D[95͵@wtokj!@W&TGդ'.-$Ku4m4L1AjT5Dh|+(/J^ m[R[R.zSP"ZNQ?E ΕB24,f9P1{ajQtet,ft9}$]W){(1=6N行<<E2{adSmnq-$`mb:d6m~d_!s$d\>@RTJ4 /YY+ Cie+j`.{Nb8>*3et&eĝ@`C#;"33ꊀAH|[xVXiJcAуc o#Vb,Nq܆YUrT[w&bӊ)rB R.č67 !q@xR2\P 6%5ff(00 Ew!LvX d`"Ut3 733kgVh!-Yki,U*"9^xes}3ƳXl EA\j 7k E)< I4&C]|E;c$ fl]}k+f0֬⧊܎.,-#5]Tr6H[tdI)31<TIpXqq&yO~ %}s>=5ζ;3Ö?n&R_. BVzZ2 A_3 *5/(`u]ª"CBтJIB0I]m^رdYo?2NБG @ᔙ[rSJEDGMFqLj.BTX,Wlv\2Lrvqh JhU Vo*()AIY]zɈj1I'BW+ںYg\#/ icndA)i!m4c"4cgd^.^McE˄Gʹύ jur/ԏC!uj&{3]z`I."-ΝE ](E BQ^zzD%ȡYQxjU,~E5bD,Y /,*D#9pt±Pk. hIVjg!-̨D. ah \}Q< Vfʴ"AWl:B5s7q1 [TٻhX+1Hp]ns5I6ߣN⊈↼,xDj %>P]6ř]yS'"9F5]5LPu5vfqHZ) r"!h"Pg@vG6Ћf+# ͩ9 RvB4)AskY3!Fvҁ9ѵ5YEFTot{xE{lOeraXflT086|p1b-Zb2HRu  S=@Lf^V'aQQfsBp}e %?rj3-r`d{9O$>㮷q<㦿o#- *b>2#vPE ?1߫8FFoQDEWˡ7Sp9ܕJ툢7M1-X!:>hK~+ ߠFjW889}Wz1$g}RT/w %h#;"k`"JI 9>=QtF` |=`ѪaٌORj*zR#I$)G&c83_7L:ЩfL7u( ě@]i#$Rgy\(SP#f(Q\7z^Cٟ0'sk,-Mq7uB>TkYj@"v2~2uK,"a0VMp}UtH}8~$rJ ;zflߤ,Iđ@Qixz&+FW XE4yUWժ 6/U:F}iQJ:Fk{Nኪ!v8îJ)+7c62ʰVP, qZ&ȧ@E@yx,eHkO\foKțB$>1nl`@YIjVH%p0$%hᨂKOȃfg戡J "%oѬb6澉Pt|Ѕ ;҆RȎr 4㬍S$J K5"# x$HFh^cTdq`EU*(@y9yHkk$ =zDWSZT$kV(" 63IcCp#S0*GqLBedI[5BQ>?~\{z! {$Ho}LU*.nK?z(\ϴ(%"_j>jtup>8Qt<23?EUZL>VFvO'{K"ŕ;E=`̼ 'A I<S]*%;ls0v.+(c B#>qfpΘ_NŕҬyg\ZNg_3Du21#"mYyk.j >\r =7eprƩ&gFFE'a=dAE x䍠샺 n7#tdGcRzgnjA'8AgDxGN rb)~>p5[Q0q" m EUc*pjpg)*;#^L*\a쎌#:V [[~8?:W m2w=5ySShO"&lNPqLtx#JR`NAl ^Y{6.(r$Vt55QQ9ˌT_ k[Ћ=U ]|^=lkiatSx!~; jk]UɥbEkW`8+9$֮KgGF>V%1Y`Ҽhv5u]4\k:eF0`S,Hu0 H*L XsDfV H7_h!؉Hg6̺8[n ⅦVS:1tuG0|į  pΖ\5RdD_.al*'iQ,; V"$O&p}G98 I,S2W&u9jz5?.rO!qA=cbsDXdZ,|l3 @8|@[!zL01P ep((8x]#u[4i~m;O;x#rvZk!x#)(g6V#؉h=QA^Ɛ3[|I2BPmb.4>l\ò:.fS!_K0ck<[8]υ)Dֱ^{K'2$15Wb=MȔ=s/ɵWc @`Ef?4A93H!Eh>ӏy2,P 8  o%n[T#+؁d (10r~&^8}RdM"QF >,$v)`;DQ)O{fIA0h=Ĺ_ R+ _[b5h$F"Q> .uykct 1 ?cπx F e`p>"U*+tܽT(@m$1/++UHiw$W\';y޴'LqOeC4(ÇC\Pc N]aYn=dt £"`AIK(;͌"E'~4J11U3\@>;mCߎN03pp Cm+"/+x3gy!BpPAX=a5I10)| yd%L7*G0e{īީD:x.$*^;"a͊+wXQl*j8铲ڊ&1;"2RbCm* [".ĈP6LMExm[%{m6^=wBPF&" b6QFEk2ܭI55ƱZ1*{oa RI j0FQH(";i6)Be`ejRR%x0RZD$ݝ;LPݣ<-աaR)wwȅTaK?y/֦"(ZK1W>>^wz UG{cwיYf;cJ!o#oLI@8zg5]R펝]|'ᷴ&u:mz+j05siӦڍ6B`h4ӦӦ-V@Ӵu.PAœ0w᱆p~ôrL@~h>jJ˃~,^zXfFbYNSj T﬙+DU=Dd/zwNuteRZ^MUD VRR'32kC#[-  \2ZK`,O @j]H 9x< 32t]}NϬw4BCŜfόUI&Q}A 7'Hgyma\830r 7"VV{zz0ddEkt&vע>Z)2F]|3"i= 3d#Dqwg1~>MHW*ZVKKfX+1zm͔Y#V( STB,$($HHf4B@Kﰎ@LT4gǟ#7_Sbp #WYOF 9$1iD4`h$D,I1 dd"EZ@e"cؐeaN'0OCɵ۔vOJDܠ98hxJUT, H`,Ubq=1ŊSc&׳TItfr$MC?:Q oѪ!8m_ѩ6SW*0kȤ4wǼ˴hw UaBB8[OfܨdԹDfآ)N?]`3gp`1bECIϠ_̒LrI/<%)JRl?`΅$`YFU`%W܏~oE6JX{)A̱a P ɏ"!#3WiT9Gqo_JKltgWt']'뼀x‘d#0m='s.6٪t>%ks EE{(?1Y3ZEǞe9L1+3,¦=ZG ii"WjN{+2tf$(vwayή~,Ov<ʪ[K6%̜Cxb2)TLۤSEmS$&l,I4QYKEI$*b̖iMQH̲2*iIځWUU^4WW) d4cd(IPX<#BuLiެ",dbdILdQD&p5r I }I弲wo=`$KZp re[9ȒY۲Lǵe}>@6;胱(|3 mKS$ɔ'0S } i妴yxu-֬wg#n۞c3#/ʮ{{; c'7JjVl@\e oaSoj bTZ5]bor ayvxWn(4q Gy#ѩmFDlUpGF#fz UbZ9d?K4_mGQUSm'~}f0w9vDjz{UcQQN8t:RH,fk;#ybI&IXtaC̞kRUtYO)C{לχzsw <,!yMIYà"(ۥ$8%#}?t&ٚv=|i$(YY>aY6GDӭ \؆N %@L6k9 E")r91s#FH V62WvtYc-!4sXDae1@ 6}x .Bs^rbE'VLguUu}ָ Z7\ڷϧ ͘R=d ͌DbO1~tbwz4tWYUHAo>uOsu8h*g>ĨbcZ˷ FHAKY dJ8BČ 8%I}#d!}7%K'0QM U.2B#5%٣$bUEcB+kvx%FlAʺaiG(3C|~;ׁwQt?O>r6~?K*!f%TdJ+:0AAGl ht3Y3P8 {>rcY+HmcBC&R1x5,Cu3qBH;:*y;$yTChOA n~M/<8p) 2# ’T%+' 汪 "BP(!&.?+eji+ 3k?ND`X='dX} ᙅ@`iO)25Ocߥhtv6^f'%EfEAh!m9{,C3?л̅Be~I%l4r=$=-nC-_)\k|e__nI7Vdm`@m7>eATu3Zn%~S Q0$:6r,W]RB |Eɺ;AL=`ě#wݟlQr3#ɞhX䅽Ykt;3u-#*#S?]A:Z)n vb56= h* ٓ2X~P' (tBQb*Ʊ\hIq/9m;N|Fg&m}L<>bsN10Lb{{8#&L*K?tu(CF1cSb%ur87 A=T~*0!1Ae}#23 Rrm(nNr3?!Jb(P(.1&t$ X?jLRqA>5&>la?C#j$\kڴrf>]|>G~\.>Qz؛OeVr M@0]ռ%05l)y(4 Ħ , ~рi[MPBQ4-piĆfD~ܠzF 4P)6y9&$THF"N$Cw焾,| C!F>LDL.d$ًԭ CȐI X8+cB!8ƛ{tdbXd =rw@5TO4QUTUcmCI~sZFʰ.bABK4%@lgzd%mDy㗶Czʯ (Ǣpvˇ y -s|w'(.pPhD ty'gRB&::C\,P]QڑdӉ8jeW4fE ]gٳaCBa(Nui}rPN}mW|f*ftY%XSr^L5%PzI(F 4`, ϑUIhd\Oc v–0eȿeexu|/ѩ}gcxgy9㋞zyzy4?[aϨowhKթ`q}L$*l 믣9 9f"'LnS jzNϪ?.pC0'tY4A, 3h3/UQ nLvX'pϜGdT}6f~/VP#[;;<hJs! f2W(7kAlYғj,MUU ҠK8 ݸU'3S,,dzLyɉ֟}/Hw4xKseЛy_}_Z/vE(/ċ!/ F0 :>/P8sɍ?RqFYe)q2 ,)P"N@" IY"jRqO 'Q F \r01֓Þ&1 s8mPBRI-c/mO - G00w0ڪHB\L5;i"|Gu!ʹR))v:t$ !BQT 0 (uzR0'R/HKP~[ $K&ZĚcwܓUVTg71hy DtB#U f &9~G$x .ʚ)k '(ZH{4-<Q-җ> =|M9T[!`ѭX ?hI2'đkKip|K܂sFԉˬ )^V_d$^|:Vn$bGJb<. 4Y?骵'첰?u׬a-ba; VBf)YAMiS>JWќ1ib^Ҕgʭ!-(хK$uF0~ ?CaZ$Thd*EZuAEJ j~O62TQH1b869Bu. Fঢx@BvacRED*Ȫ٤4;&oRfR&:7i|b^2m.Xm?oBLcm5򂱬 / utx>JPwZML_+| (5(;Cco[gu`PeN k,NhCfdo Wj[ML?B/`Eb'0btd`P4 BQ~=/tj8.ALH) _FEb=p l jiW[@-YL}?0_F㺪ӆ)vwS~XZ GY>;PHTV I]diEife( gH]*2 I6yv@ u coFP_Xsqݔmd_= ՙ0‘Ϊ'/a)L䢱ƅf``'VL\ Z$V HH\KLj8tN9Yp&Ps{hor`1T" t\# 5˃eGr٢Xa=TLsxJ7 zb|ak#'P:%W&UcΛ$rOR?kGiGoKx.O-Ej뮰 rjk03 J+0J,5= "p0%G *Puy`zE8!m#AreZ[I 8 "DD]jvW?]hU&Bܩ's CYA*GF$nrWxJ$$(kAl<ȍ+9{K# [Z V11 iچ· |q#RFl%*KNMz/~Ѓy9EDiY9&J޺-F h!8 yzr|L5_H&{Y'b[PXðXoN~u]DTAՑ!nZ4H*B4cnb5˦!4 09 _ȸ FV'|5v0a(JPBzC # 4͏3+N&* D6dcEDU!$l:Pʪ!9F 0;iCyNMO#jhIò>mSm|^C]  $m\Qu`<_B4:;g|z< RzX'VUKPNG?_/QQI TAfPTI)LI2/̕#^/xyN͑#g0=M">hd ƚ4CP5 zग़mO3eY^pieKB*kFy*vÇ{Y'h3ڠ D3Fj- ^M*+H;|JW)0nMX!syY`XrkJvpZtg(Q)ZM*w#(ZN xRw (y:<3x:|xA~hX OqA!0hIrniTl/?l hM3 USMvl+u[:YY`TCI'OSV:8_Aek?;KS2tL4PC]WTZ/iKBrn<Y>=7B-Dhi<&㍒[Ӕކ Ep. <~&Et难ҍn1T:gSUU/(뉌Ws;9f]m3ĻhUϛCԮH0 r.= cOC.0N_zʸ"Mk``_\8p0Ag#BB7KJ5?K3ۛs2-} `&{t 꾍`ѱZ 3"E0瑢Ùg3B%IHdzESRX8Fbq7Va6E[!xlÎ-dw+"mQwP)T1w3Ίv_ Xw? s4G}zܬ7%9݌M=llݮN%^usi%dP@PI Z#7iBqv[ֵ;yK'KTWxgsdRޮ*Dv#TNj8]GZџF15] Ѳ#zK 1WT*b֢nw37~uzxQxa,\0;܃T1jEL&ADxS=1P)nzbWCD-yHJ&aMy-(9(P,:]PpzJz~!~9#ĚxdKlw J10AqO_c+nv&3j0CX/la۩y0~ʰMxmBW0DȀ1bN6nV;\cՍffŃ d40ɡM h͛ű f͆ 6ld6hldţF&21!d٠h4- ٠Ѡdٓ@d0`d 2# 23f͌0; f6`E1 Y/&l$Q5 `q]\3 lv CDCh7cGC1/hg M$ @-* @ͦhɓeA Ef7IQ$@\"g*frZ$ضЂu"LF ?x♐K'8 z6Z[ a Jj)tMHu&yĘ:96 xW`i@IPR-雞 -w+pa#u( 1#SIMi0\ex% Y8 N5e6< 8NOjSo ѵb$tIPBJ@b(B-,R|DFIK=F~ǖڪmßdo[4i˾35d77SBRRc&RjLy ({/HKH{6C9a b% @ӱP,7 SM,pVdj1u8.n%KalUDnI\B(`CCg!:`[,2VCUby0al=ÛK bF &#lHEL,*6䩦Mm>qӠvc85PN%AI=4 ' *VDz>>$蠩C0'B\ d!`EP*!PbeE$RQdA @pmvʨ (2 D7 UAPB7}>/w{@O@Av/=߁JR)!o0m$0 5'iz\I@8 < /?2m\?$R20R؛Iܽ|1wxXjf)\<#lZ$BPD:|_l}k4_jϧ]_1>|EgxC>|lg~|RɆ/Ia`Zq?x<8" &E 6%\X9+ ӛxQɜ\ט38H#93O?bת9c,ݜ4#[{|R7X@: eo{ qLl<Bĉ1B<*I.wKr1{Z6"kFݼ<.KI bAK/C#PXw>7'ǀ|҄g̩<%ukC _0DzWY:TGeAP8G?8nLЇ >m"Yt3\!٢! 4hhCUj#<–4C e6Egjgr:$+ v$. S̒JT2+@f?6u(#֧?}M|=(qe=!1 K$[RMU-"iI UQv"_dr(=RpͮG>4EtS--=Qp3QFf>F7g U@/!7cezh>|FLgl||םGWF_Mqhlj sI"Z)?AYZh!NyLJ8u[d/y&@J$$Od\&_w @;tHWa$p?n!;C!`~6ֵ4M?tqϧ/!..cP?y_y?;>\H  P!6)G`ƪ ?$5TEUJY0R~d" u)Ma{iK&a3}}|08$Kz;#]tdEBlS8X|:9ж6r=bfol- &4KধZ9|Fo(Ko aWn!o</eDjK]^qًT> 8g+OiD8Hd5$A4d:C mc #lQ &rj(.!0qc&\΂BCb3ʣIBn.,RiMNV 5,TfP!$E|̊>H30z~?p[>ǷAâq {avBL|=D?5$>Q>x>=}e pZ O*<ƦB$QE!p*\%=CGzʯnY1 ompp 903 t/R$v?e+#pAAL\lĹQs9v}(a*t&8*Zfb (ݖ9Ot@'abUUU{^sv?׷K]̇A ~o-^_f }wg=j! omD*)F!lJia'hՈcK)pueg*Gg9P=P-ÓB{PQbKpp2"`1LS!IRq1ҝ@,O^OԠZԂȘ"LVL"^UIC%!]e('F;C)EKS@/to9~鬐?"6Y㰩G#0q8!ShV;?am0 pC%($ɷN22x`P ȢbH`擎P0QKJ4<+bfó*;̂ YE߶.e1X*ѳ){uۨyv *fGWi'WMbUO4K(Pe" ăɒ&(B}-i dPnP@ $!6 OJ)?9Gj?ᨦ.! %_Ɓn]؇>Sfr+ydY~b1*!mG8;RTCބ_ZMp]TSGT4GPP+@83[wp>Q 9)Bt1 +ȁN?5$ispb۹P4si")b)/r3TK}|AR-u];iq#"F!Vh =*ηi<AnP-+ÐNCL@ҡBP3+$$%,P&s7q241Qh4`X_ FP#:$IZ[9y~I䓅!RCJ S "(dB; 2urH$zÏ~Gi8qb 2OOi@*۟B0/ثS'<tT"~g0`G`a1xݶhInuFAR>U+zL6pms)iF>O,S rälCd8kWn; ȧ2D V>Eb'Rµ^_o(}11Gz{kaF0elE%$v"2:T*f2ti c1x<Íڧmiǒ8U,n3NUa\srOi3PB9D̟tD(~\J[q`Esȑ]6O6dhO_SmE|Ukv1͓_[7x›𜻵Zgct5 *:*:/K9.(r:~O~Q|^x!ԦW۠8̻nSs'~t::ʱOMjT #4 ' 2 ;0?v%jVeB1J5' m~Y{iKo;ݏ+O~O{m%&R+cԟ ӑN,Y?ۜxJEX;~2\NSi52D§̘b)QM#|WR>?!O=^11Rn`Wkgnӡ!2M2&|垯lc)Z \U|mrzBH&;EI׿{CLl=儀-B?^h22~8{Z/t3g8jI:*~43 uVb/[Fgu #E+06g6s9Mj>j mI P`FX``r}Z"d`LX0@=l (QIR'4D1(2a&P%Ql)ul FEB@&o`|nR *~H2["ZAPtz=''3ΑgP"鯺$epCbb:2$1*(?F)a8 *J<ˣjy:3XP/k!,?hC&)i?O&oo>=\`Y">ﺇ'8,d*8bE}2\(7$CiC% /S!D5dT+𲾈mwgH4Id ~߿U(Aʡs< 4߲p۾]fue6SX+c\d%bl_ڳW;ǻi/vJ-yHiN^lGpuoA JXK<G-kў$l:"pEc?bY@v_k"0i)|DP1@ʿCH3|0yEFD!xr~:oqISs%YX,ǙNd(6w%a&$1xF:[oGlgINI&-T]}1Y4wݰy΋!c?d}aTνV~r9*ٌ×bFBHԄ 䣀~ m=1!$P^|$# '{1j88/ WvjK_2Ň'EOTOq9֩ "g\vChUi'0F͋#Ui<1ۨf#'>-U~vTs:AL@TlTĵj;&$t _>a26W[i%&d^X ZVe1φRd;̦npʄ9-k.e'TPO1-o٫3VG+3gEyz0(D=Mcќ~tAB4b)N:裸l]Hq&KrZk EٚNhhJX'4sOtrppX,GxB*Y#h$& LL1Q!* 805dpy#rv8 k=;wf HJp)_+HfsFyZqMϨnEl?&8MEJFp 0xe6+4̤NA M#{tFcoȼG?G_- mIp̏RH쮺a`ĦD8ϝ pL&tYa8W(,Ihj)K2ZS 4¹ udTSI+r*$/4P2]S#0qY)~l:;`07Ӷf*F׈z׬!Qj-T-]S뚸}$Vd2k0ts7R+'*#ȌHj=JDy`>ޢ3нƋȠB4󏜑2=vxm Ӏ]ĵ \ b9qq[7|vvVڑI;d\A'| Obxg*nhr10)PfԞt\8! #ti6&U栭mWMN:=l\Tc}onͮ$"$AѢ`|hl@31I*e%0 6<:BLwn|̘Xc4&9"f.cB0ݠ}ɒ v\;yBGo̎{_P6q | (P.!eWD{lf_^|ֲgG{)vGQAb-YA0J!i^#J*8 b]G>%^^͙؇c#y`Ϛd9DH%~ ^e8@t$} y G Fܴ)սfI = Ks^ bC羊Հlv\ɠsxxóri<_kxwVzD{=\puԅUY[J1)1>H"̣\jSd/MSp>[% eL_51'`e߽mffFQ*0/%U|M0*De}SSUR" ɚzSx7?\coӜEҩHHz%߁?eNdH~~֬"o?D4?HEUV&AfiԱEL3vڦvJbFhJU|Ҩ|Ġ;(^YkOE Ldz Lqf@"SO`hL4EB> ,a"z. B DD {pTJ%]XWa.Hl9MeNTSZѬ%,]ڸfK ‡*}0>i3vM?'gqx!h!~6J(% R $C*I˧ދdCR5~&ڝ]kp-(7 &D2DƳAE!Q'ZCۚ24ӰOz~0q ]}jwxM|-}HeS%iKJdE9%k|Cߜ+ĸ;-oI$%=M^9ݷ3=>X?mFK>[!C($/RPn_jDi0?~_HE/9PA:|Z,˴4#%#L飙"Ṇ۴IbD  %89;tO Pg^օXo$U$B_͡xƻ+1U*RtVKQ/9 Z ?jϐ!ۇ3?`/)!#I8I7=1K#jHAb4Mp~Աf1L\(SO<<G*ÿg˱E2EM^a9&8f5޾Zدq^Ai&j&y=>Q] 9ony>KCT";A bM=9#gi*Ҭ5ʍO媍-Y "_Ǚ&~s U|p|c +#X}O|IS1U~({̆u?WѦu0>0#:!a$|zz?}ntM}'Aw~Yr6,'ʋ'z1@d;MWSX?q?o!a}<$8ww?8#t2C}o }L}ے)O>Nd:dQ4~Xg싟n;FZ>8i;Pw﨩~B*Et!DH_PB :LSZɽ?EIcBa&'v4f$`Z &NHǢ-0$vne1#>Bb9/>tUWd&3`n(lSÈGNr9/O1!S.Jҩc Z_Х# }Hh`u|u>2@I?ռ3-j+V-5v}1]{WBt)5<8RJI0=H6?g|l~'jF>2 k(du,ܚ"R`(Y7Hřy`,XJbTĢRRHLdr`C`ًZ3a *='GJRc~ϳB2omS.[?ǻC=b'mO![)8y J8숨ޤ'o߷D-#Nzݡ3xldSKcujdɆ] n C/&p$%H[ʇ{aY&^A#؂EveC2Q5Յi,}'0E?ŪT9=_%Kd-/g#r|ŒIV@{R2;dn!I!(%V"I$Ȥz8?9ԝWܛ߂#b!DѺ(1>D}l6JdTŹS"Mw^(h$1%՜v[1&kE=C<>Wo73^ B"w*$6yuB)V I☃^5\U-al,Qaɡg(lěD"ԘCN&hޓg``z]B<)*B gkg2(6OL}K}Ӵ7Wn颢8M){ QBp]5Oq=7n?,1?64j+LLe+Ctѭ#:8c0O'a к Umƒ˂CS G˒Hĭ ^<\)Ex]8{{ V8:(5 &k4ʼm-ڙ$T6M;:xi+Į1NPeAT.PT+beu{ Y%B, OARA *D0>pe@Mhp Fէy:y[yσMIDe"BJK%Gl8t^{t?xc2}P?6  -?IEEӾstv>da(zj{>!>wA'/_,!p?xl?>B%Cш^75Uh+b<2m%~ο+jmm3%Wb ' 4ڇCłZ8s?y~'XuGPE#y84H9:aqsrϊ VE,3"li9CmLT(Fw6D|"Gyk\Ɂ$3~U8/O?k0+$ӓd DDXճ>i;ԌP Gڳ~+H`BG0 #+k<)2i" O_ ǯw?Gh%tW4}Q.۷gщOLKJ_$@3 嶹 *&9gYc7;Gއx` J"i~&@2?3 gD~lNdLZ, T ƢC{iCxo,Xyw~HshqR*ha@a`O9LjT^G &P&ͪkKSBm_CPi̾(bSE<9=2'ro?6CIcrG*-XؓgyCCAEOiY*q-i1Ylb" b{Ti^OR`tTB͚qf7MS} ,jR_&0F Idw9rwOk3{)fKt[@DŽC3]ͺ<{%'|O40˚e 2sC ݃nha40˚e 2sC \6<3sC \.ha40˚e 2sC \.ha40˚e 2sC \45pJwȖ* (5 }'$Tm6 0g l6YnLxB|ljɏUv)M)T YX |=KWcn2A0JB}<=c*uwMbϯ7/O7&=}\ 0Cff@tb_8Sb ~Y4@$?ɿd;T'&yhD$_"Dԥ l]ͷ1s_rؒ0H#R\&5!7LiEo꿆EM?<\s8 iU%^+׎ %pџSh"̞ƓأSq)Gdw<߱Щ,Sd#>HA=Hu84}]y`I&P|%8 lBdz=p܏/|!'u!HP>s;<06C=M'ҢDzS VF=%eD4gxIODMo爿n'ߋi!*Y>V)~Ob6Bē?#?-pp1trSe*)•D˜"–QK%b W (O`H0$!C'^ p˜REޟ)"þBJO">70f#FVGMQG2Lϙ'"""drhTzGKIhcI?a`q9}]* %  MIׯ!TtoD>Zj1az2|Q_zI$kߟ2?R(r.F  '0,`= "@j?w_#rDXHg,c?wFKH8Ũ"qʧNq4l-j7g7.1 =*R2 ctYXtE b2BL:>OlVoq/ l`!%z$3%&*tt࣠`"(&*K&SQ ٩V*Ȧ'|lr IP!lUA"BED ɻz4sHo#G 9D5eݸ"!G&BSG`tp|~LЯ΋"T*>{ {(}WYè'72T<Uaٜd~&C#g+b_@|~qQeD[!cQP*$֨~шK~}z?I>5%TvbO\ O|L! 8+!?J9я<)*Hn:x>ȼaܒ :AI׹bp<#҂xM$vB;MNsmDDNSڒĎ}D()TY&O:LO7|+̒7zΒHG(sygoC WciT)w_ zLz$J8O%#ϮB|6F\z6f&pz#xƍ_ ڦI0P N  .#9oD ad^aE9zYTF ZDD hņƒYT9R(3!g-HՒ3qy1*F rGD5 #b98dO ~#>>4$# 9އf~9(~|XOK^&y)A֘P政 yLHXjgq$F"U- ʒY&>8Zi|>m5cUN[OeЗ hU BwwH4:h $H>4N=ش,/e`!!X1:.dw!1 ͡A`Jasccy'g 3:O}d۱'h<3ͬ~O'm9;{RnvyO|9bttLik>2I`9t60am*<=31gpa'`℠H~0=U8gJHw+$6>9U=xCDY'엵q>Wpr0XEYch_T230$z}4[ø怅6D';c~?]wu=!BJłTJ*FI=CԒI'CQOF{ċӴ14԰-a,$d2MF/[$%Lq| p A g!4)AU ZɈ?QDIi=@xsqʏg%I?kw#`+xsbD4?g# ~Θ8u[( AFp@N yGV!4b]1D>Yfdik190 sTdi)@@8b=+m(SlG9$ ؙ\QuR DwyIR'ŕ]lv0:7c?SiX+EJ"oE_;c_?QrH&#c䈞)C/ćGyHB&&ID7@fE;UH B}'>$&̄Vѐ?1@TD{w߲"WP+k!ePa|E†D<}AHRfoS=vMc+43H%`9 3YޜLJW?kuDTrf"4X4YQeLIY|E?JU)TRJDuŹuŹuZdNe g \̜Ak9Y.YŹuŹu9uA9u̜uݭ ' n ֽ"r^"s%ֳ.Y.Y.BOa'O]$#sN=?CI>?>j͎͟V'% `qU{7A@HRQCE*8ʼn\,BH(AȆ<nzDYȍv Fl6uA$:A>0ć %BӨ0|?,x_I&vuoy:o!,UYuKߌ=d/P1Rw~y%/#<ԑސH!kv|OOl񓈣qT;St)`7L 2R'xU#95 *j*$BFHڂ $i[U֙Vvydob~lh+Hl6pø|%F&I  4dJ?p1nVBC20yPD񭧧$!eǢG`BWNԓUJe@#:$(4*_AYzSr o+%b>BB500H/]Ay_gEOS7}?+#YUS܅ RQP8Q =`_|VTQ@Aĉ% "b#"D X° ̻3"Si7]mؑ*$uN,4wCx.>'ĩ!<8/YM5VG! KCC]6wI 2\tܪaH<-!b@w\h >fI$|4"'s2@0X TOΉ4qOteo@>m O\}d$$geT'BRkn x8ެᕒV/Փ 瓉K[K# 3wC C?#t2r6 hHg<" 2?*hכz4.bUF8U+$,L5O-c#YCB3T<( }{Ӽeon5UK]n0X q0+/YLc+1b26mqc_b?L& B./aEIFѼ9(x&uCQuOqwXL=m6_hhts28]<ʤ܎&T߇$ ;1yG[FPOg4Ot5}.PD~-?뾿Npk! <\Hc>(0%ffn8=ߞvcG 緛ȄbA2]f׀_7w"5*\i*-Ѧrd[dnUÆ$< 7hn>Lpk0 ^'RCUL?4#YHֆRi d"zҦ&6vCJ}88TD#Qj%#1Rh,J?)3ҧ7RH!+H.Jro s}HE߼ H,G2:ʀ Jk9r~d~Lw>]w9bK 2GgteVbQ]l}k;G8c'yכ31HhyHC|K#`rĞrSO9W>; IURB׌.؛Iev¸z*ǡ`=;as",KQ(b2ʂb>XS 48,R"-b3ʇ"L}^; @.1hkyqp { Z>)Lg1DFoxދje]Ѽ;v'=VT 4F1#%Vn`8VJ#sI =PCn Ʝ\ w>w 6WzDxBuO9F]R'| )g O~8mP q -L43}hE,{B [Z^L0RکmUya9ˡ3^N:iѻGhH9A?nmq_GL5:A:qSyN|v(b)1z Rpݪ`vD]ӅUF4% m̏ 9lӨ\DU d  y='1x>_1ŽԳ,͢6eh+[|Y&(_&}cM%ˉ rɴɿT?7\{T ظX#=M@4b6zO=]2̙$y 踚A(\鳕ĘcZbG0 W`sy"rfn[,hU8*2  NͽybgӝLX0<"w {_.|D*: Mz1!: y"PuүqދC CJ3·<7R t+XZQH- &R!akidҎ_V|HDE5h-H@ ƋKC XH$`pUڸAP@Հ gR }s{)cw;U,Qcnw2&[U&h,-pt3 J`&a(JhX`6M-l#p&AI?tq% 3CvsHx uO^#7Vef<+ܘ|3[sAL;M}ÉQw_Q5uxuc88c:x_Vrj7NJz⃉jbۍ#FuPDh9lr>- a0qıs0e J"f\Q-QdetK-)i,&0rzx#n 4uq"RvvNhSCy*E{y*J}NznL.&'|Cai0."S`9'2|x>,?i/YY8! ;)Si聺'3W **ѭik4;%'1#P~U7* bx%ܹ mɈ㊋X|ꠙTD\=_a LHMGs\8l]ZJ]=/7wAY{%nSg;GywmTQoZB|`큺38ľ$s@ZhgiԥgBC B0PiWeF3X܀ŔABK =b2 N'ֆ>F" :.P 5.fJA^Qi.!eKUsXfiG ?6&49|mă}&xp.N(D+Γ}ף/8W۶kTSEK|Z{ƃU)dLt~Ըo< ?VÀ7\Fcf)Q4s Xe k-m%]smWvJQ+@bס4DfX pyud =CD\!v bu0xL0뻴};G4'"]ښe)!a(g D>HI /x0PK88$'8ó=,.e띘Ɔ_1Bʁ$Ic%,Vtt?zq<@xm`s3JG x`HAaqbNFpLgdxK x/p\P?;Ǘ8D|x"L2vfhHt.#P:T&H󤇳~_>\TjadZIXH 1B`-oy//j KA) *I  3k)'q"ȪY%Prd:dwC V?#xdB<`,|UI b 2I.4wá"@ ~^ }Iȧu2OiWJR#$T;< L ~Kq@@ s$l&rEz3P*}V (ij\p1*%[c%fT4fjʩTU Hl m41jǰ%ʿ^' +BHD JhX&B | ЅT9C tb#ZesD zY&Pӱ=gfD-Ka1;ycFݧaM.e$.61φ̭6-$Bd u 4S:DKD4(l}R}KÁ~<{;2ù5GL J*-~1(xx`ua4MV*3Kah˔$8|y!C8 Yj͈ZA0ɛ\`a"aib-,`X]FI37%ʀ%8H}XlȭM@ (!|<|^eAqXK ;{D;Dǡ)UX)bQW6뵳W-sl5CJJD1R!!X$D:_. G=8dK W% HP C` ~a7oBt vI1~Q/a$i`LILhf├W93n!(3Q8JɅC482Mc !ػ#^&|>ؑ5"ѼIO5ԃؒ8/ ֱG7hQ`ȡ!=4w. A?CȁKzq]TR$~4۷dH7^KGHzYG+?1vcQ 5QUԎTǟl4 JJC{Nc4#ICy4C_HBI KJZj\5@4XY  .vM 2SJ ڶ=fd ivxPAZEF$$cǫ#} ojm"l)MvB} ~fij J4MhvS!UDHPA #X{N;RO*=$\$mM"a;F&ҮʼndmdҠZ,DN >YHmz9jmO$yAy*^Ni?ict~^R=8y(aR4@OIyV A!hR:5 P A9,IdJ|NCY&SJP%/ϭZhEPG XR$) )- # 6T`zO2'*BXSK|$d!@iE)چ2`ڊ R {{".&˩9 ^JZ@_1RXU *iI'}7epz]M6,bM,KX*1FɲYtd()A ejZ,5ߘM^M,FYQYMIYDRP2I3g+J b3rJ2iC.t!;Q,`톻N7_9,%m} ܌JA"PbJC;k%iidԏWDH3 "씈`i "* H ypX'h!HJI2)0##" BB0=)D@Jʓ*LHQB 2 j= H"R#Y*hֈ8Za1Q*r N!⇔""Eх[FMZzdH%DL1 H[bRlQeKH@$ONX&l:"Q(O6g `p&$jN+!m7/t!%B L8QXN g9Ahn! Ԓ"!J`rRBv +$1T/xRbx:DQ$(N!f3e]""HkT`TJ2 `U)V}H0L5w28V'|H ^d t[&i CП/ݬA#t>&6!%y>{/S*罋N;A #(J_% !S0̈"*.@)ϘKГ CA{$d9/袕݊a* _B&#C53H3+ APl/bBde20-|>Qp#j9(06J|ۣ#xK@!3P:FgBHm -" -a4s9̓!}=ۻl)^DUc ݎffj]Av\*ILY"*Mf!U؍XF xJᗢJ?H (}"!"tPЃ'Q˵agkՋ=%K@uT̢u=RlA9 0dnhmyЏzb*%DDi?4r0spP2)0%1)I+XIKXKs#."o$ ( BIL0,hi*QNے*իVc;8>)=7BI`|l) &8aF[A Nx! @sx@V+Ro3OiIe1\iyr,}o rh,L`Gp8Τr N0҆CrUXbd(˳줧TFrMuX#ۯ]+kJf/Lk!ԩD#[] uDȚ$rs?才#S6nRB%|E;m!@R5 7`IO:MڣpOv Ay=zUɁ0OL=J/;%[@/HN!qW"gM>?!hpN7ֱ>}R7qoic+ގ,w64% Z)b`:Y:dwT=< 0wN2/8ғtpHYA_4Hςxl= ׶}6zR?leq-c$``y)!&' ь0g/1Tk(,:R)5JmbD!'I:dI*I$T^y hRVɛ&`}ƺh7oDc`h!ĕ i RԊ0| OΞL[vjfFMY! ʐ40kq:.# FҊhE]D-+CzRڭT2eFWnDP"2JY @S5>'D:&̘ * Xs;C5T:tNsJ?,䙂%|TB$8+ `ybO3(;.B RC;nuw$&wH.f ?z PG C6A}Cr!RR|sj;>GT"8"lFbmZEji`߰~s}K ~)]kfFf]xVf&WGAC4?:`&&!L6Rulr#m2pT w栢=*[E[k^ A3war93-09,hL1t0I`G)֏F {\ff[݉*5Q[ɚB\B@S#&14qק0@"|}i$TU4*8C@M?̀xҭL~S ςs kGQ2 ޚ S, !|UjILߨ88 ܧ1Oˀ$?i)( G ^R z`Ca'<晎;@j(1y,&3+_U"W4yhr8ZնU!?w<E0MlfL4_FR&m|qz87Ї?6 ꖭb߃ő0kFi*͔*,W2|{!H<'R Kۺ5}bjb⦪l,*&ؙS;(XIDo*LaC2QB<٠bb3b{NGZB%~tE5o.gI66E\0Cv =֛mjh4Smco+'cl-HJ-maM] ;|&D$\FR\>h|aTt&o Rws1,,cQ t?FԚk%țOW?[$Q >w7SЦ>Mϗ;SN'TL*) I2z aM a"&QB 2)#'0DdVXζ)d Jq3%֑DX 3,xddKj! D>!^i`xBK((dQWg3S%` ;bTPH TL2jTHTݨԵ3&F3.uad8SqO@sTR,ҒRkK;%9 CR R5ݹ&I$TP @NRQ1PޫAܵٶ@-H`&"hJA#)dj%:% A%%h,lPb (iVv8

oga=/dyB_c'ZFg3M.~L 88J ֐A6X!NI>#D, :Hsw4HgؐR R"L%I!4CG8HnH*wI2G,>yǃ"p 㴅)@FILEY1m(Z*(FY_dѣLD}pUe&itnIJaA#MtRFD BS gHБy|;ζV nm7WMj}B|tQ'^n8}]U\;_JQM߮b7(O>'~VkM ]vX89O5ËM 4ď$ѽ&ə1i%夾gfY9K_dQD{oZJ=U2U E,T;mZV٭d#8ꫵ\)"h_o.p?$%ސ9+4"<Rz=v 0$+H"~#agnZOC{ =J䬚X~%i䐨sD{݉yu7+،#hIxǏиG4{vûl$IWZ!`fJK :ml)Jr% ;\ssQ5ahyC#;Ybd/G".O2PvF#J](u#`R  &R+~XC2I fAxPX\|ǟyi c0P. H zw\3t4o}uTfdsYKS}0gԩUYb(:8/X5}üAFkުs؃I vՙk rTX2+Ǧ񍝞w[ 4J/0.5xAGT]0P4 ӯ#р=7N;կ[/A_XhPD9;hj\8=Cv#JD0H2#FbȖpVfI[K 8@v}5 ߝa wFQ ipF$ܗ,U_V ž|3!BkZ=A%(YGImYb0žpl 8IG/yHit2"t# 8J'$&Q"t!M!0 )\=/E[h (Sx1G"UZ)|oMw~0W"* rv7kX3v~q5)H/0<="Pb؎c|B6բ ٌ#Υ+HV=F)ABH ePOӌzwS rNAG rUZGdi#ͳ0z.p1plK^$zYw~5(|QOG=^3zS\E )n(1de!<=phB ]fuݝg`Ih;΅iGHIXCxS\:>NŧJ"Cn{ǁZ8 R A*'a$!eXiZ IBU`|rf!o6%xjД]AYcDo=WY&bivy6֙A=H ,ဎ+V"$ ZJK@Fp>B$?ߍe7̋ 2Zc۞yhh|(MGCBVDǐD2OV# =021,R;T9t['Z<6EMe@Gd.D@f&禡{hP(o1@РP}@Wpi+c4hEJ+&eAY-OkZ;A(@G4Ifb|dygҀOn"L kNy8!.,,JL$DFOP!04B* :4d O{k>,%b]ml`srJ1>+3AA6TfKk; !.1=o5Ecdyh @'2p-n0˒+n9}QlN8=AőyHS4YLv|A'3D0dv`ȣ"cX3 E9q&9w?hKDãX[4mR%mQi)fFE&[+%cZ*ix]MH:"RRb&b*()0^G ˰CɶmM6k0=V 3OLV`&IhLF%v s>\q#52ƘСa6ӂ:`H\R޳Gm>bL7+emHF Yk}n=B~T[vϿx|C\P-$ĐĬ*8IJL\pNTr9cT.d(D%TJ!ZcY:@m/n#ƘSD YgaJJ31u"ud=>q ]ic124`,J_woeB_(z&kGn,zP|d0WCIi vh7mbtc\L hbJ!m@Ҿ{ ;ٌC vВr0d~lxlwE 80;V$#fk.eV~]k^ 5}4_$(+8=ٹeҫYws i,Abyd޳cѾ:sbTh%h~jf:k) "~|lt2TEBQI\WpIfM@yLvH!Z )Kך Ȅꄑ.}@ɸ; * ?fOG[#>;(" H3XN8ԭ #.Ra P ]j1vmGY86 :N iIqCHmNH:Q\:2dCMZy" !5klg"Tێ&ԏ%CxK#um$,BsY6wȤZt$;B2d;-Mݦ0NR)2"L,"䠿 H,%?ǯsGz|i|Uh>Tb Bv&ۤH<}ǣ/}l)Ɣjw7Qۻi-N{tΚ^-&t" `$Jz$,xq eJ=r>|,1!)עk,XX/n'V!)DJj63 SHJ&5HۀmqiL&V& lIhh%Bȩ"pN:Gۈ?GRs_gل]N1ZQGh4lHp2ϚWr1A7{܃C;22-BF9c]\'4IC#'$Z8ξ ǣy#ՒSJl`%/ CN|gbR)AUb헷Ǿŗ `j= >0#A m b. 5+0֠,;'G2q̀xi. ̃ d@ҠpLQ/vmh010`%A/d`1XJqscN /WV^ k7Sk0l(IH8}[e%a,S Fw2]k;t=4o؃hsVRa'#9G(WNyp929PAGWP.zr5/1.Y;fBƄ o0v5#-*bA7'5bF&#v( zTΈRyf«чM+}XPH,{-U,@e v#J:R%= g|`%& Rb:&CƏ$!Ir é15G6#RMdObS<# xcܒ&$S!ٍX Xq # WpY 0Ip:w/*!6c112m٤1EJ-*U;"Gڇ#g!49УQ…'T"qB42KJ9>8g,!"/+(,BP2\R72+ JDDuB 7A @ݾe y"$"в(WdγȦF;d֪4J"C((+4I,H $Yj'UĖa ieg,5襼{sHUS*Mܢ8ht9fr60Sxu1 >Bl'/J dVWeBF pѥƌ?wS'}9y~ ~.:>벪+F?`-j\oYxZ4H=0T}$ $#11![@ c3& II4XO)yQ:mV& ;ȼnIɨIziXsLMK*" %syoTǖ&:kE4j49& 4zԔd`)̗|lPܚM4iXY l{!((r@ Aԅͱ l(FI!͢.>esQk{ќȤʋ6P"\NƖ%3Bh I. :B9bgYErAmHui'~FN84l E z *.AqCN[md ̵zaSM%#Nhuu&&NwˊBjAB&i`C8!$,0BM0Y?cuۣuIXTX &]`Q&&;{LPUzBQ"`'ce+c/5VI7HiĊY u8 糱*#`Cccg9`# FCȊ4b yA d>̏U@rP@>A}& A93{G>8; PBD>C:|>{l6Vc})R'#z͐n[ Ub8hLCUPDiMd $L1Vhkp܅RE&& R(*,"\ qnNT!J)JMi: a4C Ѩd}恒D߅F}Y}?LnT$\ YєSmb_J!Tk)NM+MՂ/O1he3B\s`rHyK$dr<'2cGBBqqfxA0FB,|#{?JfFy<Į{Ծ]tlkӒ0Z }.{Po+e /{oFN52-`ZdBT#=l7۞9FREM:YU  h[|E6q̂1 (j M1S&dnaBfZ xַN7۝f8$ 4fX0JG58.\o$2!>Qq ׃"}Pt6C%x]tJ@*Qd@D@\ܕS%R VUaaX@!aH%`U`YA%URTJPIQi(H$ IDU $&ZAdHQBȈa,QeX)]aNWزD=8! %!̀5T@62Aa=!=?ƳsIEReiGgHbIJuRG4d7Я}ىK"d0$Y(pHͰE^eFuxkV C$-TYMfTťRjI""֊c*I J1RA2ȥRi!Ef,( ) "0Se5؍lY))5QP+fڶԴE4(," YZmU,! [! i"QB4RDMDZ ҉$5( Zr()>s4§r= w q!"ŔE#q$)؋>يN;%71!1'sIx(CXj#<./~$[!q}ў8h`UF>Cw#wմY%PfC(i ؀{ #+~gNa&` $ J{ee1i׍Č1lgQ >`:5h$dcp7q0)2ዄ"A tcm+:jib!D"?YAd^p6&A7t'd|?ȒmM[sCKPc_a@na4?,‰29Oahw>M>/|d#^v.怞!vRa{8je$l&mZXt# -џ=Š33Q5cyaet.tM[R0҇A/6{b O,%Rɕent%Qo~Axvdig2&w;I\ښMʓtzĒe4P<$=FNЗc!h,HD~;`'swXN4l*7-s\I)MDg[*&{Xe$ C1F ZR1IS"BX*!mYMJa壛Ӯ}?$~Sd 8<'wVCQ4'ǰq&= "tԀe|ҡȡ᱆҃vJ h~Lath~h_q>PQVOU :R i!"CyCtG)PM8DOdhJyuP (%IquC(JHw >򚅩 ?d&B Qt1 KJʾaS@p<yG{F5ONI&8,غ =T'O`r3-T%,%I`E@d9ߒVH#"mJ#OUMK0:HR%MHbJܑ0;cVG,bns`JRꫦE)iJ(Ԇ$J1 9 % 䩂H,@1EkY%` r![iK'V5(fvr*WF{FZ&&͙*G_Y#~ /Q]'qSuY .S \~(iBjCP$>4hE ID)4~vTy;$fNUL^1ЁvjIByMg!ޣxFi6KW̛MOj ?c'NIY0n}i_ZJf#!+ײ{"kMPoIM1L?%&beQ$I?M h"RQNJUr-LsMx~w~M`Z*bI ) 3-BH@C4i nIH;OŇp|725Ha.Uf&Wyl Nx9vrzdȉ@Gףz\U?ûn;1D3@ԘayD^II%s8h4:;In ,ۻeiIA<0www4 ofy|7LG5r#UMİ* s9rYHD)]8H[/']'X 9y^=٧Iڨzw*(Euù ω"L(S0Db |&E*{Ŀ?Zo7Z4iWH]kMlY*Ԧ_s!Oِ3%bA!{j}>>4Lx+Ҷy$}'֟9Ȟ|$M{d$R=,g<L)0\2:J7 s\ĜduQh-/o?~g/?_U?}kS_gz??ios?gogW_?_ydo$ ?@7HON攅Xw! S P Ta aQE*#Qi+eeXk %BjkclfkY3dSUIV[`crF\3XIXZZk5,kZR!T@)dV E*e6d(ą VB-YeڦTkEjQ  LH”$J?Eǔ8Q"2CT6pmtەf)V2ΌCj`Xf $7#dpf[!~3B}0y(XFS˄!M E@9.`5?қA4/[v¤SJ4Hզdf"[IjL-P@ R0Cc7UJ3ƒAT8 BEp+Qy9Xp6.&*l*ȧ\>|ܧ%FEy 2/Q!Q롙&aD;_ o =>PiMla{(!Š UBw| JyGQ"n'z? mM\(~[D@WL*OFf ϏB8M gڝC],*H"r,c(btb%۵.&iwΪ?쟒ء7BFZK#aOfeqz\8IuAjU4£fjf6$F*ZZ+jI TeqЃ;T?% t0 $-BsiFT G aFQf:PZ"Q)O.Ծ;l;A^"gG"DH bK{3vGgwKp_x sb/ J i2l9pY2ۀ'iL3 ȼ5Bė,<oe'P뱨БIlpxė#C=ax(BG>X,('M,!@ X(q60ya!'c<ビ%6X$5l圐UPkI&#v20grR$܇knW`Nw4j9KL_6ChrÜegQV%E+"T@¨(hD bPViL - ab)TAjRGbsbX$̣ Q,_2s:$8 <wY:Yy9؍0m]~3B $#3bBDN!2yD PXZvxAs/Z#()`\?>B=bbt1>AA!O'p>ѰH;Q_3k?p;,X4Bz(2%MHǁQ@6ba X(R@0$d&We-S2iV[\W)bV(U!1W Z%` +RHW%UsQIDcs{W(U§&QDXb(ờ # :w}Q>A%ɇQHR{y*bZ!$MQd'լ%$ 2d~.HvmA?'/EsDb$(Hj0W0Me0Y!~  Rrk JxfKC* JeN#L e.F{(7Ö́G"8"=%%za! _}$C>Dz%=j8K{wL܇ǂ(4 q FUe v ;BQ@ )%QIJD`phB!O懹֬pDC'`qtF8+a'!@چϱa>@Aۉf7#KfZEiT``G pb8b8b*J܃H<ƎMyH|#u%Ļa Z*EDSl*p "(H4M\!S)q8!¸ȲLyB{qԖ( e%̏Y0_mpN Ί&Pa l4!6zqE';qb*Aȣj6HXo'Cw' WNqԋ)9})rk{A'VB'4a) 81DeA}JFu20` Ql ’H(}qIv瘥~u!2뼥g\ RꣁW؂1EYK &!hF_nphfn`k qah'&$?|SJG ZY9 };`?' h":[>mz}8~*8_!fE#RBa5](ŕ!f!`3 8Lpń]ґÂ6_sSxJ4?n9sM4R pܟL'ޒ92n|DL$:@0~vv0_ TCX,t Wy,s^"E5ETUR-ZMZ-)RZڋ6)6JSm ٚM1 &[!+JmLu-e%Emi ``L,*҄JY$(%l1Q`0eWTl2]Z66[#ShfuMu2[`bSOV.$ >>FCp0p_6&; &YBpLCʚxv{g }zB!v)sd]2-TR{Ѓm+Jjd)R6m3[sQ;B.)$$ICJ%@J;$@0o. ,_, $nBX{Vam?>62*<;ѼQ $s.MLB̀6alaOF1!3U⺦ӲyV"FHJ'#ɺ;$#'Q_krl1+|qmb"&Ⱥ$7t'('ݏxi!Pc'jc!3ơlC|łIںiit&bH$n: n͠t+ }"Ҥ?|!)`e9AB`'2}"$#npv7Ͷ"]t #2J8/_g<SV&T(ԏ Id'rAاǧ3 C2p?!w/N7=hGhF*@䇶{Ny2kuTl~,K/Gm1;1p@DD9?z lAADX1Cbk}O V-EAVXM .ާE8<ݴK{&% ϻOg>j}.sTHTY/(lUL"X@ydBȵ6`Bgfv<)Br0eci8f%$$Dz, SBWYnmZ 9[BȀ(4IX B(}X3~O4w1$^ O%СQdUJ߂<- }M%!RBSN EB+7o[j.ɓ6^UMuT̲TՊek"Ew(bF3F$4h ~N7VlN|V!]Ƥh0V,3_>uiZ 2P370|Nާ9iq֞`-/ S, c Œ(1giɉ<f Q i B$-q=&P4ܓY-GO I;Şi%f,`) &gs-Lr\CS|fnM'[mkɼ/Ah 86 nSC#J:0 eʘ.(ɂcDLkx֫s0KDhՊ6(p∆Lh̀ ,*+en a5q ō(l )Og?wDHFIQ֐Wo{dqtO6 !!!tp S 4 ċE($BA"&eKRKdJ-,FO$B|}$I~{E wO榄2aJrt$l^oRΏ<ߒ"T)DB )@_p]n# R 0v(fv<4F$=k2p?=ΥNaW'R{,f@˰Z ߉ BNT9tBf6+إ C2XJ"i",ha/uۋ$/8D53&(R4@'? ɨY Hzv/XR# A`Q4q'RS֝$JQC&ךM4Mm wU"C•J 8^;fFp#mr5ȝuŐL3ɘD*b O<]3TD 6".LeIR\*5 (erYbRG в@!Ћ1\dbF<YAHMc@f"#*B;kS3jt,0$2Jh0BA5 <=`T<Q8tC%JR`'H:j,yd,t҉HJ#dd,ȒƹHŞ*dȲo {$upUBā: ?M ?T9>ɟ0(GPּUÏH'cѱqp,3 mOe?U6$d;H&{PGG4Q .*PlJ@kZ3Ŗkt}ڊ$pG+'Rnx&=.Y'y JC_jn[D&Wez=i@y 3PPPF6vGO.BS_;$zK,1pp~dJ=6IYq#AӺ d F.lM scLDIaUꂶo CpN!+M|wvTJV-Co7m%ariRIv0S *>)KbZBfM#NPJ+h`l*ٹqYIf# m%)F],5Z,J4b!UbՀdTLVd` \B#$a-<9nbɶpRWrXɀo99d1 (% Dzm9 rJ>~Y,Z'dd' ~|oHN7FPRK+ҌHAa!3^%d0~&Y0aOuZ yIR5+>}Y G,yPYymRͶ?tG[KA u_p>eEE^g+COX{@yII)(ښlԖ%I^4$,N})0&~XH&mE)Adڔeh`hSRMIa C :XHr,BjJ@H H'̀r`R%)"@Aq%kK5,hdH(KB6b'aӔ/?6 $Bwfa0sIfc0E2?e'  nƮ!C"=ę* Hca,^f64!G G$/UEÖ LGhnym/0q[!aiǚ,gpRtABAK雚 +`D'$nfn%b22+r1$IsñBC;˨޽xq<<;&C@8-M8`tfh~1[Z: < qhv0LJ,rOyN6ԙ;2v ")nX a>U@=y%7 miCz#BDR%-HJ>-!S+|3&I0oI/B@sFy^I*)ܦ#1zǫ:6rM^4{#eT!!Xբm0EkS"$=|gFkXQ&fY:M#г "VY eELvjnmrWWkbURrDS@0Bb@djXn,D^䇭y ?p3;ii9nFaiX-(P)J2^CÄԝ;Otd'VϏjm$}g$c8H1&Tc#x{/ydbъ"JIUD)^A: pgp2 wBJ&W&)㊘B$[f!}Me"BE %A?B+l&!#u2IWո㻺q"<}BᆗX J_ KbV)cHbSINi(DXHf(4+|azaS`!<Q9uǡnv7r )5<"TqX1dٵhmP{A&M̕5 HێF7JxhÎӆ ;rz+ts8ݬHP&@,PÌ! ٬_0ndnĪG=!(` HDK@X%(BSք @UjL,TrܘgqA&Rg+AEA!.l8;䅁Qe^׳Λ@[Zi616dLs?㼫>ӌ$1PJpڋnؤւpBBYE!VHJI- PJX!K)J[%I1l=i{&`@%+ q6(G$0Q 1F\TtA[}O\yO4Y J8IRL貧{ 21,0B!D1VxlMxXN,+0!tr!{#RX{L> o hdxX<>`=ia4+ 2e0[iXa:͖"L'MWHAl>};"ZZQInsSt ,XO0M91wi@ϣ#!Ű>'II)T+\`1?wْO#䠮NKBPy8dIu315 0T?`;DO'4֨@%@B&J鑷77#@R$6&$"ǜM*Z;fE];&pZ Jg1Rʕ!!b7v`Rawtd RaqY%յm& E #F)JlG.v)K[UL`*(̊XaI+f&AD=jĨ`_iѦUr? HmxD9 mݻMդWaS76L v5Q͓B``Saa\_om(]a-$}4bc c@_D8!BHiY %I Hhet$TD+"B $ض&i+e54iSe"LKIlʲLlڳM5K5F5T6 Va )lieijV6ұRSSSYV+Ւѫ%k&Zc IiIU6fI&ԙ+-)D0RP)#KRFl~pGTV9%d&jw] !lDFPBD$se60mW6Z N-Qd6]6(]_2!R!uP`D, C ,N+MA@R5@@ /WL")W=LLC3&(u?Dƒ/d#L&w{y;E*E)+[TljR|>9G~IPIGef8Oa!BQ@ b @T]zX'8yXViZyxOC~ap_G0L@χIPl2c(nCM]d.n0HB(RiCsat#mw68*!( 3q 1[ ZI GZu8(K۵"vn6VeS وB B(B%qE5QE.dbbDWM (1BXH`X[J0:+1%"U& $ ZE!MAY3hKLl iwoݦFLaWM$⤰Go2[A )x'HqXSoɼ55Ip5 [ض5"o*CGIM{Bf"{vlYU}xb梦1 10@ Tnzi!yvr5\>԰~Hngѡ?> DB+GokxFR驖H}i`Dz^OU֪PKVL.Fǭ?/0^QK*OGdW`DK&B8H"h0(hXU%Ȍ@5~zNH,B8}fWPpiCkof;bJFK:EM)8T-ta:n@"o v.]%; Z*氒CyE]9$Β!|1@$pBeQ!G$C7 d4Y&Xaf`oPĐTmT&I5p34JAu) 8l $o %ŒU)doxTQ~d;]H ›Ej RA1 W" 6E4Ä/ 2D>Ô2rH'9dG"9b݉22ȔdK?聉#2Ht{bOJ|dG/ O8/̍.B a2Df`T˂Ē|J4dr5l=fYOC,V͚*ҐT+Y yu?I花`DuxU=F Tv%`:@&bE{!c" u :R5E`ZmdHSW,$ȓH) tX'RБYԒuR X  eԭ!mP CRq 9H{46L X敆0IH{d}!1AadhBk |oHqqN'E|۠ 7%A?|hs{iy%,(eFIODҐXB%#^ \v%C/al*a'$`GDI:S;5'Jȵ`N<6̶6JRf(چhRj*jIjjb50TR,**c%B/]$I5e,tm Ş Xd6$@Ic- P{?R!!@%#2%,//bKa*Sa-JW;v=T$BF" Y*&PU`>XcpЉ@"A!'C"2@ƩЍ>R&Bn<#?28]5d=pԏq c1c *@H0@-IU!Yʂ-DB(ˏov(b_ vqDHSED Z6%@ZJT=Xǯ7> (L!K/4S*u N{ #ZWSSJm6lĕ,#hG6(ahoLW45lL>&,d4k$yBK(lmBSN̲8IhRpgq|F&[fnb'r{I pﭡI0=6ڰ6#a|ld,HO%>HPDn^x̮Mj<\wF!%m q8(R `n,KI$ȑ#P izƌ (aE<'Z"ڝL% H x =s-&# ,!ȖIP;Q$ kf@FDƕ(cCт%y r5*P-+2@Cf& b!(_w )Wp.5J)9mB 9}6>%GΤP_+b*:'vG~)we StUMLTW2G ŶcEx*Ji S~)QCðZ*sM@)dJ Km (*$mG2B)!"Qp[ 37+j^#IMM`QL4mKeՔߑyu#!Q5J:}=pf3C:;I=r (fFTidaP3U%;Rp3%ٱX:{2 (HzY!ʒQ BL!sD qKhpy`]3T@DG3<͗MQZRIVHHsX&tsʊ)L1"nvI)vuaAaMւeRB ` # 9#>0%. P$ ŲaiG8;,E"=j' h5z=h$tD.ظh0BɍC!bT(ch̒=7MqIM\/׊/7 @! St|},Q|d6G|FfkdFs%J'+$ F]lP.D$TkޜHoINy- 6)" $$%toڧ77.ؔN(zU'Y(#pw M A3 JW31!YC+ Nn"@r($8 E02`?KL AWhoAhJRc;P@ĉ~+"F%2, ,6gm$G; @Z2O0bbii%ÆbIKJ_||Kj.XWqrdnO,OJ@x~8M~s&UV% 3G~O_̹PX0{Fy̽ F -77~h'/̬H,`H!|Zs=81Dպc1wwvj*&j]YmGD 4D>_|X})!/!|ʪ]y-AӧOWiXk&yaÎM=Q>}2kuA@+["@fO!Y#cK5'9:"X%XeZV[6B h DŽx;30)*1Yd] 0,3GEGU&4gQ7I~8Ko'7bqI=qd. jQ `;R[R!/?*-#! a/$c!& $!vRIJBYihR L")4E l) LiIDi!KJeI,(ThUxAh)RC7B#r ZqMj~,;|'r% TDiT~?JrtxAd(=[$4l6h+,Mc6J1" j{JG禖R;01֝B_ͽNҴ0lb{,P"$*E5R2~b'h-iX5dN{쓔S4D~ٌA)NB$}KdkΛyϣjZe5&~(b$<=m uzUңЋ,KjG'O3=Fj 䏶&,H4D=!<{== GQ1OfDH08XCoHu$6D@)sye=&]kRJB6~Qоp8t1)ӧ!0f$N$FMKL$!8MN$`d}ШZŤ0A1daJPB&`⠒ˆQ 'CS b9$]S$<)tGX)x AԌ Hſw:Oah 'Y??Z)(i&PNo\%ie|詇$%mMboqPðgSa55ӫ9<|XiR1`4cYi1b]˚ѣ}#D$,G IwZ2-C*[0:ْԼ$9 ) af Bl^:1E(jx*O$laP*L T@h1p  uzU%RRihiMBҵ]Fj"dTa2LF &1Yԣb)2׎hܹF4B0BXXZWdXd>) ˴d&u#V#YaQT6iI"UVɩR J(uY*Y4ZI1i;n[ Ai{Uxz]Y4Z$Foq뽏PBA "?" j71 i6yHH~l-$NU0 PS IMimbܲhT*mLM:+tZbhQ;*Ӗֵqy6>SIT^Tyz4$<|0tK8&MH6;I:񑆞Y86ScvyY419$6g* aQ"ҩ$ .0!lfCޚ8$oUS4Y%K!ȈH ^#C .t.H*;"za@[}[$KŐ2u&$mljF0'>@L>Mǵ杜FJOLA#J9b$reՄ8'U d,g 8x =~Y 2 n:sE} JH4etlLH +J~.r!K`*Aᄰ# dZb Q{ȹ[M-&ZO, HxHU&PQ%r(MHʼn#H9]ǩ,DU RUHD 5ơ弪l0DIC(A)C*2¾n$BfSKy":;l!ÏԛA( "(*䨐*ð"}1+0 @*TdBE\YmښkPInEZ,aV"Ы !Xެ@&%))lKD$V|dT(B#))M8A)b(J0PϠכXllVL0)~Ca3Ȑ HA)MI.H '%_$*xO8^EPhfĬ+gs E[Ѣ%5FFdd[s'"Ȳh(QsG(bb cJWK,3Pc/ƍ&Jr7DH @6WA$J=3+}u0H@hl IӔlg’0[ڎwė1YP{I'RǫQ]:y ^{9oPen=t?ff#sxخIrࢉ} I7e5p #)tP{btB,#PrT VhX*E<@l qcKqFR ;`o 6*r,SwȻΗJȈ`v;@d"#}e/}u];\כ^,H {AO%$܏%AHGq;'`k 簽 ^0ֆ)1ĥ@5Bؠ^ĖwV`B@ci}';i?SY9S@?Ì#`궹511vZ,»$t,9\4b;h.<qS9+F͒s!?Ji-9w2UvH6R|դc]iFAq0Q[Q̒3$ZkedP@X݈ 3k;$_M &tJN_e "Pd`#1 j^dQA!GC1܄sٰЄN0yBPJvI4P͔ȂQ ab'ʘ NoR34*51`;3I1F1K.YМP4 X:53kLaH;|$&7mC4OOFMgxrE)~:).YF[I?Ubry`Pf1I\4#΄;E<a]̧`_Eޥ4-a!$(;p1bQf}o\.pW~N1G,GK~q$#q*H$ 40 8] Oi< p X5a[`lf \S1¡bqc$^'F[2g{+li\k,cOI9:WL/2X˅2Oy3v-.eÃ'oq B}#hYIt1R)d(#B BP,WtRɡ7#C+yHy?<`OAeI}Iʤ1v7#^7![.1 {1Ki\3TJU(:tɌ:ϹN.q$1(;w'/zOyclNʵ ȉĞhiqMY[YnA>(`V!l(Ysz&2R=XCzv8rFT{Ƕ5%Vd8> 8{#'gdoDTi' $N j|[wN 1(F63{Zѫt8P(@JGc|PN-㗾v⤎_%~ G# >} Y82c֎$и>H<#̦f )4$2i?Џ1d pYQ 7,@ ].M<Tc;]sPiUU2H\guïIdy>'_JrXRmU#lx>ԋ_8;}|a>DďR%B+ڞϟdh^ܐA݆aLOڎoNId~h,oȘTNJv.zz )`|^K2S Y!ꇇ<ʠz axyRȄ()iIJe EJNQcTP(Mœk'C20(`#D܌S'ȧ2i * N£ r_ãgn|ޣԸX;Y=I=c{UB{}%QG!XVi`H8`f0PAﶽ#QO:=6MQZF*UHCx@'0֎Nwu c8hִVmW>Tb̒\πX/p~*"?I0ԁRͰ$!#$7) l?xTAdc+#4,!BM6뭻d4IS6jQ!Y 6beiPbbhEUr&H*J`yᐒBSf̗XI Bqe&‚``""R*d8[cFa'ND<"pպ{`E!JBS,DˡRL"U]jxdb&ZRUp̗Lrc ʳ TBJ`T8- 0(6dȤulĘ]C޽w"D>hhR?,hY>FŨ!#UuY4᥊heJQ%*v?VB$a6p,XB;A{Hn;#@401>Tt$~86dTQNI%9"6,tIHA$n{aB脋'(a䇺?JXNYg.tO@DN>r6;hrp&>:yղWM4dzuBċ!HR ,ͪjkJ#PTֽLz$OjR>T}$4ɶzvxv@}yO< XNfOl$b:gR/ iOjMND="*v9~14߃qb|bqż#!{xƸ;qc{gygd3Ƀ '[-]FAXdލ豈')Mhu_&{>|Ag FnPpŘJ<ᓧ~FZop7DK6aB-Ej(!<.hX=@W\y zU;J! *V&81[QO`DMйtLk+1̝H@ɇ%YJcP)bAr4L'9 -trجA*e% FIBLh Ʉ3 'tsE(ژDK;ím,Ů*r5QhqSfH|L]`Aq"y!1D!:m@ m3pJs$d f3Zd\2G+Z b{"C)M @rT%z]wD*a `A.r&)$F&h#Nps+E4DL!yatW0mxh5Lv:d-J$˘ RPA.Mуc1D10`GZai6Pl삐CY;B1^PXSV BC0蝼sTKԞEyՂPlfp$/Ѽ-O649Lw8oCstbp7=Msk0q RwEFLϛ !4%!ȒQة::ÄM4VPVPtKe*NJAV뱰ЂDqqw)ABPQ\on$1rc:fi9xM ˔O%[AB: Q"A8frDأ*lv+N㸃#DE# H31!$ j%j)M@.xAR0HfW ֪[nɑn[Ym7GfoaLAEjV%j:ؙ*"80;TXt ʼn rL) dJUMkm1)*c0R'b*#=. d% ' &#NZ-m$N I M*dT4PP׵AcA$IF I^)2zߟLcFd1+q V8a.J(HB 02QU3UL̻qkdžn0ѹ!!֝B>~ aQw=Sw+Ct(KS-Spzd*PBChMHH(t&aP eAGzR"0e:>识 ƒeK!9##"" gKcÐ$ UB A,`Ē>aO x"a-Y40E1 :M QBŽa0A13td1ŐD"(HJ Б,)&$*DئVJ-\[m Jꐂ_KVڛ_&I IB%Ɖ]8 nDP658UFCP7 2I!57@`KA#ɓV՗REh(Efm_XA< i$>_qO:3oMʂmԐP v;E mAFtDޑ)V10`DV*XB Y4!)=RkGJ;H UM0aLhl,(0ùDQHSBhUCN:ZR^nxSP^'&2Y'dἌiڊ:w2) (ju¸i~%Jb>2F4BL%vCClq-&w_+$ϯ!20 Gk 䝡Y \s|tD>i&lC4ߔ ,b|t&` !$@@(6MR` 0%d.::pk:Wwkwp]u]ݮp@@뻮swwwwp;;wwp14nuwwp˹ܻ.s]n㻀*]e-o|_k _ W,;P'ǺKIyOz$s$'(>W9/bA`Hh]h0XP˭7}c7Yj BDdL!) E Y QneTҡa#zaʡ]@\~_VnOۀ]JJЈ?C& Rg l3$31 WyJ׻`ab h5PDrċHGKT |;@Fb?Ho.Mr"r2&D{ ueMWzEIp Y&'CכCDs?w2eܑ:gQE(}4v$A<(Mbby&rG_VˎF2x Mu/I8٦ ɜa pl~\TH1Ę8xDʣð|==Gs!GBr@bЊ-^ 75C4Z9(nf;B9檥X0H3,>)H%-2 Lj]ͮf,ҩ2.I0@d֍}i}K`Nq tSC&S&di@+W#9 (i)HVjwt @- F'2`B$Y/SY2G-edِ!HHFٺdm,TzTތ' w|Iv 3Дb0f.HX"ZW]fF,H'x )&bg&ߢuG5$]#]6ܨbfԼUxu~rut zМfXJ bTk|͠*|WR _ٔ$L%AHBJ{lU <Ob)UH3_zdtR<90Lh FҴu#kF(Ce^, vtOo*XGd;A:$$I·姝4lfLzsw3ǓčH>y3e O4(x&Nrd OZARI# $n[#ٰ0`JRB!d gO_d^QB%;H6`+,$.HEULRUϫX_L "_w0ݒ?_L2Zs5r"0_VǻdNs|Nrc]C d Uه0 V#RgyD=ʅɂEG*R@¤>'>':eZI$bA؏`M|$t~NW$0 p0 IYmT~I‹ 0ٕhz%b=B?LB`фK:fH>Ҁ/T##Ƴ$\E6*ŅY!,A 5rɓlb_0yd8J)%aUeUtk$GIȒ$ >U$qQ]?QqG!E1Чx^\+DZJ^eQHg8EE<$s11PZ,  B"F,"lԭLU5RY!rPԆCvLKh,K$JB"I N)HD v@;UC+nOxH#: A+Z7 O0Lq$"SS"nsmOfTBz"~!rb{@|gi?cf=[Hd?+|]YU^ c u2'% "N'bIHВ|Tv7}T֦7#[hزmR <43!iV4ldVyaG s4(L PL/OU}$I<$\# '|&~T"_ZT&ߌi*aZ%x _SP%'J'*d .`87)BIͶW~4WĸS: }?@A!y*k 3+wG!!,?"ԩ/ː12W9.ekV&pRPp DѦ1LWDId* qSt=^b3$b'8gX!F8= sȈ zl,:9 5DYJRQ hyFXX<#_%[sqCS Jٻ 9 Pr&OQ+Ru0ǡa224a*c1VMʻ,[`T$zhHv$tB,@p H'whz z}sCIT?Tlc;۲#-R,2 RyVOZ+OdD?<`e CT<K|z>F29- ha$zS=#QG ||GG?ܞ10J/ D׸p0~$Cj(W="@~#@%4 6X j"`J*a탢N G3u1HIq=Qp֤тCߞ=h0bz!qS~ &G%鲠z #X`nn&:MC"Cۘb45e@Գ9 bJHj@XHABQ1BPD(&JH+C^9kb+U׺=mxωE?A!I%%(>¤$D) * "*B…J2dN8 Kpa,۷`ʀ YW{{oLlhi)kUvxw}I0NQ(H/>Z=05R?BмNgE6C sEx&Ati"2#qNxtDnWATx&rG1Z3-j}E $`auJǢ>RMѠ* iה]+DW ph!Wa/Q0F6fKWvX{\l:NQ!08֭nM٢E٩Йg`J0C83!Ey˕( Ŋyw 0DNv' B{5FK~INJw N6nfn+#{/"DڤI!-S0HW̖<2lމS6Q6fmicj XBPz H8SEԔ@, 'ĴXM68c-YI\R1`DӚ7ֵ-$s(e0EO@MO5,H‰{;"WY0%Tҝ@p5 x J%P_@'R  w5? śct2#PdMbxI%d m-W,4s@$ahs1ă!PìJC~9g \.Lb'@W,ɔqfa mh54&m& r}>BWDda ZKߛ;kaȃCACbWB휦Y)bbA5 I/_IȌa &y?7s#%Q!U?6rxOK]= 3`B1G5!I){z- ,P"ЂR(K T Ġ*Pć(0@nB*H ,Abo}/GOđ@">CzHc.;hlϷnY kWp3 4-"!\QOʏ{=h֢XPBI:DTU"5{ՎI5DB<!PD(Ⴌݷ`ª8Ŕyj9>͝%f7T >=HR;aZϷ5Nx9kn)fVǻ@䢀7:j<ܷA{P꺱{;ї|}f7_]]sުq>znki]kvz[m:\uozUV]}ۺݵ:x0uׁkmluwzB{tqKz =n[V$q̕Þ3uzײ5ٞ{9=r/ְFuL^]ϗ!f/JFAf${AΏo^<͋k۬K)}ԧ=نy[C9э;PJݴ- owssKa)20;Wtsj>모N4WK[f{t\4nPeÅz94@U)nUPfLݝ̹OM>2wkw+Ykke)f͵뜰:vk6}m{25D>f|`;l Uz{PɆv>ݠXmwCݗLE"^{(,Any@( @0kheғm@ m3}{;3ƚՂX7@k-;k  n ._-4hh>Cd`, m1TLh ]Km0(5M@[Jn闰2>€(3U]P((UO*}Nج{xx@fT nTiK YXQ^(T)[Hӌ 9(dWgfO9 GMP,̆ow^6dVj`%"#mZmKR@DThNgkחo+Eh 6{m |D&d&Fh*~JOEښiD2)""&LL(<)jhd  " ҧ SAh@BQ"A#L1OQS6jzLSL#&Ai4 I42i2i$6@ d)?ALJx#L" @L4OILhOʦGލ5OSic~9CU_j?#*8b {AQt6C&"' ?}ߛg??6gXAƛrܺ9  =3P 1E0*,Ġ!p8(#A@ 4B!$R"UL]%PI2(EOZ'02^8?[j掓f%iv7 7jbDuKH|W!a;ƌs mG&;ie|Ua1rE}$:eC$~HC qϽ)vDgEeh,$sUٛe95W.|^gіn5zΞm'ʭ۾=hܦIPa#etyg.6|6GV4p.8Ri;0vga1w.+ࣽ=:_k'OEMm4ovWg!`zC ŹGț]."- ^'?nǮ[CH'تPpC A=}r?zW|2)JveρC|>_aP>BN]g!4r8#,y:rQTzmdIhY>c&q71G_uIh0@aHɾ{t0&D&t`C$.*)hb/;}=*]_ox/ 6 2D0IN`=F0|Hy2fv&Ȕ#LHB0+i"l-ͩ8R*`Mͩp>a4?#eyKK o3RLn~No߭;7-kjfehnvxJu7 mh6;Bkت3Sy-k/n d{F?_~k8W|"ydo`0dHN״95q|O˅X{+;(e?〢$J=Kyԏ>=3?=Y^i0iM-~K卖v# N2D(0_6c :oe7G7GC ةaOYG!@d"!4]l`lF+H!4q"' R-3|̿r*OߏbFag{~⯢Ϸg/{ |=+?_ SĿGy͇!tIEd 'ŏ>~;DCbbcqxٛv. aiYP.r2>kR#ӭKY'@Mb 3ueJO9L@kp {6i$9,,&4_-AU~ѝ5!ɊE;5cWTwpѷQWL)1GZ-2~˩C9hfgůɓZ現gʗ'ƒR. sFl&ƒ1t p[oN见)D;s9 0@ N6Kfe1Qj3(]A G=Oiѱ]n94ޭ(+N8WUE@W0y[ J0Pw@"59}uA 츗;uh3?{ŲJ` 䒕_Y$GZDO/ 9V}]GXdr9|44L7Qa4|u(왇ՁvH)9}xKGӄ}/meM //ݏEH1:4<=FcH}ǚ8me.2M.?}2Jn>/qlJO븬P=k.Oߜsx:(xoQ5t#NuHp1ݏ~~k64" =֡ L1lڡƷB7jVblPLCegE49n_dO?I]vŋÚ,yz3*HQ6ه6.#V@c,0-WcM3&ds6^L 4ƙׅiBp!zٲES6UL= ƽxP:oPE(SKi7 =lB9&,wnpۮ{8BۯЏM} ̙kHY*] cOƬ7rRrTzҎ|a7{J`6#~ee_g iD aNN40BlufNeͦXIb$pk9A:~MqDrÇ2.;k#Vy;io\4/$cŷ'Ot>'"A c5?0V"?AI$ǀ>}|_ @$齽YS??D)Ylf(5;QivQScjqzFdeZDZXlB,َpߦ72s(}2ԢsYK^YA\A%3D,xtf9N8@?Cᴴ:e\mF\޺N][nL#9Su5a[J(߳:~)sʤ<Ы?fm)X/{BQ m৔"d?dguJях[ dcLyR1Sbq;ެ8{ y8:d&mj3K}`~ƿ=k{2W'>uGtsF^q#l4~Ce!A 6\l0O]= iѱ\ yVXK_Bݖퟶ 7[zqeݪq@l곁1!ݳs]p0ГAk)0ͼHɵDigmQ ;Gmi 91'#~Ai2e63!>t/__a^ݳaae/XFSR|~_xR6dsk]Л^/ymfrn!\U$@O<NO9@Pb?96lY ?HJfn Ac3%ck/&_`q"z6L\0ȿh4}G=|&Ak^4f<jcY´l#_9㏚7r*)"\P(a}%[A-i-'|'uQ`Z0|}O]&^oqX0WĐSGxgxg?2E}laSI&癑ᤶꕶ_w^4|iW=q_M~xǰm"̚bp"1ôזC\XbomN[n/(uoщ[u緮mY9թéN0}%/Qd|De~1qP36zUƝw{ sT# &Gwu2Gg*1+@%abb E?:#Ԥ܁ڳ58ɬ Q58 `^"\tCt ddN (sVk&$<7 >HJ32$`&#ٿtP{ D&}8C`؁;!+D%YҏQ9=;L:U mtA{׽ #8_IO֒!lg9g!nր33&%jL2;0^O+D.>#bOAr?&yYcGFhgG/?tWN~/ 44rS{释UerB-$ Dq69LLwOtaϔ*zvX6ޙu?=Oηq < nbǗBEPH Q0P5ԩ@wfݶlҏӚh>(T;Q|B12Oll&s;]4jc ~4\`Lmu?d]3(}>;I%H*|o'5 175c%҈z0El(ij/Sրi s7BĜjaA\j_8@(Hw T H}8BOSꥯb>\ΚLnbX\X9%~'!XC|_:QPܲ.;; 2uOFҌL`9AtJ@xGfd";.wݨ^Tia.Z(2Nj",bwv@`esK7GVct}:  'ZKY4M!CXt:8]KFzXS}^:qe3x(9GtJJhfpJ 7+a M$ސ1+%RkC $7x]y/1}cF&jZ [ .߂I= ;!lj2'T!yC!P)(@a *BUM(8.?kxJcAqTCIPx<~G]"9}ckFv.#,~-}Qjr;E6;vnDŽՙ|うa 2lMy=GOCa;y4P{АZr8'*F$6rdSR"y_KQΚצUz'S7N\GXT#$A!m/OOMf\&( ;DD;&Y"%dóN$hMb%dAsL((}1SGPH>`t4TwqwQCQsr|pcn4vBd#H4NcYsӇv=ۖͱY$"HZ^ qA_b4.aP@R_|Dܓ)T%UL\!ԓ׿0z`aUQBS9LraMO??DDćlpጅHO}; E>G_܋`" 30AR330Aޡoo`/`k)9eO~'_*NZĜ:4o'~[--J(0e "q73T!9j_Ѕ#p7_>T ~+F tںu[o,X_⌳n]m>:vm-˦ Kv_<=X{Yl.牴cvo2;?b?jF%ۇ6?>MnhWAdG-n\W͐?֫n0LgVlTͼQLN?0k@Лm2QНm~9[[u3iߝqBjJ6;fyO*k06-dcTecdG ndt3>KɐP* euMWr-H\-}y] ]Xɔ^r R)/&:/#Ȏ6m.tv<`yc=!onWNyO*a-gRYY¼ktna:׭TP^C9:jGڅglgY"&I{-p{r<:=5et@91픥`"$JE=,B'D!KH(!m6DRGd.J M(]3S@8K>#J7} XHFH!eI*?@|ϙ (q>+J wo^p$]Mcn Zz+~o-.POY@|Oy!j ꐢoJxULp!wES?$GP\ Pt!Rt"|Ј}>I=29H|b> Q_Tf(8"ڏ=.$GT>0d"( yUĘuIP$_@5Dr ܫ[}\,G]=g:P<_1uxn`(p$A2ktc)$( t ؟ `NabY"@bB` $"Hb 'A~QB~ȉ^_/{Jx&t肚QCH"H$fQH  $d"R%f $i F%&$#n@!bUJ`  Wyw';C<$x܄"v5QJHP BD4w]A]QdyA"4 2  MW]< d QH* X`$I jEd!B-Ǝ&Pz؈tk}1$LD EGy BI#˪N-}2jT&3Z1aAq>s@~WD R O9Mۤc Jy<7`q 6A Q)[U=sL(?扚T3; 1yd+jALБτl\TR-HFHRRN! Ie(H9DL}8jW0^4! =Fc)(SMΧ78P,L RV&8m21#*Ö.NA Ofl cvOGgƃ_  A\ˋv &ĀA#@Ĭ!BBP: p#A%B7FCK3׶ 42p fbD$@ 0P %!>!xtϪD6h?8S!XCl}>sʔR <ЪaDͼ:Fa=0H ‹ !N>9؅(&(WȺ% 9`u !!4@3+B,tݞ- sdrD<>n I0mS?h8A7d{Tž/6bFh8? 5jޙҏЅ DzA5[^3b_!:dEfh`)!4PW3m Q# M˄)`|v9Nv"'L-ٯaX-!cҬ=g,R*) >۞A]q/yS Nv+cϹ ǔ` @L\S]֤4U˭,wvhgNn?qìAYP*Le4)qO>^:u~`# 'rw͚2 ӆo(~fxB^ 듡o\2X/qɢ ~~VJ>Z]uEӧUY&_nq,`]mkl?zH,2GwaA?F7 yyE[|q ɔͥHP`=^=ё;e .UW2:'TRk[^wdd 'nDH'Qe').onRs{+]ڹ_wDO1 _$xuTͦ,Rͪ\@*==~~Л~ !zG`Ǭ=g| LH(8T ."H߻fuab1~o9. V58)CHKm1E m$b (Q&4Ej2GlE ^㩱<#.u1qpf 5 nQ)5S䪬g -5L ( V0Xh̺bFT`p^&D[gXa28s[W|!#  |-?X\\Tsi# :g1DDZ1Cn`SOUdhc&u"鬿}9!lWlN gُ80d2r)V#=Og=#BeI8nŃ5[< wÒ2M7*Aׂi˹Do9pغɮIPDe%ap:MK&UTX.PČO:FN CU0*dxA0 f( p,}M :BO]5.JB9%6Ta+"Hlctr&\Ԃ h\aLfX[Y],%Fc-wq+]mY]n넖F!Yidy1%B!_R9!_-r9}d@IГ3p1L|!m,Sf ( a_NG?zOo8wqXjDaM;ͿƑ)RwɻCY@Zb>ge2$ hS 1LYyX!d< b_e+HF|Dz~ Ico9j7@>" xtf&SHPmʨ_"D@$O8<ʻ-gb;)|:OMs2xޞQLO<,K#") _gy12!E9iXAp"p`Z~g1&V Rtd띖qRHC9_RNW=A=!4U$5= MS .t s"'WABZS"$VC`w-ހWh#H441)t` 3AdVy$ h :ahvbO̹i*Em 7 xbuC3 ,kS!->1}a?f HS >V3ez1Hla@TNL)N({bh`CgrG{Rގ!嫟:qӼHTJ zEDpa{x1V]U !zJ+_a`2#^f.X)5z}V:vn☮4(|Y=BϨw:c.cH<%sis.J:P.I΁W|@z[h1{'h:@$ T`-_f3u9۝4N }r ==m2U6Н;O{wqOK՟hC/IuM;mdv/6gk,)p4DxJ\\F^8`}%X\ yo!n;%yg]IncVC?gd.: {ʺ(b 6ЊCm5.UdJ3UVFc#Ա;:ú%H~Q׾{]8$"].X&zwm#l0]]apCD~ _i֨òڄ"X8 vwA^ڐk(mql̉#2?\J_` $;A6A^k As|fMcuv3HҦd΢_l}OZ9E8[W9#Rr=]-<B{tOQN b(v;Il.*#rda"1s+OBh `O߂͗82}$qH?8Y!"/HS80EOG{dvR=gm_8y5l"0Lnme?G!.avx Q h3PbN㲋6*Syv\KT>x: H[jsjY׿37(dXs%*DPRHFRwPdC}YTj6cHpsJ 'qv5'n^ᐄj'=8 o[Ґh* 3,'2mY/Z[nYPҒ1I$b `ͰeB7i MƢ W-?ܒMf<6B.$5өvgv6#KJδĉmH= Gq{[eOP7t@h6zMOtdbs2B98P,Zܳ>7&7^Mtt3Sy"=uOQ9~?^5t', ʹŴcա1a/ec[gZ}9(NFܯ<.ߑE`Ù9ܤ)VD2=K'x;mXFksg;ٓ "`'4 <(7!FN.'I 嶖ZxSnjEqo%Ibr}\Yf2LUUDDDDDĄ!B! ֹq`U=:Sod3 90Iݶn*Z?4k;rtysE'Jy׮'R15DLU=r#r՜Zi{ɔ pX~8'<=hh;7i)t^N;n+<n jaFGlWt6;$F+Y\ 57w8, zQ z|%ѧs*(!`gE %c!@:sx׷&B0 {Z²uA[4)7@[.Xr SUH|d_ɌVݖ"mkiTq"p.<T~g/odqpG0r 3j(ipǎ8XXAp@ZQdiY9 h_<ΥQ5@.ʘ>Rco X~>Df fyͼ٤/  ]fbU".EMꯍq|&ąhd%XLɆL\'P tm4..ct1V<|ã %radl<{zNن1|(LG#؁C0-̂uJHO1Q_EܿS  ;U.r*&Ljf9u{Xcy1111111ĐDDGbH%<a5Ã80Fa `C>=aʥP T & 9&>0( 035: b<=F;l:y (SttjM 9~."S2UrTq#L6YIF(LkP2˪NY,R3/<L/0anoœ@l9Kl,ENn1*""dy." fNsE1ȀJ&9KѶ ڮkhwYVLSk Ldؙ%p\܀*P=(! n]P: {=tᩯ,wp:$F>52/$z=U;Cwx$!h֑)̠z1W?ѻpBU HRe뿼ˊbݯbݤb6[+$}G:B`9'4%E3H7 LIl::I~e:~YjIf>xJfɖQjOR7EwBrôj,P\Q??e vp RK1קwVh{) anC-JCn3fa@Ƭ=(,XKׅ؟Ls~[(< ^N| tۯu|樃B*@f-SF "dfx f/y j FuYAis6Aר:Fk9KQԁ5 6~Φؤi=j5@l]h`~Ӏ8>"7԰j;R3w_dh9K`4ukWi^ix9`~s.N=C.y0рͥ}#TH@t `F%w D|>r dï7 BSBi 4V'o 94a#w9n|oo_.r [FJHeѻ/ :)XdU_(ǂKcӘ26 V59o(K&J8HfvNF \S&!j0H^wW1~#8йsy >Y 6GBH+.#{Yfb.bBK/jEb JN1IDIj,^sK9|?,!S nsW]7kFR܋l;!C D(CL$pYk^7Hfc&$VvA>-tܐ!{I:CmC]=)x3G#5Y [deCV]K[i2%PF!0&j%nKa\Mn2у*|x3coCm&%'ms_ۃפ:GbEz'/y 7sF2vvo|s3QYNi$#ƍhLӅ40F \NIfD2aYM ZsǪi$$x)h+NVOy8'+h%ltԴR|Ug"كfmV\・DžjTm!f$.p#4#/]b4OxuZzT~Ҕh"f琙hEEۂ.e1Qhΐ#9_oq`4~y0]aax4;oj2ԲKA=\+M;;@:q9aDIw%ЫZ@{4rk&BBʒ86|wBD$7-$I3Y|gG{Pd3i!4|,n*xhGU۳]yFklqp@VnD"[ d|V(4\1Qt_h AѢS]MK]un7NdUޚȏdΰU@ĦM~C|sa^ zWn`s6a O29ŘB> ?d\~/s rA,E/G/|m}[9:+d;`2nbcFZQBTf9CR KF_1 pm ~F}Ý;G>O 7 xge ذB]20hS>]9 14ƙS^$RN݃@7g#;2?2E x:iASf::kw Є95NT1pk9s-FhrBꁲE~S딋a*3?RF>[ȱ}Yl )*²;~ݐ=AJԝJ <`?|$BM4nUXxY"ϞfGɜ[gkqCm0oܾu,7 8u]Hϡ$}0DN' [wa0t#QŚ/-B-/;'=>wojSjà6W7$27dHfi4ĐBwG{MzF;05j@N sf_N;\Ą#޹#"u{vC ~# ~dƛJ&{$yznc݉kEAV^O^-$djf[H&}iH{͑k \lr}DLő2˞D8ǔBż݋_unk| 8ȘQb 4TJlҦpAgvEX!^R`a0oI6sg],fTҷMn|<^oZ8@bHm oIxhH{p>rPk莭"pʴ/c}YB{4$W#NDt@GˬY:ʣ5!~юC+QB1:)ƤZc2+פ;$/4c>i T?#qQv7Phxj&4+<>LC'+rVźv)b0`n~TD?/<Ԑ!qJ뷞˚ȣǪdx3O_(, 6٨x-x8_9HK4/5#LR 0EpxD;!SH8\pr#Yץa;yj8/OSanxm"FC^7h91qTkqsˎ!!2k#1_0<Ajڝ<ݱQi]cф"*Q3$ 7&`UN ?W1YsNI8:S 9J,@!ڃs!Bk00hw-s۴ ODy]ԚZ>a"]̃LIXh(ab"QYQWўT!8_oH:В eP"ňo~Dn;N<&vhf`LC,}:?27' Ȭ=WygO6RϢh`vf]ȧpFv4~ٟ=ͶؒyOt`GU1N{-y-k΃k-M^wڀRm\,e*Ă"5"f!eEr,?T  ^~yihR.7ox¿<Ǹ3DL"oB8hr\|E B$~KmףsEGa-#Og/U?GƍlVWˎzﳟ-Rv0ygzkck:0ؿaEn,J̬ \sO`M[GbZ/kXĢ vhSQv 4$EbYe%UE~ښÈa7'F)GuP5g$JH{xx\ fwJf'&46nؑ[6\ ܠ|ftth33\J0aMla Ʀ͌iꐻR B҉fJ *4:k x'#7!ɯX `2!rlAsbw&uso#TRh׼ P@5(4+m%).,90iba*,}CmciQov)H d;iV*Yv~&!z6k0ߋKpK•h uetY(*f|}7>Tӝ@̞yȌա #}L/B16X=.:b`_qIRceSMAۉwu ҼrNªhs\5!n~8Ag?3+nz8mruph]xL}'G^:5&mrD_g)BsfhUKW=0ͮh;=ۭiӑ%{;uwo2|?,Lv)Ľ4ZG?#5;%͂(+˞p< V$H<+t&#' 13yEHkb ݦдfZñNi- 9:< S+ai#UMcԳ)Yfc[^%(Ui@W,M3J&ze8D!ӵe"] Y4y8m&U5qVcJr͊P$xNQ3O}s-pX&WZk+&UgweT{uSu`i&!\ xIu+$Pus*)gB9pl*}ݸ鿱e%9&/ށMt_,js OP\Ϫ(r[E[2X%%BKUZh|z*ٽ.aڳek_7@0Sx`L&cJJG~7,$]s2C~ 02+%ԶėhB\ނq@D)PqN1cwcJCհ =6=[`:]X Rl!Lj8БK&K*ؠJ vsX;oHM4']WyjFDEG:$_8kQbPd d:7C_)ތn]x,4d3eո4 z[ R`#|:a+EDeXͥ~'&3Ä.9{XYv)q mag5&W9@|51%MЍۛ,sM$m0]Nb ^0G|+ ZvF쓙J_V ?7s2/jGD"α̬ٝI|&m74UNc%WHfj?TQw+,~ĨL|ϔp r3 ")<]^72/y+m)kD?!׻L{s HgP92 (/ĦByt:uԝ6$89Rcyt% mIWhac*\sBB(ܲI}Y9Z }OKxR_ L_V9>3gI=-ף9`M{5<r?nW yy5,%vmF=O֥]+=YN! zF\i3a(2A1 B=N$*Gڞpga?Ȇr/!A&x>f7#_/IfnN3 ZSkH  X>8t~';GoO.̬oF1=?z!rmir\X"Mp~gd/ϸ.:M%{)I46P(\AB&T_R 7>hn;NLGeEv.)q$1̽>$p8MAOc\8j+皠4oZA-G{p /LDGQef 76JF` 1lٓLq,B,5o- w/Z1Ǔ#a}夹y$F|̷_›8MX|־߇t5xcKxjW'+1ιy&fHz_)E)Hu E-Lkw 4h"¬tѷGhэd.]qpb>̎ >ۖt36:_$ï}&ptF}.Hbh4I"D,6/qs$[vc9s?".fX}c5A&mM&:~hj5ɒmaHco8LcHo>~hY\.`4jft6Q7$tmHb#hϠ&+HY*np2nl$0n$+Р9?˹$ype߰R8Hu#$4z]L0/tq"{i`qUKð|9ocQ7v*i6 98e6]2x,wb" u _ )-?sϖMSF}1R8],Bz2Wពζ!A#JW7" 5^# z)ڭ8@Gͥ]gGw4ϸN)k<$l1J@26-c9+>Qf>SJLʟ'|7A>kqh / r3f%gU&HzDjf2L0z,CUEq_-Tee=}KCqgH;_a]mkvܝ{qr3f܀}%۵8MuCɈ;mw!dqyqHH9zjCA.bϒb= ςO(Q3}+.fZjgH0>LBT֍X2Lƾ.9gL-zE0Ή 'THG [AR``YJH T-*_$#A졙 Qa }IX 0k;ü֓OlBƨKӊ[ͱ.qG\Mp$5"o~r|d:nUtdUkpQ]<~Zv1n mC &y\(6bC6>QwPmqo՜A3-0Rw hY[NU QuzQq5 ?&jn4-6,Ci4/+ d4re2a\}gG%wx9v4{y\ \LbR1n6&ȰPU|gox7u]I6t׆?O+%O\rZ;:9(ZvӖh[]EE]{;>Ɖr1Ï+謗|s>|<'| e72빶3Eat"=p_iraOjDG{ج=x`ܙ`V50bs{%C۪X4`aFMq e#fIGs &Im߶Lmx.a(l7me 䧝y4GK0;-]dV0D2'![zotǛG{4I曳+HI<[iy8$T!CnF' k=WLgg\`;ZX1f ޯ|P9'` EOp*H~^}F6ܱqR+_U[!9MwS1M\}7'hoą#7c#ǣFEq~zЀi]DZM]@?9m~IhLc8ڪ_4 1ב#np$$n[bs9`W|t|I&^6_Yb9s1UtJ&M7۷Qt2X( q:v?6da!inN+|s~hU5ِ/*x)#6ѠQ#**݋r,sV.!T1ʃBCI& -X>r W^ gV\mv\\5#L{L< L0׎Fl(@>u/d)W*#/谺{Oձ1a _6Q\ eb/礠CMvgaGޔ5?O['D׍ძs"P2 H4>VXx2~jCK-G3%{đA9hy25C$ۛe. fQ,Iېxp@Ǝ4xZRV!o=QKeLOP]Ѐu57]jÉ 1vaE6fh;P`eIʗչ˪4 zaL\$P#[]T>Ce,` 2k"9a궒 &fDA;إ  $zhȗ㔝bb!d4G՚tfvE.=%7YXYm ¦fj-qfx3g-1zhCLJ/d5*{㴥MC1jHn0;oQ#-LqXq V;x-AfgA—gėAM !bC(9TEP1]РߘXv@B 8@ GLnPS̜WM7VxpbY",6͎۟{o|Y_DRq՝!s9-f.'NoGk d11Z<6aIk"MV2DR#Ar 0g9my3.0Io#Yp)@QC Fcve'"cˠ4LBAa>E1^t׻!93UȼLhfEؘ0wB7/s.H!݉,IV=ACu-9WKlָzv<6we NlFb&XC}e!jd.:RrvS3Xg 56std<*x/9! ODbO:2OB@SuNzuf~~n6P r;Q~TCVðy;[CTø Q=%Gq8ėYps4A'4A+ӛy~@9㖌Vj*ot5Ua!&fM ڏX>U͎>."ϖ{E:-o_â~Db9:L4!, fڰ5Crhے*ρx\+'D4?' ~jH}31>: oәuBBv']O2`O6s졎8锆.bv /דKh0Dž.*o#df}98os Q=\sש"?`*Z1[F9Ai6)JgODž_C$[F dɶ1G\@wAٶU5!˯ TZe8"9 CWέL5{:aے?Z`*&X-[KBl\f/OqTw0IAb"][~l 0ܿ6US<``)RQO9D(fn.vܟ,kRRQ>k{@_~*Re PÀ.ylX23en1aI)&#vcIU +o:`ON"֥tv\fbpٟZq5uǛUӅMIͣs~D0oBͅ {.m2~r|PPT h>yO?tanNuU-3CYͲCb8d))Di8nԁ"`FV*s`^&9le $ȩ|QaT %-o_=,/2Iol>3mbWSK⒌\E"y4|<5MY7T"{TFK$@[waJ̳?>W9諼!wdFĪB誂b@ou`m鼓Cv Lv[Y٭ v>NNf{$rMꮙFauOtuЭ+ePL׉k3qjۂK$ ̣t}nAǭ?MR:Ԕ5pe)>dzMa=]-@W"ҳ%"'XDsnta 'Ţ`s Z5h t$onm;".y$`fCrT$sQh$$ZA"Xmn&b BB8- ]/|i7_ JWi+43i{gqȇgM8ajx{ 2ԧT،b>,C`TTuJ#|МwrHsN l23LD0Nu}FMDۣ&(&hN%!dHkw[|8]Bf*1"a2 ;01LT/?OOx~hF~I#0UYH6$]%S+#v%i< eg;O"\oԀ?.Jȭa۰E[C_S6.2eZRw6AA/DL_qeO%L6G?W5&̧.RŵSiƆ߷-`3/6dJyjF  cþF5CMm/Ri!F0ڳ?(9yGL(f"MT|{1?Ӊ,o -uW'X᭤*B b1q») kȅǢh{&9LK{I= }!ƺCs.07-(=lޒ-NGÄ?;CA=<%F10ebL3$H>&lm~JsڷptSXC2RA]W-&@c#1>Y7f-~ƪLW2Ky 0Mn&pƶn?̘lt@@+9ڂɗ 戃RaɭBf%0MFqz!.W` B$*Pcs3bJ]0 1fӣmSclzAB(3B,g]fW I#(4@;aDMD!E"iEagض9L/^~]@`a )7!-A+To:s]pW5DtoP㉘%~r*~ZM&adže"2'bNr&=3|6n)}xއ>p@:cRΟY}^4Q4i> RI~}e+WlipzUNQ@燯\aG[H/zm%27-PW߳q n~ íU:&U NV\Y[f'$DHB&㴴5yc8j&$a\-@AۦԼAiVy1TӜ)ЗW7}i)aرKkf4rTO o(r[2/T"JHv,(xr֙7D ~qU $y::j:%d`.JBI4YqvY 8LRݢ#xƭXZ vaO4eVKJ-X_1$Ixˢ JCu#$0!$4`uD÷Rf\_!j 5[Y@"ot%ALB "Izs7HǺ%4.?͍z.3) .'&n``b3"{;R<ҍd8+ydN` G0nhPDh3m+jQxG4Ėdg1b>cn?GYVN*,r>*Xg[.kІ`rɝ!PTh~ ٦|lKf!খ?^U ;k1j-ėHi7⁾(ϡj(.K^_;Uq=O;~Y-YfCt3laK93L.lh`^u}ٵOg 0[PrlC" 4㍮UP͆st 3YbiV"k+GB H1JiGCeyGϹq}mqmH "{~)\9D=B%_V"dj}Fq&ĨW0N(4־{q} U-`5e"V)2PCS\4gVy 6`C2d9kwB !/GACnpjo"5Q}%P;ډbVQܒސH"tBeѕ}$ſvD*Y\4 %I$9EHiЛl ?:XnFCm|k\oչ㲌i j#bƖH)CV9ud0rEY;F;lw3YGs~ƚ9#mI13<5m"'eĉXL^)xjlԬ 1m[?@o@ޣ$ o9' g"zrL50(z'BۜsH&rZnĸ1f11nXbՉ!ro4jBL VRZu2/rOGx{aug-0\c%y7GbSlu+8Vp_ 1hڱ  3ޡ2Zl$vh<&;?6M N{ʉ[(h:FiD* :>@pJH3p>Jႄ42Ҡ!PMz]ЇOc8cr$!P>-quG_!}^_{z]*cJe;mHPkU<?% F*y4}3Ʀͱe+é>'dxI5I\I^,MtwCv3 PJ_l>̜'}j2b?YgvSboCYyQ$,pa S&*\SO 0 ;332~eV0&jDwS7Őڞ[cS[Rxh |/Rw_lgd0%6䎆T81ݡet9TBRK##v0de#6ԖDK͆# jlH&Nt9Cq )r~-_N[֥mCXش2 }Lk{f uT[mHXFz_Ekl+D_[oƈ3|퍏Zl+  RXxekm#Kg[Ԏ9 OYF }Θ6&BzĐw!V $@v@ ðPZct"ok.-7s.a AgU[hĜ$ e~_zXJB'<<*0iHVPeP衇ٿD 5 _S'XwHLCGfkO\E+'\M:I2Jwa z/d55YH1Xn 7PAw51M~PjvNd ͠Nkf 'F[)@~3xE?1>@*Q#՜UQ_+l%uDneg|aqk3t|t!EǁK&z>@b)f˞)%5cR)}7<]d:fƁb_#ߗLhX\!Ix|>OQ/mZ;6$`\r*/{$L/5Tj-<=۰V$ s-JDY/6t0|Ԗu.X&D3 ]hRGu"Dr9ҕ2\SKlRŝ)6#ϣ-&l.jEDngn__,0x?9|},5k!DHOc"b Rs.a\Q3= u#C0 MkYX^ޯAM8FtJbL#dbn^I8aXy|%/}謓CxJ G E>^G3ԜvXaD ǰ%\VE>IQf@1w4)ِ`%(mPzE@K c-ȏӢ^k0peOnӰWeOM/!s3Hh2v|%WUdCTϪdhafm//s|&ى0~ntB";:Ӎ7&h(J 4!x\fQV\&˹kZۻ֣A0.ć &3ҾdK} 2v '`]=݊:7u 76hiDG_7_Jj<M*C#Ƽ&gK͕Lj9 'J|@/fӓ[v"1ιpsSϼA4- $ק0#|OS$d3 njLƪoe7R41#xꇎ3%o&qM&.ksW&˞&T7ƫ2%,'8z߾,ķiN(ok]dpwjgi1F7za6.8]7SUL&ɱX @T6c9e蟞 ac; n~=.5E8ڹlg$Ry:R7bns9%ۧg7eIsgD/O1\!rwEpG (ͧIlFgUA²ddIj/TpaVCs}ޛOƔz}#dj8zcLu3w5м/50й/P`|L~cTIVT0%Z},'Ef oQ^&u{$ƽtuGw&H{Lƺs(6jX"B{9~"7mRM,ߵz {>#GG$s-{fk6}ݛd ̋gw4;j[f*.r8s͕GIE:dF=߃ ]ISx<(q+ e8d4lkfށڄgl ،xn(+3$8vS-2ǿ.KKq6xcp޻L`v+rlͧBE=4lG꫰c`Zg&{ :ou#!I0&m&x~ ࣒۔hhbw1<zn(\J^wq|44.kl<2m1xF|8ut"arip)mLo3nMғ-3IV?{@w5sdFqQLX(u9d#Q|sYvr.Yg6q4U%xi; HgQEMukÇv7gZ;ZV':DQNS48~J^1S1n;Dԭ_;/W=A+ɤ-:AH5LJ2!g{*\ ;aާ\VF&fznf!s]YbGdvm:)q/pR\WјE'Qo#9˃?׊7x|f(-~sR> "`NJǙ+o\[8hYć8,NM3f%yNV}9肘st ONҰQXw͕ڕ%'9 <s:/p_%1w|VgG }np޸O4Ϻs@Z?FΎߗ:`}GuxȣhֳqAq>a,K]w'K(п)Ȝ7dW~8V!^J5Dt3}ryD23fs~ :!б\65eY|GtF@+ut3Fɡ9qs:o TIf\8$ m5G7Kv;WuFDKvIl8D3lIV9DJ:o[1ۋQ'0#ƋAg#Zh4*)S(M !m^[ͽwS~~34^/Z)iɄFf߿ ЍBs$Lte~sM[/"06.RzFB"VrwU<7]׃-(S`t`-}7kf.>N7˖Iu3(YO#[ܨϥ!c"ec\&kQ(6JX>%Selדx8bt8;7EG$~V:ljƲq3|Q{[Z4)91˞IZGe9wNwۋ1d3hj[~홍5GA:]Ce嚣M81 A&M;s_;6AG÷돸F70uMGSϝ*/, Uxyc8>w_5@*^}@ ƒQOEegVd <I#n3ޔc,c S c< 9dcjv?",&$Gǹkd jlu(Q1_+UnuBGa@?Ĉٕڝz^fAq6|u|G#ۄA81N'qSıN(vlM?Q>GAʇ\B܇y"D6`;v[qz"YBqQ_ ѥ}m]yFH]-7Ø:tPv9>eGxW!u}ޛ'kz8F|XQywN8E! l":Cs$*V!P;?ښ=ѷ*b85'^WB PM V* f3[ola9?TđГ/%kot=d19 5/Z|)ef1>Iwx)T }gÍʋ4iQyM2N_82Ehsp:+eG|cuYU8+9΄$/2"V#y1DQ7lQ %B jwjF,*GzT#q8$471{X Vzxʄa0` Ff]of~ 8&*.7e`9Lً#ov2O"h`? ml vϋ:h]*E@AȲ|pbw <%vhKLmY0=;S~pfw!tv},ƻ4Z!Ntۃ=g1:%.80]x|;:s~8yBZq}S3I lgivpN'e `ٴ 12_ǟGHwb\xKR8Ȝ`>u*mj*AA@0q\qIo^L DQCأLB$d9ɑx4:* ƩɈx= QҖšZDsy9, 0AV8fS9$d !byo;*R!ρr!̑([dȧ}~˃:#"7_-KBѰ|{Vy*x5QC e q×4%"׳\Y18V3ds]P;!L;p-$44ڡ>f|yy.]c4#S0qwVULy= Wb_۽r`.#'w0x ak6;.ꟲ{PD cT}Yd<8PJwrYGe4% >хk"tw1`( > # @֎r? $חy";p1Iq ^q1h\8=pdzqcpE,F'W~¤ΛYݿ" ɓu߷dyj~G$Xeve{].8> Fz!~ SsG˰Ƅ N/o?!?U(o6 sǧP a1 5 OB),RjFӏC4M=:]_læGf3~'}\Y!,A2 *CsD͕ !,Lp>)ѧUvSjD:d!+8*0T9H7XrMàQ.!" ɓ=!q#ϧ8>PO-Þdo?Y2}fA4u:fFnHs\(`\,tǿ DB)<3rJ_P5&\VcQDv'7n]lN-Y#̷@aXD{3$Gk(a|%\`fN t)&θM뇗XAu%2ĿruYd$Ar撏}1~pxO&B{IG{%lKn6%%x:&m*{`JCNA2/O1:l1$TX!9Uc|#ʜDzR(aM@5BFMIcvYY@&n{&W<9l~BH=xvC=jY fq0?~ߩ%i/a.Έx]wަ}c!9WVp^jTٲ7Lv|X|^z(A]uϙe%!Bш3Q^(ߟzn5'<;ӫ=ws77梤sϏ1ï,tC)XrwAH9=yXA S.&Q W~5so p]R6=ڼޢYuo'P)c]F 7{gZ7*`_7]հ ? /ᬱ>ۍ)pԞ8{C&:?Cą;AT@!i@8Yȼv캈<Ĉ7N0Sxh" B6| ä z# @a(G㘹b_'5g ^?ɱoPIbaa?LUPUUUUSIvIS o x}UIAAHoxNyQ-j9dooh_<z=ݘgKͫ_!>ˈ2?_&=~'~r3dHmm;AMm$oq9x1/)vuidI[y ߊ>ߟR,}/sR\X3ON?&oyݳ;(;]92o+_K+_[C$^ vM u\N톿=O|4dC!['?%{"$m8uAZ>"66wȝ`BTA/{N6d<]vf2 9NB?$b֒7E6cՎCRW5G64'Uj/4 jc.g7{pL7(CE߂@|eT냋̡iu`T_ʲi|#0L^~!= %gڇgf3)]145- Є '/m qjbd<ӹ&lgIνfQLNAMAzL(bql!QDDE$ARA2)>Ś>r-Ia1b:QJ;A*'x \h~syu?џB\ܗ U< >R@m+?`6AK'69KAZђ"^X ^*bvW Wq1\18^180 :ZFF}TD,DRTFbRzŠ 3F9^q2vŌ*jOΊ@_8KX3ۦlE-[ LCCtjtYyˮ8_G ?i%#Y+"(6DtIonfe':5!JPM  $}y Y)<*8}mQebx@y'SfL_x\|=%\kD.@? Whm԰L\mE`V%{<\13"AĊc 8}N9( oŴ~iZŸ AWat)fPL*C,_צ"wcN\α>j>be*Ԫ(W{YE]f6`;썾yZo5yD-$N*d".}[j%5{r(ndۭen,[[ʙ}q|] }\m5<}5ݿNs֡U1_!Ο.qW]9K t5Xt ~_~V n x^E}'I.n'㦂"G A `vJ7A8^adg ۫XIME|#aΜHCD-.=W#[ommcx-0<NK[ABv$\U+*[(`7iA)63؛"iB*LZK?[>CXls'ćD1)٧aK׵H^縔brN~>۴%ۑv/R~҂@s7tS~'ty1^㓷REݹ0pcm} ]7bWc,;\F7_n{}oc,8lmr1B&ftn||㞘B {I@$}MWS>-Hwm32f^]MI !3YDGH',vCHyxeլn_ӷIkޙGp{n2c76Ml0aWmXSWljmiiʖgzԚpQ8q< X蔡js2u3Q=҆{W&7s_q0ajǛmWCN_36K wuqr73}x;[~G?CG󧌡1m,Hp{"E&IlTQ<; o R#kC!{̚IhD)!O]Db04J5%)N Hj³yn}o>oMyLv>3/%SΏ+rNJEW?c47M)+Ku)C :U4 E J}zB2$ȃUq(08ȄB9);Z@ u>Aϫ2Is|.?+1WƾߢQu~7!E>cn^W7!]E7ṕ.kT9rl~{f*xoTkn%~Bj*G kurGg(A)F ,v $p ChCфx?~-|i^I>s@SC]O(jO+v9_ws L;(B ~zG~۴3s@u>({%CBs{{.lMv&?] !đJaw۫Oƾ>f}D08_O 3[Zw7/'lr*qD;Z!]?6Yና{EkyI˴sAM턈q9b1g'")t'J.soS5FDMukXl!e9jq9dxUJJcΒb|7wu ˿ dzH$^p7-7}mG, 5h cߪs4C O\=ڧј="6"xl(IfbN2pm0yΰ\@a Yj.T:%`a-КFPypvv|.ؿd7} ~Tnꚶt/?UeC% (Dzr3 P kN LOtY錈f'g[o)[7R#a--K/0H2:⧪"78:ӑTI`خȉLvu剫1#<=gl+"t=ttw#`FmL!jY T p'#oMD]X=NKCvyCNW#tp|Kмn.ky<f5+F=цxsDf۬!jkDͧ8\kƦc{C֖q\DB'H= D娠a,# >yȖI2`K<"Hqd#+[P҆}W(O"IzjRTpF(92<9яE>e4 oov|X{ݮQno4UtfVE8n_gdSiϖ_bT9^cv|D7G`w{$El*I!hBD{AL;m+1l:X1~He3;3/Ͱu>x#p;$$PzOE_.JtD - |(PyA,m|Nd)*6r)(d/XY/eZo#hFd޵Pb֬Sfvܚ r8@hMDDLTMUTDLMJPS@UDkmF5h /{ UQAEElAEj*M;mEMD|4AΌ(wUy}!;D)!کVS4G36 P0 Ӹ $+2 6<`e5C1඀i^GG$I{/'bx#Vؔ2nN?RB>f?7J|0οb8 8Q`]9>\a-\L)w[~pZ8ZyR%K{GIq4!7hZф^taS;] N4|;*)u窂n7|{Է톏:BdFHrh:yk}W\{]q3{ u8~m̠`x䌓zdYg ߫=EDg$JSdHuo+:yU&_YRSW&N\ Zd#d[NVa{G6h{]LtOvm杏iWj(0ǜr(154P(Y-Uw3fտ .-Xaĥ9_WJa+9#(˚?u:yv>s"1wzY(\ݾˢM*zktHv!Tgny ro'wO6ܸi9[nt5- 4 SղA׷^sL0շnG^oLB[dqy+ϖ Ɯ/vս7]'Z |4ge lu ا? wdXjV=]" Rkw@(aKNo:8Lc%i (8\֧@+54I:Wsa;g%qQ51a<"1EE2kp(vyߎ 4t:^8Rg:d(O;ԑ^qX9qIsW, 6y])!I 0^װ.m|=D3kH|J#@yitx|LjFG7L|YωiVX1]фlί(O zlV趺;ۡ{G P<];z _ӛbK9<,%;Z9.N 1O(OHItGaFCOqMq+Uf(,˧_KAjk~dke0xIڭc.$1n ͲO;V&btGW۳ōMsTu5҆:wh%pw`h wߝ&\N3g` H\(CT*PEq7âY@ѫ<>\"\✎[ЛEAɓpI߲${l: @xD'XD7"@Am,NP.8f\1i?G*GOr+;7eDbQQdyg(jl^q|?h5W-ōd3+kЬ)ZtKÖ wǧ^hk¿y6N[Tx݄ϟioׁqfRc#ZuLqBFAIy W? ^i\7&֘\NEnHm=׉7"ݫB) x T)c1*& ,M[a߆FS+/su |2*?V9|4-Љ9۲0l8LmRTZRaْ`K7`f88&BCECZXx.C|qQRu X$r4Nm"F8L XL{gͨfRʼnr' 2 35 ̺e + XCiT)Xd`<= hFA6uyH $ BrxN ȿzb1t9` Kv9ZXSł/FS2E@q$MGCN,fф0JS3Vh64 0j#eL[/[LE*5'L>MǘIhHٱgGJڮP3bK}FI.(,`W,bCf؁`lvHܳ«NNUl6 A FƑW&.e9Խ ѥ\RUq,d Fpd}{~Dlz~zx=@$/4``B&Rwr,5oJ)snR04&-ն9V K`m0HseV bY|2>BGtor&ѣs%,p;1` %#B8Y!f@i*m"k3r,1q8[k ՌC@4$ٳ5Ό85pX04Cx@dOEd%"*L4-`Rŀ]֖2 ` q3ep|x ^l{]*F~8gpnCl-:Zf#o0)Һ k lz r_8bM|5&c PW2.=2G/@DI#; ]5?]-gnh>*,~P~==*rbiGDܛbX<Ӄ3$`2@ix2 tkóA,JBxU: z$00pz޿aLG ;. g13w~Ab h{$ x Mo'KGut]zv.e&Z]* -[{xG VEZ`ڟ/$ST'AaTy!q1+#0ưm0l v<}r0MPFeL@ޠ @vH${<c}@^Hi /ι /EFH~pݴŶ̷90&*ӏT/f#Qlz c>C1mFk5k4bY-NAa ws{L؆ [Ѥ> *w};0h1CG-l,9 /*C8"g]gTP)RpX=>tfӉ֑xdtn: `6͢ i+O1CwaĦKs[-cex I XJg n(  ǃ5QI$d)ĵu֝e"ʆJb1,1$;1 $[h՘Y eHq˲%%JE4FbIDAN64Sq±ZkӹgX )R>5٫ ndn54hK[m-Zґ:sW4hE#!̊2;n$D-Ak695#=6,܇\S.+Z}նj!ěa7X: :l (كfm&bFN*sDӆh4G)U=hg&6ApL8 b"h,):fԸ'gfkNoB6Mj*[eH>4zt%wXĐЈXB6;KT9diFHCUȵ3 a=>s-T+Ծ*.mɂ!dT{E $m[e­-N#VLf[x[Ӎ%T*Vnl4fhxAηX[4+-FBPTUP4Hw*v8ָ-4 1ۥa=<3% gLzPI{Y1uTfav5)m,FόR)FrTUf+VICLEщ!mvr0TjM0vȶ3y}`pLS\5\@NlѽL2h+:\e`V@İhYŒ͓\2 ʶjEPrEنF*}f8SB&# cR~Ϛ̗mMwA/?zx ڠQ>| .zzqJqD>i_O~*2rOP&W6(݆Z)$Qz8 -3|^=|#'^$34H D/Fӥ%YҘHv2@fGF uEE2GA) j_c.k*=ܻ8T%p d4Hv kHwa&B73{{;q1% ?#Duw & @y<~@!G$ߋ~3"$&7 oqmlEP9bc`JC>S]Ѷ12(iD)b@v>[wUy6&=h06"aЛy.މ&A$C!2UGA`ƪ V'XՌp ?sRID0^ll[D]4Rt&  &@GH.&|rM!P);s\0M*,Fn0%\P4p;ӿ~l&j\]٨G2? 2Gni2i 4_+qxݑjoCyC&eP:v\sb(E DPuJ/j075M5˅#kEscxy* 4310$@L3PD3P){Ha<0H08xx Qp8hЁ )!YFW 1,ȌJG5 P zZ{D]bp,Q0 ,>?=kpdoXFP( a?܄ Xb9DMMpIM"+`dJ=@ :9#!8u^Ԃ6&(LZINC`^`,v @ B*DΖWh НZylP ,PP%sDC $A?%up;De%\. X 4=

1Y"}CAt"B0{16:AI JB9e X06g1((AhU1H0P؉ް\5 d'UE2HAO _7Xkûq}fEAOx:;vT' Ci:[zdW5BTŨ<L P.aͿ #gLg$@"MUtK'z[, 6}ZTx5RD*u="AlE+#dJ #K?*8L9>U@ &@iZυʸ?qɴd@:)}nhz N 8PdRwse sWsukNi$~&'ɔkvS=͉q02&cМ;&>x]'H5!cXӂӃg?!A X GM7l21># 4Gj 0F<2 DBi&c?R.06͑‚J_?ܐ&*qBiɩ6MIrrl8"jIjM`5 Y4jj@5jCX*MjJ!"p9"{4!X!"$hBbX$ÁL$Ei-m'Eh<9or $h%(gBFS.xH?0!02$/ d`U$})R LN JD*HR @&]N8X8+ކ2@=$C + DXxB~G f +L@6:H6 r屓() ->j4Jx@ؚ3@=8ucP##22 ͢ 9+HXFh$bAe!$H% U@(5fF]˷} 4#lqyІV">jL %~ID !AIJL,̍ !L̄0 ێI H& ˽񧑽Lnth7&XRYQN֞m{>BuQMAn_Ϩ|sc{ӤyB}ۖfBhCDt <3B>Q ~<7 Hv)9]2bj.ZKUMJ ΢ To 2D ?2rzh>F$HdF«Edl L*91dLOт{}lOqֲ!:)yI2,Iu-lR<_V[S$@T{un|֌5ٶMd|J(>1ܨj\Γ:@H 0rJ B2ip+\+5RP+= }M=Z"zq$.D 7 :f@8k{< NUF"і^ٌ&^QԿWH+Z֞DWݳ{uz`K\~WǐFUkDuBjÃdúcS_S(An 4`?WaaC 3 휥s~݇r+/í:Np!NODFB {üj, "IJ|LhH-UZ QWr&I hb/H:w \aV )- D`&H:FጇLu1M-s P$!hRLK&N5&&U)$aHpzgj:X*F\me؀`~6B~Oh~c_wfcAA^pEzv[ҡfU(!%JAN@@k+*?T; =c$F<(< (!9 WoIs$Ftt~jaow",j8%؃Jl`7͝54[ή^5TGuB&]1 H0?Nre0v"٣5*lJ @&Cqx4NyO;N %\bΐuԒ M']6ߍCEw vC2S``-!8C e@'qQ9t,Vj c#?xh`pt\B"9e)-9  hvfZE?cȱ@4?ː4uմWk>3kַZ ; #FAtG2y4M!`JZ BκRL$8U@;+iY^%WtrO3R;F2 (<\MK۴v._]%))O⹲ClF|YͷIh;B`ah(R"op*zJXvXZn4DojCHв> A#YP77DŸl_!͟Cp$0%ȑ/!ÀGj682[,(Y((!*g 0Ĝ@%lof#R&&ea~S@8 K@Lƪ& lIDA)KMPFц:=1߰8 ߙt+̅1oR s%b3$b\"e09?>(TP%R!K/#\;E Dđ۬tȦTӿ4RiVfAqvjא&Tk\4nN@~*l: A'Nim: LJx(]Ab|[&^/pg(;aU| 9"nwB fE?'@ X=Ŋi,Q s`pظ &TMJu"".0}rC&t-1TZl@\n^dt22&G$xڜE0l50~=j雉ww]ӟ0Pqw ؁ ɻDotfK (<*G= m` XCN]5 ŠrjZG0IŚpD"'`ϪU@$od{`HiۋlT ӛ7p%Th[Rm71s&f<~aB $Xa7 U'3 0"&QzK66Xâ>b[t]-®NA0,A %f$ؚGZE ySt6hS@mCW}β|C]dtg L7R+b66iXkh0ot<ڴ Gz4h፡m֊!Zb>AB#F"" T=J{Jvr_AĤl^$4:zM-ؙ{; Þ)0!pdU@0@F-j %OXⲍTz<nXhn6{^xA ܅t64R")c yjjMSI+~>>ZY "ĊM_e'NC"<P)RR 0! xP A  (E(A F0$`ÇI_h6e&D $*!?np[: 4R(B q=|rb> N4 [携f{Ϻ9QTiN5"Βt7rDGN`D'F.'"ԯx8$2E JU S4ŵ@t!t߁4"" t(C ( c@ p;E  >mƝhṲV1,PdYv`dHPMQR?=@]s8|~xJD"u% h.Ǭ(vRuCܒn9fʑh\m%k+zlmb;ˡAy@l;sH-dAMDq+]K T8oMk07Q=!ƍ`D?т+GJu^jt2 /툃:;#\yP;#dըiC5C[1uԺh`JMӲ@ Vj'cdQ QE7'3SgjBiG;##*R;\95Ʃr>OEc1}7' \wiDpEsMh5, ?i HF%6cEXPH p}9f0X@dB FbOGoJ,$CSII@ADHDI 9 ąyС/Ǐt'r=?   ë\b0qf!ӝəHAK!1 a!%@oi.Z9Y80gN V7P#A(XLsɢ#+@! Ҵ'ܳTs&m!@gu](X"3:H>CL1V7;vӶN$cc ,4n=+C$TXF46 %sS×,lV]O)>=\4ijm(>^,ٞ𦺦Ӽ^74!D< Li;-l te2 !6aƸj?14Z&_%?H$y,yPfAsd(m4Ҕ4 TH@(?:w&;f]+.k CO[ y۵^dKG+3M,wwe1 2$` ~^OD`ZljToqEQG/2"hqRT< NpdlF}u0,k,'`FmM煺 ?X7NI9 qMC5/RymꟀIH'b@"B(hGҿ%evO|9LTSTWS$L&j B6wA*˛oҤ JJl1 ~^ϲycAeu_#Lhբc@-`O5a gǹnab2oԡuyv"tQcBsVρI k"b]5bzvw%B̤3XZbd  ؓ%! ,<59c̈0W9l1DAn'^K#l߅@p=Pb+sOnaw<.loHޙ ¤  8tp]4r]fO1>?GJ K1(Jwu;6|Gx}yNHlR0-AH;I>P}saAz 8T=c*z@T`h>&&.Qw .1ߟяGoa_u}/ն#p$33 ìe]'0y}"dp)~R打_>ăՅSj!q%_vQ~yCIݧۏa3\8ᙏXo?,~sTP/ #2OoAiYt2ί玐?%sA- o}PAAxWQ}#.:w! !"'(hQC S!J$QB#BqJ<]sRd/m2݉Fˆ+ˍbe fg9RD@AsCi,=49j26p@!K'\@քyOa_,gqO_ Ĵ~iQT$(U!c͐za 95%X¾^> Ұ#y@~Ё`wO(!g4;a>C@<  ^3@Eǫ MR ^LJ Bظ BНׁ"l&9+ (Mϥ2?:Y= 3?:d"LڐB+"+RyC-Qrޫe)ޞ= 18CbHڱ%3Ho3Yd&J][BV䖤G2g3_?ys_n @ftHI|&!h(O/e  J"@D4Ϯ({F& Fp0 ' %MЧc⊨-ُ(5l~>mpCg$@dS?SAbE`=: ܑx@};\& F`HZ)HXCmjtR.K*fyHP=O904P|TK_[h;PIzDGs'G!NEԂjD$@ …vjf cqJ LX0& C9ƒ&biw^]cSخ_*{ǢU]?pit❩?(#?wbq%1m_èi`D`{#??xq9j=^={8Ini?ɑaЙ}W{C)c{ey 'h%Z8D\QF)ǓXA\|faR} }l]Y} ȗa6-rjb;~ufo4pIc h-%+b[*-%Et( t0$:0 J[0&Y'k>uzn]MMh^IK@vQ}aR >Ꞟ! l9K CԱ3\Ó8I2 uahF "9!J9kVHS\ pɬ7q&ֻʕS{^'Kx%1QC3U.CAD(JlWy߁i0S@MFsc&n-a3pym[,2M4O@xCE酁1U"fOA ^S+ X{7|.؀/C=K;yK+j ?VK:1`/u/,E"OWgPnoYGϵz]fۑd6[+фtT:'V z$=~!,M$Cը2oMBxQ{3=z!T,` E=O%T؃UQ ?kN7`ձ&5,ƅ6 2ϣTBzvt2xC_ךLR5kQ3c3A[S" p~B671RDl" ',x4n1'"G< ݓ9- % <"4 @}"jTb(A距qJ=?dp܌K-,P\}YSB +(6`:tH :w O@6vyo_=:2BwrOtBR!qe?, k_BֿF!W|OQ^ }9˿C9٠A4c#Ѷ?I\? d$d$C {ʾrʹ} 1OG!Ȣ.Zk$>Oe<~:+}2jit`)?/IeCC}4OlhP kt+?d>9CbJxW߬ D/M l9JU-U`mͮRvSiymz$ X6pbivk{fL~L~%!Z@ Q!T}9)il}&^Ց Jd-4``@ ].G{'H71ە"w@PQKBA?QB{ޗ 2 C@;G !(}]Hw)!\#)<@2OR>yJ_:J$_@(3 =qu0AQA@ީ Rk"o;u_G/yɇiKi9ip܌5i|!j@Ϸ+MA=@z %E _xgL@gɈi^BrW%#UM!IzwReɈb]%tZ0JPu*J P&i8ǩ=eHv(72H Or>GWK}Ž>*{ >T2PHj(ȧD>G/ȏbPv-(`L^uF@L'Io0y.]$X' ZKe>XퟪWug`I?Cj?cTQ)/9e12nE>VX +'{gwUl Bnk] :Ama wOPndpCwxzC^vÔKJUx ԯ9__nܷ$.A7{h0!Hry<{ȟ(X؂$0sNMY:׍GBq  <(CCSuK%DWO1tSλϷv2:kSĒ(؂5 n(}~g f1LʰiJF#0\LT 8P(3=$NxTL !?Iݞij?@-x:N؊ 4Xx!$ Wo'!&'Y*}@A! loK  mu<2 s(Á/!+/3߀:7F' $餦Q.KvxY\NRW:)I5'Y6O;&0!!D YA*<#s DCOY6!m% qQluHb|gҝS'y8DA84udMVv^N;wܣD74&cԿzH/+& l CТfDx2!bv h@*'EȂPMȆ䨼O26ON d5p\CQRh3S >M*0׳ECA &@.@=S^29.kj#$7tp]PNrp LJBPbBIXD' 0I@C#$*5@t{Bz&&z??!F % e_(@}B|h\tP}S䏄G~x*! 8 7sc 0! C6xuyydHh?((4v hg'`"&A,!lcb")Z(|S# Nd! A8~qߦFIV2?ySWxw@ P !P;QA#OP'}6fa.րm1 SXR!0p~g- QAG%2P"F8 AKH){`f3d]O| @c3PA_ R%$7@'qJx 2y1˳k΢~f+]\>}2m42c81>J".$N*TTETTUUUkZ ~\okǖ 1p_i ³~&;┐w;Gtac!?ƍ3nN(0bEO?c 8~tϹd x#{Md,; Rg M/= `*,q#> 6u ,cSH<`'w` $IE?~8u@?$ 2F8h""<ؠ]Ph@-ps1`D(g6]锚+ s6'#'3 XJ~”A6`"svJLjg4RE z". (zS/?IXCxcCp3_?>_Iοŵ(t8qx?{.}#$vHS h {.] $Ny$6Ȍ`/BI׍G( <)ovW2\?ZU85+>;i;/fqSfk=ǥ [A1YDmӚK`}S"|\Ё A F!d``HaZ&&PH` ٔ\$#B"$A⮑=KEY`h4.RfPLҝ%N";ͿdÝ؉ /H` qHA=P5^+/0vver `s :]"@ { :/b A $(5)ܥS(JS -Raq/6%BI!ild%]bǍ!gCV'dy4r=u: |xvRncnTl>jՆ" lY =*$٧v_`RcFbAD6Jn=HGj ?T3s. K#pPcYE,Ҽ^TɁX?! |fX19@fh8@uh# a7ѣI9yp\H2H%1! d |*Ld19 YNk" ~8)B؟BALT"ZʅCChe&]lo$~M& )VIg~>kϳD>@{yh_-T Feedz =%Q8pg"kЊ7p W lP`?p؎KW42ʞb1*3HL#/Hn (? d I=GpDo~@6xVgxcrsP1]gU`YY 894^ۻ1zmt> 6e9k 'd)Ap= !/*8^FVE0KFw<0 :w+@m"`Q@2L˘h&DVT6$BG5 pd@-r3s1%ad`;I4{WWr"`(FK<-nBYAf6#D8O[ 4+Q&8V[VҺ <|\֍ݷl<3dL@`FI>!h(jDiDa>{Γx'VY_7~m2^6$Ѷ #Nb)>s?,jK;{ZauXo7ݸ"}e|'ǃn 6C a|F4d})C>2 )y`ؒ'F';M`nS;X!&UʥQt rrd vP|,!Ss }X}Q||UVflV">D$k;g:~H=S\__?!?+^W FHkpQ13ߢoo]aslA2 OgY^!_,Bod_m]l) QᡭQEM^sÇ=s3!  (9S>7EĜ78sbXH B}8\}†T?)k"9LCjQN9)H8/(x4M>\r( o5 On{8 Q/ȇ/ d"HBC4/2a8C ar xd-(sm< z_^T7#1ZSp('0 =?NAz0Q%(H6(eܧ'T+DF!M 7`BDd2rSo,`R{L\%X: ~j .^N_"1N@r.>=(r. \r7+ 'BX$;~H_:.ϙ?Ǩ?<}'{ʒcMw^C9? .[ 8]TrJ^7GXHBt @ {`*6>1~]<׍x3|`̓1fJ jL}glNXI&/߱xhBP$Hiyl(NA4۶QAaؐz$ cLu=Z6%G>|ۘό̪L`M3"jVb;_)/TӒOUDsk® Ql|{vo'W =e7Szny+n5}΃[6W ıc1-nߺo6#b=w+ж;͕HAl`kHŚ q.hC\~쒻Uv[ fFY"o1N-ddA*3USsq:hdĠ(ghSRozy"bDW/u< ˗(8MU_7 Aoj!prSY1 ܇|o&kלw$ v91C.4[13Qxvu ) 7RH>/} ś ͞NA 63sPAWUq̘ 6)ʿE@'M3o #eqd4a AiEKAl/uLb=61zA9x{d%PY*j?0dB}iݗnu`Õ\*0]x֛qwQPc|?_8Vgϫφ'm0v;u\Au4C5u%隂<;؁q. jxfx1`SCsnCdh1#6DQHX kV0f Ȑ )C0>'2\_ [>.9Nî }h#aEa;묻2OЄ\/ZǴ#|ICGEQ0D=FFQ!;.lD!!'|(:sϴ"~dK5Ll-!cYCSatD <\c4ýBB 2=3} 5*|U:])EB~~>FŏG0v?& eDD5j+4ä׾hmkJgy&rY A.Og^% ^0 rG.΂]=oZ}=!QBLŖFO7nO.4SQHdzXL$CIf@>pOk;1_9I&Cp؈Y`$tXQ$8 FCGni67Ys[%ǂNJI[h@``fR A@~]bIx@h)60$W"h!Te 17'q '$0@&#'1P@% J:>P "c~9^Y4f5!Xeu4/38D: %?Їg!ayN }C2]HBTxB8t ŀ@B @ĆZeXX"e$M*?b_όJÀR6s'8#s(} XsH٠IY|>Lq=hn =ލm$DDTE#3R"]2DDC #`tEM C%!44HP*AREAHxd )  hȌtm W:0Ji픢9!mzj~ٌ1níYg-hhmBż |Ls]zIp\sK8 4w| ! B*e.#SVZ+hʩ"|dQј2d`^8YW!E"q|# NpSCK#]l+\l M-p)SFMN'aӁbh"NXaV $\`fm64EFBsA9ýi8nR[8`߫O!˿i' :PDb,!l)wMO1{<!'83ʌ'5JL E8Tjfe粪w>9?~]dENJGx! /WKF }TW"kERF_'h?- 6L`C!"Zq+9ɀ*hY C- 8>!W$3#C">EhDJv6|I?ҟۇG6 F,$uCwXx[K4U@ARACE(c"4pq$JD2䉤{>{%éȎ P8E<lF`⸮f0hSpD;"d0?B10@B 3/x 1 90b_ELpLO ϨV xGHk%O%ObNp>CZ(`*pQQ7z+ s`zNpp8;D J܌"1 GM[ =FD,IA  IR x~>j8wtafa 1UJ">@ҢFQm#\h;XYC$ X+*BB&6M$3y1)GF.;%LB@!@.Pe < |蒌sB y/G#O9<@Dү, kva)r"@fJ䴣) -4!HU v2`19LOO!R4,$w1 !|ϠM@$H Tw3cHȇ![#+K ±T\.!9{'QQ"pa44oQ @R]E>͉&*Qz./a(pd`ꦜEKۨX m7̓8h-/_d 4 w_*z"zO$4?3gb ';HXau*ОSyHސ܇P;|*KZ AkM=Kep\Hf + !D%b$ *%Bi~ SY"o0'?QE>Xz2Uy : OJH0q<!\_Gd?$p{#!uԳ`EBȠXXċ ?ԧcNhdA 5* Y a> {t9(1"0Dvg9fgTTeQBH@TXS'}&P4Ѻ,LUH(R?T|e\11LlO0>T<M|z{Lz0fCU tDB}>H!ըC!ZJIxC.UzGBQ:$=i9$J9 H + ,44O砤ïDCi 2GMnT3mcc yLrI؜0)1L2 W%0̘zv {׹zpɄIb 5˅rd"\{rN!B،t9Qq$4kqy^\aqLH`j@+Qj `GATRRUA$$!*X& &*Ơ#Hy|F.J`Pp&9uҕy' 0h0C [&i2o 0식17 ]hv>;8b3TPqUOt%aNJ bDb(!Id4: 'AmD|l,!5AD$JK*EMD& h1R$8) #73) ]aL$=@UXC3bIV`VJ"D " $DB H; X;5CZp~l]7+`R,Nmƽ-.LC/*)VܴbDAB7.)E 011 f#n4cETN e(vA1kHBӅ@:Be4  m#BE2R ֡"u32Q @)CdD[Z&V)s71ǯ^pd)&dg-1 $Ki5@isC ^z耀(E "^IMu,iea}iG"uR) 5ìeQIudy5kHWHZkp;)emt|:3;EZvI^w,]rIcz 0-"4k"#(ꊂ81" Ap0wXFSE$ F>\ L WTA V('VƒxƂn灂T5=AAv撑 co[)6,LR7H`3Xj9{yzNŗ45n 5dPirMC@\a ΄{iLرR퉒#m AQ-RD栄aP~'()  g.)lhLE!X$M> uR~bAb1dl U@e*z`euX5YA( i'W,&{Q8vQAJ}Q*.A(3\T8<<@"~iCH(2 r}4=>Aa(|H;˨I`OPNqPlj wqA@5?S+$ N@`2`fe LPQ/?p18v=@! 9O1* 0 0T B./R!gF;!hw˷_U)TZ)&YD)BHH? WpLKIJꖑiкҤ@RUD!B 4FjGA\QBB c  H+PRQ\TH^N#R&=1a G?"@!9$'/O LekAh{.tVԼj &;)>8? e -$|`N( T H }=wLjj6wٝ̓,KTzsn<'gHa+ ͙*K:5yf݌ :b3;7nr#SBp`I$ $#qNIh >w'b\ 9br{?aOp և'M2 !C 4MFd(>SԡPr>}UISIIRJDBPIQ)VtLPS*!L+ ;/>?'Jj("YIcN)q˟ I1cqL #9 p<ӝr<&2&#J*-K>eK뀞D8HF1!"5 iO$yϴ돺q梅>zр vSeX B?,nO#{L[BΞi8 OZ30rf p^H $EO|p҄/dxGs# =P"-^]ƭx{^_?{rj#rsZ[ &CF*4aC2nh$p0tg.2!C`uBpP(e%(T)̂`hHU-bS +0r\g`ʲ0%VD|KA%CH`1ʅ(Y ?oyyvRb١`PvvpluICiB$ Pb?`m _I܉ q)`e ,9Hi˥"b$#D"`u&IA CdO~=vH_ސr@7 ǚ| ׈ ԧlGRNˤ-RSl?X6J0jF2T;-}Ѓ*}vSRCvz`"rC˸G$N8-dԉ쓰WX;I5D 3==_g%\BM&d'(|6ȺC LP$Ll)Cč E_#2Ggo `?Ҟ(J eC:EM1eZ7pm,ҡ q <Ï_U# XFbdI4|4 P_o⟩#%]8xwcc'%9:qIP<0B.^Qr%8! )hu\I|MC{d9"u!&4<`"yjc 1 AD<6JMkp<cb 0khѨs74# mc8rp|]C}<Ò(b4F4EM#wd"\XQȡ49Ȅ(>=t^Mq%L z2!Ps@DD`qL03U˃4!n!τFHPRSD{ M0{lS1PA:&"/Gqǥ@Q []sS2E$IQ\#{  ^qm ͪ*7lT{{i 1)C@4t4v$:lzÍ (yMCpsʱJ1bUD-B$SMQaNͮ0J/y8 M+M1Dt ;7)8@`T?F)O#M-!ca& `.AJ:`.>a 'cHry)eLb1 #A"bM.$&J&fh1##lG((8 1 \UOx-,(CX/9" = Ugx EH&hAZe߃hQ`$$@rP;\9R[z";֊ X& I&F162cIDQ7'0$C 3% kN` ԜɹD#I] ںtp" C 6< Kp ų/G@8bF$ Šj<^xm2- yc 8R b(i9= $ ( )77t\f#?>J!A$y3k[* xSfߊR:5/^`qh(8d]RW ҁ?C i^P}̲ByȪ| MǴ7WwʛNx&?LQM0EDLތ^1& B"F(()& $fh!bIF"BV QH# P%1CSb/(zS`$BC@KǺ7GY.}dRpCJ2]RTh2u89&@~hDБZƃAө?hkDrBϘw(,[ C;K?(| z$S; Bʟ3)ɥ~v̂tBO@y5") xS6]PxI riK m.<m'D>&|OyϼO Q+ b. &͜bխ`M5mlŚI&=)SK[LhBѷID16M)-p(XobTFٔ;`0Q~}}aǨ|qmM݀dp;(Ԇ]A-)@ˑ$mlwPRs@]b }~ެk~#҄JN"LSHWiI+z*)G"E# {CEzLpU*D҂(Ra0 822R7/yO %@]PW02~coOi:V\5" P&ݸ2w dLRJ9͒*ئMgd+~] HиAROQĈ#ƿY G 9o6_s" >-:{ٞj5ID#j4ܺX:bzl}| |7Zt>'Gck23B7.3xB,&//Fo0a$t#GoFӨd;Rf=7k hmGUr)d .sIp[G8NqO_7gȖ [SxbS `=N)w \&Ճе|&Ѥa| Z\D?'6i,b=>cRBb0Zv,z1ǣEsF؈@i Aqv!C5KC$Յڐ3;mr㣾ɇf6+HΏlHr4÷~eA븃:t9tت&RckzPv1յ4ÀXҫ QJmc]toX`9V :ׂ;0FR⬵iDF1a ;nR<:k4*Q'%)&9xf)$I&. 0xvT7,g4#GFKGwgW:xP}=aTK& ۂ,W$o]4H %' PviS{3ɱ4bPh'oLGr8dKs#1"ANDH愓h:oKʰj8t'd&syf5m<8:ŧLEhKE#p /2)"ojnImI|j/dH+j6FW"%^c*8=诏'Ƹ*{'D?o<0k[:Upm%S^C-l.s &elJl:8іHd6Θ!-c$tQ|@i:R؏R mG/o`Fq 5$@&S]:H/.)tHe0sDacuwi @Xsf،}!d ]#fx9c<1ΎxA.iQ崦hx#O8c0r;nY]87ON/(8ɍgxh! ?_*Ć"VF9\jxt. :4 @]#ʂW(d8hho(JrjN c6 m<] C8۔E!$D, ! $sLKA!n(M:af@hCrf+!;ZTVQNH (,*`TuLDي鞞y|le50=cZ3"pB<&4o@kG1uy>:? Zܱ|oS]DP[];uIgNJS:uCEJ $z7D!-4mF:" (C+Lؚw¥&\9Ǣynw"fnz66B뽀>G7'}OLs܅3fwF^h/.B;1f1e#h) F #اOZpvcwdZj^Cz"$%4wǝ 8n(DTjw̛R!{Szg}aDʸ;n׎NCa/v.pfmH8 i r3z>GYr{Ddb^''WM*9| emxJ,B9ِ"m6D9}>#hwB'qb3>`I3$Cp(HG4tugv]v;v+S. $ wI36r9߇K]]2qt|A[VT3[ ѣQ$xiz$ wpقoQWLGf2f,hˈ,'H( ((HL g_mz鱢ШGNMEw7CÚft ϓyoG}W W4dE?Ύ\8ʦ wgccDNXc8Rꍊ.ܢH6o.!gC][Υ9I}-0fG5\Bn.ICAО wb"{L}\\8 o؟cYEkP25_gӝB"H&BhA&fHa̘Uc r YMI8|)1jo]qCۛЕ8-? b t ܲ6lЍNqUԻVFi3y+#7mm{5uuϏwGBhQG'; F2DSAmOZcžrܻp2o& Z* !;ڠ zDw"QJ?N ~7MҘn>3wTtuٔ::neK5X.|NTs_:[kN<醺`-!:#760G%;HSUyo{ݎSe7=Ks\Gf#0Cg]޳S.zGEO9pUBKLvcw، SZJ>n {.\rCtUDw&L#_x.&M7R6Gڣ<]rvl5yR6Ke]30=AEI\27uc!71:}xIAL!SYql""HÚ(@  ,Q Q (n @Đ@5'ĈФ31P s_;D>3ɳnDE) HA K^>w061dd "DD8@< eHoۦ"(4T=ˇ:w\# d H&h6-V/U"}NਟDX#8AIsy+0(5~9R^5%݁wK=67Tbjbi ،?kfz!%Q+c{G%fja7?` `ہ"C0<.S'.חDG9LԘvPo)-Orɹl#.9k,"OU `! Od}xp\ɂ"YK㑿׳BPϰa>\w4Qn+՜3O, qWhN L(VitˤiB`DlEPm|VK3uRd!ٽn<'l,:gLI!P:55u2xE22Q=XrϢz,̛+ZH0|ˈ]goT{4ȴ;S+TwH_/qrLO9f݊?ld]WiNP6D=e6|I>Hd3sNOV"S#kӰ["ֶx<1bIBLdPC2k 2f|D i}5_D6g>r n!J x6D^5/xsneズ'!. w&n L%]jLQ-L 1qf;4lU3Y>\~MMVrĶ7:spr ~\cS08;Ptk6 rZ #h~'Ÿ3iVLx#d̒  )9B#8^Lp ^٭B0E,©C6{ǦwﴉJLt 5<- mdFm!jAIٽ0<٩l)sF3cLNva=x66t(.qq&+:㸾]<&\cRu *) '似2"aYMPJ.̝BB#P{5>O&p>1ܾ{PAtVGs=ڃZ R\!>=CrCq&EJގS3`0 B pSpP] 3KN#n3чm`=<\FwF<иwHHwRgdY9k|qѹ*5`J5zk+}*Y#Xd>ҋଳ޸Ѵ|NSцr=)^Ɛo{|@qߗ,C0rt'di32z #8xku)_qP R6KG'nApxpY4ꁼK8J0BmiSIZWږC`]dn&b! $kp;16knKfo#PI8n9棟 җ#LjFJyShsN^Z R(r.F^~76Cnh^(r ӻEʩrA(g!Y冃O^U +*x#e,<8 WKjϳ0̣;hH[` pc6!At w>1_Ԍ4nh\\a3IV  +$r( CF @D[ 8EE"2)̎'|xB=dF*24JС#sS 8#bivhFjN Ȉ!`VhP~8?Duo=ájyJTR{y) 2 e 4Jj/xHԀNZSa7@ly .(u"!& -}&RHGȎ^|158wv #C-tUwj#w<}h>+߁7Y!Ȧb &%($'s Nf(Żx; dF3Өr,MeEgqIf3stCP3FIUI C5J$@H@ }W,&;2x:UtQNn*` R sa;OA4<r傖G-=YEDӰv4]L &Bx$ˆBˈvɀ=;߅r%:7"j9P|pdҀGǂdOH*ϭ JS{J9,>eϙRQ,mo¤Z%R.0s mb]IXk8Rqy,f4KЇ(ccWc E\#x[dɠ%Kw#nd Sf̪IN&b 8ovGZQȈr=@smߺ9ʹ=j9xΘr>HYXrqdl3zӪ)>k{hȇ>/'{92 bL,aj.y`p'/:,ʿ[aeY73rp2xs 0zz,O[ЀӠ;[|Qlw/aKg!?OF]$N|ewKd ~[q$Q&ۧ^{p{D>! Ԉ؝o$z#dg&$D $#JHgQw;i?rDsZ3}xpӤ6.T=Gziky$N\C1D`j9`.Y6k2W`2v8^wXz^8q#gr?KPItكԽj*v)|]죸#Ɂ"n<̓4dɹd5t$75Ȏq1t\NhKovc>iBx\mͳ4֚cy3B-a$ݵo} E֌LyUQ x~3 arlԎ6>ׄ@`-$Bqbn5 >M"|=]EӕFXl1d8pMJ܄1RQt'_tDD)!4-c鉉@Y'E&Hl:HDpt+>H&4'wSeGJzO1N2D'H(5CJo"r|ϮU0Ԁi  PhH % CyR/+!@NH`q'U'DE(Tx(m)-DUULU$DSED&1AJ-UU5AQTSTIJ2PT\dFd(*""%*%h!(&*b")ZH,FT) Aʠf.DQ] LG(*L, eϾ bdС!ps(n$|@h$\vC2.zo&,dJ *PTJa;λz Jw ΁AJ4R0mJ^`X.!ө "i8[\``#0JqdVH!PR}2lFNQ"4#NeAx 08<$ q5!RS\'SGOԙ.>bQor$*@CL3xAc>8+zP h@-5Pzc{7L(hH (M~} R$_ύ%I_a량:s@ȀsEqrI IvtT71a#KG86OMO4D`5{ʇ:A(a;%4@!pRjj#ghg7d8hb*CC?hLrIC{^HtB G*=?dmm.*+XMc:qp8Ԭ"; 4rb~"SlSB t䒢@(( Dq.Y)X (B$t& Mbb hḢ!zq<p3ʻ0D0AR0]6.. =]I7"" 5'o_MMLgȈ2725m`T۹?!td"(u<,L$OqǾB{£E(Eـ %C! |p(n% "lBH!0@#8dDPU4aA(U̾M(U'@={Kޜ[/?zrC= fiUf bb =@,+9,Ir+1?ܛ݀c I(0Q*y&s^^wȏVK݊(/{2b7 7zlB(\C]Cm H4)oP=SMO)&EhB ͦXĀxH |:Ttt֓}lOTB >Ny.JaմQ`HT6fWz!! HD94 H'F'x~0w#*D*R)E K4^pGWיu|8S\o)N#,|BD?1*)`2NcφS@2bnN2hv–@! 4J4>M)!Ŭ౤0*"]x⬠#"v}@{`}aL@X"SxC]pHB/-"#z^F>91A&"=@[y ~0DQ@LU>LC Ci@U%iHB@& L@+$9)t'CQW@""h9 r Tc"-Ǚ0 !uL>HQ!Nnp9a9OE?; MyS5`N0?a)դ?g8В'V_[1h r(/yi )*p]  U2 #(h]| ᄍ yx8WEX9{ H>>l]!B&>ͷn&B|TO` D?ùoGetz=,|`Bev֣Aab}`ixxX3<_ۂ>ӂB':[s*bߓҚB>(#g,"4\."*j[fvABiX?8SBb` 82d\2F-FAFS!C(B"08 pp<`D `HZ4ǐG- Ӓ0 $$I*DT!H LGcxUQ39`!q?o)(2M1$KjxObS?joƨnhhhb֠jJ9ǵ>j%D Ub$rx,G7 $h` 4S|rkf[0k~_۳Dsˉ֮|Ф 5ά Šp9^^R &{@ߙL @o,DHJ95K {C݀Rȋ !llۤM?cc0 Ü@{O= >|?fA `(bXmc!A9SDzDUè #^qNsqO!tRG8p<@# a?6L*H&( m,>@Ew$o+Yvo>1-3i1\1BMH:yM:ZtWE+ P0$ _!M*8 *D.# COPIvF̫aILF` K2t<-hҌBE-c'1G' 8N`mH,A2Lbu@6 8$)m2)1$HD#V:(C|x ԥ!Ѡf䥣J"&4tX4;DADp:TŢ(h4:Bb.BjcDE-"&4_HJ!B' =CO!22`4ff3 otC[9)U5 a&X"YbX"%h Jm J]^/ި>?gF"3 CR ԧH HF?͡Ԙu$U 2U$@4IPP3IA 5APBEQ *D40AHHA T54#@-#SDĭDPDM+Jq](E#A8P$iZx $0(>TԎWX8tz˫ fHx^S0EU(JcM NuqbuЌ4HD}Sϳ e"Pp<''΁.2 \yE3 CC8|+e6LBnB >ˆD@/8 /ydX9<@~sGF_(IгUҀQЀ\O\#I+^Gq80D$OO(uH{ ?XGj]g"`V?$2/K2aR$x@!X%մ)YxWJD)@BB V"X@"Q(F&IBb*$Fdh@hH" T) ##co8#hspNSpxxrp18ZQTq&a;'Cl5XbH ` BN)i1H " ˠm4/`9ȚJ( *T4<<XITB_9qd'U H*p*2E) _~,*L< :)D 4'`y pA M Ą8{p>)*!@dF^ J/50nm܂/z>P5%! z]G@N zN&$S\ Z)nślAFTBPrIʁ7O9 qsӨ] HlBQfP4>C/0`Fq+Q$0qA4P JX rC]+~4&˅f V^PjUz8ۇlO >[8 !̴~R J a"r[xƽ{'_0sx0խb9kZ(%43,!W~G34H|@h:4z}tDo"HR&dN$ЧP_^ >:IHiTTԱFuSJEygbE f @z>%D_dI#CcRT?E)hHd4Ԅ>">,JUp*HU+\Ca_zQa%3h<^: $E!%3n}īϷyOAou'}xN09'+'s}L|0Ot|(@4QTLJQJJ?E#Z4?fcQBs 8J gKU,i n% ?SE?B$)#tVGft&{ (D+&5Q=D= O˲3 +п)g?dT@$x2I)ζOMO7?)~]y3j/Լ;&fx+kĔ^M[k18UZ՜ʸ?L8u#e5Dz|ILcYRGYs7üd#$GٓmlcJr76fo':pB{޴h(pi[EG=Xdl! b !$HU8(@$|;ޞ<blg>h*hD+u~ ~y?%]S[]`2PC ZFTTG @ȗ`o!f77/88>Ulp!mC&9+ҧy (SP$GT%}-~KtI§@1›J:  TbHa (; r 8u'g]AxS L=DCD"Д$BR_&lcB4DBpIM--DJ+-"(PLH$PD@SKBJ4EKC( 5%CBNrv6ً? x(?>#Ig*:× YD4!C%Tt9zu CͻC+8r^h"vC3`LE TR ? s~^,)Sk؅$;"BP@0{d`SIpxIb` `b ;=&HHC)3Bft^4' $!&n*JB ,DQS-Â5'$Ԡ !dZKJ L kADc(1QJPb|>7YRCf1!jy!(v@l)B}S0C b1 6L5ŋ`,h7>wEbd /O:`" o_tM8r}! &m'O4e8q qN!VSsHji[;BGYeb!,7Fy@dʔH80, C|-N@G/`5&HD-ݳKk%St62q?u{!_]Sozhz+Elj#UEI\8|2/%؊̜1xT8\yi~GCGvBB/h XJ`iD>@}D$ 7(hpOVUdۗ& h v´}59I@v{L @6HQNh{ 38Bn.5K'\P8R<ģJ 6tH HAibH" &HYH( (H! & &i !R#ɏ]0Zr5/"2y(1=vP:[_;qSiC Q׍\ҷ>!Ab>`y06ށ<& eB%*M)BR%- pSFl(v51y6=Uc LO,ELɍm) DDG|(3#zᓳF Ԝ^q;&4Dt&BE^ ]X$cL:8Xhs@ "bv0814:8j# H{=-M'TPi1XV h0`x%G{F #9ҺU\Sc7U^5Cwi JH"ol1Ptu `B0fP$b1*X,,Ud7xpxR ض"tRl;'us !hX54l}vJPD F6o N +׃ g(—9)Ji@qCTu')!i,d h/`L s%>ljLjSA&F`X,gÜ-\E'%Xu "Ci/~0X12s'j=;+.rdO$i^mh&"S05I415cH !Vҁ;M9昂BGJ!lW0A &7`(ZT DytZ!4_0< V1ys2r#JaO 6t!œ= dxC9 jY)e&rq@;' х0>I'"2E Y:g5Gt䮁(ZSh6:(7>!crP"D;dt,r916 a]AC5>./-Dӊ L-Qp{5bִR:0f(Ҁ 5j2bS"`ểWQIM /ǬO EFiJ8FXQ sjbE8{8vHT8GPHA<9 SEU0T11A ,hxJ+K3LY .r x (C {,}D\ % nõa"P(o!ݞ8#b nsB""vzÁ9'BQ̔jm I :2J)MJ rtT<S({!S )8O Kbix<=y2J"I+`1dT3N\RW M144( n@@SweJDwL^ZAB@hu<5qMӜ"w9[7*D )[gYz&U PNxUH[s "#h!!Cˡb6ێmG`o=_z~;GөL!"f'C;ʯ0QfAXlcQJ yp٘@|hwNt(1 jAI*wb=J9ЩhJ"te#I o_AE_z;)_vL>A ;O v-OP 4}(xоqE$\4d-X2ꪊ)xU M1twLX7y:;.b8z d,;>  v7)-mnm1tߘjƉ5@`l>2~`Ԟ`rϨ܀ d7y='PA[(ILDPLD5BTҔKAI5M:%Y ᎈaLkAF`h `h̲q[f9b$@ `'$$$%HXBA)U-v${T݄p6 J ^"_K\m0DH!%:E |B4II͢TijH!1 DD(@)Q/e@ȌJP@'Y4=T坓/9a!z@P.< 9=sPxc Lzi) ܟD'\D0>ԇ.(Oy>R ƓM>X:I3py@E ia ysuxAq 'Np9RNptRh"ѷ"-r_'N\҇O rP pF3;C*P,DC‚p|!Q0JLĩ0- ,| h B$ĉ 6Ah4:`A&g :1 bZ)Zq;*P~KdC J%C&@uNRv}@1VCl)#N)B'Iߗf`w| 5]:A% : quMH6B8ރiVr&.S*Pg$+Q yxqvF݋LGVH(@`PÕuiro֐;{ ǝ Ei sxff1Jd%^I\A $M _U+a )8Hm&fȯ=JkGᣱg 7[csELntP7@K 1T#<0EN\M9g&C;x2GD'78f(arBD{&9!`~ljISxA[i$~ yL  I/'0q0RQ ,\*GiCB?SQ9I`Q5Gx<{=:x |O{/I`wPPƓDx*Dh)3Ry ^q`@O?q;yTg!WmZ&! R@(jIf* H6Lork#1)r B Xf!j2袊7 LHd*$eS$(!1$VVÚf1 $Ey<3AQC@PIZBCT PE)@ J>h~w>z!M1O>Bn qdHf 9DYWX\I b_փ FT ,21 U#DplC b( ̑[xdX9)\|N 5% KATPD:yT ,Aa"HtIe z!ؐ0"iH3h4NSABءdȡ@ >C+&PJ"Raҽ?nR}YJ(47;Ҥ# J?8 AL5kna  3@P":uEK ƕrECg;HSymo[p' x`?OUү;}ִ00]omlۃ gۧD(JH|m4S,SțHD;ӯ0 >c *0: <V|06?e#(jYQpkBHٿDAvG^ww9gBP1BĴT!Q1*ABq0L$Q d 8T &J*!nG_:1o<>X25R0-Ȅ0 q4f9psN&B ,Hf-DgnO en825@AP]0(;܋3"&B?vQRkbD(D_J>qԵ'n=OzRAXц>vVZlmK":(kޗL¨؉!)pOpz >(m3O}@I}}hlQ 4=.?>s+vDT2$LA Oי<\t?t?([LD7R։$uEKy*\ֲ\ ̶+( 4L-t"xJ癠H<4PHIPȜ-%bRHN^sG CҀ2fI*z=vz``NG]\qEH A&N]jN2zS>w::k\X &D!+  (B0J]Lyz9F Gwć$Ieh!&$ha(Sxlp8ߏan="UzP`c0eM8 8 i+IX"tU\SpdgHrB~s ȞHUƪ* H2{RgB8 1"i,]T6 x>. $Ǭ1 Wp%L@:C2xtnfy#I4^z$޷8AJs:gtpbq>t"G3 6?/q P@b)VJb$st0dNpù f&)HMO3 ?SyYFǂ+Iȅˈ$eh`aP!A#sf؉>dv=GDI[P!P6PfuڰJs fq(H Lr8t"pD9*@{CmHEHBO0Hp8Ѣے} $!1B0y@D89G =Fb'X㱠w^"%;:n[,(0 :@;iQbMqb0w躐'@w: PM#L#h{SUTAFA'"EZO@k4#FqmWYTlLdZ0 EN)pi;gS!4^YwSta |  ̘9 4xx|pDCc ֋6b⍪ŅJg) ;{6Mo`&nbcPPxpAq87Dvey*'}9zR'S &d֝& @hHpmblEiBek&&҉qХx2%8:ScCQh"*15] %T a9%`EuPxcs;pG3c F+zYƜCp0́&_p4yrr=CR>*&:|tϨҮ "}t }O0xE <JCIR-(Q6KHro`d Pi49%!gox?<v2:bc a9ˉ%!>&X[P OIO!,a2>*b?eкg4ȸf )܌< }۰TU(lk"2@-X LG=IlaHGŸ,S ¾B8#yYR(#F4Lo&J?4= hHҚh AH(UĈw - T* r \JLTL4 #8hAt9pJ\ rJA?/׸ ĵ18/eJ9D4WNnvȜ9Jz##Jf F$*h ЍQ0@LPWHblhipWêzr }d!q0Ș ,~OsBԷT2AWyG;C\-cCJ@aabbsdIV! &e I9B**@dA0C!r;C]21>\E$Z FV b2 Qio'j E3CeO(+Bf!˹kЃX]"y:dq$ ܣ&<|д32R:9<*6)! +'P R%P!(ҚJ H, BFO,P2{ex pFA&=c<@n]^%iR{w f`4Ox1LU (yxYH^d@H}eiLA8!OZW3Sv(tE<` <aHDžCHI #AAI@B-PL)baCM$@1Q2ۆ0}<< rH<#éHn bJbfzGr󂸑8 `28Cș^BR8Ci EK3̮!e)M)c`t Gp!G"\n`ġ1!!X(P^+ !1IE@=&PCNBt4`TR&V%R 7t #%tg*yJzH WCՠ6#1u\$x*p(]V L` *ӡ JI/%!IࠑqIOUGB6OT~ "rB_(B;CЇI,JBoia؍~L]䟖z^1v=tߢJE$<4C߻%^ዩ9:n @E:I8Kr[ k4r ulMk)aOXyF`'4s`VL\N "Ȧ H EHR?t=)&64Mۈsq8hwZnLH<ODTQK:V*A)N |$93FD܋Q)ԝ`[DvYp0J5_@c,zb <*16h U*MiW#y>Jfvӧ1O;'J %?܍kA9$~:#Wp0bdG @>e VSa* W $;y et&}̀vTtןXPh?"C#bFwuÊp"S`A.H@`!3PLF&?jәr,FoVxLMgTD)w$K{|@pE!pT } Gҁ~?լaO>Hd |!f4>X9\!StU; {MT- (E"QR%|*2 Q> >Os0n)t;f ÄB.ZXcfS!b6@I) -M-KE4L5!qHiۅ- 3!2@你 :'R/ZrE FL2D}|<<@BB@>M@TԨPW&_+=cAoj_MۣX?[\A) EV=l_R}!# Na*vI`1`c [:8D_"g#% 'V:}b@X*"XSu"$JB &f$j @`D8T JtHy@N)@8?)  q JA0l28`ypaA$J(s¦H-A5BDT(I1RL(  *@*J2+ 12H00*@BP@PĜ=.2C/c"Q C"8iP&VVB0.U2[`r?8=d$fEJb;)_O{IE"!*ttp I "b(FH")W zl!AA aP4M@P0@Rj &HaJ(@>]?|;qʦT~#A/y*daD'}@"! d$s`efC#t)'s '(8n(bCcÐt"'`z @`6`}Qhn)C)Uz ^e&cZ!Q @$LIı ) U0 !PBĀLD"B" @@7 p9[(Dr[aSGQh@h@N7$vbr MD4@A"Q:Iw\x%d FwPЪDHc㺟R:iyFs"`l(tR O6нAfSJv?<0 "q2$@).vbU@Ǽ/ {=1"*;aeSu]!qex>!> ǘC| W?daEtu7DH@CPB3$$ "5}+2 6ԒXY2d#btn3L%YQȳ 77PT=dd R7rYH1ȇ*>rb9CxYH h"#lkp FH= _(씭/= ` dn&qR dKd^ORӪDNp1< 3-S% ]sc1a & "B'dnAqJ1DN9'wy2D<"vIxBد`Gx;`9C#: ɖl(ptʑf@ҥ\./Ԡy<;h=,p '&!)%w(?('JQ* #wVT6gyx]}yʐB MM"%D'E NĨHr=\~= A%)$J"B)02HPIAAI @LKI4$JD,A;"a<%S!BAILCPP1TU$U$E*JKA_#&Y4PD݋O=p%*PzIڀ{m!clAEIO&e %~РGL8=RFYt)x4P7"ҁOŢ$ I M!aFe57 r:ӛR>zX'/4R1QCT  .B(~bi X5nX@eϏ$"Q WH1' ҹNIohc0"&`:ZHݘ  Q"ǐ7FA6FkU߻;o$"^F>  r B1=$xQ=yL,pL14 bX٧M$ T1b 1>7OFrĊK} 6(xK%;:(:!I8ح <ΩI*"Β6lr-bb^<#Ʉc,끏>^0; @|ҤQdPԔ4]ƥz*R$4y0XP )hnPpS׳k98TYdȩha@` ,ЌطJ c#F&C-<8Rr)Ѓ/Pplc1o0`3FC =! 4Z)-jR#G 5\66U$ff sU(i{UM:MUDh@ =(&!yXHBl p? iZ;AA <'@B\9J`eś L2ʞNyJ\ب|EC祊`$&H9sz<£ x(!\$n(%NbAF"J'AB3 8P<# A1HZzT2LF ^d };~3M|40C`31)Oy>r0,ḱp(O{  !j! qЪQ;rKOrTCaL D8"0c@jJ։# %w0~"$ CЈT{2G!& BcoԇҞF0ʑlTD 1D@sNAqSS':wIq=\f;ADe$nH밼f2߲~|zpbR$XX n.7xQ0jM7eѾɰv9',6Oe_HP}_سT9?ΔH&0#B,ADwX1 jA#lձ],FLN8`eq] h)gxi@J ؘ?m,q󫰫މ\ Z& z2B??4WQ9W:(bp&2LH"rǠӞb-PC `%J<E2: 쐉 9h ؟$Zd |#;1}90IF6"/O9Hp :@c1cHUv  @) ҤO6NNT(U*v<~R^xI BkBG%߆Һb~U$s wGV r'2팔 &dЇ_ʇa9>! s|sysn b?Y=# ۓ8A!$|Z?&$_2$_1eI&& .1EƵE i-ģzC`A%'o T@P1C0(%nʿj%#l@JD@4M1T5lESCAJ0JA# 4R4D%D4+L0bCII ! 152JH -!( EHC`qF""hbY %$9bY4SLC"cI&鈒,TgccRhb6ɣƦfh (H4E<^)Èl`* fd᠓9) 3Xm.hZ"H98X FIa(B((ijY tĒxNwbh6\C1D,L C !c*7lQ"b" |CC0RQr\R,@h\M k㘒B*BAe5.UQ0D$JI{PB>jM$!eJf(3&Ѭib211C 804IZ LF~'nȇ Vt4dӠkDB'BS rB xc,u}DׄY"bAf #b3<ÈQe pEA 2k )FmbmybH3c5I4PÄAMS゛i%aFltvdB S*I?T@?@1 tbͶu,'볡,>hk@q6Ua |R4QTny1 s \P?+I@DDLC@J)" T"@ RIH怈at˥9/Ha`"9"_abt`9GeVe$_814Ki"5oW; L^fB{|+ a$1*aHT) bRLn a͋Pt%Cɢ(e&KZFU%e-M"!CEI!VY50\,q*ġҚO4Qzx7=J .:YC0?]3>7 qCuA 9^]x^l)j(z#$Q|]ZPX"M>: <<8UD$9k &dqt(ESIKKm&ýG9nA%Bsljڎ8(ЎLFld,dD$駥VCqadrG;r"&q9 QT*p2 `Q)T y?"0iS5'K !wІ?4P!s$4QNƠȿ25PS "),@\%4 @DCѕ2#( 4D <*,%O=8 B@ D4**%!HP@b)(y$pr )ļ\TRpx^k$MJ )M"vP";!6=_:LT$DAAD!AI JD($D)b "TrPC5t0Mš^C *t~T"g Д% $@ BQBY@҅E` AB2`R5 OD:v(e(8gnkE5CW/,C x 5į2#`}-"%/;n! ټx&W1 ~=Wm8fm]ROyj:i/G^ẗ́Fr1={t@R}<+癯7m *!#'p~.7VlI8g5?g\:  ЇK5_<ryc ik!pfР@)!"a>5ȲL=tT&ZU,.@3Bf4iD M ddģ+ ֫}9W7C"rْdpt rϽ`rڿ "| % n4^KeG6\ !zlV/ˣł5\!@hc|2L!)7wJuG%!g2$001k 6mXaҸ6py'Mb)8F ~ _~@Уׇ Yc@"InwB4]PO?['eTk5=t_y%o8U5z~mqzBu_ԟ~7]x֗~$;Z%G2 WC؆Eeagִ h슭}B5XLWc|^f"/N8yvfOςͲ}_gj!0s_0m2/Xyd*La0$+Lh82ڄrhM<$оgۋim ӷNfi8ki WG|4 ər'8T^ObdFUQW=4M5HM<3Y3(A1;a715o(N՛^5|?]m7=H;k ^VҞ;?r1oU1q D}kvw׏TF)f6pz*0Da3\)APwvXJ3D 4ZlXڂ7/gpzLw~RUgf: 3;~ݏ+`Pntyu?$_Jn (̘MS^m%\c3NkM~M.T`9uN#nվ%کuԽS$׼ hKh6>._tnQ뤑ŤݮKXCJiA1GPnK&M[@'O9IDLۣY?%mo.s/"L,bc1!biUauԊe %@`fgzGSC=oH4 @ _y/oFv1)(җoKqSTCCea:'*WCf!,fd<pod)60pmk1SݏѮSU& P&"Iu'%B9+˧f`ip p\' NӚ3),b0!91SNyMH00?+\$.O2$hDE1g 4LB|c")j*izy <wtMg'٣Oq$& B{wV)|:u"O>9Nb9U)#GG&sUq8Da8\#ppvXrMx1ѪY!A@i@d9AF8+ə1 F Y!=ǞΠ<鎒 xS1[QBhGS!lKʷRYKɋ*HdM; ך>YG:z<$ Lm F`B>'{وBժif|YH_O!J4}$M)50Dt9I,alHPh# 4AlHrF8Oa;v I xq XO׀T)ud$!>)>.LkC'Gv!B@A6!HRU(W0l=@+wD!biN =ی7Iz9yy O 堯,0P$ Džf8%7 QL,ed!E"RCPSU|m!_d)Xр4{ks IYJ(؉?D_7IrDDI$L_ [E-C#7JNa&<rWC3di msbu/E`SÐM9G|Lߛ>Q"$:M^S #`NtmJI哼0]19Cy h|I9sQ9:&AE@C=l@^p!;A នHv@5ԐC yOd1 GI8piT) fhLfJCܗJOZ(ׂ}:k*  C1'-Z{p8>ΤmkA )seƈ8eœ #68ŴbtsU ;!U+E50̚8t 8qmRcoxeȦX!":)G  L&2UQA: ,^<:ؗ4`6MԆ_SE`m&\q4[kx%xo``D4@⧄z5E  c}L]J0t:WD1D܋C8<;9J kؔxy$$^0E3mVUd=L)hBa&ݘ9{%:=Wam6QaϫDtQ;:ba&d2P%)d)CH"XbZ` OFƒ!B$~hjHX“A"rL'""!'fM0FsFKmd$"SNZ}X?ˑ}?) PJ 0DdJi1fb UPzְvH3!#5K@B* uQIP%Z6წO$ąbL3BR#=7 CAn<{}J}&) */TDUq=4%}n}O%;R6CQM*BkYV]0yHQK0 @ LO~e1Lu:"1Ĩ9rWN~h~XJa =^B=~PHpyu |:w';_(.ί+NI%CDB?D]b0 QaI>XA@]*RTC 6b$f)y4nRy fz9pV5m&M4C9)fZHQWS zKA(`C,iN`I#l: ",B-D'I9"QB3#0pJ]_|5-]z? L}>D~]/K (3:2 551`%J! b$Ts@GF-1nL;%xhnƊދ3/4 E9Tv)_p!{/:${OBjSx2LhrD ڐ& Q]/C}9_%cxCYJEo37Y+NFnD Ey8ZO#-OՒ'~7OQҰɒ+ZE;>k4 !_ w/(Il\8y]Kޠ!&8՚~|i5~~d@"f ! Q$@"N'hڝ̝?Fl)e9[Ay0A@Chlx|(W޾C㦹rtEy5:~󎍃&iˁ 3"]N 1Sǎt'wi h2H.Lh "`J7,Q\boVu|w`h:$:satXq)"ވgW}g/Fi4'')9Ǻ87,rCw,zgў8񰞂 =k2\&d-t9QX ۳~y:X۰vTpNBgrDcDasd[k@^6A&#yzߢP;J}!K `FJ\!\2V@by#,ld 6ƙ`P(2QTck@͸wʄj fo 3@3i]9fbS pIލĪ@t^c54J]\~Xgߍs̳j0A8`nBAh'zЯitH!uF=tpvQ3caPHcȴg:Xi'ު¬x#6PMz֧]4nl^7 ws[P(J^Y,mа!7yS MқZkd~Ql}g!l9}E QTӾ:4tqFXn\3Sx;.b6W[M$aiaP^Z 9t;+u[diʶKֱ0=aFd[phfpisgflĖu&cDjN:[.=V6F9WrQGo /-sG0IdS1qIGǢ2jiB N!6 [RQc׉6pVDGN<¯͹C4XoY#g}Qb4ᨠZUUZ"Ba! }6{wB<Ź#K5yTfJbIL-ѡz1v%qshhbXvS9 8;ejs~8fGIe!Ry Z7Q0 d9!}"GM9h DoIx1v%C]zo0b0f 0 annF10!f5 v7Wd I h(vvC4j3w{ettϊ1 k!kApf\݆Ih @[[̥fm [)NW t;bx4\&#A(:VX$@&]7šAJ2yXkH\܋rTgL&Dá7"Z%K q1 !::Adf.n9.3*LXR-su!e< fߊi65plM)a֦w<[d8.hﴧ`i~g":#>+ s-FyblKD+Dh&;Vw5,gd`rƇlP%hM.ic,4e(Q\ZHH$K[Ch! )H(g jjK G/0]chjiE4R^ @h9 -. lüZS5511""Zt҇MD؈!c m "(%} P-(R 2Ot?%RKFliְaH1B7!0@] j8э`697P840rUL2][k c$c-bwa4ֹZ$RTAz]!ㅎ0[sA{f#Ӷ \w!A.1cnsG4l$<$g[c,ōm)FvW8xlj±,Pb 8ȹpOPGcc\ab mj;C*ѯm1gj-~ [6pT1ߋWB\++r[OsehYZF @`Bc͗5:ЖoZi ͖ 2 ZEN^?4ֆFhm*qm(qָ "k )x'3ae_#>Kr+(F Ņ/D&,*l1[=;mb;l) N˘a93P ے%d5uq"6, q #}R6{W6ZvQL8 6,sW` T:9!$pR!J8@!i}sRH4Q.BA{ '*D|15|,3"GYjl5S@PEeBdYNd.SЄ cу8D&N ˉЂ]@iKLXYXьlK1H\ F9jTsù+LkuU!Z^°K ˲Elq YOSϖPѲvn M% @ đ cQT>cѕ-1d]qaIq=}N/FX`I<-wHF&4Q&mC&p%_~4b{aD@)K(OhP]N}2 !OyG%P)9HP.f`3sETd⧅GO=k ~B*9@a$4BA>6{ă-Ot+9zNeѦ)<@bP P^.0p(7đhL}DOAx&|34f#4H J4ҭ Q+]o(*BBdЂ79< rhC~$/矯0/;*v P;(&WkA#Q^BDGՐ 4e0@/ _\ (@?I^ ph}B ȟ88J4PGĢhT(}@P))>$R#B#|d0t IdrJO7(Q(To[U>$ U !@r5 P#T(S<(`a dw^ ,SG:o'W˽ȝ0M1+ I45`{AM2D(;ny6TCt)UQ CU~}ץO^HGpW;'b<y/݀vz(wSCѽ 21J@m{ ~6w0%:S A,%I#A]0"ly;'۔,XAӶ߸fC5|Pc !u`=N0{DWg.C>m<cG75ީ4mjHtaΙu2,K,fε8c fqrRfs 5DY_@, ]7 }u$E`-|_#blHo8wM_8z`HQ- 6IB,k]as#cp%,jmjK!<2Sh-2xI|ʞB(C(L;pxN51̺ 8m-lwG^(F0L p^ QdWZ޵o Ga܃(s DA-!@{͈#Y",Dٷ<;#1/mc<8"&&ђyHh b F+G63r#4j<ۆ,p-'O/8qA˄WlAq#&t#i;!ޣrE)ZDd*)B!rWiii J2'AGd #(4 }S(E6!dT (VꄟE=1\D f#(8(yL$WH*4} 1)iFt&O$Nr |9Z@ ZZh uD@PkI:4%( R#c۠<Y& ]C~mVC/%]#R` *h""PDʑ7LL{>NFчu1M{qOE%*_nvZ(4BAY.*tIIH?88 1CHJs,P)|-SBu*H O $=Ȃ,J))UC_   <|PО`s)1'+ A1!:ʍ*P+>(0 h;ˆ1#H> HYl>Ʀ-eY+a.-xoahnL@35l†z^\,FV8ظM<Xc20FH#0\ٛ"ٔ, 3¯iI9nJ7nM2' PiRxLgVZ|7790.f0k#o! f&Z2;W.%^H 䡊5Cᇑ#S AT"FGc -*NxQܼVf!$d%)TZ;@('bPDy!@^mo*EidNc*6ΐÌIp@JED!PUtF|. &]Ҩ.uC}q' : QirN.2&'vSm6a^yHYqERQ!$_[SU; " Y?s-C 3AղqZm!U0ʪԒ9ǧN^< BM'/sR50D,`&(ՅMIAAa6Dl%oPcGhL^B<Ќ(>G0< D  |5n1 v#5etAK8DCHo @3?`dvT<T|5)k>5 ($JQP X@ {0Fr!يk d0~w1 I/0 8f%{01^Z q\NH:y*h)ޯ!Bd.J#)r\IU,AD KE:("2?RaPMXHHF"jh%|]H iTbA ΢v5μ̴*n(0204 4 JE)HAMKE,(A$JR(?X{}tHHȿ"8hy;@@B'G c!;|Hq   xCu;PL<'0D^2ю(]f,_ 4a GV8bcp5ܨRqADЅD"M!1PKRJ%'T~S/u0P@H]F`sҠbb`p# x#Y#A&A3}Ly

MQJcw! :ӈa02^Uˬ[MoC%M*l5nj]GXzh)'#ߌZfi@PP=)Cv2prWE9;Ӎ}O sg8ܴCjͭ-4O zqW7i<(r^,:R^Dp&=]A:+!}K_ =ڍ.@|}#MFaL~KKe---džEOݣWkǹܝn;ɡeɷٕ==ϟC[7JhP;+EP֪ ѿpO2e_9߽0 ~4 !f{=}'||zy(>Ӈr"ىᩭ2 12<.40yNNY+D$~'o>޴>o<$|`jb>TJ>JRk憏3>#ӵ6F 7VV۳U>xd1nk3ך&6Hht;gք}^Ľ{7`Yuu5eC宮zq:Ͽh[hqkPv6ӈ`\ )æy+&㟮\͔~aq,B@M GS=;Gz+p}w`Rȟ!րi(Pg_X9^!")=_/)ȏ#b2Wlu>uu=n53S+ϖ}ɧ@NkQ׏|?V쪧òLyHz߽uƞ2gs{nd8xsooxbpyk=Xz"AQA p$BA 1BgITD@x$g`hxz22P8FeG"f?~$ZuEckˊW9>~N8a9G]̛/^ٯK/}YZ0_ xd-ZXn=7Tݎ{YCzCP^2*GJGؘσ }`3ɹ2 2?˧}}FS?g30psi9U~ULެ7W}FYweG<7x?<\8O}hJ]L]Cŷw9gyPq?+(21~̼=%[fxC1 'XAzzfozM2)NMӰEFʻ7n3ޙZ剾\U{QI^A@ЀR>p>4+In|e,^ !zIQBϻ>G 7>@4P&bu% {חk_CດϊhOMz yib/FKn'SeX6&|a/oNj>5|szQ|*Sq\_0=^,e%-x>ɼNl#g(& żꩀ~{#Il(_w#pY$C%f#5 PDaNAOX>GċuMp޸Affln*N-f%\/**OgxYWt~1#  OEl"r9-v>|yHs&.Ynz txXwC˧}}-)`=[} ;c@{h١}30\hHw pfbUK'<i+Ls}哥BW[K}wn"y^b'~8(?;/Y`^멹89,7۞78Ԇ\E$AE7>Gj("!R'ٕ$H74oJ t>G40ƹ2rQ@`C M232zxc0ahk3 fGo,OW p7wIjfln}_%H̎'( o_p{Ӣ')ZLF<(~p&YVkk^6B]'a30oHIJф\cq%q9{cᤂﭗE)K9F2 7}׊G$Mr׹7GrS!6Z+}+"O`7p,;̣!–~҈[xH3zY햎-B$408~U|vOMd O`Kc[R'90MHGGqixp#f0?2~a,]W~ =K8nٳ] L>HSo| Sxc9U[ͬc眍Dr<̑o%î'|{R?hmn=j{|CW[DZ˒@Z>xtOaX`S5b$i5?6 N&[[6pv+. P1,1|5i= Π2MQ~h> 3g-/i&,Vq- tc7A);׾ϰ|Z;4y*KO&2%dؙmb5<]#Ot$#:a63x\z7[N~S5J+eCNFc3mf>=2tPMwSXiطCO;k43zAH$iVȻe!)^%? IPf=\)}52R'{uq'-)ƴ}rz42CGY|f}!ABܫʱpўf=<(;t^9{P~ԆF#b{۞q/,IϺQڐw}xh^/ &Qߟ#\Ӏ??zOf 04 3  ote \ď'Ӥ".E+yq\Cyy^d rgp(gw*Ģp(ZՄS)kV *_~oUmZ,Z3g-Vgѯll=[xlύhѤDӾr34~ YuG٩ W#fSsD; &]3qi]≝v{i*C},h^EL#!ZĈ!P"W#XM#)z^t_^G;.ɻNUY#P&~3nE4NFf%?HQ̨2PAHE%!Q͠~Cgm afc~V^7-ǥ2K0{l6xeAm8y׺eכ4)Pye[kSߣW<@o=>Cp4,:JNJK} A>InWc>T*WBpvgȕhhZxߊ &6}h?+>#üUlB=>@)8|Z ٙX%TR;%!HWs"g~QH2U%[]hi(_iM]!Z1s}' Ż22mne1 z2N;ڛ_Gq2a BQ.@& l__mm7Ws|kY41Ŵ_<}g:ÉJD"gatTY$%*}R`sz]_/ڹ1@glfF Ÿg;JI|{g? 2s6Cq 'H?}n""Y%'ln`nu.J}ܴ7i6NFR)ͻiϪlV.ju͖7[F6kZpMz1ޭ DO_Owy+SrQB j[O 5,έ5o0~-`!!0 A|pdTJ}zZrb(GY<(\}l`$yȣ=s7I> /c@Oañ 5Q_f/ :h>M}oGք(N`eR(u aNo}BPRvHУMoəܝv^s^}7Y/ϻ X;587qܮevZg56껵qҦ?>}f;'|дLgypxơiw`4xzocJirywޕ׹M==0d@{rAwA4}w2 8RNJ{9I (M_0f7e@)xt5$t$9ik.~[30ਯಪ 2L? :5oȻ*"QcȬs<8k4hƮeN[iۃ2]`w&WἍNk#zDsJ7߾|8{Z=C:OiWL#dg-rަ°Dl5"MYj7D(_D{6G`>ΤQ$j~T-~-sUo.lK_C0m9W"(նEWf`k'pq3R֑w]1^R)4}쩮<$$vֲ7EGaN3@>[a3&+*T(%Q J)IEUAPJUERE_sz]n`+TSޅT")QBT$PRB*)E*TPP%%JQTTRRU%H*JJ$**P)UB%P!J*BJRTU(JU(A")RJQRD %UD)$w*NwÞRBRlֵoq `㭯Az ˇpavvu T)TRE4#.;R{݆^7r0]n_":%wP*TPQS` $e{ǣmz8.n.p&;_D_ERI)J cx67`;ӑ۽Nܧp·p IJ"PY׵Jk[mBʒT$HM@Q[ӏ MŹgp#ܾ=qncfOR.;HUTJhLحsx2<\cs=&y;Q$XZDU*BP4aÝiÉ;ws$S3JT *R P@ iZ i5Cc}{Ž{Ŝ{8#[ԃdʕTc|y!UJ%ThֲOãzzzx07W\8ǣN84%PB.@ʕ SBR&&)Q$U10 I*E6=!!VT*mE@m-J]%bX~ s] ].؈tNs{ɫǪ1jeRFi3J7{{XE)ewmݹWCQfk.kک1%wL RĩiC#DC-\uˢ͕bu\*>ֱlgv􎙧2ıWAIS5ݫs6VTVѶ&[&eٮH2kJclWVTdi&R" 7;S`TRLmbEuW[KMLWkrU2*%vkt@đݮڂ6nMDu:+fmJUr[Qk(vZ*m)i,ZF&ּ̕yrD@ ,062 2TL٦]e-)Q++lJݖ66iz:f)Rf*"&MqoBMq]78R\"r&ٝ7!IZ'twJ0ę\9q]YPRA0i5R(\^ktMh'unޮ%+ EL1ױw];utwWPME2DAQJwgnnt5˭FQq$M)ֽK׶t\]m.M$6l^FmzmL4]:6JSkgw\g^nҕC0̴ # ނl\[꥖fi2͕uY`S,rRܮ]m˷v޴d]um]]L۫vf"Jݭh4mVU^RBu13FZ"D4XJP0Y@h(X(FtF V)PЄ(jCBh"Ā4ԠĠR)@hjҠL)J.]BR ҍ*!@wjXDJ @4h\RJT (LSZE@H X(.RVZAHJR(D*"hIҫ@ B !HBAD " : BPҊĪ%")i@[BR QD)ɶ+V24=IV5bjŢ7Z֍Xi5Xgnۖ UV(W:j50DQEQɋ;]377KrrMclsVFnΔs]уi6Mi"uv\nٸ;S.e9vO7fkMK3$&f̳M[.uw]&Rfwtu}{Z H@JRe)b']ۣn]M#O_ImV)Qm%1NL na5VX*XVPj\AMґ/kNI﷾}DZErc˨KwW1;p/=y{ط+w]^sc(QZVڃmEE\Jm[Z-d-j2qJ1) w8v9 *b\Em(d4j!ZQ(!ئdE0rZiyn*6@\ӷi7%W93uxMݷ\lglvXS! w#]c\r>OlAQJLww%%3FB#%*FfH)ֻ]ԆNݛ\ uXB( )(3sDY`uwIzccɔd}s!Pc&6- @cd3p*Kv Y\6Co=mzZ1MOzz]tvͻh6FPQRD&ъI"(T)DlUJUfaS6J-J"S1c% bbQn2nt7ZI˫vhm Hpjܱ$bB;kydkҳ%(n{2Tdr)1DXD^wռ`JJɲIv]pW"[sDll[滮/ji .`{^jrLPTK\)U&b4E_}W^E FNks/ocoͼdr_.s؛]qmеn%K$gw/mnmLY6˗WuXI:^sy>k׶h7OwFMf,RQI]Xkh~nmh;kDMF6˻\6jJsw`Mo+ь@X1lɶ&pA1ow^ۚTQrs`FׯTh;iݽnRZbQ`d{ۓwtQWȞ i%_nܹbj"J/mhQDl`؃;bѳV*-;JɱH{y_9Aci%lToΥf&56bŌIFvEEK]W +(kˤOX%7r) ׷C!uDFō!Cح='nQe)W1jR;wum,Y% ZbUn[K"J1yu n$X _+.ި3 %"4k/9QQzQrܱ#vHPh%gnIVnz)չJS5Z]+ rJy]6 Fܩ4Q^kuN71Mps\܍DrL%J9LWBF6#dk\+oE\tm7lcFWJ'i@F4]r]uD/i[ArɶtbOurĒmnb*Bƌ[i%ʺX"͹&>-9ǻW5.Knbim3+#;iӯ#}s;H\UL+bIv׽!j-Q\ gFi: 2D.pp\W24Z-T)X J pBʹ :)%T Ƞ2\-mϩ1 %|ܧ.;]BD8ӷ :s&3NsǜwBQ]c^Mrc5ˁ[tW^j4=Ir!ݱeY1 e!iUmW2b{r KRJ!G ih^j=;q9;T0̴.YmlT{QS+QjFURRKmDh[-v㉰JւUJSpȉjZZBfBBh-VbVFeK[qYjJ7']s{.㻷tޔmiiJ2h%+BQj%XLe\ J/9= hi9ܺw"wuƱM9LcVJnn67+JƯ]#FUyhTv&4i֗3u#rTvwWyV$L*BV6Œ 26-˒0".vG<ny#R4)mQ%XW\T֋s53 aұuKEX0VճD+ȫaW)㮭ҹ:;7wINwRj'n.v))HiKr׵uQ,T҃cR,(}nzssHW9]xW}/\EmaU [hPF 1ĭ)m9]ݔ]ngwNה^.멻N룝{9DQyhVJdʅJTΎ:}%qcJX6UQʃf-lRƖKjhZ݇u:]bp4XRr4[o}ynbb)4.7u ]۷ץIF#cX뗫yݼ %-S0+%FDc@T<+1sE{߻o0hh {׮!4(]co_{7#+nFuv6uX])1 QJvu*Zm1ֹA%4fhɠeVGC+.`vݺb>p}6}>_KaA&/uwJ;yFv=[cv6j++KPe)- ,YJۗ,'״&˨.ج"DPZ|nW6fs;w2$%LX\b(!2Z:^XWMk]5;]\ÈXašӣ,!қsK̀vC_|-v",2x\bJe苷5v$DZ5sL"ů>|1`HȼOz1IAQsE8Qj5 ][Т0LrQwm{W"|[t5v\#\2E1L `,݊uomyv$CǼƍh( 26Ld1DTZI7{ E%vK/ޮbłʤڌ)0~|tje堹q0jPm,KckE3 ueM|(.p^EDkɢ#Tcn3Aj6J$V nۆ(ѴQcu¢{^lj4gEB^I;WdEzZO7{1]W")eȐlj}MJ+ȊJJFˬ\ڹi޻Dnk2k:ܳ+˽B&(aoQrWKY,] ˢݬ1iB$Wu˻c3.PB0RZܕk\qu;QZi҄tF4g^jE>/I%F$uF(P-K kE-;^̋Q4Q"fI8ˍ BRd]nrjr9YwPFKQ0lRQFOK}QfM(pE]Ms9Yl" T\i)1=a ڹE^X>ޤu9ܛ;vh,LgF!%Ɲu( yh]͹bb $vnAELZ,mk`!MɋwxQ;1-۹&* E\Lź(FA W,X4$[4Z(Z)*ݩĥ#I0ۻA2#,m0)[ur/smrOCԢi5Ȣ%0[Dhad+2]4͍]\b;r\#F(3.RbQ]lW]tQekY&DWSc[kM9tJ3S|X5Wwi K[p5͍WQkF44k)1 J-&ō`Ѵ%hi-7(fu{}卋A- MbLQ)ݮQEJ@4iZb[\2I"j;Q4lF,IeݹQQ`؈vzmIQ$Pz=ѱ"'wlhƢn"4Ru(Om(\A&M1;wA64XŲRuE,QSh-ƍAAu3Q2Dh7NhFhTXF Q{jaD^ أc`KFa5uRbŠƍt#fFEPF,E2؈6X*DqCcjH9clmƳPkDrec{k Lʺ"kF7.Ib!AELQDkz\ƨF0d,X.ndQX1 ) ["hFF,\AAFƢR &(ܢ$i LFLр%MblA Ez;(㯵1%a DZ50%* H [.jHhERcZJ1-MQ`E5`EHIWtWabbҚJ1Q&̩IM)m6HTQԮV)-L%F]e͍$bhRmfXřllX.dLfIb̀b0Fb5V1Db`KXW),ToJ+kC&E% RcؒjJucb0ҤQQX`-ur0M0RV- F&LV),XQ dfdlILъf1TAh-dkj&Q)cPi+BXƙ%F4ʉM 5RFɂom͈Qbz6 1lVʄMѪ6(XM&ȑ@l,k i"ˮb4Qi6,H&QuHbZeX1卤V-nQPXfFn"-v6J4A;鐢m%QKcs0j}|1F&HlhEb EY TcEHj7MF,-"ұQ F˶h Emnܴj1X*"hEFXM: HRm"vcQ064I,h4ImI6 #IF64[Dm&-D -Bk%I$Hik0j A8aiMv.kxísAb* 4ȅF62A`QQZidV$,l$&AۄF؃I0i$ 66-h#TdM,FŢ6Ir.I`$lXHchĒF%1Y hKFEIRX (Qc!ֹlkIґEF"I1f"DIhITci-+dh lh6vdHS6lV2Q.b&(hdcbMU&"3a  #b-IW J QZ7tLTZ(5!Ɗ*+ܪMDUXW#&KF!6"4UMJEEIMz鳾}WA(ThڍE*LlXiS1 Ahأhlm&HiPL+r*5F-3T36453Ri4sAi-!Hm6 %&+6 -iRkLTlV5TQAlF()1i"ETXllILP ی&LlIhە’MDfQ& Fho7vشm` ",l NIɐ;\ɶ1ldC &Q@Ts"1EӖF.L,cj"nZ(QAQd @M0F=EަF ,RF!snѢڒW,F]Cc],Nt :lwtlm l.pđ=R] @5YZZD-*S+W$ѹ>gLru z5=/nwnwbݍ9.W<ԢJУ Zd%i\6!{'ztnQˬ),Ĵ5Rԕo:NS ==a9uݽYe`P."•1*( U cU%kZw/OkӒ 'ruAw s {E}|AJWVnUXYN q} -Db2ܥ&1[R`)tm aWʙ\K BF6\Qf;Q^Snt]AFɄ+cwwX6K%|S^w{۽Am-]G%Իq \Q]P#QQm+YDS \Tb6ˆP- \+Ri\B dɘQVEʂPK,#wRzu%dLXF"Z,iAK[RR+izç9SwNҖ%EPղ.6 D̶cUI(%W:rq/wtsNPEJ \1+RrQ[=]r;뎋hsUsPk[K"-[7CC.km3UB!2V0S%{$z3-7 *jGLs܈)cTˈa`gVc dϬ!CTGUhۧZ̚s{7hn(ؘoPݻ:e2~S >7l_ 7)QXkZea35Sl"yi "+AP@H8kT;mQ\yUO,O۔fzczvZ1/mf2vuP}Nco2>I0g~!dS@5!KBwN%21QAF1Dy0[N+#tCz ,iY3*핃uL! $K >r Ph3Ud4G6*a!irB /g>=v$}fa2J"|>S{L]> #wΈy}ŤAݴMި;DOsx{3i#) O)$F1iwqS)g۪듨i ]ȰQd3 c*™14ކmܦla!mO/G90EF5Xa[Y6Fha)F5̄}̉S%aX#13Ilˡt\~ރz%EUTJw9{DzIHOaj YkFQJ*tH$=C0/;ѿyN]$q7-:3:]g'٠EI 2r|i9 (gs[e7ю8BR b&w砅;k֞}\7gIHNj(`⊄u40PSt<\qQ(ǘdQVm}i=\jS -\WeI[(>WvCڥXFsiMysxNZFr]ww jSdm(Ð}JqՑPjoy. hIr˹h^p-3hΉ@Wyw*F8&e׃r![]Bg`ժmo6t\hX9ߡ,)ÉILe10_k\Ϛc(tqrekqSMeiW:h6D[:43G)r"4$.; % Wgk Q) 9}o=#*BH,8bĻk·ZstK fλT뻢p#1AەY(a(#-ÜtN5l(4K&d]LK7.G];8A_rB ƔEPQ5Y)9_vnasS^-IR!&S2=!$qB]I}P$-MHoʉ‰=#2t6hO pmY$$y 93Y^5$G/- [v0Zj2. 'Kx%7:x>Y{)D9ă"Óœ^n J7>&Zfvּ9:"x~Pw-c"Ob@5NIFGWٽ1VHI.ёp.ab$EՏOF #HJiH*mK9o)x.hD0fp㯥xsO٨L&? IerEhӰ~(d/D\9ڃ*dk[1:M_S8ػ7<6bLμۢ?-,a(y9*S"Z|2jjצCY ƙ2lкї&-Ёwo[2^J*ln]Rڦq1+iuhOՆܢvݛh$E]A(FN@MCy^hljZк=mV&N&ϝfaU$ԙ&q1ŭY(F#9sK7zkk9MTlrsLy)vꃫZZ] 4{>lX(,[ T 6}{nG. K&H:nǏԼ7oNՇc!l4vasIl36@plӱmóDp3 7sT&!$_ǹ+OgQB %G &GV>XHBn<$"8E!ťJ)KX masgxzֱ˂i5~4sޝxH(:lnrޘ A[H_}a {D+8/IU'jҁ| q|L8Vuf]CKu{>w55~nmveZ4I1Vg̒רo[9O$L9d6)[ٺ3)..Սۘ3Q4ѧ9}Ls8rA HN΅/8Jn }{sn%ug~gq&:'zEIDXnJ#ھ@ʝ$ڹBbѢMĊ滅yϳEӌ8#J9nrz8­ 1A2);GAqV|t$Ũet.c==7+B|܏0BG;XIqnTa$A`/Xr n*p9`g2v02URe2jLH(4!!5=Ȫԍ3uFso+z5'Ʉ0?(x;'f1b p#veI4݁۹EOUjL@N8B ka`ݲ#>G)@Bk $PH$;ΙSeM5*`b #KmٽS[aL D%VbPdJ NTEAY'лvW-rRt~ 2HL"EŠB-I $@1~@ALL]4Q;smDci^VJ u DP,)j 7 Da+#22AX U26 vLDW,Du2-'4<80 ,dm`bIGY*%<"-̬G*Qi$h-˞csH'&i 5(%"-" HJ4ThBF[Elfhe!@[VV1"$@ ^+A2 Q6kGu?6Ρ^ :$~8Dr=WԐIwK$0u'>x0:Ύ5j[2q8ټQ(D(Y Z֭?B@aawHp"nx]gj&FQ(.8PQ풖oB%4ݘEQ$?Aqd#K+9V8Fr@0$i;e ttW7Lq,kA (7rrt8y2%H梂DKEVKli| R*M+irˬ8Qs38uTI&kSH8ʑ`v,Θ±K\OT 22=PZP%Cgi&[5xZ,mZ͘Μ=J(eOizhٵm Q[6oF`Lj5[565m=mWnwupq6kukccf[kMmV5yzjZM߾Ō6]l(e7w]Ћj瑰p=b jmylК $|O=&z 6 n)m3ѥB((.0`-duN3:HN_5]rgӢvrWW\Wx@xB4,䧭fǵ˃ 8x0=n/O`ā.g{oа2xe'2|w"lרg*HcL}\0N^ga1HFh|ݳTʷI=ܽvMۻ3 Rl$he{t)0olM7Le˝qȷn >ZRWDr1Wwgʇ,M^zmu}e7wy_v pGwd#2F= d.ZNs}m4=}vDM>qiVطYg4N2vmgYh˥moٲvԨj%2l^vrݛH5ozUza,doV7YWg2^ײ{ԞgAn5W_Ѿ ž/  x7*{w)Ňtr*PXJǟffjsaCM*Ő6 ѧelyOq ᖔJ#J{w9τs͚] ;5lwmEtecB;*J7U.0WPAok0彩Ν2YȘMYn̾OC=eb{rËu" XD'l%3x&<\Y|!q9oo^{[|ulN!)xnrWiw P(WU dDb(8DĨ4x_$;o3L#9 ~ȤHypeݽ5uSHNvcg4pʩNp瘞H7 \l^֏(ڃ Ju?j`\ +$i 9J[s4 V':_p|^^>]s{DDXATlabzd)ȶL^Xo+ Rx1֥QH FmN'Cudjoq嗌P/6/vX!u7 0aC>&@O"yVMo3Ln˧O>D/ד5 qUA$|rܳY{(S]Wo]~%.s]dou @$CH>5ߜz9Ɠ=w'J;x}nB?/ySBDyAJY='s(~qYfJQFaĞ(Gy%BHH;Zޡ׭]vmWnUIM_Rq :Ɖ"0I=(b k |zF O7-ø)Ç~&/] nU⣡l '+ R="FO7D$t ]+I{-ywYFC~0k:9XzSHSG=Q #6Æ&pS׽* ]F`<5*LK'QZX}řCzqp[VH:Ze؟ +&*޹w.:Q]ܣgRтԓT>sc:ط RՌ UP97L'γ`ѲSk6j;s]#۶"EQvw8W\]׻"*S;NcwW&ޖfI3s~qc>dH}+3gatpi{ G%Q8l5WǛҸVfdne@k=~֟ ;6}6}j( v£j^:]y AΝZOyb5Z}5n6Ţ.垧5^)yRc{/tn8w彔(t](e=({_kZj˧Hh<"ٸp:A 5'r~Ap%o$H3gXq뾿Unrgv򇍤DPibo/i`+s!6E1663[=Ԑ$WA\).gޅv".\1ZYwVeva .KLJ1zX[q4bm3;O\aLnKѮ{yM/v}M䳠̏W,X[̍nnIeOY5fk$R9fNy֝XSv{*_X vaA7kreۼ+(N s|+M\;R]8m|Bj\雔Vٶ δy' ISޡi1Kj^-E]^{1Ν__WiL/X~h=ƃFhwfY36^jc7.ٙ2db9mw=$wQ}š:tԾt{4uR 6ApN6PF`fXʾL^Si!{_:!XyȄC`z<'.R &=ޚSݩf>nV&[ խǓEܳ7Jvn7#[CfU3xu{K-9zQ<ͼQ=dn[]ٳ6zzJwۓk6.!Tl0OR3)v?W}n+b Fr{Fd^{ܯaWz;헰e4uИ3-嗻ZKza|L艭ng9͏TnQ~љ=Nfm}{m<|8Yln7սz VW[H{a&UC_c}Y޸ )gz{o{|"E6݈uC]Ua6JzRxÙE=15X[XŖyH8nf\y2)UNg7FM KKdܗ·nT-We&WQ Bk8O[- =wW֒xlͅll͡sDl>]mGAgD }Hܽ)ťtᖢ5UcD"r2YJڹO ۣ *wA{$]岅af-{}tӛzi¾r* rܚ {ˎy dɼB">]i|2nn ;KA\' ٽ_;3iB}vRl=GYZTěRj /D.LšI%)&![ZR5l pv{IVr4^1%os7}蚽O*aߣ`&8癸qޞV뻵kǬQ@b&}r8*{W+DsxX<*{[Ō:;JŊ(.^kY}߻%Xl/E?޷[?=(y{ߝ ̪)XeX1W ]"S}{b$L˲TA 18n c;J"mEbm,W޶n;lUnoES4QU5_Ԅ(k$0 j(9N' U|{їwa0>FR&no ajNfjdㄑ;f=P}fѩP;*g M!'a&I _m`233<7隱癋V4<_fg zؼ{zĆY+5t1MǜhUD+(i[4෈y`wb-lk|B!<ҵ>W ~ĄAd J8f,cum qzU}Z'bPÆIBG70;LkZ5s>;8W Dރ\joA֚BK \ ~B H"*ȓo{DՔ;wbl)h74:"rA^҈*~}f ?;QSQAp tͳ ZѠW!^u3c qS9vJwtɣ40TFh:WfuXF ) ^ D APF.ë1bc}op_sxV"n+QAQ0 du0a((LK@ FSow!(,1FPE"zΛbxdAHn6 Ec!r漜B}{޿{o1B"%=ݤ V*+H9lw6o TsT4;ʮ+ o$Š"4R1})njsnD;3B~_/n70sl]%%>ɑF0TD k]Z-9Qj>&d2RwnmQAlЪEIcW] AEf*%$D?k:7% Й&7߻L W x;AJ[N3RfdN\13>RH5}CNf*+o|qh *$,Dw8cS.ߛc~*o5̹4<<%i")ߺhw\rǜ^֐Tb"*0Qr罚6\u%"kw#ϵORĂ)f a檰UTY/xD@):(15sF6"b1]bƅDZ=g:RoKPC+;*@a~l Dwyŋ1"^?( 1#t'#P?N?C0s=+zYK7`U:ZkKXK '>d0v {BT!^N 5걪Qߢr ٝgqі朏Fc!N"KbjTJpIYAyDíc1#mA-kṈ4ozTNn")# teXe+6TNUjB]jIBrj ?CHG -`|1 buG2:#i䤽ba]>gh=ũqZƛDĠ$0BDSO]Ƥ17o=u5CHJ^.8}r`t(}J`[ݬa};֟@V B` TfDWjR?*~V. |C?qYrc5lۣ{[:;bL'S,fYج*{x:鵡5œO\-q'vշIWbc#b<^pK6@合n>nOU3I8]T ڽrmpK\Z&ߐJɦ[n`iR,n!'h"KEA.y}$jK)ǚDpyv:^v a鮴Iūk'UIgkvDo!={Ӿ/-X$0`%g9i!v;BEKlQx0ۑ=2+lYȔQ_H (FuN#0k1job:3f8E*y}Aw_qag} 9<]X-,c Fl+Qq(m~X[G fӚ -Qth^T^"#WJ\BԮU|,nN .ό #J8;2;YעyG涸Z!UtL9Xޟkx26&I=  X;d'h_M|4m(d:\)02,+yv (rܲbyw q&%ZG JAkIQ$ gMja˽p`2 =>wuc͗3}'Qqi{aT隰FN˙]£C/zA04C$غ׷ޛ8oz|iZ[1mjɆd[؎وaA&Ҧ|qֵniDwIECn'];v g8[zpN^ꮍo3=zhGh< m{kR5"Ji$aT!0=XOև$ix%ݜ_;bcx ;8@0<0NtH2_)'peըbI6t}£oa&4ydž-_5yo71n!jnRdhk_>n֚56mmvѲW⶯ƍS[e66c-Ϙ4v y6MVkN`UB3ϤE/nC3r^vN8 m ]u9uL>6_(_wߐN 'xTZƄ_JE$BP. >1.>܌ ;t|dd= =di9ԂRԐi}bMbqJ)>pt+ÙpBxqY\)PQV̦5 *H X}s ``*@Z k_u˧zGcf8`fWO7XXYm߾֚n7ͭ7ǞM4iݼbOS;n[2O Ϝo K Mh[ysə)sO/r;ɰJUS!szr=a'/.{L<4hcO鉣Nпs6VCQ.İo&zțk:HyVs \bXy˺ZF68N$>J)G!HQ4#=s11!, Yv#(S4}Gw\sg\V.`on}culַjm̛VٌtѴ}nnf}^ycZ3 &Z6DE-'7",v.շoStq#簳sWTC^koz{b*UO"!}zϡYӧ ªceBP߮vՓ͍e2OI i-DHmyJb;ʾ1$TXpCFMMXִWcm[>n$}i|y5meOm=9SVek_3wTAyɺk7M {p}/IJ:$) JrL]uwsu*O,<Kl U{7u~۴y>5h ;}Oqz$*qR[RVu>u3 nڕ֏$0j` 3BGԢ0ɠP}M,:@|{pH#M XyEÜxo|Sw9L@` |$}jMZ53<(0"Jґ`(Gu6f| g*\=?cc1ldwZ6Kcl 4piXc)`,^SaDsL`j>XQCnY66fѴ;؂&"@*l3b7Syi_QpxE~OwMェUZًKNiWZ_C)c8Ygj݆L+{ugq`\Bj*S1KׁrKD#ny(ᨏ#qY%hKn#ލ_=SE yU};wk"+c ^Fax{{Skt`wt,½%s=a\tiW ޔ/J;[({6Jx T&kGsr]Sɻ[̺UnўۤǓWvNj99(,C}*=aͶխ.c^C+8չޑ%Ҍ6l7u>L<5XSBvS Pp1j1]]X.;W{ ϖV OC9o.ێNxp/o\2^Sj*␍D†s- pPD2%{!dFq/:hk/f[AZt㒌^cK<tǸ=nP{B Iޘ&T(͹ǽWuD݊{PtS1 䢟+ =;xtGqkwywt޳nZx7L`&ӛK(C*N***m냗k w:eQxn;Wx; ]ZF*kUy#Hs+RDd%mО3 16^/զ+S6f#p8 k&4Q胮nQY7h8ӊ:v8jcCL.ꝊR8!}]d#qu^9X[ۈLz9ڻ]W`#zd{ 1>j1p78{s9]R̗0Eu9d¼&}Ƶ|wl4̾ti.*uVEkjzac9Nil5wEf0Urj]wAɽ;yx5z|Wa#ڙn؎Wp,̛*57|*v9-X؈&I]w#]˻;ރݜt};;Dz :2eUow%ŁZЃk8ݛޝɜ2 \ yA3CˈDyr?S{S:@u5۹eـcor;˻JH. Nh6u`\d|=U!ҼazZ1l=؜bTHoG.ܨ-F,Os2XOh}kVH:g1:hf n҈ [X*+d!~XP**weC pΑy)Zvaiv6$kpSR FtolShvԱEe]*5}2x5aV*~MamcX*Uw.7/(͗o2{9ѷ|nUrpSV}$*E+Uj܃J 99;X{\&ΩR7qFkpl{i>q<憑v{{xz 3<[0K :do؇i\| #]]wֻ U=Æao2Iq4'pxBWLS:s´#>#3˽UU^kvmm{Mivb̾_&]n)It5j-{qbU e._Vɣk jBEr#ӽXVј;d4ZX9]0v#EwVNpf ޤޫXOܙsn/ _1U  }I1_o$3fdY,^B%^h]1sr{y߂#&wyፍ}ᕲoUۿt9/"2R=isC+M={cl⧤V y^fd߳SƠNX3ۭS)[W |M< w ={oմtz^'|u{E}7v:Ou(1A K5zxF8HB βL%%YjgA|}Pl~XW܅ m)5ny(b8Fx=f5ebs#}WMs{4T R4R7 IY+Fy{}HS<P^Yzܓz,ڳs|zuREXgseَ=7֭q“ͷ%Lyfx½ݾ SvUj슫s.g\'THhbu\QKN[AǙ1 _.4詷ٛs0s43}6=- qssy%u1)K|kkx!LvoN,uoOs2n{wJ5D~'ԮV˷ExI4mOc:4!DA1s7Ms||NM:n_r:4(dB|z ѡzLVꕁ}N26\ηGs3+;|Z9sm^vMw^3wOYzG@>N|l;CN"'SDŽP;Д'癞r}bS9\km"2 :ѴNk}Yܲ.1,XKoi^SDl@$ ? ' Ap=}24 ^'uۆKY*hĐx p: qݽݞݼ>r%4 +H$}R~~@v#*ق.9NSo}^3MFY9voo ]%V}K@EC}r Ų܊".3+AaYZv_e^]-=h.٭Y ~$%!UBSK{_g~U(yݞR]ƐGO˝*=}q}HHÌ"@D&6.(TU]=~5u*,$ER*F"k AUm׹.YQdŋlFx3B TDKq QF doآ#Qt<ݠ+5Bd0#"2 8zF$+ k7IllK+[iE^9ZA4*A(k}x +DE uqϬ̱ AVQX%U<|㖟w ADDQ'mtز "*CP {2D"({Lw1u×>U/p1+ffHmQ9DD HLe(4"a ERVDDV Y \id*# /ZD2GPԭ5BrIXWM X/33 X-whx҇] tZ&Fa8bR? <r/F>_3H諴Kg~ݯE̜lB"gwPǫfY.mՇ5lZX*+X#IѴ)+=}`ߜԞm17f͙R e[9))нx۬'-M9t=g Bdfj5O#~[2ͣ'3v<ó/uʥ 8<-gM^槕ɸBl烌\.GmO:nۜen0}ES\rP4h)RKG}+hAo;6ժ֌˅Dc:Mʎrx NV-rېG 96?xۄcq2 >Z^RgnX5K]5'v!ڦMQ;3/M7wvIJSM*'ftx4SH+l}]Am({lByNNfSy-Ǟݐ$|=/f Zo[ډk19vf\v.2ʨ+CXq]Or+^Ǚ Uٝh(X5I^yn%$c(O34ޞ^=kDݮrݬat5nRwsQ3`(:uB*欬c/qh`ppNQ:tۈ ;W2gN uukS\\1Z/2=WwI]|{agcpYҫٹvs/ܻ{iٗ\Wo x,&gZwwr~[yZkRvE V_b]5ٮIl{# ˂pXLΜ].eܠd/pT0yozuk4jq 3:͸J[Qqr<œ;o)D;N޺ 5ob+;N:) tM!s`]uTP%%X)eǫTvW' EZ9Aʷ;(rVCbZ|ꭱ36\$É!NjIݮԁ=G=ɑѣ;^xWyظs׆9S5/,W&VN{x\z2ռ1 #}:{$mCz fjte׵Uy{ ٬ *b}vC;P`:fgtˣlWlw.{^6CVeIz.kMO V8M#J5ۡmj|T#U;Q=)š)ۘD"3]^Ʉˇ8;4g,yyB=ֹ(l%Q|#]M5 LXo:d9 RCxEfZtǗǁϮdI}ݺߺ/0X_UO'nGq}cs-.|ޑg eELvn$n&vH *b03PB^=zr33x{5|NKv]V {[XdA)j=`կk(wa*L%o5rc'6M(\qS {VCkqSA6W s\lWunJ8/^nwvQp#bwwn4^kA]Ԃꓤ̊su.9Hh㎞Vj4L}h/TA R^̎*[L^[xˉsц̏{W^\;5%;0;9MV}a*{z^oCa[~oCգ%r!{8 Y}-70 ks]I }G:'R'e1T#Ϛ[Ƀve:yVgjR[F[o: o[ZKt:h: *cUIg'T'_RK^chzIf/Ȃwn.b O}`ѮK~zψ7PݕE[Cڷ_3 ћunkd hY5BвL[sCZ06+~0={8M5U;.n\݊]B%O;ÙگgM`{գl {T Ci UXHiX2dRxX=,OR3ݢ%էepqIZ*hy9Q2 1Ԥhg#/D>#Y&ɜVsZ;vseGw+t$(=꤭wyJd~aU(to$&lvYjX3ٞ>x[ɼưJsbw2| `N;ףԹf3oiDcE;+K&_c{kz;z/pUqV*x ɰЙsri֪)jkGw5_= oR{핽3YmYlMfo;;VomJ[7(-+xMm8нq[2$x+p#[;ý[V ؎؉[xY:-BY "XwZI4Zܑ#7fsoT@kC=Fκŝj@%nU[M Ew0Y79^ׇ8Ygvӻ35%:ەUJ89]X_=UDeGv7;r&astb 胲FU|.mf񯍣i/Yl*_c_`1V̘Av#. 2{|Ĵc}. gm*;΍3Yt;\vvN#9ֱomM_-M۩*u}/nQ"Iѵ7eC;H-6MŝMUAvhܷI@Kl3I+kSFa *rT>lwZsfB<\CFg :hmdվ9tŽM&]ӷEOxV.| H8;sc`r\3Q!hto] .WWBg<|f9͍oR׷KX#QTy}ywzzd+oZi n7N5ͣۿSj#Y֎$ݜ^H ǧmtz^Y-]ɐ^Bxc0ˮ0]wpb6˱!u6f^n_NR LU JoӚ!`ڡ W B6QwK%WzsFg Wl <>ɸiƻL=7 ]nF89S\6>Ævuޞɽ35ǀ76.e's8ݛ)Uu 瓛yİN N.s$W-|sl3FC.&sw75w1![PXU*{Md<׶|\F|3v6u%ܭЅ@jْAYwh}&[8샥uJEw4"kbey6E䃧4{Ӄ9co-j̬iKbλӌ(/Ұ'Nk=ǸUXD{Y/'VK賛bĺl݂=]*3u4siyYCzk\m>P<4w\/zTnhif&ЦBnܞ~RtUzI}u'|PS]n8픺E" !N8;x{],1 v%*#kJW>[fvpRXfg^Ƭ݌͜Mldh W,k4]=  jy+*%nE4W.un-[~Vũn۴ . y.R{aƷT5ÎO\ q=^a0*w7`otަc0^ŮvEbхVѓz Ev(a[.ވcK2޼\k"ut9~^xbp^}-ݐϺ_s[޺ed Q;w 5nh}'*vLb-cP5NͧMٝ}ulmXu̫ؗ`eM%ҦK~M(rd빫÷kޖg6Tn }ˣ"LbIrEQ̕w]/n6 D~|bGv HE;y~U)mX4Nt"!єv^漏عYőCn {SN}_b~-2u7`eݩ;F_nn s;WvWvpge[v6k)$( JRO/=re#2©w$^0SS &>|mJ[ZaN[}'R|r #sB36i c'i=W.%D6ڬTNMVg|:XwQ{m%rRɧ ]nR.nl"7 G< = ㌉fr`:33M}6UF{2wzNh믝G՝^i:  9[4wcZ3f 8$7Ontmme%2gp۫تݯCGĘWaY\C.ɧI=h ӛuT^6{]..A*dͮw @r5]񩙣eˌK;_Y Շb{Jv`O.ƴvdغ{КcqXȂU'H]sWu^E" :bub{]v6+6mQWo}sq-Xf֌UcnI4*3{.: zO񻝘KڢYvX̎AΙzyhS\*G2"Cwe1dS[4UǧxN$STbZBWjܪ@`8п yP7P1/ptdpUo,_v5&$E: Ϻ" YVtvX\zaPff6#AfJnuְbNo4n"fyۙB+HߢE8"T]1u}ҌR0vWvc|SW9f6.qM/.skya3B CH3+kWطםe:ɘhڪ-p犡N cu Y$} eeؙocg"T命jk5"/CkzWQK|M[2![)$#hof/?FN> R?gtj-39L=a6gs&oOةK'%" +` w~}V$n\." j6ͳ:'xmK5Ēݺ\.a1w_K+Xy\f T]м D{a7_TMTB{=Y+R+.tLszEmxoh%x 1h`9%i鏖L uĤo9NзSF4o0q192];P݌8Vpw4xmɅbleYoBp7i/Op[xaV?]7b|-"yJD9 CʪOn4=BnK:E\|^x.̬t .?gҾgʚy>3w YZ6D7KW^I,."'7gR]{qFtqY:OH-fWj4ε"b*hr9y%䝽'-g:= vn;ٟ>7}R =+{j,`lqc{o[vέ{t^۲;;sZc;KN{0u\gS}W\6#kk2o((@gbރ˜6؎XT"+{7s> VpVho[~zng;tzތsW6 s;u7+mIgՌShszG8n-ĺMW눗[0Iw, BԡHCVJ^6Z=p![QT 'ln2,jsov۱JR:fmM֎l|M9ڼg Adny$9ѱ1sCC3eʏm]q1JGweġt}"Rݽ*gv|p~5kf)s#^Z8}ޢ<ݐeosfo3ٲ+G}yތY3M,h\d+Fm;/E3bǻj.H/i᝷Q-W3 (Q ;ɝlT;=N]C$A-: D7yޒF;W~ z]…'j${&{jkTnd7reݩ̧}vWt{sr&~_-_;ki$:5g5[b:9hRn twOC.;m0Wh=k~), 1AF5W;S2ԷDSNSxWx%/&=*g9!r! ddnΙ;)kMΧ+u*L;RRԣ KY̺Aa22:>U pSu;oLF@bZ >{)6"ڴ?0xQg5ٞ|d,t3ܷD/|ļr2b샥w!ڬ*72Ը\ey:29{Dgo`;lJf#,rLW,wM{;JB3C1HaUtIù}u>T`PoWQK_\ J%2v$Ƣ @[][) tu^(4I%ϬDxۋ5)EQ۠ki)t^Twgkr͝eyhN".S=OJ psޅлRY gꥅAO;3OlmVPV* v75Xfb- 3Aޚs}fQN&DBnpM kduŝiWx$WhGhoLӽ}ܤxӨ1%8 p\`׵rWVVވ֓aͽI}pUdaNٴ`;xhOh=>($WL]{uu-qw(\LUʛ}1gEkXǸo_{wQJtr:fZX"vnjE7WDN7:PZMeeM J׾H7+O`(9>4H'=*xF[û2YivYy[_DOKMePD^έ8\Eey6J*'JwE. ցtߠh#Mi6?OāD\LffuSvoqnha- NgOi~ᠡfV]x RK*1>A7jdIas! sSv3fX՞nIv6 Uth`htx7w㒃|"2rCRm3k 2gHI2]YwIy7;Nv0?M; y:<ǣ>3:BunѬ[q2c]O)i{}wA/2Qcxc< '֨O@Mw,\1؝t΢:圓VF*.xc}䂊GUrBPO&A3/]c^+ӻm鵋4gi q9acږ& wq$geu'7z-cq#ژtp MES$pnNpۖlhXn]#|SHdao$3NȌ{t.-xiI 8nZyyM<3d /{;_P:SlGZ5#;rd#${e߳ɭ;Ւ9cr0JUȶ[wPG-i7ŕkVA5S뼽S5Py'nkj9`tSViyܩg9ś)]*Ju{9393v@X4q(36ˏE\s[:Q2n ͥz\FZou]:)'x%npg'\_iyMJv{+{4,Wd*G}tF[حR{jKbwA.XnXw_&=Ze>rPrta~Jnۭۆk{y>Ws1:6&9v ;%,xr0݇Ehs:*ew8 ) ȁn~ ޹kzҽJSXdyeRFK^L3g$hr^_lM-FRjbw6F#ۦ|*ϴLU4H-!h<{yUu#z/x7nk)^v{흑C$! 9'9&״VvfUi E5˝ٓw>+l#ؕ+:N: C{>G7svg'z.k(}Vn77f`Z7RѽvOfݹ;}pYQܪp\tfDںkǝ=}3=stJ={8`.lG[쫏fRViCF74^Jdj]!<8a(4Tv狕 .5rC|+&*弚ҼVuK˃k^syVD+YݣlV6lLy<)IRm>ƁAV26Oo,n _V#Ym zC4o!{Rea*&+j^z9n-b5/v:MƐzǡrz#=Z:3^/cIk/ko2̙9;S]Ղ- Þ|iY+]UԠR:4ͯSA<\^zXg$HN f8VSNK*ʙ/I)bU9+ihM鉔 |ʼn.8>7Q&{B~7rDR:/yv1ho^[,FݎT$k $Mݺ{#)siq|`&?/~hnmwRT ܓl6/rkɷ˹v887l9 ɦ=wM͝:urzPd\ iЊ)r3#O8W ݖ1Rɦ jWjP|LbΜP;}k~37@*7K{4+#v<.׾/w){g\|g,cYޫ bv?z;g tRSݩ2 FC2wj9nEtꋻ1N[1:gmL{vnIbLLXl1n)_^G)ߟo*+ ƎhƱ} RSQ<:2zRxcK<I/gəyxsGcfNtiV,}u gckMv*}Wbu$yfﳼ; ۠݅"N载TN|P`lqULgqWUY=9x |z1/8_XɕH!AmVZܢ̴:2yݹsRn^0(Y\ʎZ#fRJm55-uN 31wNs@@W>br#w&ז]޵0|ə~*KL.ۼWYtd?d_]'^-lװ^}ݿytg6\M_M Oc ZD07Lcgs>};\$T S"&к7xXOۣS$a>tW2LUn-&nJsyYž;\+DNOڲo8,o>ըnsфLYy?h.|z݂FA! ?Q(Ɋ?{j*ݴU3,+DF5{Y-SŻPuFD,V8+< [J={ؚH7,ZCrYd=^|~"5:=!3AkںB5U2qynhuXA lRKٰxv'^4TM새e]A')eꪋjhCH84H26Nws긘g)Zѯ6MjƐ> E`Ah$'E鷧CDOB; >O(yMyEɥJ (iaYoÇNs%aγ8aKɛd-1!YTuwt<*,(A¢y}eEGT oEIpZ0IҔ$jG膽 &u]7aΥ_7Zɓ#bYf6++d6Z] 6.[[>kmȮwY0h˰E>C=x?Gn}M$-vc U`\XޡP9F ޙݸ"CSlX/ d=-NL5/wT TjWmsDpŘB?B.1U~z']] (:iؚus:(t1rסpxH6fZK^}M;\~YƫYi`<Ν=2)ss5WnyS{e"rQ{w#81srjlǝ"C*ZW"FS3,es^^:/.u֥D)$ÙڬeXW0]j{5;xTcQ{;H޺6W>''Y9s # K.!**z(~-*swqgfH2t- ._b,i\7\{2{ |ŞJ#8a W%17 )/2q$Ij1[efqjsGm"y#B!`2H-";}G>"rn6OY*-. ң᎙cJw'P+56>*dS5>șGřGqNy3@5AC5z/,LO&J!b(Y |ϙ&uP*xGRp5B̈Abj| ɠ4m)(!WeلYfvd`A$ȲDV@yf\~ WRCpE^IK_caLDIR(۞ǝdu@cf߸_N?zSܮ%o~!A&H~fdNOzWvUCՓ o9` D8Vbpf Vs@o㞤&y&g*i9grC:TaYǜs13>.CE6<.>LG*>d-ؽGލTn^yY6۾JYw|nQ;v۶Ǝ)9jY}h;zMo6ӣN{1dl18]oo֏P>?<m ÏVZQO;^&<^>EzD2 z`HW"B `;]W)걻g@VkgLN "b=`c36d"JR]}m8&5-((u 0^VzT;,RC`x2T̳niv}éC$};MPw;Ml2EPm cN<65oTo?>o7;T_ܟS8:vʻx{  ?ם;U5Nu{'=>Khm}o{L&:^ˮs5I =֕Bz oTY췺3LpI ws'Wi*(XHB[%~?4~LAmjԖ馧U];pR,sck9M̸UYwkKc[Z٣W(WO2}vhW3_߹ԝ'- E4s\0 /ޱ=ky3/O{Ni?e:Y'O>>y@L$ݵQe3 yJme`IY˼=Bſ41q3LWXYu Sa RځOPQ7sϷ}>o ^?<:|XӲ쩃džN{tD'eI< -eDr!$QC?RS~eZZe>֖c9+3.Ŕ؋b8Vxԭm_,ӥO^VMVw_%>Mnܡ? T˷o3>&hԆ!Yk^ g༚ B K!= ="%Y,4znLN 3RCzkVuU_'e0,UΡz(#!";*By0>CFM&>): X~fbqA5W,v1ͅa#hMv<8-bˬ[t.aGU^^|uMŞ EDEw~|o9wvmm]~:}CbDd< 1jwzUo.wϧI珫/P:>u{b@/Xf_sZGhm%a.2aQH9d7h=t5!ĭEX?t[M iaw9ۯiz|9\qm_[46ʟkm6N3lj.zM{~=V9 ^rAD=̇JIn c͆o~='q3zN+nb Xytobņ0Ky%1ndXTPWe:J @Niݟ8~<^m8vѓ68鵷VmZlNڴo>546oQ}'[mZ\S\ڦZյ6]Qmkյ6 ftcd.6kQ֞ !\LMj^}(o$d>#M@5%1?w~:w},q9GNga乇|3y"WVOa!ęU:ɠw/<&rIXqXh4AdtJⰥ(IO=O63ΨyC?B~_4mIuS;VFQmlښն]SE'm.}iiMDsp}/iښdw]NVmNnc -QC P^%kZ ŕ0TW۝Ȳu`iHPo:͔$Xnڵ+Qe\˫UD)eji9 tN1D_w3k3497n5#bJ\C21U L `ƘDZYM3IfY!(6Ąc#R1&!m>h*$ >*qwI X $u֘#s5ˋ-:ZSKuikB3BV H7!C%Roh-@nҊ3iБsW]qz^l1C W&K"؎v r R9uk=wFm=@s5F _zbdŖ_ Y;&Iņ-3m9,C:{|UHόZc.11`3~0֫#uv*6rBi{bK"^])Q2bP$~57W:vϷuQ X~!%jZslP?y5BjҙϹ ^ >3[E*7nJuGT_[81Nk$[gȋ8^·^Q<ޔ1,FH O)Ȇy(+hFpׂLɎ^dr1u4'td*V=LɧYZ,Xzۆ!pmeIY ۦz ,*)5pqթNZɫSi4]uoϚC;m&]wN>SU #hސm2]6QҮf]}6iZTuí-N>ZUUc0wA@hu7.aܪ{=^vX';#?xn 틖cGmiQ~MnZ wf. tsj2x=Nُ *ܭ;}_W?԰6yb;5=Q3} PFD“v n1y>9 =n@}PIG)˿t,DmjFUt!ķccGT sqc \V ɦ^ۜoyCk"=;BYHnr!*T7U4./mԃ疯yKx~qD9m(wϺծ\ %{ ƄFMRo8{iP$qF+6霉=TQiTWH~yR1>UK-o9m +>8sl7 Á y]cp9nf]؆[dZ,Խ4  AS# 谬Į')r'~;v֬ 8&H}J>;:/Z)$-C/W]*fq=5].[pș¼*Fggߺ]_ofb,C` P)rr‹0j( ǻݬd#Zo7VڠM }!6zp="eST 5C>7rx=U)&%!Br&oa+zN_16#'N*2k>}띝NWs ´9MDչii|6e;AXJrmU]lS 9*3393-׫3I ?)}S\{zA19q#, Vž#^c5 {VÌ#e=诟Hck C:G.g:DJ<Dm9{`$R LjPD\TtCWs0[z=oBhc ̈́*9/,͛v}'5umُ*/f7}6%( o*BU~{(Z(zyV HlaK{: y|f6x֪e8oZBz_rˆ ~Sh.%*3vћd\Bl8B]jX<~Clk.p$$v{#Ub\qǒ <(^/SsSX'&g|ZW&]ЃI0*aTsvg(]4qMepB>#1MnκOUaq'/]۸10DikC$Ow76ۻÆݸ}PZυxALخ˦ikfOlӹ$i_Fz7 }_W1'^9ᇻֿoqxy[ua{Ҽrp!$7B>@y;^ri~=%WHQj$$;;[].'dX!YٜpbiHv+>ʽZ>\?('N7Oͩ^pwSE\Z[Wݩ F%\wl֩[9g mmlr-& ?5j+mJ9Z{ͩ'T+==@6.@%~MqDZtyy'<0>0O!1ܻ^Dќs2`] nm<w5}xKhL(qU-+!LrO!YN]JB@u*w_:fYYVSjomd1[)0ӚK1:ZKyX}}+eťkm[296֟m 2댆J~sMChrɛnhv}͞s;wD= 0{-6}^2Cǚ!JEѐ{kU-u+1RpI=0=v!𩼷z|^(==ԂxϾޞ)#=7<}ؤ=_Cy%1Hʒ>I鼡I12(/}C̟Գjc)ߞ5hɐخ7VӃ0˲24kfskac`dlZɏ[X6B7<~3˦kWY]ozNK&'B=mw?MiJƈ~~ fwSdw* Ugxvl*ֶƞ)hCl\Q_ozIPSJ*/{0emOvk56^sihި}\v .\β=Wfь+nɳ=Й Dr655y]Ým'cvȼ@›ig |&v,ɔE;/ZtZr?q}~uLCY*^Wn+ UwwzUr6esfcV=dmȟ0EvJ՚;@ghԓL97u{~Oؙ~{fCD#Q|NvAn#pA$w Lqx߁q1 2l}ENaW<[-4$bB myTŋ00SBać>;z,^]/jc/ƍ&H9Vɵ}.-d`ګM6jZ]*wWZn&[gM+he2e Shv1(UDb׶/ﵺq?f"9:0^=:W5V)ZPS2޿+<γIbZsfAƑj,nDGЀ#5A 8$(eVMb|>h1gj3#~lè@"$dcr] ^ 0j`ɖv3%ԍ?2"M qc{ /'N^qe_FWwZFD)aG'$e [GY}}wd @(¥"m6C|nq2=쫰K::Wx*Eiy{o*C:By:~]ykYũb;̺" Bu Y&VQ((sbqIS^-di +qV׌-qmq$7kVYIt:gkWJl.ٽB41*&B!SnrM(jD$ݽk4XRqժͻbgPItv@0g N~==KGxzOkcO7v/>jy.N2#zКO![syI}ʂSPG yARs'kX՘6 ?AA== @oY1@눊#VY(NgQ4$5DB Nnul>}l >"sw,ChO'u +1 u$u [t-|y_zzڦ8eкɇul6f,qʴ-bڦ˘b2Eyz O{) d߯G`8W*Nh7~ή.{vv.ő|uΛ`w4-܋8);oUŻQ_. kM/ WT-xOS9q{[TF>V] a5Oaޮpv2iu:Xt -g> &2.%F>Gj~2]*NG/wz_^Vߺ]q 1qlG2Y/vht ȇ$f [^K=:Uwt^(5oΖ)CјJ/㧹xVehJ&C lUXm\D5LSAEEݹ}3><ʨCT{rVU9<0j l0dDah|mafxO~ Bt+eDyJۓ)WgZL?q}ݔ7ǏI~>gS>9)09wؕ4؇cDGf_y( z'Vt#-75} ?%|\3 ݝ4q3qaxn?.QncWH"+9 ^ýx2rÓz\#3P,w/Bt&طvQ 9o]괉As^VI KHF{q?#NL!@om#^ :x83ڳ3)Pš H=fBQy{(PxLUݸ߾{#Yzqb7L8S0*(9x`xem=Z8I{Q9c" g}{=Cє(gcq3m}bNL1islQヒy)3Yʩ.E[ GÄ|H{1SUr*I\TM}izL1+0&3Fm/LA aS=7#?{iP0P?c:!4ZDm0wW2 -6G4ͷ.o>ݦ{/JtIg^?d0w'ɺ;NTZ tvzI`>7EC9Q{$Mm>lw=CN\']/ ӽz[zpϞan]k>!a'>a;jbNE"C޷YT*W¤Y۬=RbBaRzps)9=/l:Qۭ+!n=^\-J1&bGvX2f|aw}5>its|0~?Mas7n6h5!k?o;}af zOS^N4m7e>G}U? x5ӬTD O Zٕ\Bm1&SҚalk!O'lW9+q cs~5ZX>N}1Fd5G544䮲;#AuyzjGnv F:)ěH5Z~ 7AO_g}{:p۰ @37'飧Ϻ4 9Шh2fIo/}Ʃ}i=YȡHUFLj=60PXfs;_׿b?gc6W]Ly=.C-v鼷hmpc$jX'<2jM~X8ܱ-L.:Ӓ;̬uv=FsHvrvLURww{:yt(ا~:۾ߛm7?}~k7tyRTzXyzQZ.pG8p8L3la%cIfy15!*y+ G*ik <`i ^`<9__Ɇ;,zimps5n[kiK>r'v`eqSpb9ę.v :eN1 nBBlٽ ya>-tgM˝ڟ=}C2L9B~=>{Q!,96P&u3/2q:Ј^;i|׵rGwi3s]}T. 4O(f<[˖Q9d2s;߾][dZ%;[Q*deeY4cZzG_gGrS2t2A۫l{'eO=l6\D̙˚6M8Bѿ>:wOstc]cI&]ޙÆmjZE|ŏ\RS߾+g*9aj:75j:Qin6-)9Z&);Z5}VRyzvq=|~Dt<bw@lAfs땣g?wn9:e?@+3/qk1Gy`HG/Ng`/cjEyc^[m|2ViQBbzC޴Z(>`|C~iMӝÄvN1d.t.55hmFR]ka/E.l;lRٶiZPreZ9Ulur@QAD" ?s^ǡkEl4_'d LQE\áх`0J2TmTb"hd?z/uMꆄ̳хf%f& @Ń-tQP K79d rhn/Ե,7,JŖ)P^jK:&&CQ%@2`@8+,ԐdmOm|Kteru VrSEwj\2u476w}NuG=(l6-Kv;@᱌Svsfnww xgC ]J-oO w&O0WuEplݍuE4 .def0>KQ=%Wd,U=ohR 4ka'!']&$X`6[yfuH73WAՋq hW/M8UcX? Oo=U DɵGPjv8W?Bž]-s^}I Ծ{lCOb_nn!$G#ѬrͯZ-џMI.ńB=QS>$q Rg++!e!f͋nD[lkڷ~Nv9Wy,e ݪw3(ŰF:CI ڟi:~P{ p6"H D)S99M y3׹toʕF!5wf O7ū8^Fd{(zs:A) 2~;g* vhzQ(<T^;DZVr`NLZf.d{e\sX)*g0{xݕ.M84duCJ@qF`n..<iΝ\}[^6h-hTmUK=rMڢVL(b'&=ѤxŷP0xiBG//+CΓ|o4WKf38h]aBl:qzl *oҁ H^~0Odu}~8~MP a "aS'4I0φL:G_ *ޞHxUv)YU.0ZGݚ\쿀Xwg!\p ; Zs˜z93CA|3A @t$ˠ^R ,b;NPC' ׉3} !B%1-0UrQ}M'ہ> Ȟu1}s 6'ZJv:̰iz(qMFkZ!/$lT혇:eg%2 oo d9*ky8sShf!ۈb*.UU}}"0%<  k)D40}d'γ{/.p݋B&fܪIn_闛z?7]FS;pzϸw_N'ͼ1=*_~|&wx=`V1Z4gN ĘQCq5oӦ*"q% l'a:y/~))KIx?ϭ߁6r"s:jĖrq}eԓu[G$>$s9Ǫl[ҌM&Dٰ {g(S\Sܹ߀S@sjhВCL3} &] /|6U^l) BنbW~J(ւvFOZ(+7ʂwW9n?ZۧNW뎶oX)tr̥Q v'5tTis㛟khzJS] ^JBf7va#O KF Ͼ>Tt [a ȳ"qt.ܙjė$)eMKO 6 AE9kY r;MŔ:cY|"2Yh&+ P0|Y;PE[Իᩮo,ӥk:uD@~Aڄ!}XR&)s!*6&8EXd2fqoﶎ"s3 ۸"Ue A@8 34!LH)TjX4JtDY&ܟ$1NhU{mUdM!2Bg>Dս,KBϾ>D75)R44X+޸`Gg kk%x? gnN|]!6,Pny[ŕ/Ē)VK^Yny޾:={n> /zcw+OK@&^c4BK_kBŤe^f $?2ն-Y՘}xaLZAA&z`:_08,H{ҟcſ&~o~aG0<~L d'{=F^ҫ7J 2VɪDb8AGE.ܚ]A[%ke;t.q|m4k0fYnU[Dzs)Zޣ1=$@/pc&9qױʳ䂿n, $i< c(h|Pz֞ag}֡y1EAjHj+DNZgKWh*]SX7BaEzTM;$#$D͙AVGJqv'Wy+e\*quD*;*wg^źWYՍՑBmھ?$mDz/(YtEI-7al۟n*D"lO\>yΕ@lD};fH" D]z "^X_/#tgsf,29Ģ<#}DG4;4G8 ]( %MBwq(am4oXm<̟Wቬ1Lョ/)eal|AS!$7)s D0JXC@,cɰH+/ʺA(X7yz9ߍyL~HM 1Br( G;,y|T|]D40KL&9.*r6Bb "16"$nh%xJTBogKOJ ϩZJ[ Yۚ$VcJdlbI * 0ߏ^iM[}^lӗ\Ђ un Sr.5GkBeN.:cCZ1}WHaQ8ȩ 뙌#Q[sa˗M#6z"rt!zwRؒBZv#%(dCY-Nhˈȓ"Uf_ň91H:">r"F"ʴLO'IhRI$dA9`TcDX;:ǠA&Җb"Ƿ6&G 3u e(pd7jO@3 ǘe}:#JJݽ̬SA|rsz; SW7wY Rwk~V[mVv"'t/' tS"wϷcļud0Z/"m G5+ȯ%"%glC_oj'VTL<E>١3 +db,"9%qqn/T#utbe]/szS(Yd i}c4͢4Ze>~A"e[.J64K@/ g0dAy=[wwcUF¾A) Qф6V {_S(^06S .Nȓ٧G8ԚzeE~7g#y2* c ^P}[kzױ H 0fx4zI'H:K؅/Kc`;zmB絭"M5yOIݾ~?!H >F}[\!f҆Qr^ ~([ݳ19?i:|"j Q^|ݻ߹~(1bnnҊ6fJZo(,CmAUcw=YsZKfK 0ԅyl>DZqϴ$jHRnY sl ōqM<ZO*<׍ Er㻜(p" z0@AEX(8=+li C6o:!/#iV_j9]PBwxg,w쮫5\}DE?n C1/jhӛǍ(ӴEl@)ܺ3ii$ X8~MR[Y+.&܆K.3x,g}t^yúv0_ &TE]߸u4#30Y5)^e:2jݻux I+[Ծ'ُ?-_k@2z/nׅ + !4!Z&!gsb<{`sݯeWf-^Di{RZ4ghyFOξ9#~V ̌ypSd 7+r2 ՞_,B7GnA0cZ|mjæ/NæKekJ@!+)I1v yd:X"8qQ%BwQx=WZ2AInv+ro "I}nGey$:0֩Ō=+rښ0=*a8w&B[j(ԯ\+[26}?gZ8| :j7ϛ^.Jʂ|re p14`0Yb9fgfVn3Ø=Eve^Y5o&xoTXQv} bؠ}j9B춈`*2w9*ZjnNE'^+&(,RݧJ@a#YqYhY+Wm-8seb4M1-~_u7"˾Kf2Z3lcye`7FFn~@><89>{I\wOeơ=mcNKt5^zxpQ1:s3rV*m|) 3o5wJ S"{^[887w6礓&r&ȓ  '5`7;-#qLj8A fYl]i&Ov%Օrv 1SfY笯*D^3J-:CrxRp;?Bh^qib/v )熷 %M==,WiͶĻte;g]YRnרȓw=߭t]$ojES4^~ භF ^K况%UѷWBDSTiV½mXvD}k=7{BƹiTD=9SЙCIck{E8?!|W Iף[mO44^]汁t~W:&=>M iC4԰TʺB`"&&THf&Bki34zބM32(#ٗI oSΙm U$7?wa]z1e#ǯiÜx6O3Ye[ =NmSub;u5U7:}A` Df fUtJ_`4//!&|O{ @O=JO_|w˪@ۮvװ}5߱A{*;Iѯk:/um z v62p>?x='ach ~ed-6;c>}Ur{2ьd]ZZ\zb*w v͙Sm߁qo}Hb0Ӻ.>o ei |SKST\pԾ:ϰ|mOLa}J16Z*viqV7uCʤ<ē垣N#wvϰ6y0Z24ZrSݣLY[ %d9r2WmlsKT5Ce T6BL>.8+{W7;yޗ8t \<_{3]@ר'y,vG,qz<H !7h\ U,PHu?P>u* ?pP8=5ύqbA _{ow[Ӹz <d<5MhD٩.bbw*/f0md0c{pST #'`v_/kc&8.-*\9.ٱئܝsliMu9uNCjsSYFT]uuW66mB+[[-ےVض۪n֪ɒC5)>VZ5 m[?|c~{(VkLmQ;NkWtɫ[%Hm$ Drit$+1za\ATaк4B+C+d}kV>;s϶L|J_17l+/!XoZWe6B)P}uޤQ _iU{O"xsis4[0 YJ hLKW}B|R,}1-_*/.:t j'`WGBL~yo雿iPB;n5avoN/0pSjL N%Ý-lg,x,Dv>" fCNd|b/cXԏ>mqeGU8uw ~QIAǤx-5n~Yh>9Lj*| MfU _i2M{:&e%EOxXƫlA[wX⇄GVxJ? z5BEnא3!υ0_^rG,@uhq=77V Vv2e7Oe5j܆eH@g]hzf"sjZќ@>!71E1|J@e҅8}T+daMfk/,R6tgbD}&]=ߟH2`.u>)[[ Qke8lSz;0csϰrkkQ)t7uŋ,S>S4Pԓ 2r moOg/7쬑yMceFzn j_dNqkohghX&:d[pͳ zvnҎxҷ4naPh^Hv;{} $6wMsٞ<-+4w8Qdž{O ߋo{k"ĩіnx}n]ШuE k^ͼ)mF'>Cf]GZvSֺ~ N56#'xJ#c_h4\Z3V4TSd~8jM ="a2ȍ>Q /IWו/wXۨS KLTзh/slRٲ6u i2y)p{מa`NԷG1& t$;ڌkxBrLEKփ] {& (:gY8E,B>4[í6{7EL/EAx9JD3-}=+Ն{ Y4).=SЌtꦄjE.:AqzXu 򭚸-kyyw$Ӝw_A/sOGFf cvS,[s V3Z<܇aDy Tu:2(RhL>??FZ! "G/hX$z6cyQsA[ X^HxQd鸺Tl$ۢLaqeN{aT/56Z2AěoNQكrFQ_RČ9Q5Q3M.ELїTU{.lKCQåꢅe[j+}\!EZ%(_m0˷˖*A:vnŝQȆCCCU#-ywP37!hxCKQi%t)oZM>ںr A(mrK >=C^;a^IkY=o-u$SyܩXC;nXb!~O`#b=Ӫ%`f'3GVp<(Xɒ^A-Mjw1,S7oNXEv C9]]oehOYb@v=30KO2S%YjQh==ZCJq${i0vN;tdlŽE?EnbgFyszMvY2|RjTЀigbC^~ ocGXD–*'9 {IRm_MZjl nrv _iSiIFqp.U.v5E0`|g+=NmļAbj:7fp<{z'4Q^>,* iR[(;ΧF!w7]GX}M\١7}d4ÌSMΝUZ}!a$x L;*, rckW 0.ډKE7iIQ#Y)IƖD$u-y`.PD%˴vi?aL4{~yǮjS:>s,9.[m2#~5bq\⡶IYDR+7j B5mұ/gV"s %da}BmZѫ7FNiu6^53Μ1ީ."}4eԮs0eէ<W33+}6nãֈ,uh6*m|;`$2Ehu}K{O h3ûZq~Je;=SqD}.vo5?kS$z Cy f:/*BCE@8! ĞG9s8,m5XW1 *@/Ï`.֧}mnְN;UwaCsAəY5<֭zy b{}; ֮v':{o{q41PZQs@/S >b*"IqSwY# dPU}Lyr[K d"3DH꠰nԪ%Bj(;#oZǟǧAj6M+]]"ʮ뻧X t:;,}>Nrv֞9Kެ)L19Jey=S{OHφ-v0Œ~`m!T>Èy ҝ ]$OEMST>1*^0=u%[LNC5ra8M̗<Ϣx k (61=CbSY;Ȳ"j̥>-<BTݢ,{L`9ReahV/3qp}:Z{YY-<1;zof4~;;xSt:sxPX[gkMN`s2;Y^^g)&1Z:uf:zgaq4dmnLZg&M~&P4hk0dd{7# m2Œjdחi筼x0fa1-B&C~G[ =P7N.27NM\jvf &lMIvҲPQk)f&7)iS`ؕ MF$NbZb&a&t3񬘑c0 42fa߮wRV14] JeT>X9 D 20|ʔHhfA<:VX*TJN? POݯ0 ]EkL(Tu ;ܭ}dIQP"C"??g~32]L|K9%f+]-1HOy::\Xn4dE ^\#D9{gN5 M47dd2rd_?v&r< I=&̺|||6f%:Qftutv/IvtZF3!^m`ɸ4ё',_;k8=yiOMQ$=Z=MܱRU4)DCea52.Vnj麞't:Z'j#j q)V\5t,7|fj})M+!9g0 .imBkɴ8@L(2 y[vi*2 DӧKay8^WnX\Q ä.xHy|5itN9|i)Ŵ(ip f'څaYO7T }iC $~?#4tb&ezc FN[1LVcl-7~|fٙJI SR|~kuu r;eřuO:C;&m#BʳaWNnվZ;fM1gjc&eh|hJɛyf6GB0jF^ƸTb(ߑB1Wg÷ci U Y7uuUTh;v׾ G˖Iv`xnQ.޶uYO>џId< c lP{xne͏~&XbuyqMwۨ}곓]zyP3HDZ. I"~b3S<=B7R!z=ĂcK*U \w}q4 #xjkF '{4I5V:Nhwv`u)јz7 ӒwHV53Ri9Nѽ;J/W .[xď{y?=e侩8yQ>el&K=&*Y >Q%W`H`ɏ0qҫ$zǾKF}t7ݛfL9M{VHfùivFӽn6oƖ)Cz%` xko- ĵoVvU-ၭ>c|KY I"hgr,0xP1%|W^ӯUSwY<&ז.澑vKEj^UF!o$ "qSqqZ&_wb ڬr\ p Y&NћQB.LQmݾް]{eҊ`sH#W[inʪeaV"1or oz_~J{GcP92N~ MAysT9[_Q!pAU(8.w&:w!=`֒;Fվ2CyT|Yuq[mF|š:JI3R %<=?ӗُS gZmS2}nsuLf h>$HP3B^ϲa#Ӝمg SO ZK b:aK>i.f<~Sw+-<.=q>}`6l<Ȃ9kmceTz`ub-RU-' sWɟo ?ͦnkWYS7O YMZ֬r5,&qp{1AqE hF~I#c_ WͦK\ǛNK-5*)I%Չj1.4C8U+##]h"ʚ Ct{۲Zq/B@e2[4mn_Of,Ł&Xکߟ[tO|7"FNZ,vypCu뻝xexT/,{zvgpyU 8vs:ZփxLC}ҢkcY'uOjX6[dTOQ-lӴ) (xwoK)ѧ:ş^$^G eroXCL>iGsM05O!P=$d]}b! c9Ҩ(hT7>gc=obuۤhe} $ '_/m̬󣵴>z:{>Ncؘqb{lTw'hy,#eڱ+Z<[nK*S~h T~Eèi!@z*P;{ԩ0L"2g7)h]k:.wg_7^fI=I"flѤ8ʢº"l3 jxC٬"|jC$5?'@?S{}t8(yQOa0b- 6Xa2jdŔ`n,XdlM 6Y 1Sj<:EaA}08=& GTtC]M;w.i֮9X,;j*vTbi3*lLcdU̴io#S\a9suQ<l:2ܡ»/X4,29`PN\#H1 F,4JT%@3;\^!Ԭܸ `D<3̆Y"#F"ia>ÿsuRmcGw+˛ѺsNmyffoD9x'E҈$$bR~1nCJ7|+oU[MsuϽӾo,m! esF8iIT`W`cz7SRG+ěϛc (QjŠ)8a=!<%(;]}i}=) ,č}T&=T䇍Q6FkGvY38]nѥ%5:p:=e,f^[#D|ϰ4ϻ.,zOPtop e|튱8PZvPIvp0GnkظV&;m ]-'mZz/udgz5PBk`4Nɇ$xC݁ նpӠ+r^Ԙ =m.)Wyi.2>M:hb_zYD(E!}$!z8!l7+%YU[62%6Xa1 +lS X7 (ld=Fsb[7O@xJ.wۍfj1}!l1l7e'=f'83fdpl绖+p7OdY΋NU^T+`J*<\^@cW(N!g`Fc0oq _p0e! ټ0.;dDB ]{8UЎ|R1O+铖^>A+KKo>fSc SǢzjǶ ˣ hҪ`zjL|$KǡK($B`Y6mlj|owΞWDy3z{9%F]ފ.>YbS㝻+9yZ5 AnM (n]k:#Gj҉YKta0!6Ծ~6?d,3Dk]Ў HE8pHWuww ,J=Nݵk3^V'hARH1mO% oCcO6$5oRp-^ ZM*a V ^V|B() +]'އۺ%ER#w+ _SX$T*&ZLu;K"9wz,f hmysX-E/bB"gH}(K{baFڗ/ ~HA<>AQ9KHbe6؇R<P&y|O[ _"6)& #ix#Jf9$+X9Ң1ݞ}r|Bq`|#hDT>Fϳ3 ե%]v;+\]i/+4" Hvw+]%sఠ=8wyD9'U@gA@Ol!ϛe_)Mi.z$z|L߽ÏC_lEʕoS"( c (d'g.O{aZ3 ZyN"|{f"rO2m<vMNzoJogU !QHT9~l)(OZ|vb3]`c/t×>q4|lm(bTU;6lM18>b,[NO'^}ӎ@M2dĸzf2}+Q KrYM=v|s1YneGŹf^}_VwіUWV.lKN ~pð7)x]yֈ#?ޕ#Hs;uzQm >'si>^Sh/g!0h,F忴9Z.$ }h1cm%CQhG7~y=Jeem71V)X2f1}M3?;[l|t-}dgo^Wux_=u'AG]aӁXw no~sƪ:zVh2jS}fhX!.b 4ɶ.[iR{Uӽ올C}|isVWM=Kmfzyk\xws Y ~l7w_K8ZGL H0]Oo=>:P8 o0vow9{6M'Xqקkd``ZGtj6ƚ৷'[$ d)ξnuwۗɌv[b6z3jk֚LvTf'۰Xy7rŊʓba M+ W*ĜAִei>){fVSl&SM^4ZϾZ5i}bm5dY[zkYe6a;73=:yI<9Lx^p2Hk>ݚCM~q= <ĭq€Ք(vMBA b%dn^ƞj[_ib<悑(E2r (tCz|ְ}]ŗjsyz3wmYfFSk3Y-f&yv`ZmLx6 flsz?Ȼ>r! 7`_/|W^l,8ɈzRuGxhԚRI 7]0:(v# w.*>LENeu\7a$*2*0PBh׌arJ&6I<HR/~Jc9m#XяmVo5Mxŭf2d~;wl Sɔ:׆q{aQ#Ԧ̓$̹5ݾ9y`Z6U=I #H\{t kV(=[l-?pw|cZgďy c$]YxtiWmvvvYu1REi$hX&#dwuoDSyۡ7o4by} M=nL=#}znXyLF`D7ٮuߧ!}sj:$*>ɭ]Y@B`FX; O1R'C= Znjq&K x1H6`eTXǛ/^KyE=Z*,'BκgW*,TQ_7VBiC2]fbG,f"LA2aQ`(T$\L}DC=,I=ܷnWջٖKg#^z1zfd42=VCFQ$ŢKW2iNad][g6hךS_km&u Y_\dQAm~UxN Yb 5uݛŒ2#S̡Ej^`CC т[9i鰰7֤Pk(EhkN8 9 !O 5i X\fӏN)zsivLFXM{egͷuۣ./ X' /tihRc5h]6vǔ.Ȇ:~4njeߤߖ+ >V~0Kt%]I]^aɛBSN쇉͓ff4,mݫ*qJֹz#ݓ\*AHɆ-|tZos6ΪI7 kV,:zO-EDkM>pq@ إwʼuy==o~;B}B䥋Z$<)+3š-z< չݸd)IuQ ӺoG1]w}5^͎IzC NmTjC)b|$rt K/}ss dfщ!'S"wO#q3a5dx*,x&Ձ/_ႧYUuhjyPݦ _5c\EV-T:dg#U8`8F7Nlus>}[nXy,o{w ̷10ZzX ^z292oҴ_U;(ro}zб{"{rwņt=$Ä'[CjQ֞6, ɽ1+ès6OhaMD"o"]|_h $ƙkio\zx)Jvsikj$ir5Ianϰ{ӄͻ.qwhq%sԺY{op.׷TaF@잹lmt.W1i/ΥӻÜ_3zN:y]1[]3qa[p~UA*Ufo]/ԑ6%qDq&A탼wcx Ijm[{owzv\QđՑȒD>PSvߵ.a"VOXZ*6B}^RiRRf"<TnJb,3ɺb_wxhluF4pd,t{Z DNVhvp6ͯSL_,Ԥh{뢐ګNҩŢo6f|X=QX;P>.8@vo5IbkEvrC3F0Lx 8Ux\,WDH HyglT`!؋b,txLVHdܖ8CoYj&7"?eTis;pS7"ɄQ)9ZX~YePMGz3<<]LǤbs6e"Uy|0,XpQ(S~EZŔ0AlmēIIXCEfIiĐ}gsC&}2.k: \=}G7W ;[K.u udr[U'­;BoB}1k *NEQwu5 ŭhJ&Dr $Ʌv1Γ\guE(/|~ȴ݀z[6:_'~xHj1hާrdԗ1z~$!t(CHQ Qϳ_\IVcnEUy?8W ƷMՄ6CkΎ1FMb>em*2~ve%=_ӱby>iK|^3wgU}jQA-U{]Z+G">k&b+SM Z㌋buZ|#疅JQi{;4)B #Cc ^I\ꆒTBJ.Qݭ 4 .Kż_D|?:,s9_`Y?>'cپ!7O N "wjM'/ӤnS >>C;3$O 6#,|ŜNʯrnuY9s8N>uOry^{CoI٨~d6N4:IymӼöqb ݇XBӬA \6+_3B, S!:P#P w&Ise6lϾx[,{S6,V,^e`kצ#oz$5;g|/yzL6u;Wn:yvd,^Ldp7CIŏ?Pzﭲ0lQID9< \xu7RhD,>hݏa{x:ukÔ*|Bń5+Hta-r趖ҬU 0춖 YJY$<ɍ*VVU<|m%QM*Z>E߉JRd+n}מ1[5L국0Q3yn7e9tEwWag&Cf ŲhٹvI84I5iD/WalQ|;f:7Y)E+l՘>oJ{ <{z;9IYU 1g ɖ<.\hU#I},X`YvYZ[kwqe6nLV^&&n3|dd43Y3>{74&^6.KNʆ!qٿb=z<f_p]#ȝjU@=eq[ZvfTS0u5;jV|TMe($Hk<ڦR]8J* Z <ȸU2k`ȱ dmȏ{Ә=mFKX3Kfaame2n6}^xlX{/G^iGo;ݿ~֨›ެa7&DZtt:L^X/ެ p xh$_jNhYŹha2!=ONa!~P>ǭnͳk}9'MKyƣQ/x&<ɔ4R+3IT&M4Y"Z4⹋W\t2R)GG%Ts-;'JlwyejMa'G>湙JId {rv+ev/8}fto [^׌1]Y T䪵-Lj$FF65bجb&6QBZ)6b5F0ة-JX*mE&LMH6)5,LVh* 1`j#0 H[`Hbe4TZ1F*a Ik,X6E(j4XMQX-lj% $L*4D"+&54dآ-h-i1mF D!Bm%bdƨFEC4hCQb1XcA"Ƥd1FE*, ,lض,Pm,łŋ&-D QREccXјFьL3hV,FQ6*ƲQM"AXѬ%6-1Zd[(PlUKbKH&PQTQbhƣPb,d̃b60F #hыIF,cj4T$AIF"(d$(U&lV,j!ZMd6Y$S f+-BL#PkS1FE6FkEɊ(b [Tlm%mEd6RbRZhMhXfcAT@X`HX5$SbRZ dQH1ѢѰm@ch*I)MFT2Z i65j4b60m1ؔF#jBBS"Q6fc&d4#(JbD MEcQDmQF5ci#hEmQ!lD 3IEH- h -PmAE$dlj-QiTTѦh&E%c4%*"Ƣ!EREmXL2V4hIj15dLĐFF jh5D[MD-&+5 dLI26$رEk-JIT*ѭIQmEch+V-Ql6mEh1hj+@V,j5XѨkղchث&Ah+DbmdRRRHJ-*TjmcmcjZ5cmZŊXѬEL TEAZ,(EmbdZmjJ#kDV5m+QkFm%EՊ(X-XEj5Zh!bf-5Tkkض+j5bmF5Ѫ#ZƊ +h $RU!lm6"ՈDѶM6آ4FV$ $%+EF**уEƨZZJ TQ6l"$"%jmKDIU5ƱF*fkhVƵEcHTحXB6M"&B5-V5T0b֍T"جjh6h*ƈ*E66 ,jƱVFaJUB!)DPZ DhDZi)V%R!hQ(P)))D BJTZmE5QVڋhѴ[EXQX*bkQjڢ-(lZ Uj*clj--V5Qj*61IhƍlV2ZѵYXحEj26ض4*R-Т ЂЪ4kjk[lF(TVY  - AJ-FDѵV4*R(-(-NkXcj,[ckFUFTj-KThƵF"bFEըZ6(ض*V6$VdhlQ6ERLlZ5bуcZ 6JB`ƣTj()(KF Q&ccV5hC&El[ضѬ[FƱcT`5FcZT[b-6رmML-dcQQ-bTF(bTBZF Q JDhFJEhA&EiQD@A)A(VD QVV[RETVEQFh+T[mbR(ZZ@FPP PJQ(QFVQR**6b%F62bQV**4kŵhԑ TJAAdMgZWpA-(@-@ րH@dh@ :[35- P D{L0JC6B%B(UJVKkAݔsF6m֔ٚ>]ir:=xC˱>z֞= Ͼ{I^{>>|z> TTI) UHI6TU@ MTVRRmD@H[hUMOvU VRDRTTAB0T$)*$R$UHJ)"$TTmTHRJ!JEJJE-JDEB$% P+M"TR"JH&*Ul%AQP )JR )*J5U- 4lh MTUUmEhVшD"QP (l=Ha/(VH*6bՌى,ڳRMܾxc;{qϏzv=S1 -U)>w·Wݙ*+i^ lT٨ɦM+ZH[m۱p< x=;Z3穹V}(>ϽzY>gx[U*QUkaؕfdf WxOww=;oyo|>}o=|>T}/'E*AkV2,1R vԻ۹!zy}h˾Cxy}gz=_m Jf6Jk3aeVM騽}^eOwݾo;7.}uGλ%V6lR]WL L=]whs\8qnGu3;w+{θܝs%s]tu;zc{OܾOwk# ě&! Je&&0BZ;UMw W7utvtr7HCr$C t7Q9bhLW)ܒü\η ybwnNxO]y;zn773 I1bM4YnF]rBg]|pts / $)ͺ[ٽcd5Er^n{ȝ"fn\J]\ܹ{y]ҁsL׻F;E;Ȏ]*vNJ):$ˌ]˺Mֻu\]וz]ݽS7q:өwv:b.6;M۽ lN{yGGG+s]t*;Ou2mfVZm%ݮwǕE\5!cFnRd5vv[oMn;F9Ȑ0uE\^hfSyr $b&Y"WA{Q6r)nQJ-pѮmjXJ]tE]7k;Dz͹inݢZJ-ޯfb^ݔ6t1hwZTX]sdA:Qs\DgY1b-MkR,0r{$)'k`b*|TFkt%"$0w>w+wDFn.,Qd*5]BwTA\EF]N5\1b{\#Gs*JbGWvX$Ɗ[n4Q1v ;kQbFѱ`J!u1&X\ƒow bwG^=6]u\I$+1FwV;"B ڍnЋsQv$EDɨۜ1QጚR6Jp$QAJKvۆ*K%1)ha|@6]Ȣ^^ݵ0mklmQT3&k6lj*3+w+*6JewtŒS.TTe+D;\^-s+z]|Tj,kdhƽzj3kmhۻ12F]Q%I1upWv bL|oIEALcPXƍvJۆlk35j"˭޳1p1cbn (kgm"뺰w4ȆD L"i@TYAl!\o[aIWFw(鮖-u݉]b77M9QJm1g{ޅ.F7.zo[r\sNm<'klD "9lq0j(+eJnm6TQfnԺn>Zws93FM2hK,kyFO]\&ڄSM66ڂqJDd/]op!d"f,C35]"IS6dowsn=Fcy=woܭWZnb6v FJ+lvƺ\ov506&L>o`wW[3cnr1]HbMrݍ&|owfF1!ۚ%tϋrɦtuвU?cW8F]Mːrg{zOưyoX0eFם7ut[c;-kk7WkrSWkDl{EuLv$$TD^W&o\w;IQ1wt湴_ܻSmzъHzr0gu;^wvsؽys|q7D:녻I,1WrNԗ]ޞם /=үPHn$ YXQ@M6'=ռ"H[ˮrs4\W+{QN&yynht*+ĺ΋t;'zsno79^; JQF6 %bQ|b|.J+]tgo7u܍r\usw=m׺{ˮS]ӽG0#;P;uvtPwNz:u.w&ܻ^v .Lnu˫uqܣ^uwr'r49׽9ܗ.r9绋wwsw+źYzybO{WslcM(Jm I &ݻOك3ckrIוA-PBVi6nj- DZM\zm"5E|US&bTh|I{zRmEhCy΢/.wu;ɼthݝݗ.uWv+J:oxIn]uu\g;:c.^>zs%ӾJtӝ"wwu|]td>c]Rs=&wfkwu\$w[4ݘ :IvVD&{rn:αۻ7T7WkrQFvk&kבכ1tʹ{׼t.yWvω!p`^{P!#iL\ل!*o &3עƺwz{2%TEzWqںLs5w1Rhwo4m&Iȫ|t]s{r̢1b5¹ TvD7|wR) rWA**CʢFJ`>4[ڽ{ 1w׭yCsሯJ+]\guw7msEC/zlYitLꋩ‹1+,PT)KI4@|{2PH 't)ݦA&(@$N$d$&Fc |ךF$э]krjwW|o*4Y t.)%k-6ܢ2LjH"5BׄcR(6kdF؉E^msnQ RRdu{.ցF;b鯏 -Gs˛jI/m2T-܌kyY ]wz_(6vnn;p;{soWnwsΫ5ۆQ]bA=M㓞7TE*w5v4Kt'mzm޷ovwRRQW]Ѱlj5 v(L͐{Ƌ6ɠ ʮ͋%XVJ-FLAb6b%F$a62A1dL6:r6HfF#[XE خr6#i0ɨE(j+hKѨʈHFQbeFبb0lTlEX(a|w{v'yWFUzI0Mb0k+m"b٘$cA[1l1)E11$I@QٚLH-(CQc 4m2*7M-&AFQXLܮh%cdDkQQ$4!ݹRP 52LXŊl5$u݊ŋ3j5{Wvҗ渕`cFQau,A$RFҺj4beY;,cARh5$+3cBdtܩ6" KGKKF,i(Tk%{Q "cDd,ce4MsL+[KXؐ5`0lb1Al!]{^^V,ر,c&dɁcQ-Mj4'utXCi))2F"JilRcqEرFYF6djZ-"wJ]Vrܦ}l #0 aҠ)&( aϠC|Z,$E A4Pj Q罱sʪX+tygZ){OX Y }Q.DFE<+,*EH;M}ui_-kkdK4 oZr,'M*7X ׯ Lt7N[ϟfSa|!`paio:>CɿU.+ta2io7Hz}89h̵ˍ2B*;v֕M\rN#&*#Pv}3 *\9.>{5A`'i;+3]c'xlxA>*hT  Aiڻ[k1)%$t'tնwEIP E:\ VVHCUjUc|ϻs-'#I3Mu}M{@90Gt4nbk9Z q +(Yno]::ԙzkstSŃ[.6|xiMf:腷893f=6W3o@##Ej0˪T]oo>jY)s 4#HGRZM,_}unD =಩9l|Py+X}]-řY<û9lKrix'hH'M;=>w)Gc\x=ܵV83AϢڬ\vJ9b;,&{;~@ "FY.1xbp? 5}^H9ɽ!*r.fY>S8 @;C$sf['0t,z>ؓHvތ] 5<_}ڙam3 \lg J[ Sա9遐e:xۮ,x|%;>9Ջ5"c.Q=ԙcFώ%pj|{Q><p\$tع8.g.9.;|337Eє#ފ?Md>c쭹2vUoMQho&GcwFxYvYw؏(.VGsPӸ*Bu3iSvuh{o5doy5r> %۲YnL+ W3K|;]ΰa,}ˎ ergfu7Y;2fx.4][̲iTlWDŽ\E&NqF)/FHootQRCG]2^hENLiҔjw|r'ghC"F98~ɕ;n% s\2#Gs$.QS(ٜmpYf*abMZ$Y'],`AB֬V!`EPN Pk9`jUqF4; ]3:Dӥ Cr_b\)IRrR\>`@U CWў$~!`Iل[ ) \#yaΡg*b "F߶wɢvzԻN)ؖ 0lb;FޭνvX7)ΧU Q.ՂG';+7߸p!&@7C(e`*RTFΣ Ww}si|]״-s@Õ:sq;" hZ'"K6Nxȭcr P4[48\]'De) )j`g}na̬{]:־ $f >} zGḭzZghUβ9M,XWj{{yun#\7|<-X-`$}ٸvj'KlPKwљPp̼t>RF{rT]x֎(n\әM⎶۪KGQAeA}1n}-ƾyf7J` ѥ>p1yvxB+nvhЂs7S3P%`B@M6@>Þϵi8@L߽Eo/\SA_|˷B<$s" @P$ @@k\ if_!^6BMo꾟dOQ(@_ŠEO (Jr<}_1ھѯ|,@K[B( /JX}\|n{+>i}ok}uPTuBq z. ">DIEkS OMt$Ǹ@eKs<\hv þ}v2.2e^_,g+o\"_I,ّX2'4_M/{ą/Qgr_#&d乢I> nvy*U'J0-=u;7 HxܾяW*A:;%-$ZKZt  Yx:\ɎrY {^OI[8 lz5l{g'ZSug+Jyahq,{V. k-l^Ѽ ΟAtuI]u/3bny:uN!xѭN."7ؼqYT9xDq"&Y١Ъ۔YGۻJ hŖlA|1zY᪨}67ZVݽ1[.dn,ju!ٛri{=h yLh"g>&=\i|NS\!ObVxCU-t6㙺rMzG`Dwɱ.cLS!"Htu;Z]j%Xsw9[3vU祭%}7q> j7޻6 AoϼY#iݺݽjl^+=y"\5u2wqdU'k/N6:ܮ kq.l1}bx[*\mI*^ό7}Y6b7|z4:>eOfis~h ^<˝a9|nZ:p+sdvqۻG%oy-]OC7\F݈A/Umɹkzggs}35/0۹q yjVyg-I}ym7 yҼP/q2mu(ln& qml5w.VgU ;Ųs]!NVbym,*yK `To5or5"-Eڛ7_g3€BB @?W#~c{on{+^V!Qe\NßBD3mSeopLMvu/4!3BYj9/k.F_{xF'4Bcqv&4BjeV(%S/%N 3zLvo<(AN.zM?}Wɢ zϝX3yfqEO;(}V*)p@Ɨޭ h0F$"d>*jL@~?LՇSE(_ݽ_XVCy -κ _i'wZ ҈6ml:$oi@f UUpuSn3@ W2 Q9g {> IY,:|4/  M!!Rő{H@R>'z`'$i67)P( $@ޞƅ" KmD BєBAB&۴.I `_׫ݲB!YIܰP$" y %~]ivUXK{VP QCŻ']ZoePC بXT>k=t 4[7&{Rķ;-lqJV]Wmg<; Pb`,K3{%|-fVTF\b-G0w3bb \vvvv@U}R>J"k{Q'.ggի8uOls e{ź^N̼k R,2KxRy'TOw3[mNCL݌>b }|Yҙ[&a1V=`[Mz251sȟy{0L/.J|; 3GLeG *ĬJ_$eA3洩^k'% Wt0z{JL)+yMX7EQ8(  {}BϪ\ kk&x(#1`: *;٢JJKI#9͟V< !bLOnt]3ǽ/Ԅ62heA(p:_ !)v˪nY}k6bٮN׳4Qe{:;%q{Ç|85fH2 }ܘ>y{u ܞX-v-VDb|\>~ #`Cޑ?x,Z𼇛\pz~Lwe㪭<{SQbc szBۂlRW!T >MaaFvfE_;[3 Iq4AN/Ǫzd$=yԌݳLÚ8i%}j%WILP^w|Cl<Ւ]x桇\L}$YIg*P(z/L% NrQlBY-ܢZ1k}FyMBt7U>܊Q| (3xHOS=1 !Uj~ .Ta(* Q gĀW|ΧT|E I gw`xjPpuP\nL{O+[)G62' 883 X* ZS12Z)$1$1sͺvH YE׮[-lr拢F~~?n/X71Wサqo̿:eL&~\ksF"r21װbH>ԃU*Apm *HI+ZŒlI* RR["*iJL(ARV, I$Z!EjдhFJ@ZB$R6J%P (טg `CM/3 l| J%)+_t W|j13RUMJg$ϒVb@>}q_CIxyTy2 Ie8~>ً^%^+;naL ZQ;9/GCITE/5J&S^ / $kk~-rۛ>ܮb~.Dm1͘*S_4>a;06l[3ߐ>{[L;jmѰF֢]/k:Wb*5m~ltDCC"U MmbI [41̋UB[BV[%(\IA[(Z[BAZR1 ,mbFP+8He)!-@s7iyg SР֭Z+m'M*gm!u;I,e]_ᤈH/m_ɭ)wj~?_.ӅgBq7yAA'6~Ի▯l,PbXU&V1X$( Il}s,d|3$fHw+E/M-_/#uѵ͎tFwv6W#-}[sNљ$M#' ] FB-m J4u+%C!@ ҄HBwMK7Mm HPUJR`d#RS1( 5 D^>XENwadnhuKO~a[T0r>|To߇^@,+*}խr h%M's=2htG{I%~O{g׷= >L!3T\/4!iUQ~!:I|ÐI1ztߎ\(9뻹umKEͱe٭} r&|}^3pWʋ*Lm\k_J1W?*Ѫcc %emkR%56ijԴvCm҄ad*TaM#7"hFX@CjK`ZTOg[2g|`t,kD FꝚU!*B\Ś,8߽$U=̲]E .ޡLxA=$:]N~:H ~Rv: PY,zreFv>$Ov6Hsvg /^^,PPVW|oUEB 1&*juI )V! eľ~5|_6I <2'b8tó 9qSo޾{sۛZ5c4ݸ歋{Iz{ FmleRieZpX$ "MɘD4 +&@T6KHIZ]sRnBT ϗW |t3 >)%}.:&d_(+^k[nޱ2.gʹ|e%uWp[}}?yBܸG* S̭ 9JT 2%‹k+\W_rat1@@XyiW U$6V~k*oΚ_Gv] PU^)K[7LIB @|Tv:>kM$L)a6Z-_VZ"_6U>{);~~~BHh+p p%L3SWApZjc!#BR!*5 miѠrjYAK??1 ]ӟJq ˵<:t MӸЩ pO6w2N/% W%ձ1jQT&:Obu"wR>ƂŜX,C 64̼0PQL(xvK;6ZiuGhM6$ $>suU*t|' s $[\w| ߿W?pڿߖުJFojELk`q m~9NJtB4)KJ* q *(InahhtѸbQilIw7ZB-ehCr RHB www^s5#׾;Io3g۲XjrXk$x"&߄/}Om}7ߪ~Y?. /J֓V^uclOo 9pkFGŽGA,|},ۈ7-Xm<~)) vIx _ vRKEa{k~|X|.grX;rTwj[ܮBI?ݣVU6ߗjB02 CfB$90 daBSMwma*ѢimJmBZ9jh JB0>"r!2Lٴu{bcd ɞM;SM i2 G!Jx??Rb`ۋ=+q.^',FٙG`K'^nAA*mpAJ)nZJ+_̪!/Dڪ )$~OvwSU,ݼQf'wiK)S- a(@*30 J-\FJl*4- bD(`㋖B- 6 *Zѥ-Bo*x<7VVPa +j?NȚLfwVgjIf&g ю^ֈy7 8'9%25}Uq:6A1B2[ʸ!r d8):ocqL7{)_:hoB&ݝ]lb?#5;8nu, /1F0)PE$68)7*X 3fPrbYǷA<zd.=_`ܖN4`Ty={)L04Kl4;zY4[-m3]t@M4|/}R[gt4v օƀ"38ӱZ˸}aaa;{jUHڽ]ejt7ԇdb%G%b֧v Tדs9Bp(Yen]v+ qviONNkvnƅ&zxl{^)w~5_sчyf4*c)JP}靺Sr[h O|Xʮ0zb{[tuKϩ#um97o ˼Nyϕ\v*Q2_v0 Vp}r3sRCpG+k}rr绷vY3=dpzh09zh8*-6g{\hwc}r^lʵM&XcL;A"z+c 3',r nΪ0]Hhj T_tbkGg@K[wvC]ޝtM6ņ}xSr{'r;f{**ޖhR'ny^^nOB07jIF I74D}fQI@$b3qZ+dxvKΔ켏mu1DmBSO] |ƴd *Ld8ߦ Flx3.po9hB.֦ZkŠLޚ:V9*zW!S]XFSYK )w%f價ݾ1-8 jj H@ Ұ6 ui}bYkK3})M$b:i3,t{'B[LA?cRm_DNYɒ?{f,X^xW`ή;w#(IPtDCx8#L30og YЖ;^ ܁w*k;*:c(֮nZYXLdWIfEKSvΗa]wqmr{Y4;qJ{NBk=ӀZ5` e E4Ww~HYIj3Bf<Q/jl99it!U<ʍDW0MtTNc0o*s/L$lI+Y :ʙLĶ縖abļ1>篲H5^B/L}Szb%7OvƺByȉ=xf%{-#׍ʨ|tzk!ڥytnEf9]WKlee#` M[a_p8g5ŏے=k2{ep3=QUWg>+nn5+3r.NX1~_#&kѬ5ql*:oftgҏr;qWʮw`ɗtȿ8˔mgGyA2N|@v(cF!Zm_A.uV7,5ʎ:i=ԴU AKBc'3yh‡ YJҋf8hr`mԥY[D{-KtG-1Dr"WB݃cS3'Fw˰O`oϑ Ղ.o'|jjj$KS"t6W/Hmͨ1.=yNʽ[ٺ6jƷM6 rm OpSa6 MǪl*u!o>ސל·&ix)v!m{mJmxq{X2zҽumh.]m/qE?d y}P>;r]{21xEp׻@Ө3d*DžVJ Z^lMlo0Da-qxNn"W3E]}G(5)Y ^XrŠtngz"={T#n6>3%3`9[kVӜܧ&olio$LJyx'.R7:mg[Jb ̐Yƫ/wIh**t#3+},V2H>f-޿綮9v9G V70q9ʙYOxN<< +:_#jam;AG Ye8ݾCX􈢨{ ۨe/o(tI7rqF c6p۪bΌ@ <'3<)f,sS" ํ:r]X/$;'*ݳ E|'vZuUf]`z[ ܮ#l-6>;IM3p4wm>x[mIW6FԜUvj|&^s{_M_Uz\D.°{$ĭ\3 1hʛ.Ժ@ʨui=5u5iY[}&/P[(S5Rg)tyyk ^+;jE܉6gqYw|pf_v+{l9&.rf_:=ѪvJu]`rOaI!.R`-F[Z ⼺#t!/%sڵXu&h]l=lɕHʍ4: cojNu3R5!ku2duw6^ܤx+,o5=gV3Z:'UfY:Pcv3*+;H{5(Tf p_ {#o:RїSyy嗡].0oL ݓW'_*yqҖ1䷝ݿ'K⒲;U;TpjtJLTQur{* Ђ:sq^JeK1>h3zK9viL!G;+/%9qg0u>\F}YydCWf:r0zi l V(H|Yrex&sč$_Cȹ]YO}zpiFU-h y<w"'`}zpC.qlRICXA'{An3w{PQ"GJK>=_kXhZ}rqZ+\Q[![])V%{o54kHVwQy!Q ʳ0BYƐom]5{{ oV_ 3d*vr!Dۚ4NQ\ud/^zkQt㚧g>Ío',+xhIm<(ǍueWvei2\|FQ0FQ\t}^:M隠1m‹/hqTWo.;R%xdMԯjzIn}L2U49T2ѡV]^);3FDEU !Hm-ͣzu )U|ؕ١N\ۻ=O\~&eckVڧ6v]}÷IwU]XОKܗrp.u:z蹒riޭob^!Ki=ˣ )&m9kڮR]+kfJS2&j&:rZJP%mV})ST9>,~;痧tx:xA".ts?p\/ܯxIuN Ε6NqrƧ un-oMrno㺩űl[ɦW!í+ *z[kr!=-@,:ᦷsۘx:#˅ګ]ePn`ұ=(Ey٥j3>XM1/<EV]hOn«QN֋lTxȟd{SҫMt1jsɓݨ⫾߲ɭΤ$: ӂͧuOE=y3v6}SqsT,xନLc(g|=7*q7Gj* q4Jm鞣=ZMElgF=Qlݩ;[DT,#z:M7/_7W3Vft3.vWsn*9 8jie9MWC:n#|վE4.iZtxqs4zGdmfU6Rw}n7sGR3Y(˦{ C[|4@q rwtbmw ǎn;\0p#JNxc$<X<4?3HBMc9&1] PڌrFiY6xxL(VaK%.I-fϦkO3XJ]bK2ٖ CΏ{;z0삲^bvJ*w*XHorvT9,7cvTm:g5Q{QLEKvOn&Fֺ :͒xs}j>dﮒ鼁>^<JyJ$(&y6pȱOs4-B7ͪ.f}VtSKXɊ򘶰EeTZT:4״Rܡ&EOaYu%m+nv `?sggF'r=z!$sor8JvYFcS5'Wt}4J=EGᓔ(]h\'Sf_ K jL%m.fvr ζjȤ45Z!JCn{@zoS_u'܃%cnWm{s m=78w}nR= DPfi0;fDA)~I|=Ȫ ֽE3:`^ְy'Z| =K/y)X7KJfȼ7t݈+^3`xvMr_"jW<{6uơ)]k`ަ-a2̻6Y;;˰ĥl&K 5YέWk[z܏.7{wd*L0_^lY)-$Ji.:r'0]*Kră;oMv~Eo\^̗%3WY1i;7j݋jRD#8 ݭ\FᚄNJg7iJt^(B!( {}0T[3m:dlTs+Z{٦(;Z5u=TgۚI l}$lOVEܫ/=eQf87 N,.{G<+:]eds ˯JV\] szms/2+K0h]*D̵[A^l v -h Z-{pMV8s9N;92}cxsp݇XMԹ:Mך/dodfꞱj{8n{ftj;)F[uC2׊S3d4+5yrNGkÆ+UM[vnK]o{$|KHVWNMk<毖df劗װ+M؎†w2eTN*ˍ^+ӥ! ^_yY! c; DsE|=]aYSpdK+6]s75O/M:gUv3;* gK^ȸZki{Y= /ΪaL3:מ5 >ىf"y۲^U[)9ѵvg<)ю=ж#}xn%+x%*tx+ﴮ3, ̗j{_݁1b@R]UP0Xks6,qrU߭Vj5d=guLTPi0s×}ٙK.dڎO]ѓobzySdN*f$jmڳ1.pG'Tw70_5ث~ϽkG 9[ݚcDͭ$IYe;؍O; pB6]K0hnbI r,t&k~,롁v-'KZaK!x{ Ἅ17RNu)+,m ;P"f[Ec:g)[,r[}k)Dzg|ovt1Y2B2K؝_oˇ\^%-VĚګ՜rÙk{m7qȢ/.fh]D%3V$7rho~CtL~u[3o\;Y3 [x NQx;DUoB |0n΋avP@xcy:Zfˉ{:T2j:U/T]dڭ u=BMwvgE^i1ND7mʡ ǵ t(}]lu}j Į>$ώ=iyZHCkD頖v1J, N2]܌=g(3&T_W^]UMܘ2G8)|,=z#9ϰ"YՏ.G&b:=9gl]Zf ,n}T MdOBdZWG$|fpXbo[;uaF>#8z8rƢ)]DۼrXDmO ^t.WBqaTq*i>2'[ 6)mX35Nn-[JRG+|3qnܴs;yLnzn6Zζ"v9)nsw*dKb7'ґYaw^I9OK90Uռٺ w.u:c5O^=&:3o93V)W.S,ծ`='nW)zG[+fooI:D}Y}x▜G 8Z >*|HkDS^`0}q hӏ4{%4$y۷rQV$+`yv,M ǂج؜ģ/H;Ώ9l,zQ= *dd{k ҅3}Orjɘs6;{-Pc[y5BzP=:[:LJڹAVos:dckAzdpjvTN2 ܋| B۝Q<(=2va˜,ذxysT뙯1ƶuĒegKV۲#*t[]sB̼д~Bv=u3LnmMos^fP-ѺYL,g&M`z8DVv7 d]W' CKq㾫+/rpwů@^;>6#ӥP3v4YQ'wj (dTy{ف*陲O>8t zv9vGގ刯j^44"5K&*f 6W[ ;Z) Kͳew>{}|;Kܽ{M+|Wz 8+Ed7C5ۛKtx¦shd!jMgpaEؽA^n%hϰݭ܏U,e~ٻܼtOsL]L+ٝ|i\WWjjЗ}Ӑ=5w困_yIxE>6J n-rq=mc84G8S8Vw2%]WEgJvy :nu!ފtf[ߔ P^1eأ;Ǫ0Wgvje]:quJw^N7wJEVuK/k~kwpݭ'0(=T+V;a{WoW&<u6=C5l\FMLjCsOQUIYՙQ ڳ*NS9`]hOVBeőסdN)md+عjK\$c;4}Ԗ4*r%2Mq7݋kj0p%%.'w:G[}aYzɇC {AV;#M٠}f-aortЙnLXyhοV^ hLpl<3kJaMҳxfSk1G=os6ɓ6/=7'e\]x+k fʍclCA\g7].jUّ9K>WE\ccdx#$JV~NBQq%y,sbjit[2HqC`Ȋt$uܘh^,db{y`sna]:iܫ=^Hs\.YKjgQ.Pˬ鎚vF*wbcɁ16MK%hoe󎙉'fϢdt`d5-Ɵ=s3d7MIu46Ep-hd7_9T3^9XVpzVp iodAފl\0ӻ R {-3nv}ث4/U_Yg"muv{CdžgY {V3aR9 i/o(:Île*gfqqsQBehފi"}aXPrT#C!ܥ n[QĴkX~s{-b=w"g.2rh ]ʔLj!սh<ӗ8*ӧYrYy<^ƜUz+0-Sc^j$u#線$* 9!E\Y:0ܨbF8[մ9фYH7=\建hdv>V^#UAlnmjJ[^rtuӅZv\pfbLwJYg/f7-|9OLۿkmȣ ղN4euKs{Hosتw{$LFF0tTqB{{HuJKwճBm@hltN.ΚcF7sgjXI:U᭼ZseVW}r{7Iy!1X'C`ʙy(.Fv=wTXGf^pժAun{ج3TmpكDՌy\b=X֌!Vpژ::v_7:YTSZi'̲VݼhS|eVÝeҥj7"-7e42oUsҗB&qMG#{pT'חf.>%5ؿi [VΙ PǷ1Wb왛Isl09x5ʆ\}yYT}~[7!ʦ-U9+fr1϶2d%sUKH7نL{-x18j-^evaa"DDg&ٮ `Ex:+qUlKEGdRJ*i_x r5}7!5gKd^iђaZػ:OgLGB>~XUv$o#*LC{L}HXK %Le1` FA!±fp g%:bSL9bWqW9e,faBnNSPXKb@u}Z8O>yqyh]#mg#KvT0UaU|}}kxnlZsWOܳٗ=)bLunUj\ Uim)/󆼰- Pox>yZ778#%vT\/!;Ҝ.|HAKo:k/fͲ2T .t%C]STF?of 뱕rrtku+ 𽣜y۱yU9:u}KX9ӫe5 dRc;)^4dž$/C{- zݰ1zi+<m/{^+ÁmtDUV^=Bն2uXkmʻ7@utYihhoyG#FL3qՎ,JM<əxtWܱ.w~m^G싨5|_ij6,5زs>=kAwxwVe O;ï7,͐#& 6$ĥ,iK2hI.RUH;-Ʒ5G'nG-XN9n_erX:}L Klι73omuhqF=wپފ,0dHZG8VM҃ro$k7D|$U^v,xi‰_{ǫԋ^9a(-+7[䱾n;R]n^yW lM9˿eL5~6z@e[g+5!+T'V5&R׆oRӳܘGNpv0aek(u6V 0^[)%@KZ 8 m󛡘*`Guu&z Bm1.t).0n\óAzP^ iO)G6wȟ1K(jE.%zWђzo)&oɞpa3+gb_Tf>ԧTLy֘m=[} NE:|_.mZc67bSm{M7U_^ax!# { ]H_ccbkgߞŋi-oRvnNNŒ5hv=:sP!Q`&[L~w=+wSBσ)T53_[ԎZ(lAM* [ V佼ɼ [Lpzݹޓ}K8LuUu`r:}dD^ȹYiߘtuٍؔeB1Qj"t٫6܂6+c^^bZyr[ݫ;Ʌ"ww 3aZ;"CQ\UyGy <5ugtiX"k\׌Y`]k$^Iu]]=ܘ4`wH4C.,8F_$ jc3}K&\6vĂy{l~HQtC@%)vLNec,NH}oǨ.M걅$M,܊x`ޱ_|űX}Nd$xIwb5=RE%( bܧ|&V:&]" wxVge2Ȯg ّB`)^ȇ4eKtM1E=mPIdMƗ2|]+]{ʋࡷwC3goEMRj#/8INWmbp\ZʻOagNmּ:Pptmq/F):HgWӕϯQ{-[u*&G6KJm#`v ˖Ų~Fi4+` yݯ\p oŢ]{I䚮bn `ݺQ[2]G d;; hX_똤d_Oˠ!}Os@ń793nN 2MdvM* yEyܩs3ko=g?$[ Oye(]<ϻgH=h聚03eQeCiBĕHԋP[fkAuT~×Ku&1OIVme8aRĆuxy#y+~Cw/['<[&WSWW7V"/V 7YohLis)!]㺕3E/z艹{'_00=-g X-p9 â/tT 1xr~T/7[웰eDLR(սO&dBT}@Dž~үabLnr(&ި=uk4HZ-=CuY jam_ff3Myu xhn5UҞzw }smWhm )wkBeAc rRV磣c㣓HFt>rzzl=4A:Bm- 'eerK-~SKnzz dY&ϠvWJlc%Ncޘr }v,hʥ±bL4irUڥؚjT2YAZ.XJ&\f{"xn菬i}m;_7'^a_6}Wqܨ+B;Wǯ ;n>u3=5|= Ij'^{}|ўrOAff=۔wX9D͍їwNC"Е]-[333*q-%a]AϙЦZN"eodhP=q{ے`q MlՐҚL|'h; T$QL-YB ⢖k]愕Uԥ= /bSc7Tff8LFVNOEO݌NUDA4?W\[1XTz l613wwT=q%"E^؝#_ѝ;]Oٹ>e:L7#+?!a tQe7n(qxAeY±R彘Wq(D6cx0 ׯ~@<5uqE8L8Eo5Hq lM{ /^o6m)rapL]\ ʮ8l؆1sJ.8o"յA 9{4R /b>L*I{3ۺ]AuMMSO0Qʐ$  (~vB_=帻'aLb5n3N͙y=;uYO7F>L%/}kW^{ U쎋p#S:1e;bΣʸ)=YBՒge`Qv1gLϴ&_HEItLLwa4sA&bu5tqәWͳ5G >ˉXd-؎tUK8=h(pvaٰK:&3lr򁇸$[׍P"nm;Y) L[Q2tȜ۹JBs{;NLx:0,=ϳ14'[O/udL {8fN^7fAجLH6vnsq=(-70eB&uTnX,iW|^T4,d\GRѤ gcn9~v{QgSt{ӭ6'F,$ε`8[x!wm$c轵q} 8̢J"e\ *ܜ(6UھXS 1!kxꇻ̴g־d`& oFj4_lScfEmDPNvD.AyʲUIRj+gM@F ÂuN"n5XkӶ /n`}j+{:e]6EM JDdͬY*MiI;jYί=^$p.7|-öPf{4nf J~ fE{$J~ʱvPȮ3s kblT̡fnh?A K.MI*m:"UK*i(˗iY~^9,xSՒɳp ;}4B*=NVʔcYH9$Ͻ½ڠjgkb:wpN=M)Prjv=mCԴ2 J첔KULUs: <tuLzֻW;.K>Ǻ]Y=Rں C46X>ɝ!ɁM*?r{$Ux5ó՜N)ey৫+Mږ,>Xضܗ4'zhU=;ȋvuu2">og_)sLA-ieӾgK9Ud%d]u~6FPܞs̷W[k+V b3= 6#9U4\WpCg 2`捡.xOnMD[yʲN6rg qdΐ[hO  :m'ͳ %u%Y>w0LAbbYH>O!<7&~9'-Z "s6TP<$d;UETo 7ClL%0b@-+.w8lj "ڷrƎ7i;%9E)3&MʞQݜaWj>]Uԗp- 1[U_^h;r˙d[7}.]eˍ׌fGwbr+ɾޖcyYպd8-nʺݮ&M,jf[+.doQI5&w|S[R:()A&sl.K(*3[]%5WaQЬF|5UzJ-0(CgӏO-H2 HFnlh^,+G{V[D]uM {v\)oEBJSn"X luUlֻk A}[5e"GqlU*D\zh$nCCR J,];>wy:ʱNwT Mfq%lZ7tѡ=VfidEŅ=r"ǠG='>#GB)`E:{+K]!9`uKՋ{|1 O5E[-du6i~N49F )_M_*YZl;SQCƖRf $[& IFT3?i*#^,3+f-6'WwM݅.,1틱m5 )dliӆCwZE:^Ay;,v8Đ:M{~o6ma9kzq@ICWOhϪXBt*l1797磓\Ÿywۚ"ov$$HٛFɾe4ĤlJxvFQ(0]A"JEC\S* d}9!uw״h݂QΩ|oZe^ vAhec;ɹ+r'=QE(YE{1 }%ܣ۶{^v} Oifgsװ=Sy p^@iY1r+4往9%sSa 7PZ`m.f'Hz$8Ap{n&Nz+m^U]kfN xi^SgqM.ybZpZ6Rno+0"6쐮͡g٧q䊡*ͧ[)3_g:suOU)9\sŧ=/4q8-A7h9= vxn[P'Mtթ 퉻bky};N!o`Υy5&iPKn)*l=WjΘvkqqٻUVK,!ǒGr5奻̄BәiFm5RV7sFF u*0hЃXľ>љ_*nRqM{%7fw]JK^<C)(jrEԲD#ewmS4eC%s0h\6ۂ7z (ǽ`5ځy;3#ϱCN\r=TV߹xO &r&/b H{ڌ;}$h҈ƾ?3OǔvzaGݭD W4:'зX_h޺畿!}ۖUKpD~ fO?SnlB{g%*yq OsЉ795ڏ_NPo=2]#kq%||nkVF7]Mٗ@[B u繛rutꎔ8MrM,@h}lŷsis脝{^Ű+4s,t9 MS"(뽐WYe40ٱG"yȉ=xp3 xbpIR$Ԉ5Wwnn͕i=h^EU9S>'/ =Szs{"iO#݉gUQRI rD" @8 0Xve$6` jiPD/ySm I|UK!xm%tWk'tU$߀iNL W.VsvMgwwmc !=ǿF*뮩a@PS!B@(&qP pD*7tTQ hxE qppMQp7X4+AbQ3.E!_֒ yhʵ32Z.uuduh2Ddz1!YzyXVqwN 6h)-YD`S8n*fE.j =: +N0:A)><:ߙܱ<mH<5@ǘA !/0OXxԼbq<$4 77ZSޤz/=os?w0EgL2Do|TȜYD-O:+H y ֆkXT|C \e˴c)_n}:o,q,|s'ğh} ?kGm'MLH>:7o`מH؀cxRG઩ M.o_L' R^g|RLuO^#|R֋Jʭ0,8F3φxC0cs2!جY0e! 7t)GPeLcrVg%t N{6&!\,S>|]+UlNn,P4 =$Ƌ~90nj)(Sxm dMg 1u؅LOsdOrŚ T)k|7h{DW7!w`1<'*!WFR"ĮfeXY5iA^۝R+\|Xt/q]8xK@Y I@p(+G"튴#'+J=]l zV%;{rkBW雺T)CxFK/ycé6:bX2UJtL;:xNUFD+`Jmϋ2jYئk5n*Pq CN vg=mG 8<[ދэDonݝ@w2:|ƍt{V!Dc7qY+}  о6 dB@)\D*7qyYhC.Hut:z1W "}vD9z靏7~^0^ ' VjS9 gǺc+*\ ~f= ^y}F{ _;Qs{Ԍ镩WJ"ԡrXawxmX)R:3qg*=~׌)E%4\s.cQ৮vt+;Z4l\li,(A%dBzӯ\P1%w<ű-cAR^Rújxl>GywVB5I'ۦ8fգn;n-_ !HE?VA2-f`H۸NC]ּU_;<[7ol@w4ޣY2 V긂 ciYho;51//Ɓt4ܵwro?0 Ә,FE^w(_yB,6x^/t(-Ό0[<~)s1ݗ9Dwzb4Ǡnt8׭勹,fqzLbŞP)3!_رb3n Cbl~럠C3br6]245Y$#躷E/V_&+"f׺ TPb;8fu&װՇ#bFhheڼ[K |QzY$t\ѥq,cc Cx2'أ~BENޕbcxZ &^VU2\bAw1wW(+ouS BTYI|x 2mb[qaL"e86luZZ{S[c nc?7hH9DYq֦v{ݏ|vqПYVӮG`"fVOMp 1,fj)yVſzSNbK| _>ovr9nϩr/NF`>' Ms6PҲq@_}TĴܩ|I4HcmJܗl>Yhٹ(&8qWRU>*ak-f"L16BgYH@LJaև (_ MHix\U%虢u!Tm4Yo˺V6~޽0 T2s˫&I#ixhqK h'6#$ FB#;$FSt\2VGQ] Q@{#̌CE,vIO8^_Y hhhw hJ8n]faDm. Q:+%hN{M 9BjR '- N?3J8FXp[_AT:}|yÇ|8f$=%GO .*> ,e%`9NT4Ȟ"|󚲯1^ev,X:} 8\GV޽Pm IǣCm5T:/ ^__ {޾ů ?2Ϸu#m{/]ە4:so6gx 3IhGPK `E5ֻ"p{F9rD;%ZuBoY *Qw׎*Ѣr(-w+Tj3s}<;˼ӿqX/.ںh{ݽ[dzYb͹Ёd߄#Ȟ9o~cӟ~]]0-OTǼjod 'S~-b[en1RbV}M 0-^ip*O5n}U_>Jl4^X;o_V~}V2(q4yjnhh *P(`. Nn0EJJ ȏhFURVf?~=s4RވϺ}3?\y•u D 5!|4oH'{:JvU0uʣEx]Cl3~ME>c~#߲R<_*VP!>wW̗"a'ؓ,>=ߠ@.k~fww-o92a>2)=?+ޯX6B@*v-Z֮0@JT*4j uhZ%S i htcI!@(fRAn/,϶m.rDڜټtV ZgPCo ; ]~@/6y㫬<ߐ8"hy锥u;)H5/Ֆ^*k׹$]U*|(1[<-cФkhG6xĂ%X+'=@HdLy66_~TȬUzlRs`$$_JJjhbꋦB h/ֵ5FA*.֍G ^xǃ᫢ nhQ(D i[@GDPU #UT>aߔW1m.M? bQ*-!TjuAI>7=QOCT} {$xF Bd%ڵrEq@0כ2OzZ\aq6y|Y|[<"}TWåJk'F)vW!ʇw;I.,rE=$; }<P-ITJhJԄ* T* u!VTMA jTw/!:XR4t7M M@(QA+hB$ E-h*Pa@ "UuQ pUIWr@ߢ3}I NQ~&$ tsqmNk+/o2/x oVubuC|$7]G>)>+q?qjn$6xUW t 4̬e_,x&\t4|S@4 TgO J]-_ն[zo_~ >-x)(!3Y`o-\Om7.ȼ.|Nњ;#*.6jk3ugz\>LUNʪ13R'ltMl,]t~YĻ>>Y+XUJnRSjoxLNuuE>S>Xf S2{nI\<48֝52ܫUO4&ed2`w!;t<uŗRq'dOIǽo.B9n A+,I@e*CJB%޼#{Ro~~*1}#*BL^9 cwoX HtOk$!dQQGD5 f"UMPZ 5G[Q(DG@jT(iTJ"U uM0h*j"n+i4BA47MM)J"(iK!!T(EEMGABQ('g=~C v}{PbW}sЎsyw0c"0j"Miə6qUL(=3BG6줯-e8|7;1JXw[аv6^P8K9u{I$=jGNf Y~Y7;f?=Ŕ],. z#&n z1me#Gmpn3$ Br-m@4O{a%&I2ҧj k'#&M' ~- |%V 3K.301wh^.%<5xH]840q9|QBiTLG^.5zܸ 7f`Տx9. Z^1j `௃ι7®[ơiu9k&#r+wizqs) "lsT9bI^Fm Nes_2z] 2滼0]'y .s}1vhE4Uj94[&];RT0}ƻ0X>{kk#GWO<~W:0yً&,˪,BXk%B}38'AӖèWpz_-U[8~G&%< fAwL7H >>J[-]vxJ\;+{^FUU-"utRe%7ݛtL`E:dḱ"'5?5ˊk&$ƨȕ!;ud. :%~k]rt][K%iS D|X::>8k#&}C7ڂ|%*ep 6fր)L_ x]fmLk#)fd5DVDҡJ/ CKXIz.q~' f/]7fYNn\n&Z2d&n\uso5_p<.0H𠕕k#Q{0O 0 ,)ɮaQO^΋sC%~7,!=^"w|L  bv%y$^(<fF.9F! #>}$x`E񲘐^3~Ay7Z j|KE_#D>pl`.|Wjt[+}[]udY{k.$푦+ C~*~q yfWw1&o)ҵ㢇60:ZLڵ'{ķ%"[99q~j@dW2 =칗 zYDCon%x`n+4zGh(GNKs0%MGXKӸ a{/dH(8bO$437ChkjԩA Y^,.FDNQ{WDä TCE@lK"5Pù(crIPti (hSwt,E'NfHk< +t f_JďJ  ~ 2GdF-b:liDiUbgoC 'NIClcc '``zB \0jyB^`L_cSB$i1vgbD+ gp1z2, }"==`(Dwx \ tJ%@qh*& 0L`NC*K95xڎ(Q:6( Dp (J} {5Q{8ÇՔ϶Psi7Ap*pSD C {e'4AA1N|Q"R3y{T}"¶"|YQ{_USX!  .%߽R@O~{~W~?\k9z,e EMk4օ(l!@-EL ` RС%ZQ 7M4)phsc+R -hfKBѢf}vN|~玷 Kb]?{rFeu Fo0wpTt w^Ý=<2gnU',oeر <-bSʻܑo;ؚ,aĪ :K屌jJVyh}};,!d oʹo귗| ﯯ> 3P5tkb8h-$ D p1݄DjiRJj;MiQtDJ%UM'<*TxC_)f ~(GU_ZPQn[|3?)Ⱦ?Ρ"JOϋ n#cU﷦p@DHܼW_IxbhbVUn0%`DL,0:]{w>!bLD5n$QrFDdgGȿ}c Ȧ NӃԨT]U)mu((hh;kCKZ4oRCMqMN 9R!zD t``|NpICN[!6@uG_lԅQ痹FoFYdW ǖ9w.瞇FBlѭ>^.X%_#òO$61/zgBb/O>?%Z%CCsȥ\F )Jsq@r#NZ'5y!%STt)`]4C]- J{ys7=iӨiK)ZJ]%KmI1nw# !=IZ;Pqw.1čcS߭1cρK*s=ljiC:$a}c8] Сy^H)VGY_lW0}1`g 5jtb.wwLɀ~u%ajru36gLak1}!5AŢ/W=gF_ olE%mW|}: B'@<@CAzz~ b AP07JJ-+k$mj&6 acpC@Atk"J(;W 4hZPJ(I}_{2`N,TQN39.?>! #@fOv*ܥs 9N+.ʽ4(WbMsg)'DQ K!`H|K($AKYItr#jߍȨ{;`uᅯǣ’T]ԵrB+iJ” .f @E5D;ZVFvCMCPyQ3<":l% %4Za鎍Z &*"gBRS ߢb"Ätj(ĢY>1:"sךSX_ )xHCwZWPQWQvb1>ĜxY֖@ }c|y\<(DR2uol; dTg=4$2ﳰrS/Jk4Ey0^.XZ:+`GT;wUBq<;I)_jrUbt:Ӵ )3Pr +nCo_iV'㛬y"8qf*j=/iatpjewl$ @kD^d9\evef"mD/1+}VUaİش/![z/s+F[GG)D@D2"Ȧ6XD!m^s!&A)r`&;}zMA |v7}"AbL[4}VqWhk+6"s"t{wy\ù|+4 zbIN $]ild⃹Ko ;n3x׋]ޮ\۰ NJ˞sU:{MV^H'RQ~|`\R=s^iбzcԯhG(2*byQڰ,Y]ƺ؀!^>dkGW|+y-$#忢Q`݄rX-WY@].Ў\VcX2>][>/<{jќkk]X[ c;Y Ao!jZJf4'ԽZz :QĻh͗f9C4zkǍ[.x :5ũXnCV`ypxcz:۸fcwYBYHd|s;%}ǸGɂ!T:MRBh_catw7cμnMg`NӃ-P ,CBRX;:JE.:Fz{j|* uкvzGՅnyij_<sTLՔ٣q8 )WLoc7-ɒV7=8HlnZt Z_v+} ;]JicGr-)HbSk53/>ճ3׷zIlsNқtS7jTc!"'Ct;JPLgfDUXX$̎Uan 6Fzq0Ǩ].ʊUYR0"$wIt}y*wFyg (gś~k"fFc#ԩfXcK),!*ivJw]f3R˛XywJzVJʉuaMz+]u1m0i qm FxDBM'wЁ:?W4ȝ;*bM.<' XDqu}, Skuh^ +sՐi]8(0MlS〇}clͣǐJyC/w46c>8{V5U$Ұyq7?~,qsqÌa7W\"ƈǤD&$y4T۸լĸ]qh :^} q~^Hm*jܜ_>0-ӑFsXsUlOǫܖۜFX.\gJ6RAA)05w9%ip){}#c} ]% `/CDR‚PmY=ﱨtf=YNFAb,yfcx$5+(ά]Z(땁rg z6f{=ro9 P5h[wdof˙ s>{ ˋcE6 FH1(WI| Mkc+$jl}(VTMڦ%L%rNVsM>kUտ^.M5 f`O3=q]&7RCm}yXڈf]EXtd^-nHVaLKK=7|LGтtJ7QJk}uBMEa+u%H%]yӼY8Мk>Ց.ݪ+-a0({<x@<MuVigC$Ds秼ЗCw6#lزw1;}+Rvԍ|A$Qh7Gg/:#\T뻩kEb1|iʽ *v_F߹V=^|zz:6DT @MkhkhKpNDyQ4S h7S5xh<qSGBGa ¨iCF@==Ъ_!e[1 Ŭi9XvjĤ֩An>v_o;'~|vWP1=НeutKLU|++q/fS8Sy$QkǦ8i|QIy K཭lA^Scy4`=$cgcs! |'LD?'x@"Zaڇ Gͣ8> Dq ]iJhZըE(J '] 85y Bc*U*:*Q>˾?xoTq0NZ~01(ăt8`~ AW8Sas(=9OF8F;Lv,qBѠZʓ3\A+R5[_|~?U2~\߫$CHȽN{ߔdBiqjpQNM)Ů:C PADJ'-vQpkĚV8]ȅ M] g)Tn/7ٌ<+xբtU9w }>697=yJCV*Sͻ$\h>"(naj~c4R舼|2sP|S^+ͺhPwIm]&zڹF߹g޷CXv,$PO?Ԫ抉p3`cSTB 0.WA ֘@ 58j%-.P*Pxq!C jU\ďa (86eS qR,"j=;==?p_ pfP~\#.|^o`xĊ+cyi65ZoHX+K5Kբvk |Vq7 V ^MHX{ "y/"(&VT*&Z:hU<:[`(:^%hU^878U{aQA/CȠaQc=O7/4Ҵ T { P|hIa[l˂D<@- 1;%הZdY3WTN|=y5jZF*o-6.@kW^n̵} -LmVޏMu^#ߵHaq6+m(ҩkv/ɖx˽XۄDıI7V1l&ꮓ  @׶_ KAscWbTb:&ۮ|s>xGecV+_Gtʟ-' k}9QgoPWӰgAD4R{G`ta drfm c6W!5])/ca\P}*OuUp O+NA&, 蹺2T5K30Nzwv'{aB۶PjLFt;=%pGЫReg=fw,`3B,/aHIa-dot2Oޫ;8--j&/oC؟=[J1^qyƔrO"qE0pB^ss9I7υl-e4|)Ans3'u'h ÖvNwfuF+Mk>F#=9M}0|i\+Ub݋T U,<"0>1غb~K=g6`q 4B ,EbA;ڢd?:`Rgwduh"j3x0,K4R+oռNL:grKkH>ye9ExdFEϸ{N1%HľE4X 8}KW篧S=WθBzRA+Tph>8gDDž{3|dܤ!# Y ++:21 HR39R& L"ƟP-8F0i !3I[@Y x%P-_:7,A?}K'"?c'zqx=2twVcWU"C%Y,&mgmgO"M+@d\<눣E/qe?dHgKB^ez :D  ʱ9矄s)Øه.X@rHK#_ B ;=a#H3Zs&.g-}w!{CO.pQR̵N$wɜϭg:0/jQyl6e,y7^ω6%M'g6Vh^ٌ6i} вYdx[&uMy>H;Vu &ksziFym i}3 !;fF+>,eYӷdj6gu2h^\%8\rlˋx1 " Q`˔ O]5na=1eX%G^">b5waHƻmI_U )Պ6GPKbQs@X,'<#Eݨ*ol86ޫ+4lʛRV^Di KV(|1/xg1۷,PI|/v曘%RϠf9ȝ{moqOrLWm/uFS.LG$ itY@zڱaZ*Ope ¬̌n-<jML>՚F!2 Dm2ń7^Ҿog9):q[E3l0 ?2tʞe.n<¬MO.X1) NknX vVl6C U'= =O6܇p-#h0AJBTJQGy߇ݻF~L(lX.=B6*B.cHHe/Ԏj#)/V萒ϻ $_vEȮ'[%h)D( j!APT(RUM*b.ԥ\BPJTu6ҁD:b R\JB!8;5@Dy[zgڞTUGY=Udyp< B(@$MUIƍw|m׊$28jg3d}|VcOB+xJ4 ao  އ!JˏIy,@IE>^I׻RD5KB\6i%h\ 4pݔj48jЭZh4QCMҶ0Bri&hT \ h(&7C7rO|﷞q0QhDr=9w4qJxwi0Ό%8{0RAL>%a鱗mζ}NpYf!EoGHWOVr}_ty,HlD'y!=j4@D18P('t'hPS4q Pҵ(㉊UR(U*&jZHڣA4 )TT7S^9P*#QwrА]G,k02C€TKPM~ ;Sƾv!v3vSEu,8,C7> TY>)1zSBv/ Π"e'iKzzC"$<|}$G@a ߽懟?JU4EKtthYjWqU8EL@:hwUPhr!n@j5@Q҅jf(ʕiY4Q7tA]@]|~=ž|gӞF!b w>ygB|-kː z qʌׇ@`_m)?ÇWxu{zJ :گ@sΔщGD (c'~@;!!H:y~0Tf!((wMZցRVې)hiJpqp #ʏS@ &UCGMWD *f o|9*#vq(lϯ`%Zz}_<~@V B(E}|YIXoRKp!x%N>Gad;c}:=vy$t% "uwǢ\Lݤ2Ra4NR/GKrA_<> UT7#UxT7\BU5U:a@\p 0(WTRm@ݚQU5@- `Q苸BRK~3/TծTm+%G?y\sy'Ϲ(qhE<lfY3R.]K"maK6scҿ6w~ZXbIb#X ưK6gd&ާ0TӰ=N@bOvBwz{S(]9^ n'%J&hiBhmœ\5@C37BJ B^Mt9"\vFh qىo݌őG>It <ش;Y>,:qv UӺ|FRv!ZOֆ_ -GWr.F!;u  |՟/kxTIʙR5n\%=o~ A.G % Q7k\r ! 뺚ݚk. @uy*9kbT*?L~?jHd6azZȁ٥ $fX WԽPCyk}ۣ=->&ݣ9o^Bк' @BȌ!VU%T&D~fK&ݻɐݺ6yV)h4*9vbf_fav'gLǵ)$u3&AA8~k76%̥nuޜ饷ư3כ0T6/CDv[,㷈j=kq1`B {uO1[\wW%Vj|x24{םxc աЁͥn9 pr>hX2H&8 U[qܱ=-+w"FzLg$\cЗ#:/-\y1:E$G\_ ʼk)|z+E$_L2l|!@bdg!R"n0*iS^hhH &ZR@9zq/%CwMڅJJ"t )A@Aҕ @Sʯ>]vd.]"%W4dY CwDEk+J0g (C*Kosxhomn \>šPz FVlX@ӗ S 'ˁOX7PDκɥ;2=FE A^vK辕dv}T~|C"s"ܻPn,dk*)A4`x ^ē>m9v|FgDrp)m8摡k8lT`: VڧE$W6qq^d-CGE屾~Aɞ2bWwc7~ι"h2Rٺxf^ئeTwxRU-5ƎOS2Mԋ& p[]nY#$sw !`#1o^LZ+sI!t$x $b!2fQY3 Ys / \yD GFmUH|NVV=ҲE.`_xfeKr<+=1+Ƿv^ 4\э_tZd`/uYGs=Zǽl;f:{J܇$י{݆7{m1ȘFSF0q>+2Yo)АHDnobC0P*DѺWkc7*~$7e#vk[ ԡD -dO,GSvtu/nm m&w,K<Ëvp猱T ?6"f Ąȱ~W/, g դCȡa0\1iakeJEj3ǝ\bTn.r6[򀣋{yYt66px".c7Յ\ȣ艾L{kE7 zMo:[)_rŜ_Χ<" 21zvL~ ;ZO:JGv2sʲTKkVaks~LM(Nj@>hfD#H@,u݆/oE'йs+Lk!˗](P %Z:gZUxq<{v,y_sEn`z DO *x0O{&B2'WiҙhCc~{_zxZ5Ž|cCL^cI-x֑*Ey kq|,';>2Rc랲W̧-Ia#}m6cjaCn]U֓,м#_{3oZHF @=GnM(9'l (B'iՆbT*oˬ`,罘aSNj,i=Ɩ.ץZ8-z4I~3:C_b4Y65ZB1%>wl޲fMnxASB{+밞ss%`5N:-e֕< `[@a^t(K()i=v_8'ee؞J4nIZ nכAC&4|RM&xmzUƺid"ŜBz~{jKc0i0c4Ϣ/Ů WzC-^}ɕilYRgnf&S0ƟDho^w}R~@Ji#(,2צo9Mhp`[t~>./PANw3ZdH;?mL%kZ` IUxrg'sIA(A ҕNyrs0&SW~}]~=\$3qU(qbS4E7]46B@T͌u JᰍT nPU-tM(ZZ B"TE@<ߋ y>` *7h﫧v\ ,@ $AtH0Lp[yGb;3y_D\Llz8O$dUB )Lz1H'4/}&H |{&ErENEg?({?DDA^8RpL{BN "p(]fT-m8)RSPч.ȵn&jrl 4AWNsd}NR=wE\0#{RTS VgTL-*?+ȏY9QA)=r[kgY< ̩ikh1WC<զ fnqL3kNci\Ԧwt!'a#!:_~djh< 9vJNttS9;2@18R1燑3bpѫV ׀Qw,!@Gy9ⅹx@9,Mq#nx3eꕯP_o{_gп{ "p xB`MܩHmf\bQݳOTRfPM>$`)XA#[^\aUK3<쌇~Od@rp'' >/j:kP/:<sHAF2GԩlcVuLyhUQ8iHUp1v@ QOUXYG4r7ORn]Mr:}~0h&uVA30:NGo P*?1W^^D"U=<;ہЦ-1ԩZq@tB ZiІ'%m\20NSj 4tx%Zh[ML0pt5wu10t4Ut< G а6z~ Tto+im/ԃho ǘFd &^];dG@Ym3L~4_S5+FąUHH; &Ϲ30?>@dH_ 47kc C1 4]T@wd MД+(48Еd)RŁ@+QYB BSPwGChV )B+wnVJԝWJX%V ?}<$ٽy8o ހpuSvXեHs,/~>L0*(U2"T UA[R{mxRgWucxxIW?_;< Ģh! \C5hkSYT*D RD(hġWR%8K'pĉ@ 4Mt4wE(B:iP0 U(n(YN7_@3>50]Kkj$xG\‰\:p{%Pau$@MWiyX/c7_ փr(}o>˓٦|EX&YKp^Oߞo q8}܂2q<1TRTSp4"\LT*Q5!5::U*WѠ4BŁPQ t555Zؐ*Qlt4j4DSD)`0*Uj& @A(EtNyI؆EWs5m!s{}//GAPAPt`H۹:*6 2ĝ/ZSY)0Q7׹? kOs<>THJ>QJȒ`>w>>>wqo}a>%)#6γbݭ:n nĺ!f*c7NwB A=Yj ^vK)hF{T t/-u͈C#rKy. f3 9M=LkqNb񃲷r搒K}[¯R{Z9.~/ުe;掗ֆղś&ʇ"0I^SyIDc`Wlex1qg*`/RWƞUC'!Գzvt\S=+-(T(PV , "QQN{:P ]P Ej&[U(DMMCZX1j&HBĀD.h{=38عkQxtQGRfzx73#9_9U~7&|~x׆ >>luhͫL$t3ےtU]mň1m׵wx71XtP"̈lEܶEw=_ Wo<>8 uТ(HD,F#}#ݫT-hळ7Ǐ){ڟ3lݵq'DMGH(ȸdFg-~^9KƆ2~We 28Y'8*+e5<@>vT{1|]ѭt$m.]wv- xXLYEEY91*V'>h%+/nAEה;e0xkATİeiMq&gUlitSǗ!2%e/X!W (HjnK]~w>纞3*hNX 3ՉS*c׳1j WAoltr/K9Ax$9Q>d{7gZi)nYgw^fCVZv=B7-o-x6Pe捥Y59>/QcSZ}H|H~Qo\w՞{A4>uSBn-YUh֍jC .]SPMo}m l I0#μpxe Oi8Y=գCؓLP뜈:k_[G,"ğT~T2HGAɛEx3.e췖%mG#sL1賙3% |8EkZU!#Q[nNVYP~{370ygN7`\Ա$ӒZgx:[՞$%f:'W^v)@zDcMbmt -ZbY3ńS#y@#W(JvyM >뽚.f<4S@sا<[6)ue[G,]A—%iOd<}o 3JB}+ȨkLNww;HAU DYR^Dr风6Ll[6i AhbfXC.Pc^cn5wce: !{ٸr1GCEO^,V,=~(S Gt[p9Nw^eRK[E[Vw;WKxO+c(BT˸;:^Js<֊3p*]L{E͋Ihks7Y N:o01vm^;,=gOt%)*!`[/b'mtg]{ΧYp {wO^vD ^LLN{bvԷq.0A;クe3%۱U[aKcۤaĺ"<}y9`Fr@9{i,3nYPڳBxXoVsgE6jmb/ѹz*VcvLY̷W n몘wΔ+m-GQ}1~3jrB}[XaQZYeHb$Z >yjr>hms5TU#QH9B3+ޔA,-$a3GL +D1i ê'.,\+#լyys93Pd!38J#3O^w |no2v?ttN,أYS-;b;!&O_: UDVHN[s1YlM H%1HK&QL ^g_ "4l2 '\w#QH ϛHE-GΓ}}/b %-vV.h;O &´W/m`At}V}3wݼ o G9J ׂlZxP蘗 .>ƐXp#u/pn~ky;GiAI6YTc e K95#*P˥t.JM-4B3:(PNdB$KB;4-p;1}缫4Rw'W{A1 ̺qJ:Z3`^Z1}sEdJQ6+)Rnb4svh34^}xzk_wզݖp[ <3Ə{*c3&O-yY"O Cw=`ֲPgv5Ycz!yȼߞy4 lIk51B$yXdTyPU=)G |r<"섁?'Ɓ>YPututjРiqt(kE*M҅;BQօ HP C)4tJg0J6(u `.3{@+ I|1+zMjw[ F?gDT j᧹{걗wg/v阾 Q%x_+;<]m\qO =5_6Y%oxƿ__.,vNVբ֭.ZQ(Zj% (bf&U { M3P9*qM@У15jl#dPM۲}~!|=>O>9>2LU.=H*~IW/wc3nVcES˧n0B]/N7j^U<'○PQAJ:zϪ~1t>rI1}]KBJj5ڔ@)S 9,Jj5(;h] 1 wt XԠ]a\\$ hf<P ]ߏtay4)_1'm&\wx]zˆ.Ιt ;Pc4 8;d+qDמN+s{ Nwr/G-Uϙ3-\au`LCwx27Q/ >%)@¯G֢"́}6/[_( [WB׊P6Je+S_ e4k0]޿Wˢ~vD~W߿>C|ZpxuNy85Nynb +/:jhpS4+uW{'!Q.6?hL}Jϰp|(򺪌)`Q,ÞƘ~'#K<o'SI"s®!q' c[K 1xGV"P(]V&|wyr,d 92)ӃBi瑁<_ ٣n S%8;^L$^ 4)ZaΎpZ(@*9v(A`@o&dTd#dL ]uATsnS]J8yL巾->3]P1ck@OWN4Ѽ׀Dmb :IGvs2$VNwIc飵76hkqio'x`ݭ.: :QաLd~fCqLss|.n(S,A*Xw|5vy&kpO;6H%j:*zzڬ\2ienwwt`T:uk32Ƣx,T23P&·4YHΜ{f:/zuKuV&Vsofz3~XH?9lc̮tˋtk5Uv*;w(ݵtء&[k@Op^ȹkV(606BcƒE>7dz}zQWVM"3T5v*ȕʼnPԜ8Ի7l:AwXbU牬L5μT 1)$2mBNdXS7kss>[ jj>z]e% ,5-傕#PPJʼn H=DyiÇ|b3<$) ~hGOu}"}eA/G[4Jmg[iѾOzDޠI?}Mb0җfNͼ{/5'm*áRY,tϞ[Tem^5bqFO-Z Ny1z針˱Rcp0f. ǁdEª{'*؆v|=V#&|K|Z֘cI%yr&YɧB  h?Jsc|EUxUyN#Nf%rE 8fNvZb,3d3=3+u At^/+{e}&T4]i0)sC[c%0%(#)b>V)zC(w61MMhzȮ3ʹԫΘQ՞rp@Bjz7d!-9va'kjeBZ0%pR2.:Ԫ1Şc1HBowN"!&}BmܺDf$\hc]%wZ$C:@̛x[(Bsf\۝Y72as홝*OoePbgZt9<8¾>j o3vFإՉW_ ܜoM%)e7s(+w֧m:Ku%ӵ/u۝H!N`\lI搨u,wSf o$5p+HdڄXsk>%+*#, KP PZ%#r#\NlY>aM㗒&,2-A6U,btj31^F-.$~dYssIXA毚Z$;3@R#4@k[>9< \;T2C+{:3tų–׫OT|5=QB{M)8Yei)|8bYa#y/^@͵*/ϮD̘PB|g%q&-w-S2s0FRǪw:)瞛CA)PQNh.,93`0NjX[bA1c! S1lY]9H>[ 8ȲW2`GƯ?P|mV`u8V&%A)U(W‘ة %kE߄ʅ@[ZUaRBJd= ,hVegP%ؙGlxļƾv>VѤ04e +5(է tT;2F4! _ m+5F(xUKwV b5տd' x+Wcy ?~`}`Ͼρ4$D~̇վ]{O ےnos(fk@sӉx]+$cli_-im`*AOdWkňą4 xB9S懲]_ Cf/!Aq8x&c]6ХCVGMSR1 6UGl`5m2 DW;=#H? $1v9 | #<9W}eX5‹ܮX8u'T!ad ;n0t[k#g}ZbJp-&C~Q^=~^* cI/G[`T&~_ 0{;XT>qN> /{9{hZ[bj`nB匞 W DęzbpxaDYU/9.u"4ebSaN 1H29f7F5K:G~׻ďOaA0gabT!'jao6_?7|@5 0c!WO"vx{ə`Vn]J7M2(5`]@/sRBS]:5ܡGFp@ 6RfSN}Jhmg'mec_CUCnBOJ;^IvV+QKf]vN+V0xT4NCKɖЁw|Y%gٴd\[^ۤ1B ƙ4LD#j̽i]!Ra"4Elo_V*]^\o(@ #}irh*Tz|*"8D*p^ǨN'#އg>DyjQj hGrIStM4u\D55T ڭC0UK 5L A1ZZ`FJE10CCtA}xYϽ~=I"щ>KZy .9VfRV@4{D֣uJ5T =*Uiq؏m|nvi&WZwgXG4 @1P UqDsY݋9hL o1{2a=.ư[C e%S.In. l ̙[˓lJ:x^=lb_vmܬWWIaK3j A%7DvtwrVrEv.I=S6+w!Dwfy]iedHguthSph6L;2ef_ܚTЮCGݾWb;-(* $ix(D =burK$/J^bOOV-6ޥ?t?ZItyğ,G_~/ .B i$mB4 6+x/4M5Z~MT;EH'|B @q0I*ib\$\Ej(L0T(\q0B(Th&b!cb%\\\"8`C \Z?3y"ĶsnaُԪ@#+؀ְ鉂%j7X[eݔM=nz 24r<t=jhmq"U:;i#ޙV D,LQ^ѓuKkݟ|[7݇غ 2񨣈kr'Oc̀ymC^aɬ?d \Bl%>]uc) V!LB>`NrYj׀oom~,o{,=12'}Kd[.vff)zwW& 齸 4 wv=jrO3=٪.z I%@ILc\:KhdpGlvL.|P~m YP/VR٦8y#NX/9nm W`KCt ."mA3nҟ=vgn0 Tε~{ۜ=IuxDMi{USsvJS^G`{%ƙpfyM4wWB5l̯v]X|Ƚ{/<|xHܤ`BŏWm r٠ձv혶o9GkAaӶӒMeYSNsr6ntT^o2U REPQ{º ] >r)h7 -Rɔb3ybd`^$^JŌҜcθ\4%KOeFG"3*wf_bvBNG@4I>7lde;V)-Ӌj7d*\ԉD%_kHJ/[}1:oq:VM9wbKHB[uԦu ZktݘG"*1aftƍxoBJ2{1זJ;Cp.yه!/B=jǀ2HlϰsPd]b EY ^ۙy94孮ca2VrlwSGloo$ "k#O<4\y_BREG/:[\2t(-s0{.\.^λ4ܽm|o᝽@/Z0uYˤv盰 }Dm{4ӱG4&wIwkU^V+K.WV_̥q1kWYPީ2jjz|yN7/qb>L80mL /sE`>4vYYܮT.u6$#6uA1Yf ^xzUWw/r>Z59RxgeXf_}G2!%y c bP{pѤ+:P=f61iT<*]'Kϟ]6aq\ʸT8άAS}cf:r/=o5Gfl !;,^T:`-bc":fx0!y{|D/wjW#y%żNw)PL8GqnTzEV vKMƍXӂ j~x\H}eٟ{c()$K x! *`.f}֭ OL]|ଝ˨PXTVυ7x}d(+";Lݜ L}1J >hhO.U9N up < eBX3s>N~uoi>Xi-= xbͨY0WL$ZNi0 ^d+۱Zq JB P$ XO"'-ɀdWe"7.%8f!}#v \96:ϲY€'Z\MF`ULT<4sسqgu*r{-nGrEqR45іbZ/*pA gcLEQTw3hYw˽Uj3ǧXWGMc|)2&fߢ¬\RxIAiLe1-*PI~()ȠGjEJ;o\4 x*D!8n,CمH.~5|UP0P r_~@!+x3 :@B NL Ȳ9 ;ǎD"Oz> [hJ@ mGqV-J ]LLPiZf ڵ0q1``SJҎF(Q~wϧf@;6WA;߈X\;4n\W[0 D(R: d@,t`?> Cg+{ܓUʠ;"3{xϚ"VPԃ@d-T-EcQ:@ 2wUy__ޱ~[? ? pbjĂށE}7"gtEI,Չȫv#k]bc C=Ԯ`+RUp]Ҕ(88--- t4V :hT9p+ hTҔUJ#Z1~כZǍ4D:E")UN\Nߴoyrs֫JKQSx?@ 'SP!B0M]C,j~aWC{/V݉4|1R@6k@_EbIzm1 Ҥ!u)y(/RhU]U _Zʯ݆F=?yOG W^+%(ɠh'g14t ֹ& ˜*nW ]TSCԪ*1U7v_%uv 1f 3L,駑&p"Cʠ$^{py…m^ v. 5[ovo>e/6o^tѮx1%Gl[\}\{x…p KPILXݘ%]t$PW1RZl}N#b8`_ .b;Oq1/RA$#%"'C NW1 14̱z~~ߦz_V7f'Ar@y!U,wH>n 7\J(-Y0C4z=B&$*/S<_xBMe*\[#GIfߛˏS*ɑu ׭4XUW5okB*ls6$?>beyp T4wtSCDyrǃNt Z9W0p(-7?~s==b1%ګj|2}@};jZmy UϚt " .[ѫQm7\ح߾ݿMW˯iݭ 63H+u"v"C?|s>޷qN^tu8Kx (xpM ҎM1ѡm010JƄ)GiRZ)uCg:w/!ps5׾ 'uxWņ{Iڣژ"z}Y,^t3mK<쀯 8vH*A9ZKLJmRҗbU*R=h8hK>JAIbp6 Cix[vtbK¬ n&o⹮f[}.k'w\r_u2H梶sAF,r1dP=K*bxT]J[p02ہ[J\p1L]5JC 1LrҸL1† ߰iWwɣZJ*QRw~yi]B ϾbAm!3g{+e؉ƒCM#%&@3&-Ϧj?~iyZ:~iZw9ш?8OĩSĥ Zb``Ѷ01tQ0 )4MJ0sE^LtpMy#߸s?p"799c ){\'O݋z);l$ViV g )_6 IGdGEo_FvʳW^ab%%b(լտjb[ܻҥ:R~>>>>wn /:4.gu}2|9]l%W75ZYEXQy`!zzKj^=ȰMupƥG_9S'>vvŏeo"*טZ<~Qc"7*Y_jZ333\Yc&~>`ѵMU3>BHLX|DCsw"[T`, k5OY^BK?/ 7Ir)r#HǞ8f'2{9bkθpy /P<}oᮎ»i&{S.51 Wp T$!4=bYOٌo6H$[6 L  !pZ:$km3$ύc+՞ 2!L,BoJ.HC[S4OӇC*bF S0ϐ6i93 B10xj~:"( TMo{vo cv0">&"\1{E}5y}׷c9ڂ]Zܹ/)m-*$+Dy^'EwV`l-vAfd_EGyI'&}J\dT !|k@Y(yQ1Ay˹ayh#{A7I'܎K[upen5wsFTC[e@{/xֶn}p;]IEKZ9dKʺG+1U箅)3c )hHy{/7эJ }eGt`^nZ}<%}Z ;}^_bX9L.:M ?>斑,`yfw`>Lw>|~dFfo6]V{O,n.OD-ӅY;vY[RCP|-*+WZl3fK]^DIWb1yRмA]χOފů$>y足{mF =2''aE+bcP0-Erkb_oդ@[ )v!aP:d_޿kfy" u$TǕYw:jz'vv%m/t]Y]ˎxftx`1N:a92di|U3u o7uQwEXnyQ Y7v/'I %fYY29j[$auP!A.X8t{:Kx鄂Gdh8E0^Ml<2J `h-w?@=f*>'ȅv]i5))Z;DG :rK҇ˡ73 %YUt1*|wAwaT=61,o)YLMpϋ&ˆQ☧sL#O{)gG({2wQqۜM#³,ab]X)Yx8:{ K#1F#\}+ūj86RjTm xӭK 8Zs`}bw91+ϭ(W^i1qщg=^*[V"spB& 5=+d:أ!N˻^̼(:UzЇ4F^RgQ}03c^ₗضEp辎)F / ͈&E =i7(r(Fb #bkND&(J 7(ξ[4tl+nXpH73 HR;^k){%,:1~Es C5>dOL뜧O!aqlQ2|S@vFTE5'Ѯy+32VV*p)$Бio%.ڌ]fݼx{9z< I;us !W#6P-!䐦>ǏL:naY]ysѹe jQѢY7A|)[%f嬙L{bbR5<0Vj|*qm-(֭*Xk6rkOXAm(6ƾ{$N6k#f%H+^&€\ B+Je|%rVșx2F "O~q؁ MCxd~qPʾ 14&"d.G_cBTāVdyLuͭeNb{X|?߾JthtƉB{~CX.N8tV0VU KR>-dbN2u/onm7ApLҕwg"z(J"J21 Ac}>,s6 lRo% }㛆%BKdٹy7"cBtXH/~l:=1>b>|#-V?_*D  "v}>#dKZW1L$O 4]:eF9+pktqam&nR`dJW@--R@vdQyޘ0WX4UbdC,_LN".ˇ8@ᳩvg^! x};NÓ|$$Nu霧gpHnRtW%/*'AaUf,2$/P%Ln&U&( +D 2s=<\DC>/HCV| Kᣢu@5-,I&*yS @UF]vww7-sW~Eug;ZQUcuMy~˛W$c] 'a1xg_<¸bbXRӘD0 =P44CVl(VMduMKC ܆LC$B0q\m) `a "a_&t(tTmcK)-䗚c*_ 4)%[{W_o>w} p_~9!IO-^|~Fd⅑T8D+LÃ&_o*O͊ʂۓUw*arfv&D9>~8p="!d'O &9A qt&̻6;|܍ UxJ[RȐAK_OnZ=$[j{{&[}V#$d< (#'Ð Z]7"hԙ4+ncbQj .phH`+lu0q((`2tp/ϨACme1;hp?^uQ^  ξH>Bin|xj xBuحv m{[&&3`Y*؋D YayZEp{\zz 1 I}T*RLT{b[DKkllt`%R 1 hN'IUCɵBjwnFտw\[ b}à&+WwZ?F>=wvdD >oq@1 9 uukJPkt9xqkiK. #@()8-m @q Z<~}uK8+o( [ ӝFR5L\G{3}w7]%?=j^)'{ u>;9=rrD)pRKjM{Yo).%~] 2S>@ii  !}bBd<= }aK虑{b{y5\6~)eoˎQr3mWo!G`kb3Vn4]$G@[Kj-.& ])JY t 5BSL "`nbd ~Yku wK&\)EJ*aϭF;wJghD9dsq_dBßp;OG#쀝@ K2v+k}:[9ss|9 }Wmж-'y9nV+àd{}}$Гbw9j_=roߜώz9W>-o7T '#"{ϋ9>&T~h\!+y5{ W} ?'8Uʕt[B.ikL@1*RHji!P) 8㇃q7PӀj8vBlm)ozBiyd E}ZTIJ$ڪ}˵/(ѶI)3iqUˊ_*E~Ws~}}}_pf"J=Cbat=sѲ Bg`w9IoxH4P6O!`dfeǩ ~2DlK obe$L̊E`/{>|/W\c-m7S)8$q)KU+PumjZM_\WRWcmpmBvvxxybb.&b`&Mp2ELZbe 1Cu1eD&H DR.. U \p," @ 99v?&2uEbK☡|&fwfnbjO"sxr'eG;NI5;O^NWx5|<Oއʵgoc'v>!"|tGHz9V*^v%5|Nz>!0Ű^I-Ҧ@ YcL>K/fɆA2<9$E0w{]k~۔~dWֿ-Կ^> WDm%5LUUX/6yn[^̣W4[EY/qm[mW$Y =!ENN  TqD(!*d"`-*2##qD0JbZDF(h-ZJW l"TLh8UL!1PpDTTJa H `TOHUԤHbƙAԋ%1IdJbTKFdH41!1(HjA4b CPEEF(Ɍ͍5-hlQMDmi, JjɱC(i(ɪ666Z+LXXb1H%mԅ*66MCRh, !H3D$"chт@RRi-af,de3(lmEIHQ1F%KI2cFJ,A@&hشʼnCF)0fHi$bѣh Qb$3!R5H"Z4H$VeZ,2 $&5(BblfR!i6bJ!&E"XVhV&5FRJLbLBHبQQI*efBd"M PA"j-+FM1kADXԑZ-Bأc&E)J(Ċ40mDV5FCTi1lQ3X!""I5k,Y6RQXDhffl)EEI4UьUdѶ,m$QmLATF4R3DjآE-mlIfkI6TUjԖ6ITmAjŢkcZ-XEZ5UBK cFdf-l**5BY*lfhڢ-4)* ֲ[mliLkEb2VƳE(FEF! ʊ̓Tm+b+RkFՒc%,j-Tmc(բ)J[Qm-Qi-bF5h+Qj#VF hj*F6!mFc[42j6mQj4V RmFEѶѫX֬mbŵcmQѫEmZT[Z-jFmEjmbVFZldڭ*[QRIVѴUQDUljڨj5ZjյkEmjѵcVƪ-cmت[ZmQUm-Y[TVF[kTUŋV4bhѪ4mkjj+k)EڋkRZEXm4i,V5kmZ*,[kEcjVѥ3(HL[QcZ5ZjlZƍmmmF5k%EQjUjŵQm-QljՍmkѭj4Uj,Z[l[hձVZڋVlZQl  , ֨յѵkhT[Tm6ѭZ6ڢڍb6ѴF-kƩ5251k*F֋TR[ch,lUZ5[bڋ5գjŶkXET--ZصkUT[Z*ՋT[bVV(UcEōlcQmŢ(Xc&ѓ%D`E"bѱX$AF-AZ6Ũ-F5ZQkUZ5m[j6kXԈPVIi+@@8 {잳]=;gUoL;jPT y-Px)Oc( Ak(/*@Z5(8z(G ` U@dg4:TJ7z1wJ)(D$ )А T$W.RR{4Gn۶u98gKgjs< J*TϏ{7B@(") Q(lҩg7\f=g10/{ z( $@jWw1fMybt}]{׉^omAytP @PEr; 3J]:&тu8}>^  U I -pt%p9OvpgQ@P(PH*%nc&ON^rvv۱x3sh#J H |gӽ.v3u.fBU%  !\Ǹucwڞnvukݼx.TRTl'TBC8Pqs:ip݄tyWEO :=hzz.}(ٝ( 44AGID:#Z9@ =jUDMc7I6zs澚io>}Q[th ;mQg"٦q/w>{RhC<%4A 1&̓4#шɐFИSM4M4i %SSO)SL24h @h @ %I<~a&j=T) 4z%jSL#CCC#&20C@2d14 44ɠ`&i 4 FED"M4)zT56h1ڙQ M=5=A4 DLȂІFHO62MCjz#OTyAP=5=A!j:MqBe!c۳[E?;Gjٿb$)-\?ٙlɏn_y"w6)Us_e l16f8sɆLn]LO XDUTs8aD  @+fQjpOk0lq3vy(ũf9f*=+d t݉Q+l֣]y<ϏZ')< Ea7a>5社${oX3&#?~?:/~[:=3~_җص~')T}K6aެ8+5yOul)Ղ.Xj*=H:w!/!VJcd_sC轳ǹ7M {hOqhॏM7kW1ol;S_Wo︥~9UkquUnV]#HB {/B+0{-Ku~}n߲g{۲Cuð@$ނm 0k7#&~{>7_jk{`?TӘPg=țKhP}~_EMnx@=hzDۜ?rClz{nXQ@I# qAqã?k{kNέ-ppB8xyD6 !#@5HP1{ckV{!:9,oJuݙ1n.Df:ߵپ C?Suޝ製U~B\^w}ճV3 t޷vCiC'~¦>o0R5 _'/ZýDːh#O!'9 d࢓9I1 ,H7Tqw˫9.b#]%`\ Nɼ1f7P#}L`J?Ƨ5&ݲDi^3"MX a AGF .# 1%EGHRxgK;=gV2d+VH HdRB#JD-Raq HE[$~C[K`*=b##!֑;!!,O)2S奪+W0NkdQF `a~$J8݄khR\ $?\fHzIaHO?Oo}?~5SB* L&! 4F6HL) #]f;e59mYԐmʤBsr`CH)Lk$ !1Nm}\=>lsot7TD8ƺHcֱٸ_b_ǎ}G'û?Z=JLx{:w<n~?~Ws"ҳ;E.mԽY6]["{SFrz/z7:}<$iIiZ]Pv޻+~J1@S #ʷ˃1z i ·7z|림n^BѨ:t&>t:6VϢWՃBwY6]{|y]E(h", P,:(tōv<ۿIbwɒt@d-;;c_ֵa0X RD]Ž=~ivכd(e!B=:)o'SNZXRj>o_ O `O?K?,H?u=bqTȟٳI7WM J&}ǵٙ Kf ; ~݈DP~P" 1*?dsK+/V B aAx}n9kUGw4QOABvg0Ĺd$HjI -1n]\`D-,Qw(TH(a/(+%]Ԁ FJdYn-!/s]H]]y*R" D+JK.,"U|[ņljB)24eWKtbˮt`Җ~98||^o^eYr#~ORKiI0,~ `koJ^J!hZ4Q5 I?VnUxPBwބdê(M46FyH"NJXqM8;L9X(C?楧8nI :*uatVw1Tv =v 簄9᥸bɂ%oRQ;̒fPh5)pH)C\Ю 5,<=]I2_H7c1H cs0]zaI]WKk[)W-*Ov]5GK;1mYIt05PCMGn!A>ɠLsv5/8 E,%-*ִJh7oQ! NKVlbHpLj*Q0%ջ:s4Kwnuk/oTIsbMdHGmx  aW4㻎!s awq_ʈ].WikuQqrb J- dW$ycx5ϛ|t<\Dum⋵b&>k뺄,it\pVs\ovJ*X\ubݻӘcvrعkb5I]HaK`,4%Zf*,hC9.PQȣbu6ɢw\ͯfFmւ#bV&cr%)",h_+sX6K2ɌedՂaEEBEbhFԕIkTWŊ)2Ca"`)-`QEH,jJ.LZ2Q4 Ѫ-61d1P&(Ŋ"J.ˑb(؊1IccX*ToLb5 dMF#ךMbrJf6DcIńɄi5ƌSJ#NFE#%Ka12d̂XDl64cmlhM͌ͣX!SDlQllT`,V((ARX-L &JȘň5Y#& +|o/I1o*e$f1$ͤ4dѵ E`I$%[Lb4a*H"O,Vب!,PbɤѰhûn€3cF+ hQh"ł3DlbƴF,iuj45!i,E1IY6PHQDlk-b4VełQ@yεscIcZ) hhMi#QlmSLhڂ6E52І(ɬX 0ٚ"50̒(4mL#QIi,TQ3VMv4U )cEb%ۦԈd4QlPX%dXQD%ЦE,ZD1lVPlb3EQ!EHAdhɍY͠,$l&E$$$$U13*I-1`LDT&4M(H&hV0i-hccEHJ$El-bXAEƙbfTY E#Qɤ5Ė1D0hXRZbmlhXF"" b[b**(4nW6#j PQf-j*1PVAFc  4EMCb1&JLQ6H5%Z,Q6*0h hHJbT`MҵFE6&2؈6*I|dOϚ6hъ55Ab*SddmeHY"ض,cQZME*K$j4Q8Z52&̣0I"ѱHwvL!#e6 9nhheXm(XFJ6J6(m!ElCnlXM`KbAj(Ɉ E(EL9؍dؓQc%Y-2QDJ l0c؊AL-cR)(``c&"j1$TDWT(+̉ImJPF66(Ѣ55"3EE@d3Z1&k%X+l5PTE`-bň%ڊCQ7[MFJ 1҈li"h(BT͢Kh-I1FJc%&,h ,m$Dh(4[۔mh65hQ&EF4hFML%,l.[ɡ"b Lc!mi!U͒Z*-Fcw.V4U&-FؚE$E&ؙ5c@&JM*$U%h2i Jk%4v"ړdbIQJ̰j-D@j+dFɎ5A,bd%,`bMɬ -ZJ-@hdFj6+(Ȍ(L&ŤDIba4k&QE&Xb$т-Qm4hƬQX-)$DhWb 2#$&ThXb6f؄2d(JXԑ#Fɪ,RhlHd,ɤr,lcQXJ$XQj5F6 "A&5`Xj"ш`L66LID;cPQ(RQ;t֊j chȪRX"7t͌k0Z5Ff1Unh4"&h7-*KEA4JdňXT-&6ԐPI^W1("ƢJƤѵƋ!h*$ۑYŢc!AcP2Sr`6ōdЛDDmvr[%Pdj,jli$X,T`ؚlb ZhME4bōb51EMDQ6)&3S64FDhH1EFPĔNk\B"1LF4jD1e4Tb6JRlEuQZQ1F,VL!#bH%IFeQFCK)P;rF#QQQbTX0b25a2FDXX"4E,BQ! #&ɐU&dXDAPQQVh5&djf4j  PF&2RXdٕAE4+@S2FLcE#DHl ڄ&m m&(5Adƣd6J*De(Lk\D$ؙشV-DQiэ61j)(AɲATEr,#l1 &%aTj b 5*+&Ѩ5IF2cY4I&Ƌc d-ơ(EP@h,- i15rB)DآZ1IRlQd1k͍RX1 )&L6( IF (h؍gWjEc% h2ƦYMDY,$FI6h+d6b19Fy[t66-d "T$Fbł(F(ccb6 Ɠb"4bTHh@Ec!bhƣ)1c`HltҢ* HfjS 1i(b &DBFňRl-4EBT BXLH3FEQF4lAi(āQIV" a6a&0IF0 4b h6ѠQQi64B` Pi4cDmfMhA6J*)2mcI$HfV!#$3QDRXA Z"3 2a&/n|r4QMY) &Y6*"1& SfXQX$#b53Qcj6M@lQDjH`ԉI`q*61Y j-)6h b4hEF%L4PUvcEbe Ab΋haXshFF̨Db]v("Bh*]pŌTXфQQ(``6a+r62EEnsEQ !Œ5 T[׍IXZI*"E!5FDIAXJNۚMTbCD͌b 5FJPlA۫c$dѲQhkQbF5Y t 5I&4T(خ***#3 hآ9jR(h "4X#TmДTi4l8t5Ȕ`M"EV"jڊ1ci Ԇ!IFF4A bF-Ai1TlQbDTUF2c-bJ2y|5@]ۮ3ňnk&*CQfS3-ѓF礸P'k$7X,rOn˶cGb^+盐RuI#EȄӡM篒=6V<^rdQ4F*y|2#FDDg^7u{ u2PFQmv.0)_XP{t^՗ݦ/T2_%/Ԭh2RN[)-Bmv^UMި]pN?]l.n3.+h9ZW56mS\9}QܙH6U*:].9Mrզkyf;VJH4#'Oy$WplH:uurxkZ{lL3R>8:ev n"bڌM$:ُ@ڥʫsrtꇄ<;BIgQfm6qfmf8Z8rۖH0N'I,m= (n"ˆEԤ=q5} LvR2T*M-mX4PbqnfwPb5*aIOq ]L<+vY*fҡ o:x Ք  V`/\/dbZ|[w0ժ.}hsJPeۛYh] OxuЦ.pUo'C41N-s}Crc+*GM .x5Q FFXIiVyc4\% UoIJ; 5L8/"خ!E-Z mÀĪkH|u[B5XD.08st],\(1«s%M ^M\{rZ(ENUWl1͆q'i)S#*SqP6h䪝xo0Shn* 8ʹۇګWZ*Wm\yg>+B3lݏREʘ vOLUѹ nRK[LDp Gk?Cv:*e#?_X{}> G jrUT*q-"(Tߙ(r׫o^8G{׏~H{l +m;pcW ]wh0&S6\mE5BHu+ .k(n`YU[Mw-S1w-T]vFK k"D(<,YrD#zո%T/R3KwЮլ/VIdx<IXln ^U-)oHVa10#pH C$rZV-~}\>Pߗ:%u}Ӹ U7(  5mhX3A/Bcڎn*f4Ωcy*2'y|}Ә{g m)=-j?E]4'N]k`֢2B3b!@9NTv7]83)tc$/i2$!/_cD3.Ik}4Ѐv\cTeDDC_L!pA.D@}5Cy!Sh( rV׻ͣ<tޘZV̤''(M>p!?e%:Ul 2Ai%[i XrC]h= ߖ $ sx?x6[Z5٦f ŷUd@CP„'D@hww$^>殪oQ[šu?W=~z dΌ)eQtwCg{_=~:d3v}KcOH=OS9:$O C{ x}ow?Nװ݊ȞTJ PFNC] 3rPr()L$PQTƜR[ъKm⵳~h;imqޡ:1_0>hS/Ć)I 2IASWon%q&\$Sg$8hҵLŁ-/B =XxSly"Jl]1v.]0 ҪOWuj .xdgFAF_=bw2r pMn؎XH ~` g`dDekR _q^i*KI? ̥[s<)iQIլ-#8*Q]NVHdlVbiQtok󟢒u!+͙ňiAݩ\,/ҰoZ#)9 x8wDޒHu<kt:9dB- ̘Wk/^U*ԍ/VBK NxC]2࢟݅J$u3 hw%49|7&X5Ug?N2ŨܑkR)kۆ.Lqqeݮ [2U-Ҽf:G3VPrś>l`~ l!JaBLeVie\⺉]+洴+bk)[H]snu+P>8twdNjf_[SC[GBO@]] 20l ϩ"Qv"e])쯈f%E7l4hpp~Jtl%GDt<x/-߹6r7d|(BMV" <' =sI=Z6d^~vgLͫŷ9Goe)z," lטPq[ؠhqϔ.WirzE#@@!(n>"+wC&d"_y4tQY]ߞ] @e>;ܯf >_Gh2b1b,ƿhC5`;x@%IIGOpb@d N?{s}e!U;2CB $ A` vR»ikb6MhHA֑/i4AƑ@Te˒q h9p@nI!w|mQuƪnf8ݍk8akyeqƉNy1w``cx.9tꑃ3Uqypq0&7Qy|>m.NDu>_$#҅+bel neUt\"MizNYZVyѝbׅ4dƨy@ tЦ*꺡Rm}v0cC6,Ezc(Ϭ*|n j{lTq{r<7m]Jf~VBBa&a$(I!2I1!y7-~/Њó ePJMdLI $>6~Į[Op}>Aڄɳa$70m}Hf܁qn!?H*IH^O?]–f; }[M0$>?{F5K|@S:I\!ytRRt(|Ap!##X6:ăPIR˂$;$Mڦ2/?9jelP E?DU/O?mOӣs) awdͭ|L7O}kt7ԇUГvػ~*dtfݷ/_f'mt/mջ<`fGMiz˖ϫF\klJx+fvl*)U0ۚgQթYSjCN0Tj^YPo3Q: EԕN*`)611Ueԑ+RW\f4._dȼ7*boeRi9J8Tm83 XnUwgrwy7|3zgE[AEI7Ooؿ2fOLҌV~? )i][ l)2J.a A"'>(u(Ji;^#x Wǵ)L! k&3@mT w@BB EȤ;P}4Є*z;C-BDpk2V 7NI[AIIZ,T*T 5"dD:*Ӏ^JDa?vIՇP1 >(d6`qޒm:Tcƣ*Ziiw#8TW(2iɹxj~v67^Fωo3k/SLnFV>Oٮm#r>J2DP18(Bƌ!eɞOv?_`XY=` @Ԥ$]߇Dʢyc֤1r-ʉkB?*2+!?ՆHn^xʞ=}v )A9Z/Ui%B-%CPV[Aki;P`ZDwI;HBLz/$}0LI 5>Y"We[Ԟ+#$<IHVRZ Z6ԛcmmmFQmEFm&IB5KF--fCFRbM-ee$M#L)e%Xh3TUي[lS66ڲRU$5 dԦ 6j@ج%a*sJ*(֍(- 6Z(M&43!IdɰjS%x713X͢EfSZѪY%&Qf-6Ѥƫ/vLImMdic)+4lfVF6 hXژ*4im%$ͯT&V5"Y*ԦI)6T)eFcX@PyLd ڳZ֢փF)dh֍MVHYZ6JEChJK%j&K+&S4FhkeZb3"ՊQ21ضe eTZ%b1Z(-mMRʌm&m2bm46,+5[V5iR[iZZ*[dXbQmjߜfU5&6ZllʶʪhUkhJU-ɵVj-RVjU4ɭj5ZJM-EZZE+j+ZɶR[-mZJլVZҖՕ-UQVUT(-b`1lڶԦ6F" F" 0[_5ƖVmUTmXj6m ",VUjRPٵKV0!dEҦյR[k*5UlV*6ڶSjդfMVIm*ZQjfmZUh+JTmmXڪYU[U5-Y̚ !*$ *EcTf[-j[meVZi5KZՒ[-kJkZemRfjڴTkV֭2Rͪ*m&f&mc)٬i*alTke=xfYZfYbk3VPe*YJ6Si","hi*[fH*0leFiZb"HbRҌI ,DQ3U&ŪS2YeIiJ 52[.,ٵ6U14MHRE&ث&ZJeF !fF"5jښmhK 4HX,Y3"m&U"HMfIXKM3I 3wQ9{s\a+s8f/|V0u9,6r;&qj\PC^w=UQ*lkOQOi7@_"D1!!]ІcG/r7[Wdnߍl48 51r/pI ?p^&k>p|s @"\F:g95ѐҭj|  &~(W@+r~E2z$[Ԩ6E蘓5)6tո -\HI*R yo" : VHPTrry8`G-/WqHe1b)gMggUJq;ԠyQ*6dzJ9zO_mQ/4z> z{GZ̀]%RT`JFM8 aQ(fa;3~>OӻV2f Eh£+_/=4nWw2i Ԋ/nK qwCZ$ x C5XO|b*k2([K[5}fs1UI$r" l[x^vf9gD&< r.M9!@azQ70 v[o`%];W9~ZI*R%jQUdu ȉ"jHmnUmj /1bjV5MoѭT7Ws zF[TC< rYiqPA/ ]M.lz a@0[O.9psR o.3:w;0m=^;sي™h+h㷸ecV.S{w0lwnvhP̚՝}4sa ˵XTsogyPWp{]R;^;)I.vD"" -sʄ֌x} Т"=WW bhOH/"e]kt< BrPZQEp\rf̺OUQE_;~&_•Š6I61gDujKHJO-Eqd%7qǙM=v S CAYcDط`z%4<7+nAMj4/~㇕~T(7<)b [cH-yJw~} =aDs/nQݖ2oFhzݝRtwCWX>;PWP]JʢGK: /@!/-oe+Ջג<lźvs9Ϻ̴TEZT/&mg{g{uBN~MX劔-gÆ*Cސ1Ms wNn`(3mQ<kJ76׵E{kĈI'+"y[kݿi g3qDqR̽~xϯfا>}tɄP\$I3lqkf$`!Lw@:k*Yh"Iwk)hU)UT>&o /%yO ZOU׮qۏhe1= 6*:7[U_Nc5лǰcqU0!+NMvOCt*6z[tj[oEl͡u-JX*DNC-gVIVNtS&;͕c7VzZٹP3D77VB EZ-ѽY쀒KHLFcQ3e}{ocv\9tշuf+V9E ̹:>Cnգv{4.j xPyBfs[*'vcfFuFnMwjmO,cmNLlt.,BfuD-~*戦Uա̭SX6MtP#byUy:حܗCURbt%ul0]yh +.|QwXCy;gYNSTM].:F+ƚ{`GAZڽ]XB劅7[]1;`ݾu\x.,fzIה{RvӲ⺝ r*=j]ݱdeEuOoa ѷBPUu:ʟ?~W$~nInk'r YoǝH],#wȼ#WTl ؏4U]w2^ʹU2CҜ"VrOh[ a+A;2[,]|Z2E8vW׭^ Ih%*6R=qեLЙK9=C #;|zR6Q6UG4:qƯmZA̅{O;턶TG^͞\^M߃KtAڈw\j9Ƽ}>=jLD^&ο V;7 FJ9_gtZNdb"'eXUEaTT-w+Kxq"R?e楏-yD[\ พY]1mU tȆb]p`D%ORb"=J3,4_XS` -Ɓ#u $4Z\BDEUN]^t@^hGݳ%ROU\!r(ʹW6J5#n7Ҙwb{(-R* )Q8⠨6 7_z~|+ek!z}{XO\[{4pm*:Phssc#x"/r!md/^㥯dj :U,4;MWsMa@D0{9:6+dmH1M z7zNVG9QV 1[Eє<οjeiwy歡{ri !7 %uVtKKU*QP$6U@,77x0C6S U)]k \ . )k~ Tԍ|Rl Uփ G^=aE5eꡡ Vqnݫ`Nx^`^zYvx6 Ur҅wV雙TM+eC)vQ 6nyݜFrn@-'v}gd=7Ϯs:аuDw<ѥoA^y @rgIٌ0[dnfl*Az9dH,scux$ paxl@AMZ^ Y$Tv29rɽuٵ炅eu¯2f¸ecf=̓0u_%[֊9#G\IwJc^EE!kEi-hHM,A R * Ktvx()G]!`4 HSVe=*Eۓ O) 5(XGсU oTP!rJ2ϒ#%k"i})XJ-A<,ܱXi%.Y+O1Hw&gYI&[c$u 0mih{a^תk5mUZUV! G^6AݎH 22yn …PˏE2o۔{-j~ώ#a yuO!$,Fe`C$EM~I^n@\@֪@U.<˅1œl\W%GB-Zzj zu1Ƚ Ƶۺa{Eݵ}=1y+,U>BR&C%AX .@{Qkpo$Sp,9t Q5m_ZIP-=Bκ|heH hY*p TEkxBYtlWKl*qCq,1'O]}|]ʔ֡%c5sxc^` 4xdP؀IfGqG.-\!QۅUVq+F !nFxWm}dHC7m M=mB"8ZNvJEF'2e$6P":[[QP-KiDq {B~]'m?@:P)`3ֹ݆wI: waq0KVeJ)^TA+}ֽZQMpVM̤$" u_2kלBjڍ\:I=4OhWDn'QxLωE(9 !]{T̏5un%u6 Mlⴵ(ѷ*vL峋|A VGM8M&"0y=^- ` bS4HUDW&]QURݰYPg|POTDϷ 築!upt9\¡Y7F#$)7*qK$``pxT' R.bsx (UJ #TkJ!@i@ (pֹ^ƸiUQN(h A.mW7wUgEU{ֽUŨj6^ormjmֵ$mZzܖAX_Rkz]D׭_HbT_[n$TByaeZ 9XV`. : f͏AS WNuMOC8xTj㦦zu]Q4WJ]FUM>^ ~5\{L м x*WM@ߺ`IN8HDGaqM^`Bn˩kV_RÄ^.Qz=f~}qw}U\,} (-J mEDP[$H&\[">Y F"m^+W=ko]&X5"/7Ct$ C1DS $PJ%D5Pw4 8 T~2 -ɧI=묺n†qPY!ej6̻hӧ@bѰm l:yStW \R*5ς E?q/q:Q*+|!ٔ^D!WRʐbCζQ{r֞Uzwuq/\މUaZ-@r3TȉȜ!7 |izG_X'LUxdP%Ġ*%2Ti$sI7ɚR@"IcZƬYT[|kz]1I. Ơu&D4wuD4Mt[ D5]1p P4>/8aLHzmC\…6hZY} X[iaih^dT}xpp2U 0Xs:mTV"G~uTB_' ‰}qRʇ *bE(j"RחA _'.u(AˊTJ##j֪%0(t#!PrImz ~[k 6׭{nn%AW"0@䚩u!m+[&zMCP5wMt41\?!hP 1J%T}<'h)ዉ`LazXQ >8Ɠg)`ߎKu462IpsoWgҒ>V(䞻4Uu>jHUi!#mbHZU-u%-_5FG TשkBJAFUUkbwBvԣkm^5 hci_xP|jFh(]]f5vi;W 5RnU?5;dd mKP*U.6`WIhyٻu^|ҏWH [Qv G΃etHC 8^<$IT}TFf#v_pW E/*cZ|]W6溽_IVv|_ Wr+%1VG$%R6qwED(zQ"LƦE=e2+WM[~FOT Ǧx TK^dj JTqcE?UFg+*= _gԻt]Ե뺷-jSxE )h(-"(?D{zq|y(E"8k3qj:n !i@n$*-) @m >:ܗVɉkj1xOg9>COG~*} M*n9Ĺouw+"FEZk[lRǶ=*#\'Q#VhYp.ҼH-T@:FTh-+;m+씚صKk8;y0+AHI*--DfhA8F@*f8M2:hfPJ1 iB($d U 1u>Hrn {tc =IOh7 n1J'S[>V,@u߰8s;ʍjxחPs;B|wYDQmCuyA)OcTŗ֒ Ryl.vn G<]w:`%oBO19ԲrTmEY =9)3'e]A{1H5TpW2S1u'Kv̈́ζsv,OmJK{5׭oXi 6y ʻ,´՗{}e5~FˬmXi]bA{bMqt2X)ܞ-hR@Co$y7AdU!;0՝]s1hl)gfMm1שٗ;yy`b%c[l+y^<նUn) 6Ш e%Rڒ I yX-u+dBE+I;k3)q3+UW],[ѓ `XЛZ-¡cSJlpQj׷:(>D^WUT&qANc0?D/fkfcW7%gn_^F{{Ber)A2Naq]#|+Y)8",vq 7{r P{+7FU];%vf,Y'N3ж737&G]cw*]VVVF:IvKYw.T 7e+AfXddڛ]Wf݄ihB!c󆪗fUfĔ/HqZ٫B%YByUs(PiPPNs3츖b9j<x*98) W պ9Ty5cT4+Bzxqo v0=vRe3P]-c 3^սL<8EU]הuf]Y\7FU6ffl}Jy)PoGnc*g8c;{}OVQHֵk{uTICĕBz]n8iUr<^5juQ{30cQ{;RP{v),B҉z_>U۳3 a ';9'fZ/NX3+;4Q{0cWPXŹzE+VRxmTe3uVo`4 &Vo 2!.bs:fAe.muף$9Czn`Gw7(. ]nIץ{]2ERr;9سeӈ㪵)nIq2cԩ\4*(˦^m-pݦj{z5Kʾh`C;Pwٍ3D7\n_Lm9 $DԞt sh2aڊ^ͫIJ RiwàYTpݾ|j1ٮxx8u۱vZK/I:TR"ڴM \+K^ αO]"74W ,E:ݬ![nKmT,aqD\F]uwU|BG-XB0caWPNbLTC1eDupW Z;79Dž[eJδ4LfUyٖD9ZR8f ,56h7|rzu wmtmwg[yy[l4(>{+iם#c;rՍ`d]Mʢ 2(,]gn{#ķvu!+Δsy՝Z:>* T ݷQy/t{ ݩc2s\7:6bmhJXԺT L tUSV%g^v۪v]m5Kǣ1kgSTFmގʗ5,je3jnpu-TKAn9)MģoEbҖ.4ilfPvZJ9YpI7mAwqcØxJ:K;].{YPL=P>ՁT ZA ,;6;5f9LsrTή >80V(_>A0{U@l M Syux{B:8l\=tmBu&u\w&X꞊]aLCOes7/ t<ۮ{ɚ-4<];DU'yzn:%N:vznX+U$ԻMs##7l\̪]8)mMRZ {塜;c[{5f;m|Usˬ+r!օ1yc:9۩w(QGzQ:dX 3Jnr6S*duuݮ걏02.!%0^:Ryl:Vf¯{4`2- }^j,9{wnYd]n+7HG)G[1K`|J;,ҹg Yk NӪ'EGq`a0<ҶI$qeIO A Q40i/AWr{FmGViCDBvl5PѨ!5%G5};hA,hf! АEip,3zyW6 䭃fBܰF^܋)k1HfP)6)xJ:W IX٨ڠ؛\X'vx=w=yCMŹ|r󍮍m8{mgWo\օ thB6/#FC*ŌJY'qG\ z܋e5UG˯XXPPC٧zm=smtuJX 44uu.d]̥ N^PkMWkM3qRd}hmJT\Ӡ뉺2EGZVjbu^u9(w^3. ,ayys'wNۑH jqW4e]㣳xpN<_uDV1Uj=ޕ]{}iYu=!s˸UѼy*2E~獫Iǝ#L3#xuԨU-v.2Z-N࠳ smh&MZ@b>@fʺ[c'UL4GrJ2vEBi6uYyjwmJYK3MSjޤCW8\MbY-N ,b^mK^!EtYںZ&i{ÔJ,z6բ`Αټį*Պ7O@.+^yn kƃ:\9<{GNZ9W q_}?eh[bDUfIkcm.&US.+7pK. lFsv* E>gZc8t6mNpP*jZ7꽗Z1kGu!=dWfRvd۶֙˝mV(YY,ՙUڨ %v.wR.F6\LٞcZ@5j$z^tBQ!Vcć@vcȇhW[ ^7`;-^LNb]hdFy^Z )ssRuB1#C9}%G: ͟&47ӯqcy6E юL0`{N1+7z$BcS&aMLU[q{F+} pufUrLl۹@evkQm]U`漸Q≹FzMV4}ih]eҐYNSjxZjCwbhXjg&|w24'=}۵bJG^Ґ.Xu}kz5Z)3jMЫthڍ3u;Êw9 ԙ'PսRa їfæUWoa6})JدnCyh14n> ׋)%_.טEuwN%TuՎVnVgVN,-qjeUt{ ^=M V -ˡ '*brQCpFrw{W,ͩGMNbbvxo]a+(j7nx ν#%UVzwNY͝hvŜ-f̡\6G+w1ٹ[ &kx8?:ҕ#%~Ȋ }ϤLv66,Fޕ/CJ9SD%X̳)]}36'&k'ne*5ݝu2ݘ2n`V!(4oZ;%-a1R0R]ʃG!@H#n惾+&_UtU3}-u5ѳQ.)S0k)Tt9XtRkG %Ne%"ZkS\SFేsS|vv{@-$j:O+c6.wVU AJz=;07SX,u%{ebZka! )uWI*kn=XʹER:B}{z6ЮTrZ'iK Q2;啇/%1MYۗu{dDvoeM}Uʰqt;yW7:YvRJ ЌZSN̈s6RYz'ǎ2O"(TQuC͸ 71e (͑]QcUYݽ{wVnʺ+ 7ɓNu2*zKMK4:gcmm拪][ۮ޷\Cw%wĺw Z͍-[nU7dŜ;c:nSͯfP&oST*B sI-58OL)R t4zAܐ˪{[Y\m7,EaUCduKsF frn)n $!rs4 v7mD1>NL+7n3uI{S6Sޥ(A:bه.bTqrjk*bo&aSxv52`iVڶjr몏 ݩOy[ZpvՍU)6T˜ 6̭{{],-"H@kr9ml9xoOq5uwvt Cwlvo{0rhbȪ\ )Mku/n.yS(Nv;VS ݴ ՌfA 7ϫ0'Q nsU | a7ȼ쀾LP"^-ޣØWטju۷Bx4_Cg^!us^eYk*尬`f0jFmY'*i;\T֣s(5yo 8U"sjTj+=j[N62 (7\s;|2d7hyy*(؊2NB=KIהGN'ep#^v]ŝx!jc)Rv9tU**k1CH smC.<㖢*n Ӣsh,4]g0ZTljΤ enB){}ݴnR+mh%+AUxSf]+<*fڕl]P7-ko(V6 = î-JFMrFgeRyPeו`ܨnqd_Zħw޲VTy`}w0ǚRUzns8xUKb]HaW.+ffqwmdp\{6\KĺTfbתb\7gQnӆw֎49`t.M%]R9Vyb3 m΄;HRxZ y$K ϞWK6ep>}e `Jvk;7+>?+Tf8]MZ_|>t`-nf#%tTQwiz[ծY%Hq(2J*] PHχ^ dN]UدP'FaU|ZW.,єUwYj3zFe;C0oYfANNκ2b5AݹjLA{i\%Ϡ;t3ifݠuq] [,K]xRF99.I: '*fTV\uY=˵,\2rےY0\tZ;bQks4F]V:U]5ք|;zXTut9B>Y'K&dMɝ7kn^ hފUoۖxmTaCy8<ﱘ;:RJ+5v0U*Kۮv#JSiŔüs>ܻ;rCί.wfUV%»:(֬w>\63d]k7Ae-jڣוCTCQ5ۆ,t`e> oL[!xC9 Z{+O5㹓`\7gz1v y}Kgr]PWUm**= [ne[xfĥ5 t/o&<#ko G2:Xh_aC: B)*8RPn9ܜViJ'-<ۧuޫ| n(+y:V+{nWQyșy+u&Z]ΡKI t5w![vtoPԝ?htkjô5crufU[T4Fvڭ}]pmq/3eǵ-GC3ę3W1ݤIUSɶKꮰ`mDs0U9wKGрn4bPCpkyKCPB ='*=:Uzb}6vYTU[dm)JY#I8;(4U.b%w6F{{R u.C[,;iڏ[UPzti<#2Wc(ttyneZN*SN*GQ][B)&@ lyʩyFSܚwvy+\nl5ͥF6:\S:H*ЪXNγ6 'bj"&Mfqʫp]FҗgqTJ'xx^6;͎qH%Z φ{R]=o0ԡVir5ugW.}+oktܮo7-M=\1eB)en,=E^jl$M:ךwvqШ&RiŖpr#8<DAiF mmm66TKVeT&K R V,81*quפlwjZecyt4kG(i[N\:ΫCHZJ\tOTkN֭ze$mRx KDA;ZC;Fۡ^u,@XUUB\vw!ULt-iH`jr pUY!7Ϟs9Utf ,mdCU^ƨi6j6J^$u/1xbSWdMaeumm`wHd%pv;Qf%w6miut+ܳ}ƌڡj]/tijAE'cT/6sg[ [XTv]VKךe\F,m,8Q5AκZ#eGPGl(K{jnCe2U7Ge]vtZ}z/t**iw'znXzjl/Mu\f6VxGL}ePoA C}Gn)~aВٝBaozU^A{Onɋv4^\(UvɨnPL{,';ξlgku1NcgH vjuݏOa{ѷ&Eތ{F\uy{ ڐ+HRJ%.칇-\ⵡ˧xhVUmC&nnJw%m*9>*޽n ]_mĪ(,K2}uaNfE0ܳae]Nt_D`n=ͱ;gawG;U<eލ" v`Z"!akL]GJ[+uVG*l^Ui=8.s=WR25mV&TgQ <!L ausg/+Dk78ٕuG5-aaT\姵\xDeцSWe Qh^Vyo$ㄍ9{~֖XYؑ]RktoLj-9[ Wwb3wz`Yr;wpdCsڱ)Caϰ^I@h٪6\}XFEaJŗzHWiwi;ņo˗t6Cql0ʫsEجU]'q!chv,nQ$.!`dZF)QWKͬIWѸȤȝK5{3IG"zpҫyGwIa k]Z8g&ՔI. wB!Ytӻv.w r9P $Ӧ% ]]a4ZC+!ѬX;xEӸlܝtؚUյF{1WVKH9O;:•s:#IveZcw'/`اRJge 8zefU>dۊ{a]k Q%ChjlYKrj\;1K WVv 1S22\3 {tO {NjۄLv:^,[@:*̲[rkw)/$]"\% :h&aBUe*ԫo(Vnݔh/3ns#9E:R'"ftݼ׷:oھ2[]/m7XϠb*hvҝv·ld˺Gr)鏑FgQqK+oGKIR[}*^RʽSםRΣ4w:R7Vpܭe҄vDwիY뾞[5T=K= tU+>otUΐ0SN(A\uەԪ=%ezoA"ݠ3rvrUbYָ^=T,,["2>ޞWnYe x0[6&!bA3gYqNLCb(:DŽ*e(P3.se:%'4պ/N/^k~6c}k ,/sl7 ^4D ,34Qڥ0vO|x+gˠ~c ޛ檼wq@'ϟ(%e{xָwex5fjaC u:;̓wƪ^es%a>b)U/"KbMU'raYEo'egWImǢeAep&^Pv a3pm:f#=U(b1 9lIJDdx̽ر2w4Bȫv Vۃ1)㫽Y7$=̭}b؞fޚ6iyûCj2YuZEX3Z6]k^ސ1cz =1;ƪMcxPfu\ˆQlǶr4W5ꥦ%uU:MԙQ`O8zB l"1-o |]>d/.UUc=1@m{- =3#Bkm`R^Vur9τAz4ɤb`/d@^o[KidḬͬo|J }h1<ئ{̉5H66E_NJ$%~8쐽s,^dZ( }p5mM @fbp+vcM9Y V==ݗb  ב_6YSO>@I$u::YuxiYJ_2:sF-aڀ6n sC!Srl lpfbtMY|{/g."RLK66uNzT72=6t2mPαuu 9~~šE#vmT\Gw. #;n*Ft1ݰɲ4,OS<,.[lCgmVrla*Q.;3n?rmUٜکXև8ae6ڮޫS!52b!o-ܰ2ݛDcẂY{SKzsIB$u Mp|oUftsYgaz٫G-Soyc賢YM0n6ZYRʹ2ӽkknX2^)ulašt="jcv9,rgeiyt2Ujꙇ=3^؝w~$9qoaZ!״W^UN!wu.-'>!{k)=WBgQO_.r6jo%S%n(P9 n6ʹ"È+WQLJ_\rm^w]\tcw WP\ %vL@Vt:`;u*ՁfyY{n̺>W[9yJ锭 ^a ]hRwU],)8.QiKVǰ<]sC8Ⱥ|m73F;jsoXOf"e룪BUi[Ӎ[Yv*v*I^-jpWP.At5Ry,]tU,oȑ(I͖a6 '%YhW`yˏ2X-K_wJQ;NoQ[R`6Oj6 m*avVf v\/dc/"}"řPiJxh&t.fʜ9_φwj;*ƾ49ƲVfc|.}+BT9i*}+3eQOzWsyǮt;YcjuW*74ڡw|f/kIkvъ'I9:[722݌ŠAu %epoQBe7d0H\r9(ghmmAz׬ V,0RoetT/KU*[1"1JhYg |U$#2s\7QYwé'ʦ] x_]`TP60*ޫ%B؝wfIJd#DTJ 0o5ޚ, [Νf> CYؚ;7' Cl¶bv(I*+g;om[c2[wnfH70+,dRD`× A.1 R3aTᙞԞMrRfU,q\nyd=78$!1ǫ3NQjː7ـU8/uh;B=Dyilg ]2ny-;r;fimt0}2řn(tS"KNtxg$ ӷ,ntfCMέp1BS $-YnEB$0hoKՙc+QhُHTAL> }xg'{&+e(I땭Otyf>$>`rJ&V%&Gi׉ds\^H^J/D>!TN|R.クwJ$eZV! . kK>va  !2q `>1&Ȉ֢x{ UbwV( j]]6+(|ymu )cA0EؽGNm8Fv蜯[ڌ<>5`/9\TrO :)d{2%<pyxhzvCm'1 ǺRbasJ*8E[C %brD/{/Q U:PA#u(%էi\#+A7%ɤ( PcLI3Z\GWtUTU62D^跛qN<$4+rn5 {O}y2n!1z<0Z u.&-K4U]T=8g}N,bɫXg*u-(#I*↩zN:rodVj5UbI.8CD҄ND.`6ŝm))WNJ1efxn0bB$Jѻ,$93fz0˘v;tnu݌Cm V=j-m2!}ϝ-tm zPWev];bv^yWjms\ph8/`rZ3LtQu( X]mXc*KkL`ej[h:V 5:\# 3UgStuqûY!yUV>yu4io,A*K ,@bڬ-;/iݭt;NB.=>c +u%ۦ:Mqz3\Kq=NJ+:}OiIEv,0U*$r!* f`n ֯(UiU i^M ćnc\"WV Fb[1ի]]֘4wM8u ld׷Nh"Srx0E Bõ|O=^Ok/BgSݳ]l\6[= oQn@ܛ_P8zW0!|SWAΘ2jY)vrEa2*onor*PصQɷ(.gucnu- 9wKwzz_-zw AU-VW?RYʦtT4]1_rףRPo3כFTٸKιp&w+Wi뷔IYtp[˰]>Ƕcȫ7Xo"\yn_n-Mxߛi%Bjk̼DQ;Q%(Az^У$w+)ˤ/LtRd`[xa&a-)ٯ1U:=YDPIjf8=ŗrbfb2J۩k lNޔ8㶖ʨ<$GJdXВ]+"sf]>%<<6ҔRpIWm+*O>}Vz)."T몋WdvEsVF hlvP5s5+-] ^ slۗK"6J vIsLub_:[ʴ#Zsr B" ͺSت͙!rU T(m\TVBд޳+sO8&1EcNy8l͡IB1pٔn\כ|]klEdrm'5Ӫ=@WDk|xA~73]о$6 ;[Z!c hͻzbnHF-Tڀf`鴎UbkCRN+h:5V6#sEovMwsKg^ګL/(:uwGCo]]ӑ`p]ɼmEsNQKLj"b7Hc@ Ӕ3 1 Rg@WĸTmpθT6^yp}v+yU7;dvgڅØXA #錖VV. "Z@?F)Z:v T-"Bn1WGNm.hT;oI*Mx\w c'fYEnf=]T q(V%N. x:}{jܰvv}ݺ'ڧWͺ=Yn5Ƹ+f۝XV0Kō-uip R{N`޸6!^^(=g&r5Ve-Ԥo(gWgm` `et=ٵBgZW[9Pevf m`9 i Eg7%v76W{7M9ћP3"jEܗ1mޮݚ9bmpa z^ejdMmV O) i޷E "x-]d= aw*v;"]PaH5M$RȁFJt0k`i<>eL(X/ch%rűwLN:e-fPi7 R; Õ V3"F]aL C\5p7`2d<d}:r;2xչ1rWGCYHlr*o(qZeHPWvtVug/ c9w뗭x:ӸemtjvrI=,"7Ǖ[eeGY}^Pwt:{`M8WYV1 ֨LPQЮƦtB7PbaZj1MahB FUGjηr^W2u1ՙRnZA8vG/ ]]q!gfܲnPu|!2Kd澔vJA:+w0+. n. UVYT"BfY] eͻF!\z"9DKLUspЦ\LVWd>)[{m[ױgisګ9^zoLJ+w&3vEǷ& 08]WL5vY̬n̄X+F ]nowWS#my7SOS=LeKnޫDYSuC3pܬ@^:toݤ)Ţzʨg Du{X,7X9sjD7!wzR(brxIr[dճ[0clY%PP2ږŧhb]pS8!(3$i;H֬=ur5,=arx.dyBnRGYu& !Ѡj:;Aܪ<w}1k6Xӕj{%-tJcuګVBż۬,(6v[J۷mU͝+={o-V,{uq}?l`$_@h |Pf?3`Xy?crWff)e]vYSMRikL[8$Hwun`mv^},[wI$}Kߦ߀f*tTEH~TPZC.Yf}2`cہI?UݣCAJfg 4,3&M-:m)ۦ]]ݗj%5Kj1}n:3'>Lq6Z~XpT12f%vW ۅo%Pw** LGh&&()@M-]%-Y_7.JwxGQ R]v훥XY<&txfCE%㻻dXpP*@Ć]K#(rW7Wʨ>ޡso^Vr6Ftt<1$xp8HIz:#"u]^4漗qG0wgw4vL}YP>EO -sj-k^$#˒I(ZƍVѽ{nmZ5HK)mzy؈սA`P*RbHq hP`@^i Q%iRچh`ab@Jр&&Qj xjp+B 4{Ϫxsug(-*Z+yB.L6o]QGR Dqw%!$8CmŶ>$X7Tl0gڐ29B>tFj :ˡH~<7{߻9h6(UtK& H1ΰﱠ60UMZoكד_%Ɏxy"9QeNp:}ZJ2RNsg4rU-@Ԫ-/HB1 j{(*2E=hGt,@.xFyVsgWWiJsoP Sr#B "Oj&jD >"1,˿#VdX"p:N`*ףqV:J( .\˳gM8Pg5Y©MkUntޡ13`B" jX;Y) mK='^RgV0iL\RXH5Մi9d"+R{wPz ,Fc"gm1:Wuzw:V\/ֳ3@!MzZRqu 7Ѻ,j.79Cx]e&ըPB$B-₦:q;G: V 6VN-Tm]M~ET'izUkVn2PG+.G ϦUׯT-S.tJy,匫;K P0N%LSmuvxr gW4TQFuUL&$DRHCy6D'+v֓pǥzK‰%x7+nʁWBmjb4Ql7pzkBQS[>QV훕viƓ܆2O+톿5_}:ֽuB zEMtYBJ{29V,i^#y`ŧ.lѮͩw&n# .:(Pplo2P~WRRs8\rE>o1Ĵ1*2ĬsaSmp"d=,ɄRc9 "&)4v"#Ѕ9&(̞mG&athUcD-@MrӠgZ{u@TL#_j&誊8-YP1ݙw9]2jRJ-bVj@E(fZQHDDNCL#- H3 pT<9vavC2ru06ׯme`tgޙukF[D;Ȑfrɮ}o ;Sl{-͆8T8T |UEՑǛ߻{,x:OAP5K]FBQq tS4=$u0U9U<%iHK!a30W<`XؤlهZTD4lud̮MH|-؈dO(r =*Փ;o[[iCQ\EEnY)x`J@M"<׬Z csV)rʹɨ=jlCkhjkT(UfCy |Gi 3Iq@SX2HBSUwnˣM K\LVdMI,рZ j\sK˓e6hvvUC-vvv#_GGgqܽpM=5kN6xzhociVm!0uƹJ.eST@/&b;Mv%&@"QU3r@$+$;q,snjUfqK=eݒ]H4Kb k\Ng=ڕS+ /deT;m)sѫp,}x 5(>j(жc~y}sGIY+{gc;P}w2_A9IXP6UX6K yw!n:^QᲠrCb6!}\2>E_fv4J CBҫw0<1#BVÚ/u`u+dV$Cԯ*Vd@y;Ů%WL$D+ Q>.6+׽sŵE3"ޭ=x͒}$b 2IP(UYO+%¯&i)|*+XU_h! dCCС)kIw1T ۻ!:Ӯ@zL X1 AkJ5{J?ߗjXu( Y=5a .c^:CtU=Nlq$ڹ.I9Ȝ3y0FjԱc߯}S{Ϫ^?JmAq56ʀ)V>+ ID'>eD JJ1Q(1(ACI9˗%!MtD(8U|n(`] 1h!:}BM탵5=ay/*^5p69n.rՍc}"Mwh ̕T@(} jbw1˜zvjJ$M;I'N:Z/J:;ѝ]Z: N50hvGP4*PB)jt=uьևݩ4]6z:. =~ NNTpC=i^\u|U1d:[h L ιSpw٣]yBCiԆz:da!ϮE5;M^PC*HJzUuD[lQA9.6xDGD:*j Z2]_'RT->d맲qê%Fo7Buq1 v٫||09˝%uB>:OnOn{(]Lv6ׯDz5=1?LI(^Uf Zmty=˒qeX_z%U˸KQKT*| Z}^TeOZ#A|-Wu H(7TPy7;ΊK, 61*ҁkM@(tGC\Sل׾v_/M``, :NNΤ.qv>x(6⸞>ykƕ)BV3-=L!tX"CaD$1*Q5W5SXm2˖ar/$eܥV%TGxYی8KDXD2Oy㾩[iha"h61M V&C?I$[~M5v|.=Ndqe * 63ni.h@斜>YY^ReSBA}4Ljws4j& 6j{ ! 7ª`tw^ꯑ><p߭ޖ.F4Ljs5-HEi.>k5lϡ K >BNouSWMmT^J*DxQ_:v]'H.T!z@ӐND@ DMQh'WE]TND;Pu*hr GM4J &CGUxM4UJ*vcYT J{њ՞C4cXz.+dJw21`땵X[m,@ c/W)Rl}Orw3*X SC0ZC1k2;NҎ롺VChK^qP.,{hYDg< J.7,d7hjX{4A}ۯ< 'Ut"&qP3R@X4T@ѭ_1,lPu|!+3ٚC9^'EGJj1'{PUb m.I0庠W'Pj Dת;ЄJ-P=h̻ss1( ⎰Ԭ]y2;m nR@;̃`޳0Fz-߮.w (&C JR+׻7f3XN_ I5. {2uV]H -P'qV ϙY W!c{HPh"M5;i&::) -6OeW5E)CMHjeU#_ G^Nb8K~\a+sj7+'rPFe%٧PT At 8Cz^qL} 8u15|T uwPND ԓrĪD)1%>L09";Sa'^[Eyکl:;75 uOAt q'DQW2,ڴ<3MSi;+,Vq$쩒 M}$`ϰ;M_FlRc61[̅ʍ\ _;3w䲖.U ["ȬҰI@ǒII-UPBUְ*"8eDC8o-66NHD(8Xbsk鑊,T:Be} qpO$k`uUDmu@9YAS bDj*5bQAJ (>u FT"Qʏ6T5#O{w\# ]-)߬\'/68^{тf/:Uۢ1JtsnXb;V.-ڹXۙ4t컛 /C W7͚3nk5z[|e46ism4 GIjPJe;c ԛp15y5܆{8˱tf*r;i{A\(%0e2&D37}7XCcuIZqFd[i# xfwFmج|shgG (b:t}g>|iWdR6(]>.>t뗑-BU׍p$c*G\uY.fHQ YW+|ܮ# 4d$2AƏ%̺Eֺ@1ٵ.:mk"G!M%߱3[ v8_9uHC^-$gWNj35L>=\f:r 84HAE1.치r@9PGY2ՇoM)@=*1zhJ? -HBD!JꌠBX6~ =;eWJ)7%'ުiJwZ$B)MڅE(j.5*5:hf0~ d2VC2PƵr#`a 0:FҖ_(v}zz>*5&!6Q; #>Īؠۡ]yzzѳT4/oG&rp= QWϧM͗&zN(*!^BoW ˾7ͯ>#;=3] bP([CRT}݌ j hh8\e PhmSGE;x ^wSqqLM^GqqLMO|b5[V臟0rY\|7J=ԏ p8B8+/o4-Q>ԟn@ԃ|MD$TuąC(\*A{Lko[Q趽{ H<}JKK`v4ZZyj}8E>Tj-)S LRJShP i]07iL@+tlp,zBkĦuWiЮ=NBmV 4z}~ #J^|B{V-6{ժ9<_'g:r;; ha QBF҆J%@J 4Sh<iNV8bqR\dɂ.Zk Dyӈ\9>*(;7xpH{6hDM훼s%nFM>Zg[DZ(hQƽ}u^ʮy{BoS+R#9{ C+BZ[V K_4J4M@7]64^Q+J<!m0 JThyQ+J.pA9pWAfoZo4tI3 Yj}$P0733 00 .soKcZծDOsYԙW1J<3`f5N C 4, .sKAƖ7᝚܍\I2ݱg4hmWrKw0HWewdEm;ebvgcU 4ϡB~~VK|ܞn T}ʸV6ՑFm"ϤH/)ҬBg$tл T(uȵv^'B)ч`zKXDz>|BH.'JԧQY[cx]ru[WEXK.eXNAS4]bZqMno%nUXiΖ*yg0_{Ce3+kaAJς3(=p@ 1 !@[-MHIᗚUH"H|3PͭBjBΡ4)!C˟d.us.Zad}zki)\g*le"e7^%*uKD #hp۫W۴2nr}5 r1voKEViqL`a'q:Ĭ . \JT!bY1\*,iYx#<Z/2̄:}zC]EH{=5%;v8lcޜ*HQ;k YaԍuK>Dbz(> %\M4S?T#j rw*$gbbr(ŗ5mzs'w+Rq8;͗S3IERg̲HM{Țj벂 ar_ Si m1C.. M9Ive\VlVC =!y H/Y%KYDNب d4mI:FC[/L:B>Ju6% rW+UnwLDuzR:CnF=y٧B)dMV\eUd@M'W{Й:+[.{dFf=~TL8KAZܪRm bRc1CUԢ;*by{NI361N|å8$1BCΠV5[cˢӭd۴aj91K%k!Ei] e.Phٛ]^ =.T軧<]Kuu5^OcgO.+hfSJo.+mUHm2/f.0DPvV@f6FKKެ@^痴ݬowg'#5/`NAZdɭnK|N |xݻ|,"tq1FyclUsі*ơ;%*:Tb-kQIuT0k=jݍ& KyH^;CÀشk*Z$" (IzN&bm=UcrIse)ę r%" `(OYs=<>cz2l6DqƼ(Xf:IC4FH$OSE{7J}%ݴX}OTk{8Ar#Hiɤh)fO%R(!V}z-ʑEɸVo;oxbc,>DLv>FH(#qX$ >j%-HWX⩱+ImzF>x;fQ,DynA3plX7!y2u$W{\.B_slTe\SȖ.={ݔH<4Y&aT@ݤ◵+\X}at!2vdEEu)jI ;xtаc:68E8|GZ#̹g5;pOr^k ʢ…T$&R (͡Bn[vÛ;1Gaa'MRna]H#lKȅ '[dDY4Tɭ-V˷+qsbq&qD"̼=7iڽGei*t*bǝWU%GE[nFA>=e׊h ":m* 􀊨>tc#Ĺ4"(- jQB}m̔[d2 a2=M Hyiq j7zvg<{ˁf [QOj3Γcr[̬k4HHZ5ȝGȲ}UZ"HOn`z7xslAQg $2d=16=ׇ.(Vw]H. dqǍk~fUҡqACxt:n]pEle"JRmRԝu,S}WX`Wzz]uVTxw^uA՘)l]6J47xP3xI*5·`|PKzTh@QJHzj6&!YEa 9#%OC!mY(s[.!0/t*nq̆ ,| 䫢4*H 8:&@S](yD;aKef(?L !5^whbR^Wh/=Kvgs=^=^IT!bES)_2'&eD!@r y 0' jdSa`\2 EkF RZ5ҙq  MI&Nh? ;[`NĠS I髣…HXm$,fn.d=.≑PޝV]h$T;q .;uAJP4E v g啄BjbW:TQ1}|9!3哷]Jލ'RN&6Lp)d@,La>ؾH#C(Ƥ t+ȬP3Vbr-QI VκN =]V-҉ZСz)xآp RpU!0d 0,<£!  ]e =hu$M h' =OD:DzG  V Z);x!DQ3E<^u3BC4JpPn_"C7@, ̐jn4uCX 7!qf|"_2@XhUrˀ9,WGE$N2n<=`pcVeTŠ)Fo' #h:HƊipP0N`: 5€h#kDRg] JZ j&͋mP^BCM j@1U֨("hdFYrOS=Hzٽܛa$6ֹgR=~xg׍Tr:%ܹV(TUwwv.9!f)y$#"B bv QU mV _:BE77( \Z* SS 5(##mES5kh)J @Ưp*rpuj. !ڈs]wt۸uD;MXt0eغFeDDQDd$y rE]6pH<jG8rIKHW Fa\ sBGT@;]ת()p\L ܡjpm%R'0w^1CUD(VbUTOT9I8xQƌ4ݧjtt:tM:fyՆ23΄ζ;T﮲UЁ_-3Ul. @8GIQؚ8orZ>{jNlŰ2 p\PJRAjE*VUF:p*uUFBU"+4T Z&QDtLD0Gp+XT ӭgxzhKj*u9\ bT[oi/⧴;]8{X&8cA~"7(GE`WƒZ'V$%ׯz58HR )" r* 4\D0Z%0G%J= "TZ;J""4J=4P uM@TMTy^T@(UUX|ạ_U=sRCd3٘G| EPSZ(18U+Uk|![V;#*a&Rm.L?y۷i<O0mܴa$T]h۶^bFCR@MV. .YkATv@4T4 AOPĈbAH/⻔@tһe|>^iq"(q >9x><]u,x_${C;qjX hHgc7=v.)lkc5-Ԏf"Pj#z@.ywl q!TC詣\6WWnGk#+5hLH0êgh)U%Dv;*xV>}R"SU@C7Yc./] ŭQ;W._{@Ibb1 OD}b(2+;akPͮ;G*P)KteCg O+ɂwq7yb>6oNeW ڡ6iwva5YYq*5%yJ6E0,X(Q},8ZWF \;qzPR6;}'Ěo?4"@Ȝ' rTcL;SĤ$Cɻwfft֜&ruTl[յKkঠj# tZUG٫y@ayT 4l_@MB쇄"!a}!YU+Z=#{iW[Yu)̵rrrq/'rw*o='&+}u8ּ̳-0e:xEqrNE$k2HР=)TuU1ehdž\utr>u]!HoM U:i 1S5v:9^k"wnRgOnA" 5K[SͯQ6dvRJ#ڇC!K#gA17Xj1܆ ŃZڼT fT!p@#9Z)앉H*e}Kh}%!C2)YrjC vAj[U3oncRN~W4EN:"agֈ2O$ >+W˞|a//CD +mWN|FXq|@+jV3Ā"#;8uP=0,]=I1Kn)r,GHu 6[`ȝ;o%y8"(k׍A G[! kQۗTRRqv(袮I d74 \˹bH>Kv)NVW!rl`mT`drtR@$ \B]2,ٮaRerkeHHY;s }cGxSFlvif>knQ˘z4FLoYKI 6dowi57Qmqx#<[׍ol͕rz-L7riQC|[뒖r {RBf″g,!3iJ6rc<^mosk}.E(H[D@uY5JR䗐13&\~WP#UOjm%ʙP$."$E{rdZQ8-; ٣k#F36դ,d+o(^@NPqՎ!p곣)1َ[ 7se$n Q`(j$yseyu6d:BWtOt0O *Bfhk 2 S-EyigbUT<ۈ6ίQVa6q²Ac1, N6mW"٣:Qy:ؽ4bǍw W]z_u]uzuNl^.^lJMXз@  B,VLU!&6FuTv2S[L9*:q!9Q9;0^'4G@ S\qJON^\P5 ``}4TjCAVZwjp(qRsȊQ)b%!FND>(d%(֬ nc]Ycb(gD L`oQga#pngr&8NC ><ϙr t=g:9\&ʽ޶ۚO~J*g 2% mw2M枈0Gֻ6 ;l r a0:hD9T`:hW.tuFx8A xA{@P]  U@Ay>(ŌɥhA(jj0z9M:ﺓn]p ӍDj}:#@N@ԔW1{q!]$^oeVy;!v)-^@Z-xFRB3AYqiCveQ Q,IB9Ig;Y Qvv8#,Mǂ 9u]n R.hĠz:CHC[ѫMù'KoLg۷wP (o Т9\bO>O_-Z5ԯLU-FGr;]!' fJR0ݽ9Z&** ҁT Э׌ƐFX;*)"0j)O.I%Rk+}ogh,'<!DC41SCK X; b6+'=DwA.'&!QPD=*MjkX]ע <'s%h4A7pvGnJ r,c}.4qg,7rx\*"<$㠨5$Uۙ4o~WՉ VSvxyxyTJ8U 8|ũ!g$+oT aBWK.iH]XKL&`T6 (H&!SZэ`YrgKcTƥ&ffv;vs|xǏS[Q:P,^bžzF|`2#y,U+ԭ<{M_\mm+_})sّmP("7PzlU]Ġ1`Nl] v9q\rWҥ/+=}xDnlrwNގκ:*' h弍\~^YqznjIR.m.3֯J/|j DdLB{ɮN1,L1')DZ=JS ]4QJ[]i(Z\C(.i@Pb :wMdPpT4ؠΚzncr%fm7nWx;G{ޞ "es'RQwӶA_[I>}+-ɜ%7aeE8A Ơ"R pMB4v8 f-94 8F IWE1Bh i! zɼnQ^EUm7A.(7z-;w%Av%aMÝuɹq mM6q$:1Aw!Q""X #[o%GLJFM|a.4$$BJ\搝\o!iMCN oj𢵦& v)hN9E]Pjq%,D"01NCʍD۫UK|9}o5?h8d {:Lrle~䠡D2a=NҴ8}gv0y8!hۤ~7s~_d, s2Ocʙ~X,H CY-8NC*tP:4MI!;s!zOAEv]QȉQ#6jX967ugibzéӆ YNHx2z%b2)5]12O2;,~[' $R *f-'}̷ڰrA=!$)fx*aE}b8f@dV8H$5Qv)YMBF:*<Zd4[ I KEpP炨 ޵]7$( |W*P?IuwCJ m[BKFƚww0SгV!DB aݿ|'0P_?B"_u-ۋ籪8 I__iUۺ@Jh܃ jp A-NHpN)q5vbaA7h Dږ#h 4h(/bnH(@`kNN@R`¢hos,9oaM'Wiw/D>\\$h^8fPwUL}3/Κ 8eENhB\y$UWwR2eR7UuƐ8qjќN\ҍo[ҷ{tָM :lỉJ sPrnzB\{!{3l\kF^J^-ٻ1Є$ G)k̥eÁ[W)M+!4V;9;#SU/7Щ* .Ò}Z}mmEwYtW.T圓(M:ccbo3ɽ1\IR>۴4/]>%{,vT6Mn{#d@Y3؁[:3L#hYlo8댈evH#6TX-zKKڒˆ0p,|ںIRVm &zSjt{ypPe}|vjƙ#ino`G3vc#ݶb˥;B be4p "=@m.4EPQRA=PAlw g;(iZ)^w$mLLu(PH+%6*OJ>А6 b}H1.6;smqTL+bvs]b1yKym♾2ylq"aÛ+0'$ss5HОF&!H7 R''Z{q[e:sr%耳ۖꗽaZB]z3ELA*,P% q@/"D)ϑj{/5_{Q}Fb\AP?jG@J#y1\hgPʻS"m"*h2.UZ6j$` Q+y=/tnR$Ei 8,˾%Z;Dz]+QvhϷpfϦĺƹ|\$]&pkO9Z]OaǗQ<ֵo.b>`ݫQ85V\b^eqfOהhGXxz2 {u +[͇^FU>7"maZt4 ^Ă#ZH, HTX { q𜲖c/ѥL!g=ouN:F87%-I5]V7d&{RhL*'+`K_@ZQV)d[@xqSnVXH" $NyU'tEVO6n; m*y;O$ޣ.O[M ܟ&jj|mk[%-=zn$F. lGw$@UF4qU*^$K!$ ^ɷ*oV?hۘFb̒$ ('KU!U\r" n{qhh-'!0DvPʠe P`"ƨ%͂`ZŅ*"t(.耟@P)js! >MQv0_R&K{sЙ]t1@NcכA^rݿ&!ժU$S?Z:*IhN}A&gMÁxGQ885*f@.v"|TA yߦ@>My;STYv@ o&棣 `v.6) Njrcw[0)k[PT/CNW7H:y+uDVPc٘|>VᐊїQ( RqĹ'TH.q93;@\9t9 JtE5:H16'VF7-Ƈ0b = (cUD6ν6'ǏX`i ˂Q=8yUuJyGz:߇/*%bZc{k9{;{u^ wLEGNb5]OD~)H]Hz/2ĒHS!|x;J;q-Bbcb5(z026'aN촲d̒Q|P(-Hə\uw=|~1q3y[ (|pu .yWUCƗ*|0LKBnWFK6mYț>})F*q |G}W{yx=Mi/C8ypd b ovru(=ΦjZ7 S 4SA׊5oPJ] ;j @n:a﻾< xTz/ӬhZ@}#A ll̬L I;F[.u"s+]ߦj}s { jk ^MSq8dLT!DFHp@ 6XٔtE nho#rRZ!ܭˊ&"UFAn)k 黪(Rf=XSëDͼz7~Ѫ' K_j3{ωxanp\~@cXffm775՞oT\X#:ߦęOs./EDcVB9"\cދcҐYbQZFb-lRJgZuV ` bh/ gQ/}{^(jDגWr؂ƟNZ¸`1գVk˰04ׁk͚.&V[ZVt&*ۆ~r;d"`YH5Mc#Va6b <`]ݥBhbX{R66/ ;&^huzCyj[a}'- 0\KJʅu2+D+VtY;[hY9lm PWKbXa @z46Z;@FVR?2> "y΢ݶ6ÄtU4'gZ7i)$ ]1uSϻ q4r*vvu3jDB^+y5F!̒gXqpkzo{BWВ'.BF-cd&5VoRz-y !/Ke&|JVس+ ;c9^u=(V/n"}d% -EyDD6{5'p:.vRo췗Gec.S8Yir+sm[miŭU^%ƅ ^~[BMeM3,-d5):*!0%qa+[oVMMhy$8h>fr{˻%LB`>ܙvF\Y^M*P#/WߍfmV.~H1?rꉒvUe d"[֙ 00DZ]M*ˡ.%;컦Rh]ݯVͮ1WD[̧]=h=()Hԋ3tc/{J+,U#"sHT^"eGq>0mdSNG/5l5iXIMl5mwa$cO9uohzhud_%y,i{ZnnO}gRqk5<^mR]b.]YyA%diagVy ]_)#ʇ{#ҏ%cUVlkrL4FtYAU ʣ2o4Qb"";1] *yka!7BFY4٤m?@c9Cd.v4-o'}p%WN\ݞQkvqi3#BCX/o䝹LWRE r[w@H " K "!@||7"F6޵qհ^UDβ֑ޅHSrɼ>\_kԭ40Sк[pQ^:աօCp, -Uֱ0Mt0XٟHz ̚::ރ{#pꯚn4B< $cZ| wU{kB$^HQpT3n5&^:99ޥU!ecY+T\0k8bzP91eb:۵jCSy >(Xfw?+ceQtW}_}t;޲Cϱ>:ק+:Wg}6bei합eD):ݸ8܍HH Ða_j=}oYsW+/owC 0\kw1\,DD]sC+ Tĭ|ƈAた1ilfp33NM,4R-)|BE,Oa[5=Lv|zOz졃0V*iQӔ|" -j?nC>Y =T7/mMH$aBl49䪨H~fAJbbX4|E6U*w9d'LT{`}$Ij+-ZBޅJ!ka}Y PbӺLˡWޥu߽Mt];ӴhϬvV}W^X%yG⏮,>|rtug7*b'5T%ZNu'6Ap p B:;& Ba#5B3a@10+S`eٴRQ1 (~^{(@@8?L6?0,,.-v%gaUGZք+حw7^zwZ(JĮk)ʌNB( - 2(\0\Cs)xX*dd+w !K'gGf85n8 ;8b,æ"|;WY}V2|hةPq]!K$̗-){T ,gM;qԿu6 wNUZVpJBA}{A pj\ s,3-m ͦ.7,T+FO Cn{l )R|g/cE-}!k6:W J9N%ơ HHix. O |H-X$x꣙:Ztd1>v0n'Q6ئ(]4z5xyzY.qw}#8KmE;" :Y II۲z^@=)lHF%E0YyveX!͖>hƫ8j!op[lG |ezrw;jZC^; 3ۓdJg$5!VK [Kj=n%lʋOKQH >AR5+;0!!wxpnfJU%A%o$Cdi[C+\cl>N[zkBį ܢdqFkK`d$ mp:8ZǛCxg0l[(<.`>B%5wYVA3JP=G%` Jy jݹ_'ZJ[4} o#׏6;YF:fms,wh;~>aD=Ei #%kxՂUdYF]'G,ʘ&K!K\a^,"1~E@Ώ= gIe!QyIfRR W(cj A" E/]rN}mҊOb˴t\thj}ɤ*j:Sѵ렭8{sz nN&ccZ־MC ' UUJ۔mZ LHF !WmZy,[œRu$mEn=95aнFͥ. `+ɛZgɮ!PV|=WBFZI)!dEXŜ$Z׍|ZPy|Hcdv+xw#cI;:GG9fpkhL;βWL(*qpz:g s۶}Z}G@>D˟7_ b*/[D,CO=H(<BDPpv}8L@0 @L0\W*T㚥BЩqj@|שM0H0_y^*K\6 u\( PvVv$C^Z|}||z%=C|3!gѠ_&B'=UJ<>&@_|E-%lH%M! daP3J{fWI( VUk/ P!EF=`81D,JC{;c{N$ɳw#JΊ֋4m uJwafG{FYG^IsCxy*䮷 GiS|ϳ(fMK(8Ey"(2 D;T/U\ 8h()5@(!ADB#潦U0HZbĪ   i?ۻÕ @srNWvS3osk7̓|z "ah>p`?xqf ^.ɯ{}xk|k[g1.pE䜋! sk=~uA.s"Z?ܙ-mܝFJQIt% \ڡ)M4 @i4U_ꭠ(qOWyuri7YQ"?B5Sgz/bfdPRhT z~kl%`'nSHq 9$BN!hjH"YGKH;i(,s&Ú٪ b1?"aâ2,МlCMgkJ\$+;=甆P5yiUVNE 3=wpfx;``OvtUyYQZ&!6Tԕ]cEȂHbs06[,d]FNn6a@I|7ֻ4`1p|q`/ *@]NC85wSD5PŻ* A40L1T띄̙:90Lx/ZA{9pKU(>B\ϧ]9D ̣Noo-(iI Qn$.zХ[~ SӸ-}';v[ۇ9ED8*ouISTJ2 ֽ*j~*'P%w ⡊-vG5!AC\n b8(.0L*` WhsjTTp TL}dwY O0}ߦﻏ==Ord+8|&|Eͼ){o a:I]ӻ0LqgD.~ jTVtl* ]_a-_2.~cA7 R7:Mi;\_ą|o hl!TZUUxtzEu7|]_vm Fhx|Rr >Mfշc$'d象5K~8ݶL4V83[Ie֋~RYw.jr Bgkj5x6tq<}]!>6ޒ;9hīE:%Ԥ'jVf=$}\{^2跟y Jػ.˂BIa\Co#&jX"g!`-~%(4UҁUJ ,B @{@&բMTS @Jj&& 4uG1EtmB֕ mQ_E|+/TW[3ڧHfgWhs)#!@W S]/Qkb{ϲr@feՌ& W,!%})BUY ;[&XxݞuKuCan۾{ż۹ AV>frhb.tkg"KN+կR 3#owM h'Q))#S*08#Y@j ќL&%f8ƃ4#~xKPE}p&s^ AAY ['einx\Ʒ&% Hq*ڶo0rƭ8ÛO[1Tq,d/UVl U.Y|* (NPc8/:ݧdlNC ҷ\=k݈P.BQs準#RAE^>x[99/"/RKEx(i]ha l%Qcex :8Kw:$RdҸA7] ZLWs\a72e/ndݤw£9+aLN;][ɎjOOumR!1N,n(BAꥰW]Ei!*]G+䴯k ֫`ՍkhjDܻU_21d&3HmϥNOYJrz wfT4GK>9ED!©+0RI5[\}aSlڈwJ-ѷ6Ii!xU6T3%,CG9mX.*U-[9 ·/]VUN8 37;e=I>/+2XAlJ/'I(2 ʫ>dR CD$Y yig0t΁Z9IX"),'PboJ7`LT]Vq$D!Do$ɒ(X#'fH-5*Z(ƀi [U/y`ih-qҡP~mWq$нY[Ng,ṹ6U TƏa,[2ȕy%ĻqqIղa&7l:oS+1]=Fh @fmF!$,JI^6,2 LzmvylS|8)l,D!j9쐙FDH:z:>,t,5H;FuOڪ]CDABM]&+:Em=2{'Rfz>r~8YJ[pjJ>O4>:3б A >yZ(θfN8A'q{8ǎm;(м0_!梴{<)!#BDDI L_\7=nڽE={D JZDqC0LW[ZC +BWW1z9"*jbq l,ߟ<*`crC#@˳wJP$E-;ͯn>ύrȣFꍰ-Y%Gˀ']v%E* БBXqvkԽB~{.Wwӷ5 EגB'%,M7H/M@[i"0GlTACk@hP n (%SzǛTĬ\үe=k:߬u9i"yW C ak^u=!RIQ}ahKyS]蘿d2cv+IPQ r lK,. S,u*'"M_ ޯ:dJ"*1˜$LP/Ss}:BXp5q@_sF7tjD70)b`53vQ4-k8)',=*Uhѭj$2TyT\jNl=" P{Ots>CQH1‰"|O\=h #|dGԶ*nI5xHCjAxј}y;U]""쑍\׽"HNT*bh D*FG aAq"* u>'Y`sy~>y %'v"R$DE-2m^ڽ*r|Z7nGJN(H9 j&"$ARCJU1c0iԸ%ǿ4+gG|t JX+q( !TRYv+=qް%QbI^}}ȼ}hzNе*|ϻO8͇P\01y6DyXAd­sfƽDsnҕU0k=F`Ux~*.d[-JI aE@p`,WN k9 BbkV|Vu(LZVО{z=A2ur=;>O#宿QX9$$$S&Ң{:'Nӟ04GYPc~L_XkʕTGçH|qxzWIO@:8@5njBBHtsQgd! r%]-+v4JBv[@0tSͫU҉@;4N-z|pSwyR~AKu Bᬔy< *^.Y'e)@Uht^Q9"g8HNDڻNPQL`wOiZ a~jx(Q"QߔW%ڪwm[KO 84(iTYMW‡}k4 Qkҋ8Io%-#ƢP FRSk !{͙ȔF!;PqUJ/Gԫ `4̑-4H{ލz^ Wzє |.ɐ8Л ]/E x[~ KY*Z\x (ŸU-Gp{" z+UڷSDLbQs Z_Tj_4W4>K(yS1j F\sqB҃ߢ|bW捭( Ʈmk{&.Z=饷5 b&+a+1S0Jb8@ЫA 7MM @iBȋAbFAS|k(dZb'f}%ͲՂ }n3c! 𗭮?ҺK7a᭿0 kUkXDu4AޟŁ4b_DZZ-R-(FUaw3 8g ]ŏ{4 ٬h,eZEP=we0ܷv I}Ov4!qXX$AnLvrws3 ^%ݰ&,Ҫ9.3/fo7} &JR\JsRXoZp۴/epOG>Sm?|J?Pp8x!ǩ2P6A[GݙϽxL Ӳƚ!;ƺJHQiePBTJ>hE$;%^[|k|}j6ym>UW%zRO;4 DWwk{wu&Z޵tP(.d` (b,#J!8p  id= JEMwN{UHhحR¬M[؄c+o_ijݗ" 3%Max-$Zd/"m\fZ+o+kH0iR!d$R hhԪK>9b~)Q!-ҷ9faMOv&y Δ.ר/\8~m)Nȧ$bm󇞦B{7V·_ $uUV@o[dC³&'z]+7Pa)Reׇ7ajJK'Do$a;ڢ& $`xVD2YV@ˇ:Nm={xתxiʭtJnm=ǫk\H'w!5/Q(VsF4Q~Q(uX#nuu]rL{\O۽E]ub˗y|3ދF2 ZZζR]}GnSEAȢ1Ӵsm-Y+4U%Nwh7Zox+Kˉi+ ZGWЄ*,KNƏZdED'Z{Fx|T}WDnʕvhJӺRLyWύܕZy]6r1W7Riw "fTkL8b$e.!֪!u<׮'MVQSnn˩r*7Cz&!&Ԗ\ZTpU(:‚JԨ*v}{*cQ=qEd{)ե*bRrI*o%A1:diw6 [tɁG\[,Ou+@ˆߔG'IR@B#\j\"}ɼ.-v+ܾn=5{v57/zYJ7 qL۰Ye=$h=a$b&NƩq\oUXFcqN,%;%O_S:=l%F[P/n-IzU\SDאWdkx@E&V57%b]me-D9*-#m^|&Hj!JR1 'knDTLlD?FGPvnQ>kܸ:΢iMPeҰqpmmJ뭭ѣ 95PJz$B6!OWd-/{(*SrTr F1g# zY Jom/Ű$XH3Qk(6@ܮ4xԾefI\, Wl(B ҷx!Ւ:TPwƩOYV@W<"[-lL WӨdJ&",yUۦR8[umfb>teU܄VI5IK[#Don"ƭ ZKEXrAJ19"Uy|Q[k5z%QiEFJZ9 HbznҦ;jҴϯ6w<=kS#!KQYB[.sFyiݟYbJ8ˆzc\ݰkmP:!=9 *^ctE$)\/flu5T CK K󺸼\꫋NTԚI+q@n N'Svb䄍/[Ndr($8&(jon:jIڳO}%iC]i n+?HLWZqsCKi_YeIo[,dS S=!J0WR]祢ݩGelivYUu#33M[cH$qlVL>2fн#v|'H@ %̭a4 R/[Ё KUmUȴ$R8l6K(NGQ9XKK|"CϷo"Nn;,XyZ|STjqFg*&5;>j&zrEɶe&RQVqAcK^-JQo7-FA(- wU^` "T{;n㢫1Q=hoװh)JMF\`O}ۊ>*h`8 P1Ujw]_6TN-h`;T撓 F;iKUiQUGj2PJ%|\5pە$kx8w\}!j6M%[_T׽v潢s`H#zѪ[ }ۣ Wo ԭ]0ݢKhTiPЩ q[ ߛa=/9YN)CYb/P[;~h=_8"yW^^tn҅d>z]ƫiS> D>Bn** i T>J(d.ڤ%Z #E-_^+ k6؍u׽j m]o~>vmkbl%2r< Y$'S\9 @2E;iCL>OtB'݁ vڍŠԤw0Bn(Sށ>9Og9ʕB U~<1(@ ҺCAGjKVxA ')! 7$j;T} 9ȽGоÌB!+_cJ>1Z}*1u hЧ iZ@y* !yeĎMfVT巫nfaQ*!9pS r6>sZڽnvp"88(ՠ |>Z%D !~OJ-v }4:, {è<8_ (h@r|)UL}w}@qIZڪwa](Z1BH$w UJK&Z#EQ*wwrU1eATUUk PZ2[j}iͫ~} m0u5lm^bU}-\jkѯ$6zԩa!1MJE K@h*Pt4]\ZT CMM #PM DYTSM7WED?)x8rmY,{Wx/lPSZ'] ҶZ/Ow>C3`EFz l$VlT%kZ] }4Wш|]Ad' \\cSD8"HA8pbmSW3r/[u誠dlAw^- (P ҩC ׏U{lmڷƆr- ik\[kjzZ6;|[j? zr P*LTH &_X4Ȗ\fŴ6XzB* Lì3IʵimP!u& (RTN DZ:.5*((5B @(PGV(H' pj)TB(xzN )jb uHk@iHh)jl+{.AB L_g0?TdX?,lx??k^cL7ZZc5"Dq<(CR뷬D.^B ܢz* *vT8\By(\c*  s0"F巕m'^9 M+6F~|4Y =>íL>.:SKu=t]bʶS14Gt-Ti?D(=0I`S{1S >M]96~'q/~ n̐/drH(GR<:L""s&i>I#i?G^:z:)^=#k$~#?<{q=NHtsVt`i#!T"eSmH"n&X2 ă$D0j621OքʫO=]z,7>^kC˷'?/<ЭsgmQ0͒zH~8v`{k vB}'$ʚ]uNa(R'¼ёKB}30Lbt\rlg5dT_h-ͭ"n &6Zij^(LɇnOЙY0&cOu M,i#'8vs[,:>OGGsqs;NN)a)eM`,% to[euzMo8 Qx`hvq' ʼenCN-;CǸ~[ֽ8铳A]t81:b. AAZ<DfořHʻN0vB:pC &I~UI*}/7?7b|o (ZuS ԛӕrQYqvHVBHJ .Ӡ R%<^oTwwPQAzEG"M e"&\fά&GZȔH6%QvJj}(!q5 R6o.P5 4v-P!_ [|5T Ǯx}Fhv0eݗ(WvJ~(&^:DЮd&9)ͭ_|Zn/p${;a&uڻ^/vM#A` >P3 Zd`2t : ؏1h˃뇁nE~c!LB:v+?P?=q93y|>eQv/h_Q}/EJI*.w/&Ǘ́c܅\x2FҿN!,3|W/O !(9UYiIWp/M 5TZ`z* *.A4lP|٘]vl_102o%[`kHAa! W ] _m $:;>nt_Ѥ/@] hHwCzeROM{SADI(Qbbi!I hЄ I4h4F+C+dhMdѢ -21-bJ3,ɲ),E")E1F)CP#FE!Df)KLBY6XV4[jl 6i2!h,HыTc!٥DF+ $b2 dIZĘə6 *1hѠhh5ƋPk%P6M 4)h1ET+[[1[cFBHA2DIB#lPm151IH[- l* Ƅ,m&dlFM%fPmƴX5[A"6j(IMQ ELX(ѵ"FTDl%X,XM,U-6cTZ&5bIDE*IQlhb*"TZ,bIm5 FZhѴJ&"2(Qk&֘U[ ELJ(*ZI4V cZ5h$AKe ecQZ-&B6U @@ɥV)5Ɋ lb4!!$HdB U%bS"3&,DcX@PLT3Ck`Ѓ6ŨHH@j4"jńѵkh+ljTVTmj+TmQ`&5I0ѫ(cmmQmՋT[V5Q$Q&ɒ * hJ1h"ZQLƴXEhͣj51"MI$mQbEֵmAm-1F֍FXb&6؊CUZ4FM$jb#c%؍AFbѪ Xb4+VZm*mkZ6hEXѢMhj-hڨFZcbUZ#kQ[cVƶ5ckV6VdE$EGkbT[Z5Xk+hFVTlUUEQcF-V4`-$Qc[ k1 ), ,fTbMZ,h-bXhhETmQEj6Qj*lV@UFETEQ$T Ij-FmmXbQkP[Qk56h Y5X[QRm6hأj4j2UARX$QC`ѓIcE6#Ah؂DFMFQbllkEű[cV1jFjbkmbllVѵkH5hmVjѐIFD@IQDd`a&jRGGc4aӥ.*=H8 j+}j%V5V%̪2iESھEkjY )j2CXOž]NWNhhS*ldJ;=+h?ծPtf+]ؿ1nA7a6,B*Lk33lsIK՝`#g-e!6F1 t~C bYi2c\\X 3;)oR!:-333#_~R#ICI D IB~ֱѽ(j,0r ڦYɭuva׾C15Dn=f:/WAC$+(j:`Ҥ7iVTBcoCA,3 eנOq3,iCRBzJ[/-ߝSNa;c,z!nǿkHEMNo3Oֆ"8}0 _׈\Ue*#GqB< |:]Kk(FI0bIpVv.X[ 0xKv)!Mڃs*ΙЋTo#ff1sCR @ w@܊]ܱZ/ҕ?xA" l,pxhi xA.0~ǯP :OS٢)[W~!$$!&єbvLZ΀S5k: 5o쮞s/!h*W;W忓CHĴk-~J2nX8RF_ņ; G t)gN<0/~h6v?V#@dDalqI鷋x \/>кm8q@$!If (v(PӀ?(M6|;^*&JG^Wp$"aI ZE>)7F,}I}><׶&V췣_Lwd*uRH; ;%`$}IYW ێY x:%bMvT84Χ?=Lw}OlGb pOV%o8A~=Zac TLSvJ֛MJX j~Pff+`LIKJ?b_֢wQB]Y.!z &\UhI e=r4h[ɮ…O׵}\e_|KNE~EOgN^RYAؙ33+׳H`Lw,ޤNA ;}CڇO%Ffk5:jt 1nuK/-~KM(#9'΄=شbvME98:WP%J{Tٛՠ!SECZᢕGV%tu'@u[<a jnCGA2z~I2F}\wl;g2ft 3<0guH,[Q5 F:^:ø 6ܣ4va!ڍν׎OUe1ǷܽEQB42MC;ƴ\v6tbN&Prh5SԞk{a:fL DWo_Q]Vp~;vѽXo8GaG9,s;~o=/OzK qznśDkunֿSzS֯yA:K^K(Тn9gcհ1RO2h`aFHbg'\^jgIf$ݝu;w-un?oR|ZA|z{y!x E^h #QLpx!^{_^|#$tawg.;Q)| wi˂)QEa[C{m['uWX 3j kgKQK[W;e=ׂժ\<|4Txob@!ʹ!i| &||Lސ̫֮h,z.T;샵8},=?W;/=v?g>O⇂)L5ۥAěu(3ӯgVVwIA;\>zd^;#E?znSdZ하pc?ݛn zLXz.Df. ơ|]2^>M߇iSgՏ^CQWX!jS"ӖD:޼Y*i5Mn^Dԋ,47E+mM]8pa6,q!<cptP;會]tk7F3-]nU,4Bi2zbRywi)1ڜ(GoYGWgܤݨ5z/ؗjү`v\ECr`k]ڋJ4U7 9Ds [IE;mn ou>E~5z_~,~}Ϩz'LF=sHg˳j 9s:d O`\wn9X6r(IIT-0{ƨ$JN*ʻy ,vn3 m37i~T׺ͽ -76k lO j3UO}Wl}>T_ (sdšΕSu\M{k^ѡPZP'NVOK6W^bh6No/njV'?+RfCcm'&1KL팅b]cQ32M Đ7OW= g7'kLzG1Vne.ck|z wYF=7zZt~YSE=f`33̦ lam(GU%+Vſ:&,{Uhݡ_gt]O5wxbYmJ^Q}a:28f;2kY\ W*҉ >VT_. W 9WLkSorGi(UXEL9<:TB\1T~IW.;VF= jWU~QF<- j7s›uOE~Mtr:Ν f:lg::Kj=z9ˊTb=QbU;vڟ-6\'?^! ҡ=Ƨ~^M\ܲ5n6эT5PB (!r 3ۇTm\[V[b"TRwڽuTsv3u뭚{nnuIrnZT "K#ߜ_p*%O(v jBT+TZkoٲt.;Kծ|ig~w-c|nCxq3B9:!]%IfaUB")4z|E3xXIF)GGU-m;y{%"OC?GAݗzx~k.+{Wh\NN9]IP:o׀? 8)KPӻ]Hޙ)Q/k|\Qmy9O*6ǨzdQ@<rq&&D)5,?:5[rXEI|(Q.Ժeֶ69ejtFK(l*^g@FRr;!Onv.\I\F2tεM.cf*?8L.:~ӵڧg.ɵۇj k7OF)z$%k4WSفxrJخ7߼zvU Vӌ`OMw_>ѯ~4x"1y$6f?/7U7!yh6`# (~w^V;ϚZOM +iٻ}ߤ_-c5`SىaSSi<RXZwKSz)ߌ; VvF f#.NgPT㦄!.hO gGNG(VƇ>PYT|݋*ݝp |H|sܵ>G16'ȗeW% pQ=A'!1Q/;SJ 5wMH[p='pDNiqqrQcTB5R΂nY슽.&]f=u8|=5{ǞMq:EdI$?>}EyC`ֳ f1A4[HQI(kf٨`T6g`@Bss C]@~@yK4*-kGzLL}Bvgwջ|FuDOٗ'JA2 /v&XPTnT)UT~8wNeڛxomv Kv6&j흻p.3!1K9}̰@ E`hZOikjC5c8f,ɚMkLsv;~7rG\Z7<mQOᢙE߀]re3 F䛰Z;z$j}ǂIſ5C\FHK{lETZWԤ]> t`1]|3ug*v30SK"$ H2Ecl',X;Ŏۃz}E-څ'ґuAwzQOڨW^jg/o@c suK/Y^dmU_ /riԓ3\`F#ֺ$! 8<x.ogmDSEA~ $ ߩ3}x\c fY˪!0c4[ٝ#%"$ y7w}n~Wsé _;aW{1 ,*Pw d!hCF̄X2L@lBT<$>K²0pOi?"5ci7zxڽj@O!<7;B?}2$b/ &Ɓ&jg}iy9< h| )3;T~OOkt0llW]@BK+EQ@L[Up2z9!@#?4[W k<ۊFuHXHUkf)FQU XU!?}$xc#s10jc]v`Hk &ƞ.#hinˑfD/Cq~ j~'ֺ1Yas~Gb邮 S%xC;<$8'# pNkSW[ҝt"\B6x0cLIR c¤XkϲES@֡Š:'CvgHLhwf"mD0I&rZdVЎ|_%ɞ+>7{ |('bQ]NͰڃטi/aB%O9vBT"T sԐM!G~g? 'ꠠP /y}XO}=:|Z^B1(LxaLU W=p BZIqҒF?/_Yl0kK~|+fwQ_(d#~9W(>TGuuF;& g~{vmKu]܌E5D8Iv$ib:Iqa&^Z ߻l|7Fl5Jxz!"yY|Pr I5V|bt7Q)Dm s AK>{EDt|rI!EO-k)Q (;O!)Fpd֢i~Љ 7 pqZpg@' *6H`'~~̹3?$k 8r=m(/y=>II>!Xqp j ½'j3W"_1;n@ԑ,Jv΅iZcMTA! w-[Vt!?` GAPԨq [WA.KT#|f'?0t,A#S_-]Ώy$5B1$%*(YЍvn sy ӷY.H}8w0fL; VGj0rFAJDF>t1oE]7KpQ_E63`B! UےG"C!]I-ab; )C6qke~`N3_ziOyb;j-&* tdv  "c!&5{.0Xd.0Zb55Yu &1E#q y RΙIh'o?Uz=Ga{*4|6DP鬗+j7.Se.XK,㪆I+fh^jc.iJy 0>E(&qw{(=;$BCTtl01^~.js g&h71Gq #q|LfV#\zpNJg8jvY +ݖ;DTE(+!p̕$d:H׻a ( HґxŌ2s):3ݞŝx8zQs{ծUiE"/N pRJUu~&}~}1] @ |AQDoA&n? KaBBfL #!73c:~/Im2PX_>>_OK^RJ"'j;}@}"3H0R7"J]H%}`HH&m(a D 3E2 e˯2,>F2 OAgYV,pަ%qv*<*ph'tV>mQ\j,'gz>Ifs}LVՅGc¼^,n._T׍;CkA%Ji Ti mže3g@ϊ4M2uf}묯 U]jkQ3^g!+> I X[${<ˀ|Cwx!)Ngg}{tPfyWntʆaƜZAAwYz?ݗ+]A]l mDe_Łss?%%U ,BJh)ψ3d]MhW6Y ?PBeggɰ0Yn[0!Q62:d1dqߐ/߾$2TK$[O5 4Vc0j`78 EP7 }3qnn; 阼`I܀ bt7@K v.Rwj+2Ӊ[Ic~S೹j*q+gBu fif}ԴQV;1A ѕ!/ޠq>?v~ }7۟u1}"@~vwR(nL ~5jz,/Dt AyF U>Uߤ'*',r qWYnІHdK^?\[3 4As33BChA\_14oGQ)*jQkyy M4RCP~ U!$$/jAXňB,H-4D4$ҕe%Zf$Mbf_`3fb̆  u !hLf(36/(Ry9wǪwwg11en^DO `:͡US+C׍qI &Q$ Ug|R1 ;I- rh;ыu"á7KIE&m #@RVAuE mVh0IӦ{ۻ6pك;8X0'XEA'$W 70ж >7$ ZaDârUx;(2![}0ӎXJ% '-:ňmTŴ |$^.)1D]vID"Z@ҝlJ".ס6SL_?Da &4MM)&MTPL6F#_iJ}?G]Y ##$@$|˵.}_J#>ސǑ>iUϜ<„S~dVS,KpO~k'!E$b!#!;ƊQ6 c=~?t&lS X1;i#~>C 1!M'dXt;A5,ϚOg=.5`L2Z9Q0Nfq3%epܸ_jwm34&C1x٫oYQMhgdgRuU.so ]#K!@ wwd. J}`(pvxV GUzSȈI 4IL2 (f6б+Yx:T# ;S4ٿova ,3`fv$b{~~ @?rC5j"IBOeL(liƼo!"FAZO?ų]j J$۾_3*jDj,jOh8^F_d@ 7i5۞%䗵֝-}&āӡQUk,>T]xnA 4Ã`0'JLV8@![=kԼ`D.)b"0Rz-=><brWT~qU ώH;l}@>`IX  :d#{ufF¯CdԺ(+nH xI0 ޯgqwi'z R0 "W;~ ń&6vNhfvЈBF@!`nL >?3wx/ &$ɐ !HB,@ y3/GqhLfe37w\"sF~S D6d@o{,~L@tf'KImf@`{QEwaN:JpW,=uItH%MxW澬}< N+4܊֫^QL4Un[l:V ]K 1ؐ$&ہȟU1/vCU؛nhv 76ds.60:u DSdUj0 ?+4'S44߁l,vTPlck?l>4A"u^@ԍI:bL7A9 k_ףVlSd+T@f [6h 1)$P*5%?y7&Ŧ[|k%۰I'H`X+"@mlY- &Ql !&q(9L4)@#Pi%/}O@ҏr>[W3~>e_8ț -:vƓ 4衜 1cc_rF+**OPaV(a v(Qى`, +Kh% qB˵B ~Fa6~>=GJ>IqΏs"+At|@JI%#O篜|}p l5$U SÀǎ\݆A!,)U 6"3q/4{l8SaDX>g;C徿n6wBƍNG83(J1gZ :dQQ6j~ӽGR@ oo;>C3Ku!&=.L3R4a,᧶CTX0a{-FjY6Ӣ2@߿i'#ɀ($n8׬kc:!(0C@5rbku% vœґ8&[A\meIٿDDWpC"ۑw~"Ԇ *Ii)4 ̀qtzgDcx愢d%}x Ew[w??OS07 dA iAP͸ȔbqFrZcvu:̓1AQIU8N2SKE1u[kwn|N]XsiH* 6~cZjƖrvOaV4iH}`!a[Ł$+/kϕDpI|}s 4J~QSG!U5BʡeBd"W3)gb~?_=?\0O0<_Bߣ=a٬GV:@YȠW03;2,!c€ SYB7]ٓǛ%ZHٿGz3ta o|>ZohTϺ$=>WG3~꿉_PE8 1B?#L*}ߣ&#>+}>h}bzxzl-Xh $XD;~OsUTdH ~?f~PaMJFR7YϨ=,ߥn K Vɇ/wo={7J˯ wbRU* *3Ywt^ww"H?T]O>}kL|A.ү5Yku@g`D|<.!&aC7EUcP:u] %U]_e:gGwPrXPkS8NbdP=`{Y?d? {NY0 kAA L|WGfzF> |O 蛔<;GEwje[Z7k "ax 'pt#ƽ!c~*Jlyqpe,ha,j^ E[& xm"zѣ.YИHD?~5e_K+-45\^qRBĥ򈈩`]K4 U#x7is8 7rBgr^4 '֢N6'f0&B뻆=k73@83=lы=wEheI}rhMkȄ B7}x&˻7ۍ!m|k;,0]~X~TA6/Q2|4BS)b߫Ou50̕X b~NAWcKNbÙ/PIke\)Z L<b H/R 5fX5W{`,j =%BIMZ(=|W! n9Q|db 1b$XHApxԐUAV0W_yt椳R=G;#N(_x=)1=KIDڞWJY)Ⱦ mbӶ5&(ا>fYFe@ͺ7o9^ Ȃ=#l>9EuOR)׫c9 hZ~T `C_Ą"~f~~9I '5A"1ع5?O74OT?9$dQg/fl 7ݍdRcWVVF5(`56 h̸s% )BH#!14º=~"ݡ叴BI1s38z^,}S|- ;e _@zcWh qD!'p34%@Ƣ^ -ݞn;<+V&;C߅4Q7DG'C{p~SO[1ߜ[꙱-(&=7f.`'1߱b_mm463WCx|`&qݛYdމ:'O.gńY|? :EAO+n)q`'ZN|-WFk030xNj-C/.R18(H2OR]LjnTrȎjΫGZ:[SUJ?ƪcbXnQb3#?^Ż{f )Gh DI&K4nA₂[XMߓvZ]c]a]֗I Cȵ5#F:7o=@ffb"F6 E!! ȿ@A6۞ߓyoA$%%꿋{~c~bI3lu635nZB?S]dLkNkvyz:1H 4  :6qN?W}q>[ 40 ?qE=?wO?zcsm{hQtBIGB!ѩxE^{Wo =׈ؾ$K`Pt{k{[ֿ(Z5K>`Fr?><}~>>Eɱj;޶μ[$-wBIk /{WZ|ti,x;yCDhQ'CF}ѭ(\O6npk|8Q!\Y6 Pԡvzkӯ} {B]ξ}O^/ӧIݞ h%ҟS_?οM>LF>w|ƠȠQ֑v-I(,?Wy?ow5]m;榶*CR+Z%OmcSR+X~5Izo QhG%iwI-02B(Owcw{MDϞ);POAΓC+Rd}oO|/qqyOGWWZEE؎da4<=m ߃j__Gȵ_.6<DuG&IE3Ztw>rLXdP#%djar81;g{[2=M_[a6ViG vV3c]9_>Fםwv5Smwk}nzQ)nMnm}.>?wٳ6JgT\uB-m~U=gkƿښ:^}]}]?>6R^ )؂ԍmx5\skrj֧[jz&x >ڋ ]J-gW}mzLZ+6=}/EZ%ak=y랶Ubssk.sYeRzttg? 읿C_;2jXs`.|P>! {?cw#'1Ϗ1;6 zj6g)/=LC//C)o>S"1c,}F7vyO?hgg6=iy{e__9pB[;)l} kz6;\S/4/c;ToŇ>r8[915vj|s}Ƿf)ǩi{z7ϛ)wXrOS\u|5(F@ZM`Y_? |3QaHLe^Ɇҵ 2)%Q =_ܮg2YL0K Z2SP!zԢjs(zNɏGOcesfVh焗oF joGVUhFwG.Nߏb3;(.Ŋ/./s)IXv0 Cl <>YBAnjm?ޯ{&,f>|If8*gZ2FTd!rrɼ&(lPghr:##7$yTҭs{kn1>̲Җ<8 e!5%pIaBG qn\GlaY1pܬ.,y-Ȥ)dPjጻ^WodSɢtoTLA'5lPxe2WG>+|]ʹߛ Yz4\Z+?K>Xӣ#:^le~F}ҠYiP ??|w )$}B+S M])Z~;=]: /Ai3fBZфv eA;O'͟WD5V7FOSS*nJ 5!!xCDAIf͟JkjwEՄ2:AׁZBtnpi$CN.'ϗ Kװmѓ6|v3hBΩzTLSmmjGKzп/Ë!o,YA2&H|igwӣSNmtF]jPP;鈠ӝCf;ף F=Jf7CAbϑc{3j6 d-th/`F~[y>pGy>捇k4a!P-ധm">澴+v ;ʿ,»-lFC?/Sn ^Uj M}]N:k)-^9aX=۳*k8N)]][ЮZ -[!d n߲rQew[V Z o>6.$,}jo*KTRqTԊanXkUOi> *M$4ӊ.QYf:PB\҆ mޯ˲. gr4RQL-PݔS a?ZKi!T*mޚ-DyK@RJj'Jx9P}ޖk졔) 4ISOP%dMg1 m4| @}ŎPC nJw0Ͻng;]4iX0A|:vp*(TU_"ʶn55ݽڥ,}4%)[5C)!T^̜ - P%RU4҄TBxA(PT $P Q  DBJ$)D(UH*)T "%D@$*'ϯO tuij>w<}_XMp7Nۦvỏ}7E/{ {ہUY0Iw6;h=g=`6 $]%Y;n=h<+a)R-vjT\"uE&[ wS4t-=i%*Ķ'G.u[mA@*]Qu4hܪZ9K ==\EjCݷ _luӫ1)}{z]J}n SӀ=WkZ/_j32^Q/>zt|BPq*pЩyrtAJ5Y[_. =xnt)TqlE:ђe>|([fo}aE=z38b|Xz9:&cU3\ەnRk>]@n;|Z|}< u}(CWt`&uzyǟw|ؾjvz^o\EP)T!gﴀ|#:<}*S{ކDS]詺^g5yJN7XWm}Ͻl}>ϰ}c=Y=&o[A-TX\(IQVL{>>۟};򗾼un砤Z¤HRZ`^'ĉj甚צP @( @ijӯO֐y@*\{訟cGIZx`JHI(%iut  U[Bw#F@ O]vob?3n/0FoF`>@4 > ;>:{5uюEJE 7{G}Z/2zXr=S>w>jGz=0>hfkc>@ܹl(!mL @)ջ8P)@ [RdPUH@6@+С}R:J{ǼKsIz\>g}21KcD8;w:oKޱy VnѨR[@jPsbUKwNñUngw#srUܲUopmK-]܎ \ڨdlvŕ.XT\lng\aF#R[Jf]jeUnT3`FNz5劥QT0mbyg6]nMU[fut%L;d6Ѧ3U62TlSmMYʭ1IŠ"ݝ8Y aґ+Am2ss 8v9gKmW9at؍u-0[Mj-YsX9cdn]fr:u+ynLF: gz,0rbd{거O:v69f]wy1kz{8peY[; sw񁷛5Mj癥&N=q!nAgn[wn`C61&6;*%9u7r쒛)KZԜB:"&ʒBcw`qIFn.8 .8g{>}G=RyCM4&0M56&4M0& MLa2hhɓ&F#F 14@M 1&FM@&5@L ɉd2ihF0 @ hLL&`d#Bz!F42'#L@L  L{Sf4BB4CM2&100&hdL2 M 2i1?JU] ޕ'eK̎r/0sڡF Nɾ\k1c.n &j%##,#M99)a$҄x .9{ )y c2p++mi[h'ewmee[YH5֓Q遼LQSiue>QtU)BU* VYZ\GUМ5(UjbMU)D01J a A :/;_׊RZ/_ߏY?⥩e9rŘޟk xë,i]t! &'H0=D 0QBA@ED^R""Nݚ(X4ȠwpSEPAB-TS;+:&ezV1ٕgX:Cpm,ric22DAͭeѡ|ƛ fir-։f롲B=:}{Oq͑VlS<c°3\Zi63c@TػSj̗;*^`21W;✼Z;bS2w)i3+'2UukZy<]U\Bf H|dE; YOZoWovm2EP݋)ܵRU_+'R<|VT%e{ZU[k)%Di~.D?G4um 7mwTGn }C_.ͱa }ٷrj><'ʼn@ Kg念^i0ݕflB".{k{_rwfϔσ\* Mca-cd\OO(D}I*ĉ[' c*,_JTja+Ɋ"c`ԀbTͨRD=ۧMj.U4HVrX+_nr/Nͯ}';>a9F7<u7O۝v䳠#AuLɮXʐ=WYrT?^tSU^#Hu,L:%.~I&ۧIB[5;RQN]Nz aܒ Uu@aI$$ ?BoX$X%E!۹xtHC:䁤"]j_2l ["%x#II?Hl\JK%SSNS%$q+f\_ O>%ZPZ4\oQ'*?̑#1[1(C]O$_'U/@}Ùa_7>x78OQ%݃VMX#JI"#m}e `}& ^:ް>[yoy%]CKEl]z2zw;g곈fV| OWHsqo#Yǐ}{Du".L$ry4cR?C _g?m6j7ύN$Lvn"#`}l-OJ@:"(F>Fnh#30D `2bBéOӹFBy0/eiy^u k|:s}c>ڗjvHs0x8FYcEQ[.R.SS g=3 Tcc= -)CÛ /5R]aOP4!!%rVUs?Ks-{~\mZTgo$/-%-e߾Fqਂ4 gILXddDI12Ri ՒsC@hkUƙ\+ơ%%'FdB *n 7moBYoTp/@oN ƍ!Ŝ]B515Buium00~HTsBGqEgګWB1VñϙQF "|P[cƒ?H_yJUNxG=?Q |b7&o^_kz:enVykz$8*Zk&9̺FΊEAl:/[jN~#FG}N+;2M׻Q.T?a sףZ. Cyl;7/\LKZ)^!KqgCI:긓vZU.vN o-__A.]!崸#!Rp+n n+.,7DDsH jYDY) CkE(~<v^j%uo|Nck ޡUR5@)= &1V ;vZB -F] z p~^JR(e#pg$mU#@bd3}z'WmXU7:NXSuOJAbc3JС;E&pGo l$ϟTC*Ø`=l 99eLt'g 4b]yGPX`d&Yf$%}>mOY%#9_Qu}쎞$g r%}6̦9fcګ 84; cՆ)Ύbf5.`|ݾGs#{7CIs *pO?5 A9_qV7ˬVF'L{K+E|ҙ2ɠ3l0qXIG*P\A6L{!Awɯyl o~Ă(7m,&l3rᨳٛTr~yˁa)AacY wԱ=#6GgE hS{\ _=apq;4X(h[#*܄W4qRD-YTT!+*]J׶lrI!6B+XEBqW8{<7/?EBۈŚ&NO_Օjm pU_02$**?uM7txqKtD$P-\6st~Cޜv02-e/S\v?Wi~?BQ/Hn<~+yQ |* b.csJH1ߴ Y+:= DkLD] 'aQk33?l#𻕕;XA)NЃ@_!ԈuQSrf|qUQtz Ooy po>Ȁun1_Qsi*rl:~FOttStMdcɥ_)qnǝ66)]e*R}t.=L ^дGiH|Bĵa3{]@oWv!8si73HZ Ƥ?іf7P?~ H.cWwζF s#2W7۷CF8rFC 4p=mCZc)Mpm|Z.As ٟ^;6žr\錧L2$քSO8IrRQC:bb8gN4Qo%0U -_#-7~Te[_5Gdpc^No|$4S+vfT@5{9o@ew5lr3.,Wd*83K)5ϤøZw<}܋~_Bqyh'p;H~YuזU 0oՔ2b+skv_*_&"õ&U\ I,R#6If[qu8QC&37#GHX8z~ +H+unU="/[v'u["Kv#R4~2mi^;Bk&d"p G鋗EgW#A['D49Ž}U =d4^VBcHs5k QN# Aҕ3Һ@$C@pɹ DK>ƾY⓽_X&$?ǁ|Z.Qe֪} )*k],wFPځA RD?PYot- r4d^p_sz^!3f"J*1S3L:eI8mlUn<ZPux db4E~+4 N7`bTuq1M}wWnm `H´q1 8<NjM!XyY9q1|o%Fur8Xa.?^nb PS pSy>Cʦ[Οn{{i! wODijY22ʠMC84[|pKD2m\k€*H {rVaĻgJp֨qV#W;kp dq=f)N~1~ꥊEWCg6ecsPydϨtI24ϛB#dw5Sf .5SPgRM>:GIwU}Ԧ12 "BPe~y(u$יFR.iYVrI{/FcݠTJ{3/|/# "? 9qUQ YP|Lh'=DVmʚs9M;OWLitl 3wSC{q|=dë_;{?*l" Z^/jFqvKShMSJ+qu}%wݥ ɨ?gI쿗Qϸd9 q$ .drv3&Q- Q]֛IR*2LS}b[:"L#(IoLb~z;W}uԽZ3/X(`%$-17gҌ+ YǰhhU#(PX'У[hnyˑ"R5 fíFobRץ8$~qx3е-nH6\{8 `lE6SCA2#@vPh#=Eym6&Li$xDj4aO"R*yjT}MQrC٩ԌCN6=a~fq|boҰWu@Z7Dqh)Eu AqX)C[iMm6f]ߞDzwU.QHokDH>sذؖ/9X?`ϋaF1:>²_~w-Fsq Ym#R 6n~3NTG͍J4Ll 7Z0Ou=YP``JC!JU>;_wh׬nm^diDv !ze=بuHN |E2FŠ~y\ДTFȢـ(daO9Dى7;Z;/ LW]̮ ڑsw>nLU3 \pa}ea뾵CĨ fty6%s7[¯ô`ƚ:ÏW H"!Ӡ2;~?˲e7IXq*X[;}5yQqh,,W87SyՑ܈i@?r vA^iD|TPf G*j;|n4!淣UKyrQ4Inl r_/6{+lw:#RmLyUk i$J?ں!~ !BQ1%ȖlA CR99ϳL*ϹWs<=uTl:q.s^e *#5f>vX7$] jڳ,:11E }Z}R$~_k'O w{|ZZG# R|T>O:Z#z~ZCK;^/~Yv 79_20؏:T?{\ٮ7EE]]L[eJcrƐuwx~p+& 22-*&SGt'irAx:5ުyuk]wǶa{ !U%cdlMMvHP,w1" DgXDMPf :`Y8='3le<_{Ȱ3`̄$ӯ,1# HץC9Y4zncZKo8cse2d"&=:)T:էTW7QWBa/Za 6՗zN7dxj.3zҭ3<7kM/-V5-vQ(,ȃkO 4.x7qHeb@E,tڊ+sE$ J%~F@NĥfkᶺHT#? ~ ?GdHMOjK@wrp 3rqgoXOb6U r v0MЦ1Hw*aZ!q̡X#[jEc_ꌾ[_1|=IM<_UpJiXIGa`o*&!%ӨᏈI bx!DAv4<PR ]R((%#@"\2Alcm46߁v?k⃦} :9[Mxo6fOݨv;UNyYzL\1`L=j3mmmmI$VI$I$I$I$Ammmmmmh[$X=.˙(6w:XWMrɶx|c!7wlAE3i& ր; [e @W)k)?U~1و,$T٥O}V:iE ˅΋Lb0r .:Bak !XAЇ @aAKK~Qr>ü^KSVj1bAۘb"XO1{rv] O#]4r _{@2fkPjAR րMZS!puG?z & P9El,'Yv pۇhZNT@B-A`N "Ǵ|(5fw1%uw-NXֵWV+^U-c}6-L`_W$B ^-"xYÇq@`& "sBt|P^fמLN* ktyh/hнgou=(pa .@n\|-%( EH @B. (B\R h/~$2@4 hh-(<>aLE`˝A|mؚC[}8l B P~:'6]L z* d@N;-`ۡIx2I@p~= V*3tE/I1 ZUNQ.|r NR!9uZ)众6]Q&Ė2KqSMv [1wҰRJcyҧ,3QrQM$/$wh^iF >l)b#d~L$qukN|Ͽ0tGwﶆ'lY?m DYdgufjң$ADwx9gz1J+0|ޛ&|#ȕ/yYGʍ[p ^‡'LjN"{ 5!˼pEk2V2:Ӆ홹zU㡭a*%ob?mq :<U<9AeUD_*SmT~Rf!$`]gОw6Ki ƚ݁ۦrNwdot-_1v3(V=;&_ggV;31Sl}% ukK>/)q,F&x8dz{(_zHCrs)Ŀtx %gBY_fm\:L=FtjYҥIx߾vsc *fwT#[L|@[Ӿt\htm3ph@GvDxeDmu & vń@.O2* ~ 6`DIӤaw!7~ƧL+}]sQq|{Z KcX:yLnk}?\-nq}m޿=\.^QQm[?)N6C9NmEE[S7L`'Z?=G+vh4<*TbZL˚SRaa>8]9 fU9WKpE(h&gL:Ȩr05Yn67ginJ}aa1y.4eǯR&<6b0eSY*LH8u`CuݵWE+breȿ1QTqS}irqdP0?C+7 E|9O)sfQO̖y,j uD͂֠> 2wS},23<}1$YZHYP,KGilܯ/h6#zI 6Io-ׯOiO"ȘZ_# c4[w7e bv+5ZD)l&A8칰1D;kwb2V2q}#*0@Ɂu_ץ75o؅EndrI`oYnٗEFh3@m.$a~ ?ກ 9E>Ph"j7m5XNº5$B3Kbd2ZgM|QjUlx䨖!#-݉մg.(*]Vq01beWh T'00aR g,`Oی*3Y*Fؖ͛lO7#hR40)]Z<_d8]Y̿ӺWӜŧg?2@$B2ǩ !Y`xS(KEl ujYNwFh@);!y#trzA¶ h$dx\KS R&B+65?aףȆ6]~U^lMZީ0E` 71w έK@{5uY+;7S}a1#ήo^ bwÄ0ֽD_%~;~=7gDGQo7w;eZXx5Ս _-$y &R\yx̅=oH`VnұQOHeEsWQitؼ:Pd1~#7rbAPnvZRkNg>G76#0V<\h $ߕ.o imC$w4蒥\1# ŎO&WZѩ>2&"9HF>o'1/!;D]1Hm/_fFAb}5{ow&4"t=V\ Ytk HR_2_*ٷ82pP@dH{`ಁm _@`p0:)&i}*͵_I\pjG[jCUj7AQ5}jweoaĄpEκ߸ݪ6^p?;IT]=v#8',˯YgpQ,'L&k(![ 2JaT-6%EC[& M[EK {:}@؀=ШF2i`A">fUMqLgkY]+B0tRtKm D>P]ex?徯ռ^O_g2ǜoo0\a(Az*905&G9%'lzrui/q~DG5$%_Nؗ:?ai^phna!xTg$H_%| UUJ604v^ʶU-š(^`,%. Gݎ2d_qaѵ3: Cjw@Q>qkv3ڛC6CAqxl)ǡJ׺wK'(h~kJk5ծ `o܃Y*^'8}ԈJGaUqOf׼՛clb:BeB(oql:TŔzv2 v8lӁzp5#{|}?g)qf*@TM_.2⚘cBKuv'>ZGϜ|krUڭȅa{z2|\w5g@ը ɼetLĝOS8q8mvWԆ RӤIp@B٘"`,[%!;ŠTPG"*|ҤWAXpשr܅jh SZ"m2e=WvJ^q(X?\7R g v HB;)+rTܓ~/+ܬ|ƣx_s-^]hZ g+˰'+—usZCƷ~ +1ٓM`3yi WtR ZzK Z9Cfj Qο4UMX@+Gh 93>"[SM !LuIƈYpH:C*Qt$H*_-_6<& 7gݣ}kmmNOÛEu~HJөdN945WkN ؂P2 jmʐv?fHͼ-F*b Z%Y/,^^- KhC^Jئ@gp0D R%+/#_.}>WD{r6~ x+< o$pCޜ.jAv)t97S QY9m' eTȓ6vv^t,@0NTtZܡ"el\  Pk&FkPZְFBypGS0;aylۊVވ|Y}R|az Nᢁ>6߈?߲XCw_\՟/ޫi܃E|-&T'g!ṍ-/2x~G O.r?S֝;`wж<}'sWN02bZkW-=,тAG7OM ˽kqm{/>Tl_s"}SS]7ʰKHMpf aGFzM9l?*`N!/o虃yGzϚ(MU{iE7n7}Hr3T Fx'k C$7ASbw>le֜eםWp<7ON XL|"<"2\sbKGLV ZGB2|S/}dȲ]U `!Xqvs߃}__mcXI2?ь*im&4lR$B0 k%A-Nά!t?}Hxܱ{;&Z 3o HR;cKydwBwSzrdh{MkU?MoFƺX3Nt H =_>nZwn RY`4Ժ']f69_6G!% <{# WݣwOǿ~P0sAT1`]; Ri[V u&Σ8?;_`BW}QGAIUnrw_`9Q mVz kxTMhA6)BONkćWm#_p;|'t^#Cȴ1"dLA_fn'tt] 1(I)7XÚn"ʈ뷂2QMX~ ڟe4#LN$7$߻k Shc)aЇkV(>hBو !G֋+:1$izZ<jɚo[w~YG8l4H z+^Wrcӥ@ W0KNGzFOwcTfVցL5Z6Q 㑄a$At{+1wf.q( sbvM]_DJ?Nc%s!%JA!>{-cw}Z?[<>_&J&Xo%G$pp GϦ՚s?NK;JzXǵTӉCQe߭r̸&0_h_uV>[z (m}DY ) ? jj=%}ღ+3=iW‘%jf4s1Q=2΅"]ih wN;]ؗfr%z%U9\$}ؑ<ZDGoFkpgu.{RD7QZ#.F%`OmlTykRN3eM͔k_nbr#_hV*u ^"2?{"15͙ijl 5 `J -MiCE{_E{[ ~C`**z$+NxH0mtbGV@sָViIPGdD^bb^Y=P] 4Ğ,nXkpO% 8--^+W=ԏ8 ECCEDYАj0ȟc>IᶪO|Wi:.vYC;vdOd@LçFL^ptc-PK4V8 <.n8,5> gG8&W 9yw#y^SlgV>GI B nJ3 &|!0':ޓ1Ţ/qNj!d}?l[ ɩ}B |Iۤ99+W{'L uzZXH_VV[f%s\8g6[Hb(F8?vdv݁і{f/ |YZL?U =a4"Q~XTyvpSx^5A&i8& 3fWNK?X@]u 1G]^In zWr6inpfMkˆd(2ŮeٲnG+/^}wo;eQZFr&2|!lF]2՞Ѭ[1 0WLe3foBV5Z"}lӠM/oKwzȏ:e(CJp!Yeq&6wYcOR{Gd0[1[W~lͮ@;ddWx~r}IߥhR!()Fbfz q>~`5wV7dfZ\ ӑSξc" j'$[|;*$; _M4'[uq' % 5tu*W ;!^&z T鰆Ko.=S$wS޲* m2{:mt:;bqRF+G ^ #еZ4EAG_χN`:ʭ53%SG$+t\SГf}~;9~8UQ^_7wJ(mUi!y{=iR;j^ZVur'_OyJpGmSg;w:t<,^M9- QPN5TQYVR MtoK|'"8f(~;K`=%{TX\{MZIJ9~Y5 q yHl{/|It詹Bu'7ݩy9Et)ܒ[ _a\^Z'b~4S. 6+_,@5/ @4QK}}[}Dx{ =K>ɷ7zb~?ʓ,(oZ5ڼ =@~av!:tρ?"/̼qq3`֚wanx=؜%.¿Uذa˂1>A %7uۍ'Aι*#տCv3d.έ #ވN&48t?*.X<$8}+F+~$dwF>q{N:N &g_WCr@z1Woy{V.0͕޲dpuIJWR˔'K-jj}f[CK[E0^$5_1!~< RΖr2Ųڎ_w6eΆFD_}L2>y~=jAx.ajuoC`ܷfo Clq A~+6*wM+H9\܂=uV4eNÐ>tb QE,t6葊t98cSے^ pWErr #CVW*+s$G4cqǪGבK\A+XGeVo2/MD^2*'J @qq4P$WOI Bw0Л-x-ڼƞJS":0;aWb;iJfT\p7ܛ{ii37VHN>I QXzsųK#9쇗;f,ot,r0$u6WnF+2:%9~!(xfV!-8YVaBC=Azg|v7 SGKmi٤}l8@[=Iô_APJ2LxXCeb$oOŻÌ۽OD=r@}HM=FγNZZ\ܮŽUAGg݃{oٌreo7gZ M@gZq-9r?2QsIK{E E_Nڕsg@sPIBQ6u![}GQ:{ܲZ$NW99szءWgdHڢ UqOX:Z o >Od* OMƚK>>ZDisF(7o@ʵsm$i/A@=[ɠc_s& '~1l09-U > ?޴-|]ګΥ{2 8e= MЄ}AɅ'K7mxz(7t[5_[]4Hpbnc x"H`2@ HW@kSح9M冼=4g12R˸a(ͧe]! bքhj8R-]a~PP߯Yc끋2vsBDRک>8JG"x3)$ |c8dXro%dҽo6Gᒏ 겑$JnI8.݋=;Qn⿼hHWp i=hRkD5=l9Mf#ppz7A~bz&]=*_W ea8tp&6-BIGO 'lϬ wU{y^3a.]&Da/ tݗo0kM'Oˀ (&lO't Tߊ?R?Ћ  8xƜs@"KȃH\'LB:eSnaJ2/VAO-罇\Pl?y۶|aCZR$tPA& QKe81D1ۏp9#4)@0AUDoSPPQ?z?WA,╝dEaz"aTP5 <ňjdPd@$QPê|F{4PTf fa!D4A`E'S"X$AJ1LXڔEo* 0llc E]!"Z"(_Ds"(6; -ɍa4S"` WRhKkyx!m$K'.RȦ-̩g||/w^,Epal; +';cs񓔿=QCh9;,Z3ϭ(xtnGt466 gg7u H`XS978qd2@7 H7BB$JN{_Aϴ}\ A0`1\&t Q 7ea/gO:AXLjW4:ej=. @ KySJp,2QԴK E*=|-M} ٨^pgW(p ~(Qh n vP6 Cg^" Q Wp5  :ݢCq(ҁ9Qq^u&e6zlgK0 <2/3G4ر⃘.aW i#!X`&nBn1ט "i>#WAڡ"."qs?UT>rP2L>zgCh` A D!HFbmiO([|"<@nCk(96gM / ;H1 $`Ѡhѵr{\c{b,^fP]X ,@LD H`ED;zܽiA&*i":⑧(=896c~cgU))qЛdr,X0H^15Y%1Ւ~G!@.v o$u񻧚MHj h Dą&kaK7ň]CQf4bTh-3LF͝Arka,\呰U2/Nu'01p8,, :!mJbn۰7J`|^,(cq5d!M ^\l.,d 9H:lTV6;(9p9 X VJ0(^2$1KN b,Х0)k۝0e4@C+\T oko[g]Ŏw7jXߎ#v٣ۧXn8I D!  yCyk@ 鲜WZ$!k"$@})شߧ!oBz']faq"2aAv;`s(@{Ps-P.C7<π܉XnD)D6mVtFX m$" I 7[ru\M4RLUERPPSoLـN$IW`7 _UjUZ4*^.QM^ŴB@E"P B '*eDQ9kwbb6>29!Ǧ _k45L(. :"|x,`1l o #J28zx,A/% pӗ+CK!xl!U #iΚ<"y'U޻t؛op6 R@9LSk0c* D -I$:I$IU$I$H܎v!URITIֻZ$I$I$I$I$I$I$aօA0FiB;uۿm7V ݾlBs4ƙzgZ Y pUPoqgfkp `A00   ʒI$I$!8+ʊF@ :ĤA<,"A# QMYm8|z|S&uUΤԍ]@˵vr;ߨ"zg& 2NC*sW,hGn7I&Py<Ǚ^kl'3<'uMS>ng .(p$?˔Nhr7*y-fE\WD(M)@n)#PH jCInny!!TQAHymZY yף"Fڼ;F0DWbp= @"Y )~uCe>{G\j LJ8SXQZ @̻XtMd]HQr$$VZ͛ +P$G)T1 ǜ3s}>xE` f Z@pٌD;T@U]e@*,6ڤ, JŠW/.NZ/_%wU?mx' &+Iu&rꪨyMoLS]QVؾOu7GUKrA HpV6p,"D5,xP$@vz/@C=;%zBʒE5Iw6LJȹQG>&KT'!_=G>"z;vr|fK V0C2eU_]"]WRSs`*ٗ20p hHYW~k#a4ph|\r(W֩v:9g%yÔ_$j82{)~b~@s`$-+=Riİu|X\BE\P˵1>u7[,]``UPZ(2)$ h 1G#u1 iIM.@KBcVP̃ƺ6.-/^`+.w.,pIR)Ceƿ<~_l$zŘ04B*@4K4@ `hX2&\{ֈjV͵sp3c}L$Ғk E3C8Htz?%1I$tR`k_()HZ&,C/{ u+K:E!: qTTֳw.tzPjl=rjLYP&I RP 5@Fr{As{XNuzEQu`z@r g NڲH06fƘ:3-ɂdonh[అ&q|00pWn?P55#^Y$ G) F4ڠn6nC!cE6%X.L \DLFLM@3۴ $4HP2t"3$ϓr4h m+ [fd`h9r3F%5gd].St71߳5[ qh2c](h_ZIbC^[(/sYitjiTQV u2aݐl43,꛲T2 DK$Lˁ#XE{.isk ]V6[)`aAV%KwQI6>,oSA)R5* #%U-U TTn0 +&\ 8bo0"X##ydh$ Jƃ%KtV[$bPd)⪩дD|V*y$42R_ `$VF]w_w M6]pތj\&/}~T Q{XjS&űaT-82WIE$;cP) K]O1`7_f P48k84N6;t\6| AfZtE%܆ը) n yp;%m֦oMEKn3@7Kû &z]4f_qon)E>5Yd3` "j 8&5th_PBHBBHI !$$BHI %-!$$cBHI !$$BHI abBHIHI `,ZŤ$BHK% `q>f WF;Y#kA/sCl;$ڳ\=v_UuFɋ0Mcl䅘c(M7p L7I!:L4fAhheaC]e4Xʎݖi*Y1Jk1=2Q|p΢\AazHaq˒#I~ i  Ի4V耘e\Id T&1@$m9A$-əmMSKpN<؁/A'B]ĥjRQXLEr*`sAڍ&jR#kӃoY,NO%KGK$x1!quGio-̔$9 @&ϖF`j=oƺi}DS͹hUmjtHBPMu-E `H e̋n S,<,jؕUA"\'ar5s.S{h,ew cyT[9dVm띧8H/ ? fD, ^h.67s2\uk][uh˾[]]q={T'+VHn//NEXץZАҠ X .`wp+"oWz aq\(l3a猴H͵ԃ-Q$a!3rxܕ*/+-]w8o 26Xui9H"uٜ|#c @j""#nxx0΍+4pfQ~zXH ff3INZe%f5EuDDJͳK 2{k~p3P ę!"2-0͖فvGNK32.s:B  0 F]$a//Ѷ3:esQIkA5 d`4H3Uo3 #yؐ1*懶p &W. )r`" 2.cgCיk<B8o@$m$дf1=\9]bPĢ("I+226Oqa.fF^-f1:3P\LXN%ܿ~d#s3f9flP1j;c)Bj7ɹܠm1Bpzovo 5Hp_;XH8ڴV,.PD)! FBKnj.@đ#r88<@f?!jA].@!. \ ̻@quuj=HenYsH/uNy-#M\.Z&1i3U-QƣtrEaNj;i ƛ=ݍz+@D5n3.+"ٹv|c. >;SBh@t b(C1 5LIHލw;Y4I`}.u2뀰\.X0[G^ zf`bD ar " hcu%{D`)y oڰ;`*BFB@jP(27]] q :2X^NpVTYZq$OX6$huE#b醖ӅZ99b2-7n7\xZd7!,LMn2\sud@qpY2{146 /9̷Oa \),!QrK|(eT8i+pjT C2VFXeo\CgXiK>wtbn> Pr'LL } AkRDd7) غD1S۟ٚv~o}ߓ?!g7ˌc9ap .v:"\#Ҙhf$Ta3P X@!B$䫍p⁘3Kw&lD<ņKppdp{Fa5n6Vauź"fG%hH $pݚb6W4C(u4̰,<#G!Ch ) pF0ݙr۪SfÙ3FI.A1q 0k!nHhdlMt{ǯ{m+ grGiVUPR 0XDCq1v11Ko[2ȴYEq F3Sf @UI-D5>6R..RD:ǡ3.I%1HE//,!]& h+` Ü͗:A>F8M 뵪6XF\ qpN|:x(I2Ӡ]6oܨ?g:T駯z;u7atŐ8z&uu ܈[KhsAetx9h/8NhoeB|NKR.G_X3dXI駒(F3=`¤᠜,$H\ٱ<֚,ǖTXfOGLVM-*B A%̨Ylz(Z4 $&@ɞW/=` I,F\Y(A^2Z ;7BiA&j͉i6enV P(m*O-jd+=06 B1D".HiIhc tj5b k03dh%Bְb1ಱyh0F3Fcw}WZ. f-ekUX֮vb@;Zf!,0p(zky긐H6kXB֙~+e͙k-=\ie0UY- V$Ę,wV"ۊ`(ٺE˴e\k i5Lfb1qD˝3!wkRe֨&$i`a䙧* em iY4y\0U}()[0lӈˉAmzQ% Vf(ATi%3N -h(iC,^1C EV#ɥ*H4L5 <5᭜L1JƀVhRMlS iDoEJIYl-`a );c (Iu1C[ ĥ%LN4glC8f7+g sa<δYn6٦QlG'dtkifG>4qQ.a2\b@\$J^ ɢ+hwf3cxgpl !n-XtvqxUCKTΙR< TݷM@evtv(fDpm֝Y5UvǷCL]Sy Bʛ fײ$ēwrnt0^H'{ y1s!IU#NN psv:!Q[S[mf:EKwrG6g*P  ՉEURX0x Pҹ`Sl lmU*|E(YK (.j;'S[ b ּs$R9>Gp= V}C Gr#'6 wKYF2pv^>7% &?Qr;B;Q*kZrs:r:8 bC~ϭd,VEqsk!sM5Q={+"~AzǨQ)th~)phA RwU2W>I̢AX$LݿY퓄nHǡ)gӗ׍w<|٘#/#I9.ZgPj?޴ˎP~9A|aoطo-g_m*̸GK׊]h[R9UJH5MZ6R=Xɑ[]D-:G5yrbXHw CЩ#qfkpw(Δ,۶9;{l'\<}#3)=Osw001(TPW 3%&w4@'@ Md-#o7>4U _l3:g-f c2-y2? a81><6Oe[u۠Xu99[-C1Ի}cGQÏ٦[-C1eHln6Z  %GtY˒H*:Q:'$[IڿҤkjQq-`D~{GCu\&:B$aV-a)Gh! 0tT}#D =iJ~U Qd 65/.:xk !KL"hwA5le u/CugML;zkr{ Ґ )e.6vP;l @CE ,#q{ N1K!OGj!yp,w؇`;c hz3q#{2bshڂ7,"2 ̝h!hl.ⲙU#``Ǻ28dD*? tzehhB̼.wt~Z=7As?NtHY*&:M'!ڨCOJEWHUJꪣ,2d8ѡ LճS$a $s|[~xߢ^#5C!VbY2P?'ufƅ\r]b]`rg1)X]pG3GJm ttfo~yEy[} ?$0TƲ$'zgp/z6o @ #ƿ`{O.n'f!ϩgגMa @uHCi:7 Y'oTY}=L( .dA"H"OZ^؛ r" OYθ.Ck=O}psAFBd`|LeU0 ZEd*QfU0 {na(SbD^aWX-Uݺ-q: $%`Y7Y7~eZkS k,^12٥`ce5Fӄ֛6L ֞+qv[r8ZoDn0Z5J=v"2.XNkğ{$KPwl2jŻ)(4p_b6chx<߾*YY}1*=:gAɣA\zG E60D"+〦Lh]_'lٟHeVkfBS{o:e h ?u:Apyջ0c=t$Dt{\ hm[b< INCbM&Ů n7Uf񚽉 -v_^MNA &BkGE>)"sdC]Wa(].5Zao|< ߰chb*D gCt!v*syk_倔oum# !:\@4 n GS5$wX|-ևC!|x,kʂ4A)-`m @`| ׵)A\hEV5 RJHP./˅烎4:]x" h|m b_O) []s=̯N)y;I§30@Fk3 :_@0&)5Pz~ۊ J>0$vc@bEgjf)}_4@@jsi_Mx=*oʃҀ~a>&O_=·I^INcAzEK$+oRܮ8M Yӏ4~lNEV;.KA5Q.췂VbK ?m EDߎ=s8T{#Aaʚ"'PJC]#ԈߗbMז:l. }=} THפ  |9@G'M$<;~ϮG>qӳڭօ:FSPq z"7%2dDNR8>DB-52WFWMb1.}rMLH)\1r=a:g1;m\&ȮE)Nե$<¾ =!x\0"h[;NO-2X׉'!G ˇ5faw.&RD{r ,[([jsAƖ"'t9np>DJGTjڇtf[/5ԇ|?4? F;Z!DopVĽ.;~w 7&Xy7I/҃>8ގ#p\%`֦3_nGzvHGP]S-r =pޏ4%Z',ѥs(I\PFN ȲժlEwkQuu 2:-2 "`CkM5):O}y" ,N^1PAUڱx0H?Bڛ TqY?Xkgq"OJ9Bllf?`a@V,'b5ÓB7H6mde#ٶ^.1>{^]Y(昶?zZUSpdzu+˹c>Wʨ"" 0`0y\z˸3z`?[ KsiQcOy\x=UICey-c8L8I`w,?LKQ)֮Sٴ(7vx [vke,BApOShDNOD1Qgn^Rˆ6w*ڗt">2roC}7lʇ$27?7OZgi%I(}ʳdvM)zugX*d_ *Rd||XA˳C;E09IuOڽkUӮ6fo#z'XMvsj'apNhwW )W9s)'e O|_{>c3 .# oy쫩|U}c\ҚKVL1s+7&lo|%qnl8x-;A-e@>J._6jZ/hΗ!L t,H~F-OzZ H*HN {kכu׳_ys=֯oSMm,O›oWj_Oz= tH طD>[/7堳 h8>xhԬ]o`;,ҍ j@׼jb. I]'فUXwz+&֭.$59}Cߋ8jf&H?nzH6lé%H-D4Yߨ5'u⣀'Cq/|qjz iet}_0Ζ#MMMKLƪPN:WS+p1R, )QnIi1@]grsI) tcқp^ol.-f"ч a yq u(ܫ >Ĉ@OgMzv8g-OKWC, _q`-`t-JImPD M̾}A;v -s"}#>,Y47`\>uZ w[F`EfZ}>v6&\n߽YI$Ųh'rEu~UX'F6ר4&nv!!h\ XP?7yNa|hMT }Yqҍ<6s#GG&! >t|+̶ݡYAnޙv1iHl&}8UeriThOճdZ0,YrxdUzo)XLSM2vZ^꺨aJֶmuRDT_7/x)WB BҺwzR z,=_mMK 3<(wJo-T2+̂%tJ,N޿hIU^~rK q8l$~C{/I cwZO$T\ >jR >`dm W\noHM]Gb i4ܾx*Ki,:(^` >*/?*v}V@0Ie{ea<>2HI7geoW<^ڷ%`W|GET<P" $1B4@d0` `Ab }Ba(H7  ǽ)J$Q{;>}ܿݡʒ_0qג-0B @ !IO++?1`":vo]\CȽqG[zSĐa>2铱lb h?,OŒ✄hgd Tcɵ#_hh+H͔4UCG-ki;34﨑jISf|"+ظŒfdP3# Xޮo;|` I(ESP^`)3 " J[4`{"4E3(pYPA(QmI0'=5⋾+`;6CbhBE$mS 0CG▨0Pސț ,b!),oxk[uj'=J:K@x폠.BBhT@!y$DD-VrN%ӣr3 HFЂkk3 TD"=Kqny92Ld!7P)XR*.xH6w;IKܮ%;ŲEƵ,lXgVXy޿3. .`՝5AQWDn>Q(мh=wwng OV֜FF@Bup+,h XGaN/TIOczQ򅚃ڵU־G;&mnOKoy:np!ހFHI$# A/_cq|i\2(7^W>$]ȉ!H:A $HI%l(cD@ 9aٗ\-H&b9Τa7@N[Z&mcbdhbd QLJ10.I\LMb{>W~2 !FZM3 ti]gC0vǪe efm@tNln}$0Rr)*7FF4MArNoݝE)0&/+>wm^ /NhEbIL7ZFRHuB4RKNaE]n m&kzo-N eNC^. 42Ȼ +VRtҟ6ayAe:}1_~JzW(. qԹFHBbVMz߻>?R=$]ϲ7ד[}T9sP)}ԿmBU23 <2 <᱘m^g,"ʝc23wyf㘅+|| =IifԨ: M/n> oXB׮uW;CD$E$WM/B33r- !B0aZ-T BD,KQ[ ض']K+CEu ae>v/W3@p8yڝ6dc}i$]gF$^̺aJN޿nf ʇL٤$X騚N;|.Rp8&_{)>#_t&-qC9)^?JL&sǥ4-aWVqdhhfj=Q5DE3sK)@XCcX:Dͩ 8yNGEߜrKeo x!OukdqζbR aqzZ%k4lG;MմA8A!CE ޮ}"k\XsOiiͶe@z-j E28֑ :5A ^a\c \e1ӌRRRshF\(RCP~MtwO5k[I(r3b5υ` !9%}N1l7It@|~H첇઻gq2,UW[\RFu6Qcvm:+, a.m43]X`͇C!x!038B;$u ͅ hEtA`M3A I_hMH&Gu5aږ&/&z.Td\c  @l{ t~.?@289B'|qt56Uv@3Ї9S LM €͜ ġa) T=YBڌ8qO:襕_~ˢw_BɠIp9J샀ªE,Ityُ ,.Yݭwڴlܱmb/"$!yVXywuLP|ZN Ѣ# k\@SD4َYV \ m:}y$WY1i8wx. 蠛hQ  qC~!A@-D1q5񷻙\Y #ѕJ#"&q tP6$.$RڕFM΢ b b@hflY1ʫ4 p Y4VT\e@ L)BFHP$Io$+;)K3dF y `N y"/ tU l=8̑,vHmuc6i%-='ee`WA,xC!`4n yvd!Yj jdHuXeY_2hϒ`d&W Bc kTMڨA Q! -Y++MTvW w*ChoW\MiXb %GAdd\U{MsLO)K)ySkR}TXcdk cuM%Vc` )7ӱkB =: 86`.0"0'$_ n7'TfrzN#\Ŭ+# 9[o]°< ~ǀ 2`䅸5$ V31szD a8[f5q1_IįN|j[m8ݣ5+u6Gp/<́S'?Mylq]#3\O-U*wHy%brfeB?w #rc tS{KC<s_8GV`-MHj~Q-UcT_K JC|s9y]y^cchUo; Df^QUr|/W#3"8epxReƾHqCF )?EIxu,Mm: ZNHIA [3 I_QLQ{~YQ^+ o8Pڃ8M&RṆ]HL!g0K fQ%-򁘮B =dͪJH.1eSH`Յ;X W:Pa4c~2 WLʤИjX&C)^.Ea%Rq,-z ^ /KC6!)A[+.].,V&nP$bS %%'E] rsIƥݲM)^,E\&Nmax˝gL#AWҌw)ZjV^rй\/N?Ņ@$8Gd):J/E5], -, 8@,߀>'$e`ЗEDdk.U!6TO9XԶҾ2HF`} V}   h = *&rL  ֠׊wlmH,^4']-))X$") HbRQXHBbլQLW b@Pf`LX^Q3*EMsidwN3ߦ4JzHujq'[^Wtlؤ֏߹p5uG<.\< jtz* |ET216S(TFœ0b`0BOj+ شإ@k[t#)JΥ p. @65 r-^*q]q2g뉄^z $奢%d =^OȟrPÆۯݭ,G|+Z˓w#WܿC4 {/L ,O֩|DTC\QORo&ɗA_Y%a|]ߏG}\#dtg,P? ǁ{jk,c^R0Y_60l9\Wmuηlms@P$nN A$lSrL&\[M$oGB"}⣞Vp wEa-5.(u<² (>}cHuvjoۢd"!QErF(cy.jH@_ Kܡ.z,#mXlFL3:֊e#˦ViڊItruEIeL&m#+ !T#V]NjKJiZbǑ Ga/1OLtT!688//vQ+c `roE{J`o8Dp@RJv37пAD@FqL+f"3sL >qAs8]$_A} .^RR_xݾ("f3 f66سz|s#c5f3>N\|?@~='~3N}!|fPQ``ZQ@ƈW( #\|T.jM2)E&od-eĻlkBakT-2yN%[P }#D?&8Ν|?\!3SWBk \!W0OEFhE698nw\H'//KBS)']aI% 9 ˷n4k~ fEdq2"E4J_e6IOxr[k">ߞqpentPd7ӎTrEZac$&08)#na$ 10^ v-#yԩ6,f9}fA߫LlSS>A'Aciq$7Н!1 S^,ͩ .T8 -"G F &ĥT8Y@1A,^"Hwg[|IH%J1W0T('JtL0ȴ1|IO .^ ՏC:[Q zđe[MZZR\ny/~yYqwP$ٽ17 gֵOSrN(,͛X~rIgBI\WlJ49FM>|hGV2 MκqJPgl:VYؙ:O=I"&s `ΤEmp'߰PH B*?_~%CɬkF+´{J&2\7do}D ?e3TRPPR +Wl6A]:ֶ~KvY0()ZWQj[ӆ< WNrKl(1M·)vEf. fo ɄrI$^UUtg?ɏUem '^\DC-}yW/'/v]t9,z'|l12~?OZsK%4r2j-\[S,0 T(=[Y~ņҥCۯ:{࡬'0`ElA#sJޢ(0I 0"J $7P%D,3]L:{|6 ͡#X>G-El`D lck2cq-s`XtC3WX.UY q ]9pvnI#l[r]&+…[Eu9\ !-b5;\7ŀC i ӛOL\gHVLHcTral|I`M%{A>reqC$ 15`h)Vh6(kgPڪŘSյrHE"_D(8Œl^`a1a۝6;~5 PM53 kk)n{[Z {hYvټ[ \geX-ZFL FsGw26Z#`r94\P;PLBbbfFمu`hiRF될c[xa<<2LѾAKm%m^j³K d !e b($ B[]@'kfE4-uR?l7AL& )4PC\#"[M$@|"Ө1`GZnΙF;,j:S"{'(EKQf87u4OPyHts`$w%J!:I[r[z_vK(l5I;EOE#<.6^]*Hq!{/:y95 .I.%sCm?]˛35W} 聅*E!F+&M$&`%5٩,M1ןY;q/F\H'@"nY\.6~?˟5S@Dч$SLy;;g]+G ŀ@9-DժwPu{*g]o01. *(WW`(qk{IN: 7w>?K۩yHjcU C1 xPKI-d!=g`\}g\b\~k5ssZT#A}5+g蘐q5r+:~cSeE Lo( EJÖؗ]x>lUM2ӧ ^t'\8YvwhhFyp\-۽#Ϟ.o&]$s> *=Eq$n}#]8+VꦱRpqk| 8 veˀpΣ82|Ԙ XU,dnge}ܹ;03yPٻX' ǻ_CW?'\1V6`hLIэw'z9ԓ:ӬR`GjJpWjvI/h正¾e׺׫uywoN7o6pz]ZRN:]'z9B)Bc9n2_,hnȖC+ncLzPeͦTU/!,xzri{j3[S|"N@/+[h%@2b(sU&y[! f̤bY:&9t{0WO5EN͸VY vup]=[&s%pz! 2ZTcR]WH?qMk7O`T&[T!5Kw'~RZQI㠺HꤕI~*x%>Hńg߾-Ӵ?;$ ڿ%? pX4w{ z]$1 os . 2eQЖ-(βn^Iʨf?0 uĕLt2쐩+?Հe C[ R +-i++Zhj8M!NM•C>Zv2$0eVu$ݨEKhײ~2^zuPUEuI=*p(rf*as,SAOɄi+pYRp("-3s5\pE0@0랎]5_nφu/рf ̌x$I Eytw ̇n<^l`^{?yYlm e3"lZ}8@.#U;R|o_6w1&yL&_;+4FjE+}4j  1a8Gb5 yۛwe9ew v!#8|{xRC""H9ZJB$$.I>L7vE؏i\XKԸ's;][sgsڊv6# m5gqYjZ! ,9ntۣtqx">L, mnS_!x|}/ͅymn (͵*H襁=] psGNѱ U:')QPXD4Y=V?]_n^hCjw[5 H;A~ڻ|rH{Mou`No;3`%︺<Ͱ"s@H^# 33{K&'ɝ9@+< t0n"' n6b Ԍ%+X80~) L@t@전x  UKr.0q]MwAwnG+oeip^#1WRH%|Gr^lyȉh 51jTl%uKɌ]Yh9uRbS[wAw3zyx a!!,,$, pT%N#8%Pnz%l>H5z Ԗ-0ΑEֺLO= w*%`0~.NJ.`XSȺ sk3p8J r/6#3n@s>{p511egYHm۝xHFI \xMtU> 0zR"8ϊBۿ/=WV5v.G\c#[xѳ6l44lo?e yU4"5^Y?Źh+v1,t$4)JQ, ڣQmU%ꛄaB/n<){Oׅ:l`j#!^{Xhͪ7};aIGR4FMŬ}:5V+sw1̈́`ogDDHXFKf!F?-h,]n(Pm{6I]ٔ/t̺I%a k%d) #e-~KG뾪8P吧Zi۩/|36m=aUdFW;m(?KM$v Ҵ {&KwjfI&sNrBRU89tY_JdQ3'JV@Dl /8Q64 ʏU7+Rd1ʲv4kAQE$WP_)=YWuҟ|xG,^}c0Dޱ21A|ʙʴħH~gӧvh)≇=oIkL`x铃mRyN]2<=0 BcV!GˎlMc'B6pԄuW P@cQ9__F)!a7y-|9=_x?~=OJ^!㢨3 IAE#AC md(sA.:10`."H#!sbeI*1w{,|ZPِjmS@Zo[BsΨ[2[%,a&J*Z2cD,V<ž Z} `cڵ)(oX.mu(S?"wfoѿʺVb7YRГA7\  q& &S!&@Q^ODa8zR2Ysqdugbo_}Oϑ-w8dP`%% %p -˹`VT@jTmؕoتi$;Gs%߽<,FBy~Fj$"{}>9*Dt\\&`0_KX I=7R9z*>Iƿ шM E$Weۙ& &#>85R(ZƵZuYtit9y s(#4;o=G÷mlm;H$/0ȇDGYIO5sOG}/l]$nֺ[^ -X[܂8xޞrwov>'Շ>ah}L-Lw{y7UGZ6Fn>1=0 Vd>+pea) +qA"HcgD8t^oc}5$ɈtJ$Ч%ʍ*d|p-"B4h? ]5@+wrޗ˟YUAPcq-LH3gD|wo4h/~!;! 1?j8F3|#Ï!z`wx PG&^8x8{%@7 Q}7OA{ '8 |V;͠H㸓(9NA!qN{[<6Mr钟i_i_ڥppVp V(I$!>juHܦ<,ig 1URwAnw`Gqs9LfQ롐lW|}uI 6}uဩ4 ZHJ8VX-{&O]y^6e_Xk]n3&YZcf d=*Bg+k26se4;Ք}Rۊg;U_t#_[*]k/|͔< +Q\rgNJT𠕖LPMe(e,Ɣ]Lnr_OO8I!wb>~^^7[,b-}3:}c^u:wZ>8kWC2+|kEw٣[)Ϊ?/~S{u {h#n6y x,ƾw6[:vyچV3:u#hUAy8N`uR䖘L*}sX9(3$Dh80(&#БKi_)cbwQ>)t&11@ .xC 0s|7<-wGeA|r>%v]+a`Oםvڃ kݵ#YHkeTQpZZvՇnz5UAz8| 0 gK>c@G!=1I'@Aj{tRyLbSZ6|jm.T%MLF?m:zjk~K1_8v瓈<_tV]PL:J2UU$եh i*Ɠ=RSH%}H"!]@cd[HQ"[zMU iT4 vU C?{ X:Fp<*}+Dg-:=s9zT|RnFFx9yX~ȭ(VQT $OCav"IxaG :3 u)Q.+&[!R t4g~ sqQk\I]?6B4 2d L% VU HN+glLPثnAn5sM[EN&uV-X7/C>n0R$fyp';b ,2ERoL/tpXdc>Yp #DD%L 979}ݞ# TǮ5cg58AtXZ6gҦCB I"" aN_"0>d&  b7LTI9n>] &uYZcg8{n2%`XR z>.+=sPu;ҐHAk[ɒPw͟e' r?;b9 "\"C@CN‡`e.ravlِz#=w6ŽeTPj ,^ն,y~\YSILrje[2Z+mη=m%pU'+r uL0Iq@E@ڮ ]şՇ';Hg\`R>1+hCc\x~s<}QМ7E$I#ٵ}y/g+k ʉehk_L(H%Vmu_z}eyǰPc^8ߢ˔ $wK%c/u&˵ݎpArwWɜ9[jEGO]vEz P@w}] ?x[: KꚀժ]V:$kis"+"+`B@r*w->.w}f\fsA4ap$Ca>! aفHeմ]A!a~@Xdf} i80% h n(+w.p }fgj&pRQEBA EP3" y+`K@dlT  3̂c7I/_+HGS ;~}1p)~u\Xy= 2>>6 ecp3Bwj3)Sr{P*d%)v(W@xg)| (:Է7sbKuz,O}M-Mɤ g|:[mc3 q%HDF9- +dŽ|4*]OM:ҷ?*RU ( e!̤t,ų׆/!:LY+=qaAyO`׃2ZFyqWo ?S3Eڼ*ULBWZcĮ{&̪cȚ[2i9)lX3*!lzvwZuo'0὆k.i!R*I5N_XH3\,30d㦗P"j~myA!saTK4%mi]ӰU'LQD$ Y:J,$$g^Wvpy˷KY6vɋ8AX%FK\dw.Vރ:mR9r,5l!*@F742 I 1j -kuWtNEmu<櫗B/#I޳g-֨ ! cE{XWɳmg_w/|y~D  N" Ȗ^a ;R*DKxs_l xa@i3@l5r#R]꼼lUCwm7]9DC7>-1[M6H P",16UJ'6-@B _璢Z<-)"HE$9JWT)ؚ>~~_U7"rg 3LwH֎m[Ղ\4pշ#PzkJ̳cclxm.od>t=3'S;7Z (x{~fHTH׈rFBGku[?եz`hk";)N_eZ;]Ṧ|UO ѓSuFRevI"$Uid8S?;4liZ2{DxVtxSʣT\p?H ")[x<-DS""z\y?[}4p{YtFޘyZgyūhlQBLh@ X3"j P?v?xb? 7ZzEmkMmH@Y # |:Y)޶}j(y1}r^AaFe) N5\0G"@G4vQu3/ڶ [b6]R^ا֋ѿVqQ[MzxZΦOFр?rB5!ɲX6'3!<2s<{ V&U#zW`S5Yca9D(j'¡< *JAu!RL>G1$=?V-Q6/\?zdhL P2@*,.\)]"]xȶl }hmgbA B(x _=st/f6?փ+=#,"ׇ~<'7:9yH"B/d b6(# IHߩ ߄kIpDPo>0 (I+2 2#](Z)m100b XISԯeW|qxz4&uE9Ȃ=ޢ㳥kYI}W'Dm*uu.%!.vZQ &d˵mB4ʇSQeX[h)yVQX_ e=c]OVfu?Y)}Kw4\H*K/ νi6*6Nơ ^(#SfwcR@+ f~bҠ=@^E/;;ϱ[~ksauxz&:W1r]HAJpRzn>_K)}_/T5.ܟnWyP&,Y-'՟oz#.dil BLE*`8D*3EV`%یdq= !8'HHHH.ǩRA=_;:kcqF:>M?BImG3=k_Zu'nX?vuD'פp/:Q`eF2ޓjmfr2Ll YԉBa\6$.=V!$!'FJi{J2!:BCˌkpGS į@ `6#]w/J[ ]d'cM8ψ+ TP Msު03<c] !"J#VWD-M5Oΰ4 w>|W;oOƮ;ޑtIMӨ& Fӳ:O}h^er?x6~0`qJ8(gA% H9Hna$]}cr]57[ss?8rUU47tNvHm1*ȇ{)Ê4";!όYQ>pAv@aiїBG-Bf{ 7 Soղ<(}qgi] 5Ϣs{deӇQuYC(2mB&awedSqNtܭ:K DnG/u%U:sza#%XN˲/<)^ h"9ՊD%"@\]Tv*Pt҆J?Vprdm::̷K0}Ak8,BאR)Š/8Czɕ?@ $:Ar9G|TE0|X rRGOJZK_5Ov؀;3`%5:;0ѽ93} % `^3mVO{"IԖ!߹<.p Y:3x%:Z[#U猤&1)bKΰdT+Y ⪪Cs㮨LFL!;CطQp+ huU܆s|G\XIY^#xd$$yhz7<{8q|2B/tim_uP]bϋ\hɶK^ @>ϊ g$fq$љ$6`z/iABq~QS)cc$cVr:_,8Pt:rBM3WP))~MTmD4I-E,t_![7> tǹxo4J5Mא< lXKv"!8:4q{,%_lNW u2d,%u)ng_yH鰩> Hgrmjbuㆨ*LFY@TIS"MV`7?]IkY밽NrlY3㸗К}^R^"!?M=\|Ұg&UhRGnX|"6(Jw/2onvwPLIۺIay$x\ƒk-^*$GsOY`?}a ԢOہ*+ S6k顦Ƃ,gr PxIdKx1Zޏ\HW4]Y8+Zn՞1$!ݢjDG?Z<[r ;_OKU U#2uըN;r/jZʙ75 xɩ<js71Yĵj PQxjmܟ9zi}+9 -E,GNu:k6/1TunMAnqz.}dJ 7L:g\>^)QhADCU8 wfP|^[wk0n赌yK5߹ԮyeAeinZ/!.)Ɣh8EI64?nMrAXP-'Ǎa ;RҬ,KIIt*d*1Hjk'Tݟ9=. PpR?'6q94t>;^gd98?pfW!o|=1RF1,@HH" _Vv C;ZRUVM_syǛ;M`HD/~x/Y.˟8;)Ͼp(z2;B D~uDH(s P" <>Ctr+?+H8H͕Ե-en|oǁ{󻋚M ,NE CgC%Ed c"hmxRB@6ܙmpvhl?㵻OuHCd$+0xfPAJP#xM#$b&Z*{$džGdZSf|Ȫ;Ab/sL),5f뉦BX⦠=$@ xƦ H ,ίy̅N^ǢS{ x5kq9_-*6xÎ4S v?qg18oVCZ\&:V؇-삈}D$x i"Q}[=ǎ"I;~[ItzS*aRTBYit(7 A~?-+߼8D@lqed7̵lak"s>4 j8\WJBG/c,14H 2$RO_Fj_Wdw! ӣ@7 1N:UR? D|_a|o.UM,>a<S?' {]]lfyk)*b SHۑzz2+O(+*`~@KTfb)I 1Lh4')ؿ)/v )j,ъ(bŶëfMYl}ZFCa2`;J:tBaBF+Nw^o#%R/nJ9H$NR9-3s;Ɍ,:>2Ib˚((j~3i BD:tbJ0 ^qpPPAj{V:(pRwD.L)z A TU8$[l~V R͡"KN<άCA|~+k.&?lRL|R5FV":M;ҞleJUsvKDd>:`"?5?ɻUZ_n|% \ 7ti wWވ"8u!q²x3Jum>gZ-Z0U뺷3hfn-MSs8/!6$44wԵΎo ?]t7MY_DNmح0Us!2N35&3GT,dZe;>ښyr&RaZufqPr-CUT TL"#3ɖr" D bgRTb`+HLbJ2<$˹߷&۵5i:&6򹸟ŒZL4Su*nm|ksr|# nRƇxZs'?g25=RN`!5^tP]QHǵ]nrlwv%E^  \^<2 B3&+~K~/rnx&;,f/QO˓- n5aKOn}wê%|d#R˸j׷9ݲrkg4=H \[ŝ%: Mh&te#gNG\K ]8ګ}i:'7`6 >wͶk$?&~8D  N]4̣?9-\YPݵ:jH^+m! W0Q[qybV iMF* LT/Ăq)c~^/;)vY؄1@Si-.Fn!3^D@Dk,<ކ]r)Py so[1-\o!n0O|C:ަ45y ܱӕװ٥ִ 呌 qvk "tE'C՜,TfC(*Zu ְsU$Zt=n'&/- PxZf?s/;&]/$i}CgmD>ꀞқs=;s|c@BQ ǻf@Ya2'FBD+zGSNOmƵJ<YwW'C}9?{)t:p.BrAf^ ]"v2-<{DHbH9֣1 bOT45QFVM mumF11o^v! 3RB;+őeJeP+Re R Ǫ:iTBhZtv9\"Ewt}|r0PV" CH M܄xK͸L>jj䛣ʔwirv\e D1L hqHLOn:6zb,b%I7Z3FXWX˻`ʔܚ[A^%F41'vtrREmJ;۬v`(),Aj53Y(MBa; v^71?[B?D5H Yj_Dx:!23s0 'J9/B{ZaaA9N&*b(-|6_af$QJk]yCZ|Vd)$\"VYP)ysBiPD"#.m]Nl~s*|Q62&@eT;Mt4x?|"2zjEqaࠫ o˃}jX@niy;O\a>S|?itX Y @0'ObF qwfd;IÇCUC(fZO@6J31|3lY3_k,/z-F!~yVV~:gK#@QKd]Q,3P4@7bˠ^B &_[㔽.V,|ݠK&@Luwb>cFֹ`XEgl`Y "¯B BkȦGӸH9ٸvX&?J~T!;.L4ۖf,:r[Z?̚x, fWO>XQ6 Sڻ;?K͋\GrZQ0 "1NKRr~CdDP{ g]Ud4(*b)zr@Q@L?p `"jf(iJtV]n Ho3N|7?Enߴ{|IvR15W 1N /CY?DΙ馤J[`a:]h]o>ZE^0Nm`H@@@2# ncUjךA:_|C_ /m:P QC)0[hb} `[Jh\J9X>K"`I'dնGg4c;MY$éL)"PgM5;^×q!!g{YwwwT@c6~{A&QZb3P)^n#[ L~LuA|FrWY訢cTX88k:H)$;鎲߳|}xA)wǼ~Ǟ˜d\mӅU| 93Ο{oO|<_fmsQĘ 9N <|q.u.΁5EQwiwc?? C^ {OGy?:94A@Ũ-M`"ZOϗ"64in3 é\qjMQHlݕڇql>o$@գD)eBU'bz{)np9oRjjw"'T!k9vv3QmUf6-sh<4_6377w>"S)S5 ȌUeN3 uHE^KiIBtBjqVK(xm%I;m7LRC@@@&6pp )zh ތCA1^H7?Urs?+H]vl43 9%Yي:H'nL:4:Qe(.EnԜBoul >z֛S;ڗb N*Ϸ^̾0D"&p6y>wiW֯@A acC՞5ɟwvkwgrzg&v zZb.B~F<`VEff ZhJt9K S,! :MŜ,[>tP0`~ ,W ̆cb][N3Ny[OrX[ߢdP_].NHV Ps 2>(<Z֤ry 'NPxT!¦tfeUNd.ΟWFUbڥgIv\pnz| ov( լq.FRbܫMsAA_b#p  #X:4l9dmVNAH8@L#hR(bQI`AꆎPhߜ>1Px!/u:=YMȴ#1''Y^JlC) 5/¨g]&NIk>l"gGvM>ǣ _sN=|-<н>]N>ET"Pݮ\Er&o9.BcpI*p K}\#@ƿ~Fn?MV7hI^ȍ]RB={ <] whp+3{ *ǂ=G؜ ozLZOԑ߹1%f9a@Mkq IHВd甓?:biF|ۿ_\UUdZY ,0clR4{zdD/O .fBѸ`iЭBI[ malOR_44W-X$vrZ @8KIn_ eSxDAv5\uoݿiۯo\޻s$ø0"t1>XdV6qu~e"!^[W)m͝ {eUzUV:a}@uzo7o9;T=_f ^ b,=pnLw!myז7Y6Gk َPa0V̑6Lm:w7GNp`ŚM/cWMa=qgK?>cO!K,B1r`R5,z9yޖ4Hˈce0 ~g9v}ޟ{z}}->?/f0bȽGu(6\f&4:cR1ywĔ;ĺ/NCK?l:,>ި=?OoPwzϑkdgyӾhӰ/t`Tm?!pw-03 )hI!FZ棡~FݪyQV^ ÿM!I?wAn9kEj7٣h ?cHBCvqƽo-?hrTv>#Ұe4mB7=5! wōYsm!qu3k[\Y8̲飐ZE $@ F&? $f $x" PQ99<*Q!d˶Aj~8:* Qs?"衁C)@9C`s3|]l>f ]#vկ|90 f9JV-ǰL}u!H: 8*w iFh5zXi``$֒ \<=fs^''g!y۱^{1}ybdL;h4@B=6 v/3C^ (x{*:!C9ѥf zuZy0evG:P:1 &u\cY-fи< 5͌$$gX4bqtvNc .d7{c`YR8bUW"M-6#3UJo~nvExuȨveMmHGŵL!*)~kۗvǻ@/-W jIv{>"8I)Y[~ v&jR!!Q鿮5zu%P5wzʷ~f[ߧFw [ʫ|/;m~Z<x&==nP̿rPx \xuft?xp$1Q"2Āp#<}_c>߭| /d8 WyGK4 8@ !}cµ&3ńM{1[RPeF?vT!,$!-ɜ|b{M2'8AJ3$H)+5ThԪY:T8*z; *Bxe m3nMƙ8dt*l\PGS>~q? P$'>Pj#$|W;z >2ZQpNѺB=2R:C I:r${ K8. W,ҠIC%BY$p/JiAVZM!"̙OV ч05ŖKևnk V-GCGjEŸr.K3M R9+*De7JIIp27f 2VJsFN[wY>UXdjH]V9i)) GcgrQ9q4$lfr~!!N@8:ߢm(r%`q0tW\ [*uuf!$*kFUqǃ05c޽7Uw&*newpr3C.>sήyu21`n4@_쒎؞1#5# ,h:) "UevKT+Q/bJ1.RQ<-`zeRwXd1Lܹah2J>m\aka(|>/ u1y1מsvHWqe::|e׷(N~^okj`Դ5?atMM [P,ɑaG `([SR/ʽֈeu3UwR5ʈ}}6v = ͂ >R]}ےN:˥N*W2W$3?bۻ'Gk^“Nq$K=sҼƫ}ʯM#hU)~ɥ%d(XDJZ>R;%i5@1ýmb-82 RbڄnSx+F>J!KrpQņ;Wrhcܗ]ѵP,`~q` DZ_`8U74IYzJo%$u]ωE-[;ü&tg"]ʹ$;{Zu/mMTzPYW<&tc^X/qvCL$oagC Fy\s3$yquY]0Sy@p, `x"k)/wW½ld%\#Kl <$w-p7+]!.20ܒ5V*= ʬ}:)uU_mtq8nkPP?'󗼹X<wwM|\#f 23d@-a Mp@ac8Q֠%aa6 YI4/^6X;hn`gPdbLDà wh{Ko?g!(0qK-$wHXG/ĄCďΜ$sß%TNw.?axBH7[-#E9@oHEVSBp0;S Sop$@R,0L>6E)~GA 'zddaHcGCӒPJQTy "#rE*04H[o2234G#$D8!:FJ #ĸ"$D@4D= JE'VC9 +<=<5&k]EN}_ByD緇:KTwXFs|nvߵ8 /1`gSnqL 70p nb -j)͘f B@23#;`m`ϻw8~Qo8]<+qi^'LڠQJ63IvBxvP[ !C-,z(9Fy!1#w`I> 96NBMZ45/,3_gd?1|qͱLm4_g& q0.,Ed/FG0(\9,AA( |>{so~?:(kq-7k$lW^)wuzKMi K!PyLJvp3;Yce2N<X0Ev< ^E35/)Z;f#b9](3 Jv>?eZ(dd`E3,g(Q.qXgzCʿ0PqPcƺ;9(/Wr1g6k8-F~6)ܲ,`$v5AP@}0KX[j[AXE\N%7܏ nM?L񐝫FU)9 ,DGըu 8՝dffwK̛{)/x\u3ΊY}sY),bAZ<7{6 &~kEԁ '0U+nYJ_{69],ڢHLe3l:?+F^E6]s5ե VD `)v[̖ 3<9%/Do`o>irD ʙrQbknd&tXpDuːF=Dy"@WaxԢ1ЬÓQnk XSjEYr~f%xsLCݞ-K)sgv'ʨmGj:L|ƪ~&,jQ=4NCeu #SA&D~f(E L:%tsmy w\jlH߾J&/ۇK- 츀v5ZX d^U*z2Eu>, >)ե ,˃u|VqLXߴJ3%6Shtl#*iM+4+h`uOCH_(kz$T(*~&PGI%fuun>bc+.kl՘_ɭn3_Oi@`Kp}Q_) o"(JKf/fDuC:dn1u_o1Idgi a8kt0 @P)XE%V>̅(UECUo޸pRd>T\`Q?i`sVRPm O*+U'wA>`hoa*'9rA^!1UZ:HXز'gn $,K%+A8k*k=|^9MmNn5Lsً* ;3Gbu`09wݙ߃`m ˥Yo1 $SL K\ a:>ED)B5%f1͖)CywOzj:燙25y*?Xĥ"~ʵ#[8 gΥʼ_n]ᅡ,f j0X~OG6-By-!B30u"B~M:XZKrEqR@(7Ҽ7Ld7>UCI\ɋײw*_/ kEZR-sqxLhg\ d>$oN {\ϩC¦-0Gڷq*<&sL5uYZ(ѿ"3f!TJY\*1jeL^rXط~tlL6L\^/B (s6O2kϻvGc~4%XPP4.2Uc"XdCcDePY١ ҷ%~1K],Uҽӽrڄ&5IE&`6"2HjBW_b\$͹</|q e!ꃝ:!!dYB2R"J 3>]sJ΢l&wk8`l:㰐Y9/F A#"]0.|c99d {8!K T㢬nyr*(h ܊. D/ 9w8Z,kKbBu]͙A0*"5D) ,&9 T_XET$@LwTvmJ|E&o1CXU6Hi7jq ((\ M1"Cb |o @X!DSMTh0f1BMlJDʽ#!ݍZVA.'sRŵ-3Cg-ɴ/-Nj4!  )*MH@{| Z#Stz**'79ergߘR_RX $BbFUG(E^ij)BH f7<ЃU7k`FVS峗}eLB=,/ JWQB%c"rnԢWlaW y)`őcCC[ӓ =[E nCh6wZl@_mh}Gs=j`ٔgl< \3Tڨ`dĒhj4U+yv}%3@ߖ)͔}CWd+A}!~pLj*_c۵t7!*qZ> ôۇ@oC=z,OW*!įy!I%D$8f-ol1s#K&;V%0YܶN3e(`@ 7&BcBpdg4L s0 o}ӘH"-FBz)m[cLg7'38~#gGgG:(1g"e9h1Q!4O[ܞMHE7rd[OR;ʍ6[풇#&h4$]QAkR;%-wel7I@%@IJId$]oȻ\ B;KCqOyz*p[R-PE3 33fyUQu#D4gn" V{NL+Z=RIW\^'.'!X@G7n7CӖ)heӁ/t@[TQijn´t^;="?GBw7%=sBqڜkOqԱjWpA 4Z%bjRe]e9b 3VT)[}\([]jwآYǹ0joK gN)lS2ܖ<Ұ-p.7j*@FشaZ߿PF vN@y[3-.Ć[^l􏪾]Ly/rن+]M0.αOeÖ'2˧͐VhߝBOyFm&eSGK_SpI# > >TT%e}nhl*,ªBx )kϨ^x,pBkXjj9rQ&m(|elPRN"⪝]g]Y$Z]kqU5$6f)y$_Aw>ކKٹL'uZi%ly2;4kb%rLϭY;$m}F( ۯE݌.FFG)NIDNءeSjd}kls|'HFaq@[Nݮ@ # D@ȭ*& z</kv~v׵܎ʸߝultHD%}$8`"qYI8"XP+3,y3:Gv1}{y0pAI,K̈́<QΥ rMfw0`̉t 3`ۊewh23"' &Xk@;DEQŜڜQ9 X/? aE0EEfg@MGd" `=U%j ,EEwj ~wJZ]k wa_ˑh bahQс̚HB6<<!id)nFvTJ@zQ3t-R%f'Ss-h -TEːrww,!MG阃%=<Sώ)Q,RAJkD 4}.w%ǢB9'tq31?H"Wh/qBr9 12=0G' Hȟ$ v$ ;ƒb#Z-H4p *&~beB THHBJnZM}{+P}g衣S$ćW5\#ŅB/f>Of<)HOwj^|2Fh~h' pd?8&b@6+4'٭N-KIw eI g=/>R& cQ4 ]oҝr#ɷY6=48wUnfK wd7WN~rM|era'".CKmJm$-d-md"8ȉW $MPu"'0hJ|Rihn5hQ쮝w@`U A-A6]q60NAkX*ā3@`h!Ɩ^MB"]] Zj{m Cu>yXv#I|7GL{1)Pyp{Zok61s.h1H4^cge #^f)MqpHŪdhOvqj.JyAioPΖ{fH׾kX+jwR 2eԌFȃ-/7v]Z(v}lx*2-=B1I'LOşȲd|W"S8+B9TLZ_8/Ʌ^BH7'r~ ˿dC2rሇ6 0䧓u(h`p}}!%CMT5+ii, MNQ3"#:kg=-8;W* lYQ|nA* I7,CθZZz-Wˮ Ll>PɝkM"#hkI0)7ɿqo^m KGFXRsSAoRV?(출౐/hf()a5䄈lx5' +wذσmWz"ˣ_pX{>ᾩ W<1~.IR"G}j vEYJcr Yީ%r%5ss# !=P=cL̹xF3&Lň0RD_!F]SzPUqD& p=l2ǭ, 1v2=CG/ZV|tWr Jk X*w"2' @!AC, T^+;B t %P J#.@Aazف1 WbHG_^S?D_2!=c;/p_?:Oq?5߭XS /V;:E箛gg[1]YDA u@=JĻ[@|r{4\±h0acTXogIl53cȽ@Wܕ2_MD i7  -~уFfǒPh?@>5)X3M5Y yh3dw2("EU n7eN p=w! 5׬t"JƘDS&ziiPÕ"rzC C !1 آˠoOÁv xf 6 H%6]9S1_SE[eSy#cD<15`ȰCcuFSBe\Dn!3mXܸ1>b$4'1ĖH1"$ࢮ}V5s*F>mmucFDѸ")A*:,xKD'&v,@Ɯvs<=HI"n (W "?NB]La>5ʌXVY KlXe5h;~)xUKT0V.oeSxc#!PaUf2FD91n8utVr9 ˈB ւh2M򒅄d YQЉP0c^[ukf[\Έ(%n=)y(L4C1H32?W ;u)xo8# zatsU{ ǩ"Pl!UL%nUݧd7&"BlT-/siĘwvߕG;0f7Ί &@nd4)~5=G.b ?ܸԲO#[+"JI׸l95+8&m( evyL3+Rrs| JsH1y:m_opi%eDfQ՛W2h=*$Off^Gʡ9Hv}eOW{iJL|zy%, -琇0`dIhzr@#)q\Xdx[Xϋym3ρlhZ!YwnԷ.;=Z+7a=}mjT+* 6? `ZEdHhZ]R`<~V!FOܕJbm=p}6>y7kB`VH0"ŤG,m8;2zG;Fo}8r?u$H#8 ;:fR:V"ڑs,SSTIDI =.)< r`t#Ic ݏ]${ƚ,JplË!|"+Qۑ>622q7D!!"]j큆HNwܼA? xMGC^J;k_$A1 JPus[63I8)o鮠(Mm^ζ7-dl6% 0eמ)ݎ?%s NDc/>_3$MJDsYۅB1wd[wj3bwfS2z7g5 Aȵ&Wڥ,JrA@%bm^5?ԛrn]!CҀlKU.ܖFJd~vz_O'VQdbf{ZZ-sRí2Pޥ.@-&X~QxzLIz(J$-)/CZ}/P{N&FLM%l;SkQCNpo^=!I޹˾vz񯕤$fnf$o4zM̾uҠ2_ {q~U(p6[ Վ 4'P2X'wu猶4/|14,E-_ *6XhLĀ^"wkm+՛h@eGK\9nG`ykl% W-ي7u 1]cž. J^,rwݔc, !Q*E^^p伀I!Hlccdt̐Mukh'enf~eDAu4صٸOqucdLGʴҌ4 >-2. %Ӱ_ۺL˱k=)ߣy4TGM|>VuD2K`oSUU})/z%/{"3+( eK"DQTթkc*ZԂ4My_uH)篣MS?{L) Hre*6GVeuV-n+:" wlyyy1jB=U79OHqWCb峅|2|)r$9K@CDr\f?GFa 6#حwXwQl],M'~Yn1sO>6sIz{\g.+Ee3}#nc@ꮫjIob^$"yj?@ǿc;I 4 >J Rlfx<̆>d2?.c s7H5:KjM7<3M/mrzyV1p 'cpT^TgL\?7XbOƎ@s!3 H!|?8l֐livd,ӂ ?&+溩s7|cmC<܀~[ y,ilL6wT8iZԲHjiG"ⲑ%}p"D6PD<g\,=C xxR UM {1*>. ao *:2 QGk/fRQ{lƏ%#\"Gy/)?H@CHDD$>L0 ȌyQ=o"ɘLk1Q$!CsQl Y)%K [zhub}Oo/Nģzdct2 K_ *p? KZD,'4_s/J5+EWqүDqLt|٠ &D {l߉0˥j}g5s͓ZTr:s[g?^Fh-SSj8Ъ@>Y[Iէ0yPț) ֦]KRvEͧ X$2_zj<bxpkƩ3#U0#+t;dA7=FZ[SZOg-$  <" ĢOZ4q~)DܶYˏN|;Kxj&wvݪI%錼T;?!Xq(n~ 屃onPf%bv--Uef6ǾKMaWvJtm7U 1D\N/ި%#l:YY7ϬE{..ot;Su*݊:fOz~_Y=Zm $C6(Vr kKᥕ}M35^i/>jς;acMӢ*89V':c}~#J̛D!qQkD#z+6Fl&k_3:1u^IVAn'5J8<ȳL]eQY2!l0 WFikFo2" 0@ wlicJs_4L8$d0&h$0N)]=>\>"Y Lri?Oi ?U5oY, rD}!! \P}'x(]%#証snoKTf~ w;8H-@C9.1':cL}#8OoJw|:}C 1V )⩳e` > ?dD?o6w8`wWai{+~c[Pw Bu\i /m[ᅥ[2bCc>וm7Gۏ;Ēgl> G1"(DB06]- ݓ4]v2-2В%Ay nMiSe* aB (Nԁ7 X}R#OPw?r\-B AK6 ,EZ V fք wB^oU36;J;oCdӳ$vŕM MI&zqtm ~cg/29/"E~luK˔n1/ˋE1 0&u ȯ-vv_K^c4ry4[/\µQ&;jitH0f$ eأnP 9eO;L/x_^=m_OQK@E*xV , b[,J愉[9Yid0I9 )`bO%ع:ۜ7eO;ܵ7\ٹ-Eݟ}mx``H( j`=]JQ0Kju^Vly[* XQ DcM 76hnuR}TI'+U(Th@CPYyR.K06Ud ίk~-[r?[gU)DŽhKe/(GtdIc5 q8'3WvEu$ cD=<.]S}&xz2WdU7, B0Όظ5bhUH^.R =ya(iKA'Xp)|!zG+}Oc 87xpG) @CVCisV&i*eAa1+Cx|y%= M/*lHN?SfmXA ϑ'~ m(t'|.JF ܔzN% 5QFUvXDFUQCNsdMn6R mO;y@yat$D&`+ۘ.>Ӂʤŝ" /btљƽ{&&B772!.~=wYVViX)?)@'cSeP fd^er9G9ć[^9>Ϻ*b;BJr :-֟&2ݹy/wIՠ$1uMؘ\7O(A+}-p^$;^(v8[aC;+e.:JėM#K!R\ms +%@aA#Ph a T+wt^iQ^h4lnꅗ^J|ЄDXǫ ~4:8F ͼG:cΚfMy1-mŕ +Jq4#y B0 16[Qq٧T>Wwp((XqDf AyP2xmAU!w8n5w:JD-;Hs`x6CtɓO@=+L2M$)XD pĨ9LbݾڲtHUQL ݬGDQ$Ұo{#APjQ7 E U+$#ZPDQ4Ieb^@$`nzSbY,Rrem2J %/DJuD~@ʑ@@΂'ŧzbn9$qAJhA#d@™o5u_d2":h1ek|?|dl#|zJ'rtwW^b{@@$.`!JA y[/*#C߱}Ǯ36^(yTl:].v{]w{w]ww{]w{t]ꝭvZqU{W.kػbUZIw{w*vCleΞ;1TtWeEsṫrT켏vLB ڡAŴe;Rmf(D6{^l-^]II?v'd=9Un\ق+KtX4#i?Ŧc{V;?+?c#ӹ4_!8Xp8$"_ju}6~t(8x@EPL g԰( z| |^]1Ie*.ܗ9dnCn., Utvӿu8 Y4I6#O"'C_=Ҧň{wa35Mj,Q)']8PTb;(a$IXƐkzxUĝ5@EtD/bq3Ќ nPE;-N*)h֔@0H<ɣqy{޵s@?T?ˁ,+eg0{ d`Y!{Hv]{|*?|S@l,KsAc6y;f^n9y ET* ս¿>;eR5F01cUnhKkEuPjЎ$݊S䄸ʉB 'J;VyR;Fl_z0) 1>?%T[:pq`'Ki|3})ܼ<=P"BH5K[:Hý>p.QZl_Gm@74 ^L[^+]{H,_ Da>JH 7'bgWVVPV(gsRKo ʹecrf\k*]WMgx]|r%"0€F(<ܳK~_nR@1ze~o'LV3/9` [@@@%9jh/ 0 zL#@Ӳlϻy518N17tF@@~(%*wMBk8aاU{DjB22 R ִ˜CygΜO-ߎea#D\jR2N։7+U$ o8]<x*LjHgms;-}vf."oCeΓKK)zLn%}Iem[>vڣӺK%ejҒEVBN0A 'fLUd R\'&ϕX4\E5iڛuEerMğ~ 㡃;lK ¸ut"T qIK;%֙5`&ْdü[]iu +o8`O uRk܂` '@ }*1TjDJE%G@-@&7y;(O'kڸfPxUj;. `9ٮ-'³zRY>rnEn6ҁgn6_oS)Z_\6DZ;wׁhЯj8}#6z vS?ooJ9݁}J ŽNLhkll 4\xƷ; 0fNGXr~sw膝N Wp|RӻniĞ5@_JY)|qa%apWzya}7ʗõ\.s<62OakxҁoA8R'ۉ3KId0a6`9'=]ghV8vYr2hB"3=@~ĒZ ,.w==0(Õ\1}nvv; zDZb]tCD 1(C&22Y A Z;'(Nj#u!D5Kj(br8` ͙␁nAvӋlIb5& gqR/SP"0Zt w1-pV36NIu^=Nd32r@ A3^s5x}kpn,r߷]Eytgݰ!&=Y]%=tqb(w떐"XF/xݲ.Ès!"`m@D#2 +dA=&! 1 @ g(gah7GoCz&hz74(EV+"uun p₁_t%bA=o4\T1D(^S=ڜ:f" 0 2#`Z ɨPU`\Zbk~n7|z'+3<{ike1!ĐLer;HgeiSDžĉ,Oe|>gb19I\2kԞ&c?UHw\y;-u8^-OPfnTR K{~po}Jfu'Z=&*%|]M,f%ʸr$j2 -1*`ܸs)q)fQN'?!8 p"UfjMStQ!쫎]I$qr Y- HٜI2NكPIg/Y:co{ ﳢ_`׊g<0X3I] `ع N)}Y*3 _j)%W7W6và:4ƃƄy,"YۖZu&ρq^ƈlMw':;g6@h0$ rt! OUE][5Ywy/뿯]sgX4׽Ѕŋ([)a$Ȗ]MVg"2+8 6ˈCw~d1aTc$ 4rδ(i Tc~9gOAE>Զ`z&6\kAsΞ Yx(25{AȊd@tZv&er`.:)Dr65K`:W!rLX `r SKЮg>ۣ9Q|{$+أG1âHwH ``7#wIZsbɇ(-JJ'ey':yrXO]% H7.G/_QƏ`uȹ g30c?I/45W6å *#(v#ؾSBacF@"A#ȊOisxtR/\&oqd;ҼnոV=?']ܯ.\r(zF+znQ_sExDQ9B3@gǙ1 U }:/ ˭aX |>9sVIU Xm3-OuB AgDh@ D0Ba SQ!Z.D(1ȗ* $RD#4R0`}‘0BT0t @HkR\`r DCɄA gy^/nwG%w;7qB_T8vTB˼I͛tD -C_.]k߳u" E`iѐK *JK}G{*ţ0gT6&V"E$@Bvt!!R1  C``vwYi1U .%SWx۠_^^=^[YΫBڞфiyMV; {A}P@ ,9|hMW,nncLCQ4@k|O/Bc ; c?@ 4M/rwb}eT3lfdX|mb0 n5b=q7'Xx-C8.Z@k *4Mpu.M*=|BC~n i:DL0ΘuEn/|2m&;FIewkٗѨ+ ^U6kѾ|U1P}Uk{] Οsp܆v:_c0LqzA v"tKkfGįiƝgHsL}O;4ӼE*߿qO&ob-%=8^d R%⪅'C0~?08sv,i8Z=QiL@q-,7?K(>k+ "8 H6Fs!>bmkyw70 TVws9'.<(pK&ijJ^qG\nvJ?~ -._y/!]?2CplO׎ZRee;8 X.,mY~ Ip3! c.{y$h4V68F˵B Q?FmQBLӐ{Vg=~AƢ{'`k0Ɂ#oϒŸ5A03DR@@f&_!qA+R@LL+;LP *O I&ȣ6S77UYV:|V#>o͊s!$ C[Wlܳ7Q;V9@k~̶ÊmT:XeHoڊ`j"DBR`ME~OX}J_E=ɦm0A˔G6nךۅ rwc.~֟сpo=n'c  BE\`r0h6Zt|. Ӄ<3~Uhk F"eg"N  @449z'i(N nq:VY)+K'2+``wIˈq.Pypڍ6v1^, fٺZh[k)H(=`+^r,Mm])ό$1^~J jk+v8Sk>Yr^8(``SOHw;c2%9ׂ]wYz\4>IGp%쳞,7boyWlZ9󘶛ˋ{"d{\D! (|j ʵ  g)E4e3`A X`Wh y/n>yݯY(BZy^7p 0cX#C;3 @P@ $4 x/(K_dRP7I+l=x&zQ7hӼ껏1iy/EEH(|$ nʖy3u@=< d  =_ӰףYX*I;gz=4TۑQuy[kHfƺwuG?ݞv/8~N 0NKym_NQgt2 9&+~ D9@ |鐻Uӟۇ=MT#9"7f_my7]Q:k'0R<&4цu^pBïVe `A|XLR|,Px5h5V8&r>J"~'{Sf+t;(Zl1*4 \}БS٢T3dy.%ˬ Ϗ+ˆhR=ҥ/&*E2NW{$gH$Vxd"?KϬC_RjQeEw&"!PSeEQ>jжX '04}O1_#_0*$9rngF!S5HyCL*USmTrg'NZJzկQH˔svI R k~ I[~ze--LX@'r\.2/)Cy{&YIۥ/#~t1+;wqd沴bky[4aZSFHMgE Xf>9Y@IϜ*؝yvӐMWL/HD%oApz9оòJIo.@ ?a#bbC(MK*%==l,+9$ņ^v& G*" Cq ZNqeD.Oͷ+G[WZnuϹSڳy,!͜7 Si[&en *kCCNYJ#7SPtk5nc3S1%nn=-@:gۼ&I|t!}?7ݸA!2@W֤%$הY#˄v 7;\O/)0PxFi *B 6'm!E#1:l%hHQ@P@,y-B zDD W=dK5%W,|Nx T/ˊ/_lt"k7ZS]6pdݞ}[g"8~kX R:oىrAE@3O-R`m=sm0&c/dznGBE ׵9v~ Ϯ݂ LgA`H0ib*KZ5 ӭfZH4  3Tu$Tm3q2͢<@|N(} ápvc Fo+i+T_0 uM}EamR 6YCۯz gyQX-톴8 6v2귧7c 5SB=WS9 JXBIHaSݧ OUS[Q RO!OG/Za> 8^tp]-C #  $Z)"*JP[ȗ\Ŕ+} -zy@hc# ٍ* _28C.HHAE@ItK*2_+r e^SWgtku jv{SU{dk+2u jB'P1ܺe/{ўSX/sMӦ^0Mca:5{WNMU{n5Ye[SYckbYj]2uE5^.#Xr24kQer25k.VveV ak#˨.#W/{ܺ\r25r˨.#W/{ܺ\r25r˨.#W/{ܺZֱ{Pdj{Q]FF^u{HrP␂4C0 F"D3?o42.x(!4d A1B؛VŔwc4@l$H! B.QE%0*"՟dZn\"$̈aR D @DaE"F w?ߥIyR`6hDX1B6I!:pe)1$#UIU$Ť"M:m|Z Y3nH( Ym` (`,,(`ZH `4 #Fdj]FF{dj]FF{,#Ukaކ-ɭ-\0x<_K>OӰa %?(\Z ΋o|mh;͓`/zSd. 64ktX^ Rw#Ö]0z'@W[[b[}ntb#\cE==Wf{g  l7TczGw=3+/Pup<2US4XO%!RdM9Ut]O$R Jg hr^|y+PP bD BzT "Ġ"I$,%FB QHHF,da0 1XaG(tA  %"0) H!KHŀEE D  -@H0v6m yB$O~/z kNʺR#CmM:$Q|n,o?b ?~˞ Ʌ gyv顰u|5cL+hCMu #jS:9q1rF~ q͐0M6؟=#49  ᤸPx" ?3 `':00.[~n~#JKнPNA".]ܲbom9n^W2ѾAL}:r6=N)Ї5ʣwr鵸?}BX7|GKZRaS'/[RӁjTdrZXt6Ovχ0蔖 A,NCqLj+rAyM}PBl?6(,sG/~S31t[^sT[DW%8G| ހC<$%1+?4˷1nSq7 /MU+Od b{Tׅ;VQL[G'{8tnETH` CV ,e9ݤmoik7j_V)j(CߏLqr|Yxi=`I˩nM YyʙkiX<֙k/y? Gl m<,D߻CkL1M uc,g+@˂AWyve4s(ؓ~ P|#OI++$]e$ODvؗK.I;9z>ףsJSgWtܦBͶ%HR?(un|Y0t"T㼌a>~_UW2na+7<&̲i.R]ZLgq uL,e%0, 5oY_Ƥ6DR,F1~(ҫt8hB䶎x`h˥B~}Z^/ XtѾ1(L:qL D NWֲXz7&ͤyM|t qNy#L_d>`ۯ{76:s(GwZJqv{RD963Šo>;bבKENz@AA@PbdAL`u@4ւH$1c1o%]`y,QЬ6[="U\w7{vVk\-6kb.wFՖy ͌&]3?e&T(bP"@V9}z"g@\-{/z*- G\]|ς;J| G6zPn ;PY5=RjCbٷ-vg@Bc說PWw)K}qlp0+K(xt551z<}, XгW/+lέ_)Q:T^l+u6ka.Σ#13Sg^yX{~|V?]?BH,Kn&тz@3`0Ym11mc_k唨6jZYU Ҹi nnzʊKfNaf@}-O[ܡz%t $DzQApHH >?8wR秀96 ) s  d$Vj{ZJmkY֗= HgJMQ`QUh*'=]ZR!!y0SV%O31H@X_SߣRw,Tcb?S]C=Kv^!uC IGgU8xR /$ى8NÕ!b_Gȩս[Ё@ 2N iq g,!!.`%Ė ^8,?yB@b:X{69 %}?Uۯ`9j)db`-Rcr?u&v9o #" Ԣ_5޾Z_ԳtȊ<9 ilSp/+M݌<ݕ#$&rFe. Y @_+ 9=\cR]1=+!.Wx:9 Dl2sǁYzv4Jy}Zx"*#4srF9_]!3+1݊:}{1OEV ele+ӧ^gt( >$ ?26iTQۉc9BE2|w߯k+G'ui DuW4/kk1ȆO84:>`oʸ7i4E, vw,]t x``d:litsǑ VTBJ+Lpp8kfKX?c-?rq j KT^]i?#'{^hݝ "}!Q=>6[?FSraqfo`UX)J OuvC[r{v֫Ierv?slluc NAB(6vj\, syl"MNNoqCdCk(Tg4,፲^y^*JUW,R շ;:Bk3+?dn$>] kfߛM QR}E>Fh:헀A0J}geJ$oV'Hv!6(aSg# ╆VJ#""H"V6 }*HnHxYF4IXZ}fdD#sQ3 th-( /FJ/&l%mxd~bW:<.'LAH3_HZT4;gB*rRheo8"s.0{‚nSHyVfೆnY FQHת愚V{x%j"{ rRg%s$4fXNiB ŲH_EuzEsf !7& mywoάorᕟSn:PyƧatq n yk޽ N"55V<` MF5'Ti,ADvI#;`[›,6BEm#~PD~+t<0*ͷ` Ҏ@W xhǶ? fv)x*sl"cBP B.pqn B@Lg!gv~و6Ӊ x@3C@C0@7=NAiw۳<rv2A"ċa'|+0gN|}~/|KQ*  x[Ӹh:DL__v>2ro +Ǩ`7/օDXH%^8"QXŤ ŦT&qu )c "J"Ш'z>1fg唤vNq!$ɤ,ZOc ~X50=(mLah(&vM+=yF/P-p5#SMVڭ颮4+m+ mU*w(u+ 4`4Ȏw=NkmٹanGQzcvSY32 тGfNs)+{NYU)v8my15jԙoϬQ~@|".joㄦD݁ !Y nF]W䝰^%c-G\ƅT. a:DkY0bOp~Mvuca\%D%@]w T"}s0:Q7F߼TGؚQŊ(%S߿k1\jNLq>p6b;H=uҘ/H,㏨x {wYBH$"m堂tWlfnѢ_ok֏1Hٱ :|օgDǯؾ:Zh30 2I71Ow~' VE#.b wz$l #տQVV w]$cU^ppZ>>~fg3 j}Uj}MCoyUAE06%1>{lJA%xAݼHotK >\P /H٭%VDC ]/EE@@aקᙾ߷Sڮ̭|12Ȯ ZF1xL%LKfQ`}?,iY>z?s>ze>9o=E_BԈ mz3(\~\2H$ܤ.ߦ)"jwM$B۸0Y|9( PȷzVeAVP-Trg#3 }{|e,\_ٖzqtOpjj3Z|8E:$CMu!@$"2#" ]z2׭ϯD+տ$ v""yc>eu߇omACaA>.TyGr_4@:̈)"X$0CGhdz\Ae. XaPd֜ ̄3 t Z-F!`ldVYװSײMnt}To'Yk" 2.<+(#S&0.20fZƗn\@Ȉ"pHb`DIC3LV DN}@ o;i] "0DA{+H~ͷtjXϽe?dbl=^lJz".V!aʰ{4NOQ5e@W!@|65w^O6'< Gr2VNՍdТ2rC 0o7J(zrnloeˊRܾ)TQkX$h]`׋ЃhRYq Բ(XF<-񔚜oc~ I@:lx-^SzOUP'јK?hey|3wB ,qg7$0-acT#IoꚊJ^59gmGRI-u}[s9/L4ǹ .@)N r_҃(=!^qT_X,ӂܨoCC"IBҙ+q &%ظT1|ąFa=gU!Z YV%!LWs@j Kޗ؋"]ZJ@NoscWe j mQ2z}+;VoJ ]`AhB$ /`2/jq6)-(hƏ v<Ř+ ׫KRDQ5xmoZ -11y/8fhءuHW9؅;&BZc12|\ rQfi*NYlxWLlS)R0 Єf`!^u63 .qHPhl\@]6~H1h(4D?>cBF<*P=Q br\Do [8%!<ΎsN,emHE&:dspADgA_ǟE kev+SNBz_=39޺t/+p''? KcBwl"/Oըckq{@6n/id /Rh<)k# #3Hy9HN|1@ֱ&xg-ߎv:A5|s^;y{݂lb}[wpWW\H6h>,maΎ.Ρ."D@8-{k(8D(؞CS|4$+[Z=|H@"}4LD?tC߈ݶe)̂$.N|PPɐʫs]W7`Qn2 AhS*X UD5akypwO>>#Xٻ̲) Wg4йso 7nL1rպwڢLASRм$ ,g410Mk2zkp43&^ԱkU]Q O'%Qt\S.ͥJq=K8&.{HYe"Pa^x"2WmFZԶ"=Z pW{jWŚTPc0=uzym2  5'dI?y۪U>hUnn0CcAޜ!gnԉGx(r[*p_]}/ Scp@ۗjP U%e-SUb,įӘ3<ɒ`A/6YZ#e: e?t0@n|>+-Ir,;e>CYG,S΂eXdCg&rlu1-gU̺%C!p骘}xz7Բ})"l0{+qPD/q}MD<A.* F 6>c{a?Y-C'`/:O|'MO .N/QϮ4,#=G,-9Cܴt)'yx|<9*r2!( B+i_* #[W$&Aݓf7U<1LC(hd)d#"cAR%ߺB3;Etpf QR+H[W@A&T2:;␂ bHu.^9So4JDPVV3_(窡]A+Iw~vܚz$ "@|ک0;'ܲxò;= \@$lBf jߧy|bE0Qߧy+_gPn_qGDy(~~?db3)ln@|;<]?נȊ[LF]rruWu&,q݋Vpt !QXSU􈈇jed'ѱ6hm. [΢gD@'S g6/̝)ɹ(Ώ 6$W;7b/ vy,Hg3,XdZEy !,UhQMJT3W{*Qd]brg1)Rx")Q=<]nVoJ^BRV#<؉^,oڈ̰MiÕZ -E_V^K2o.oyOX8Wn2GR5bbƁY+\.@A=lթK gْmp4Yf:6f0&?d|f1* cC5StDI6TSKvarqJO^O1fCEHvo/%g2tadgA2vR̙!ρU>uݺa.5.ߢ|WߌPq%Ž" @ PS ( {D0L"Mim>Un"@|5 #ph&>ܠ7ds,Z7W4'O [ÿ&9vSl4Tr^gٞZ·VtRNK2GFR(w\,#WiPh3J}c3%(O@'H.C|kU- qI6BMi_ZgEyeoDd䫤Ob ܤi#}@![}ŚGݔ:j\%F4=.#雛իjf֢k"8WOkPV2eϯcpc.U\If7jr=.on2sM7k+CP5UrLIKRIs0w펥R=y:^ig$ΝA&e0gT\4nG(qƦ(j\F-_t 6pL)HM8U~@ QxA#`Ͽo錈[ګd5 k  U9lxne]#Glط`&S9Z3wa߀ٰf*/x3]cԧdkod.;R>fE.YΫ^I@MxrBbF晩@XSiZ$>t˒Ȱ$^?Z3_Fέ hGdfbOݗ"o&7<}xZ{Ȭ2AswJ8૭G}md.U'i29Ѳxb~~6[֐kٞbl\& yYzk,+{Q'#@ dGq1 h5F!<èv:՘'f`Fpx7U&*"AHnHsc`LH*)?_Qx&%}MU3Ha:`\h.UlJ~b^E2ݑ%^8[35'@[f1̮sJk ʃޙmZR2<_`@k RR<&mtm#~6:#Gb'd Jָo\bS.>~6|ĝQ]p%+t awnxкCdAoÃ-_" W"^7/Qpw}C?fkTdyvPmk[ zi\Үl⬟*eIg`c\7;[MhRy(2D-޶@|rIQf| ;S6AuQeD׾&zAZpfi]zblu2̞OuYae,+'jx7Hp@-܄ AuRY* xOcȓE x+f^IfCZ+umo!~oo}p^(<}˖P;B>oO?CfL]/cwb׬,v Y i ۸"deؼSۭ#nKcs_ \X|A1hyno&<- 8JkpAShIj; ˝g/GPTuqX{8 c ge:aG-~ކ}ܥUuUex`{hQs+8ef~~n S a`D;+K!.x@p" |RuvR@Ђ"(-j]߆.ğuܑ<`Gq 䲯n:hP cЦ􁫈˜!z$ܮMJ^J Y"$U~M,1)03Zfx7o35@;]q@`4!e"tWad/hXvxukd7I_$UQ~dN}̀0CgkHP̒Tf ^d"&cg@Gв!u+w+Ox ]ve޴O<="CzM 40_ ީ @ (, ?Khy 4^Α@ESj /ڌr ]3%khZ`T,@P MNus7yt; q tm9<?niNv8)ZJ&};5\W7w'IS/2YdXl]U_Wwy' 4uo١ef 0<uzdiwKf{Itfmswj)]\؟BCnlYе82}{zS%؋0}ڝ?#46Ԧ9W>g@eI8?m vK<ƎPDץ]uCWU]#og`bHZq4r^8d8s%I>:YY= LY󗦠E!Gw E֢sYꦹxhΗfYَ«#rH=R>srW.]ZzB-uv7˫qtUJT%l?0KS^B͔3vVEAh4qڲ1D/ADĈrX¼el9'濾cSfcXVZpEJѫFk0 递@݅bj ݹ VC @[տew-+r`nEHUa0 UGQ6o}eMx,[|wr A būVT ғ]ޯS'һvx7U h ,rsM]2XƼP@1 nMҨ,4:{ S=p1n{,kuLN:8Wҿwp.Fh?=*Uۧ&r_Ȝ|Fh #+nnd ,1%dE""Ɲ OygYLn<@[r~7cP*F!2z\cM th$g{kމ2kqB!S:̆^HoB=bS^I"%ң' ,Cxx͐ujʬ7|AKu}O˩u-DXsjC7h[?bݯۿms~E t}oQK"yr]^GQKȉpCg|N;믞LOWp>Ksk(  @ND4 8}3}i@$EM)Q#h$ۥ+WwyCz.S}.SOca3o%;Qpareib&z޼{vXX rWk۫JwjN=0^u 8qN0ԏZ$ ZuXeZ]^FZ1(j`$ۖ. 8Q`Zn ^F3vp& ݕe^. Y< 0EŠ`־a1eIWk`q隒4?SmuH4/w(y# Lz&#\p?TB _~/"hèdFб#"Z6T?{dZDC;?Oje]Ht讟F#B73DZlARyd ]YBXg8P+yeva>ֳ 4BuKﲇ[(*bMR;GG4s;nC04ݵ'Ã\w96N4 E!вE;0;_Т"(&DO =o{'D4JOg) 4X 0d+(a`7A`TA/B{PL?[{Q WuCT7V ٠͙:kVcI'%$AAdVMb͎֥Z6& <{\)~J4v QD..=o3M Ϩ~U44,q~vگi.'rI+ ߢ\U&~ΒOpT?Pq_@Oe魍Ƃ_ ySi>p]"c1b?83q:\Y뭁,'E9#b,dT xa[:?~/2}9sh fd J=-= ܉#6J\=LFpQz*2Fc bpaD03Vr/ 禞V")I퀹99C赹z_n~*`tWlB3MAcikdߡrQJsDUڧʷPyUG%8zN_{'# smSJH qՁgUߍ|JiíYsb>n!cgʷB-]?6V?@B^k  ,g"Ud͠wVMJ/jt/7NL<OmY}5 uEqcctEw@%ZB& zHzE6@ZyE BiX n3dzLQ0j)1=aΪdQ=pP|jOX^Zج6@@w"6Q+ i,6.orp"@ n-/@B"0D8 O:,~kk`ZL2uљ NIFjb }lOrg |sX&_}4WP2hȐl\r{rZx|4XF>PJOdTh]%u)bp EMQ$euM)*_Q) 35=Pvl:iٲ2#ŀ_dg0Q};(oU g 9:ͩ!\]Œǒ 3[><`2/9&]ڷゟ\(k$C-R@A3c~O1=o5H!㊫AoڎlĢ3P+)/ "ɌF*6$YRC؜Fbx p }СыXIQOl`bLr怙>#GE(r`tt,ԼՃI<c|d.l:FJ}P|Z^f9tkNV/,S{MhfO0bka:ޞddD$Jރժ!)-+5NthZHgɦv^++ߖmv34-^"u{A v4EljaAo )h/B(#|enРZ4{ 3t}ֆ0,"5˛ywU 5,:>_e䦄!O Qd!Rv,0[=CSN>!U+]U\&Rp[Ku @i+ kNc 4Y#?FLYT:#U(<9)xɢ&&z,BgDmnn˸b5_J\s/Mb5:wrh18pG`@|5u a jer"{/H|H/q0.ˏ2,qw6jN-1b"0Ȁ!9홧́?#^%uTӖ4 5-R"1ZR~u)U[ibL|D?Wv:Wj"u,0n=5f`$!}k1`I8RjG n?y*Z0#E.<)5G}/fV~w' iPy$Ptp <]^ 8dݎIaL0=d}TjT7|KpwzY;4׈E$̶v.Es Tx0<Ab"WiQ:uɛ>I[r $ZvE)vs59fgJ>uY&-0@O ͛cV !Ffdnq찰ḽ9[Os|¸#n2io8"-7[Ԟ9r~Vnb,ԕ` S<@:t4b˹W"cWZSBˈ;cY+Nvۋ1&5#üZvyӨAn_8P׌tv$ILԃ,~ sJV>=6qFd ;ن} 2NRW.Ӊiiğk/ JFgpG0[rQQ%4ƭ)9J_bH@9q^FM?1;0GVqk/ҩH|yyBȇ IC*=0JڱO am=10gHf ImmLʻ2DEj<~k$9=\QA( 'A?'Df*@rXL% N]PDQ pJ RlTؔ^̞z|hz3?"Wʢ d Q3٘VnFP}_kIqUGCQL9fѤX3(i I$%i%@cĠPqT1^IN!IrOwLLqt4=[QqLx'Yu!~Lbt!0= 3.m ï֤(\1[#lQ?g nevU{&5ԙ +Uf[[q(|DD8), [[%RH: h 5'MKF)Za0kA։S]g9jhj*Vȩ=1ZS|հ1RLgu>7]i"F}Tbf&ٿb0=cmR(_H]@__SSQ7JTTDhkSLBd.Q7 Tcطb8p0,jW~L'"^wF48!g^^+"S5$V|e҉rjf^V {'M 5R4= tZVVAIqiSQ&]Y:YĞ9~.Β}J} 0p?Y`lzLEF|t!Ս j*.2sNejy|u)ٕ0R^_kOݘa="mePInύ >.3S ih, Y.D_q o*ݔ9@#җDU4_ItEPG@N\8&om?;7-aL,:?-CY{ H{qTA R!] Pz!TbVa(!˿՚`Wi t|gZ$&_ŦQ6зERka5!;_Ulkn[[36.%]ĈFۛ6}tR)J~*Jmx~fF[R-TW@sQK$Xpm,s"kf 3}u#\k"㤳o+&8ͭi^)j D@ Gj(-~H닇xY%H*k=id[Lb!X :.j!Z@mAtW8@ w-S?H=N[t *N* mB]kO ˒ppHub8S=#ngKJ Wj+2U^¤:Ҵ ;O<QA#pxWCMguպW<|s" &X6u#e]r_WF| @j[U2M*+GmBݩ X}BZ^u&N- 3Ê`v|S'Auul}aKF$2a$+'Oj]FG&0gAfz3ڢfdds`0̙"LW֒ p nz^ȳlcGfZt^ $2  ;^[d>]!00r*)L8^6& wҭk]7nSwrYZ=7ɱ-w7pⰙlRQ eȺB5ΗmFzV dr*5L˗!ϸrM4*bם,}4:)-Hi&W=u ޢŒ'H `A X+_@zi?L+)˪Z~ٗ+Lr EI#RGw+C]s <#5TA$1;+?(ِNcP[8S@6K($ocQmIFX7!; uS-jqTɜk[k.=_&܁q';*f*5K$3NͼM7t)8MۅMZ$"= ŢR,TqG˝0ٽ!Ϛfijz ee/ٰl_CJ O`~4_&z< BG6gS=Xq:U O~<#Ӱx'K ]qoRE )}|HJC~lVE73\H30I%J6l>?*n wɌr`5xkc f+Q]3U,j>p=h}d2aQkGk;AL:To7QPtB$;3x[BW]cz"d:Ģ;>KQk|0]y$LjyiemQiD+{$@aAթ켏poa~׹Ef(* \C:dW,@X6,&#bgr8㥜/l8L_aFE]+H6Ah}oR!C:s0GbͿ:ܧy=o?>@Ej1 ⾆;%7ѐqk׃ ,pxq#S_#zIک飸*!WeB1**O0qKa*ibb|M5?1vOes*n=8'0(cD,+a oO)>CnCV1wT<3t4$э:0W-;Q߬~hI̓(;ޣrd9bb*5`:n ])in1oO2P߃|nru=WgI  $&q2լG(XPO.jT҈)nvK.q+3xF-ߨ#I+&K`ڌQCMeRMُ<)VnW7v)rvJ>m)Đu@Hd-ļ*BVs_,1)J#l=K j۲z]lnpW{J+"Ƴ f2";_Ѭ~TO9<`̈ F kdb|9+lButNa5B )6aOq1#[a"-OQ/1c  cPF.K3 PP"&0 QLrQ 2sIP|; v:ǰ0j#QD4W6zXI-W#h804J4} )k7d\[a2sR;N:U.E|aH a} E8Izrp).j;%1I:wJ(Ue k<]UӳfBc;mC, {y #$~n]G2í''5$iqu.J0`.͗8#9bs1 u$* aq>%zV:Ո;0,OC?^`Ay@DňBI,uŠD@a!$j6i>^E7YK{jdFϱk_WkmMQOXX ?xX="$$v]x}TIa[?G.etG(^hȅ}CfPJ@QQDgB½&)2 Ei\uzou؁ĮM5 |~*b`U i Lkw`+ML⬤e} d\lTSІXCzNwlRc!۬wo=I}6WKr*28x2@ѩ}NJ⣜_x>ˢh?ʤU@sR|J.2@z33FGL|-&(|SQ a3ǥ yNs| gz>%+0Om+C?8;ajOH^-D5MT=[O-뉦_gr̀0&\! lB:I?}\$LBblH %)8|Olڇ]EȟZw[  2j^%dܴDMJİkNVSR{I5]ߤOՄ|+!YUZ(YWv]rǛsPۆ6ջ~`fHFҦ; G:E 5rؾsxC {¥Wo9E\D+O7PQ2r^J=_zY/hC10rF n3tL Oo_d() OУiRfn"5ۭWe53[,蛒ĎBfu19L5t*$2Ǩ}Yh1ZA G*n. Eum~_xŪȬS`&x +u͹6_|(%焺]˪˅gxVl %%w[I̳Ԓ&,C^G0ײ=1^B|&CSF &9+zg,F;4,Zzi{o  {#K'c`Qs3 \ }/ĕ1Px Z팥 ͛1ch8F3XĒk'f̈Me`!m:`v" pK| 0Q~Uc-."l<;3Àܱ @ɘn H{" z&QCOk%w`zg]&]c"#_C@Ű '`|VuF+JMF b)1E!1rt\&3R4l>.5~wh_O?*ѯfRb{Ua}O|}rxjtOQOPppq[ 88@@9Jl7t MihqBZ5f2"3yaC`}T04l20sߘKZR6X@ꇠme%>=&..C`z%3_x ./t*&wUoD—9g3"XO ("ہ_gbJk')s8&AʬeوEN:wP79ŻK\+R\\/7亿 D̃'$i(!u,yF6C'7u Jk@  *wIthe4h iw#壉:"Bl*@61a^WmA5w"80EAIYS\!N:_Al%DP;y W` 4_W[)ΈS>;dUyV)qV;|'HcDUwdO0S[ 'J yя5FGX׳V9 F{K~5STK}y gV\GEȅc\l+ ]g6t[W6.jw.24g=|j:6tqxSZo3)R:9G4`+e{ {N&Fģ2#-J!W27鼪w4,fJWT^Љwr/2C橒}RW] s(8eJewApޙMrb)Z(UãbanGWف+VźĒ n}m0#czn {5K sѷg1僼zq#w-9dUNGs OA=i+T+#YuҴ2UxwC3C!5՞lQOw,_ēm\6h9S#Tl.lيCWanBpF1ƇDt0?yBʝ:qr͒^0[hX)ufƯ hK!#W`p߷ZcG'BUJ/uM̍Tr&wr?}0Et7<M apѲQI&"3ef6[ȟFX//[MH-XV^|8.3ZU8{k .3>q!$;. ׿LDQ^3);?^/k1OMT⭔' 10Է__:\վc׽$hAG9*ݱibQ)")E 7|yQ,c4B@}ēM]xRSh[3"X.v,"S9{Wps~Rkͳ؇ͨΎ,TH !zIPO= *8~4N@^Q* ^\P*q~†baǻ\,,h#L9 m6brʡ~/ D3P` 5;iʖonz2:l$ `sCr@7F@&51fM{aNl5_U_]+5ޖG_|&xnq`e\Ĺ@`݆UB,M ]?XQŞAom 9rs m, ׯ+yHQAJH@E֛RJ}a+s)פ~3Ttugkae:?=FKAjrrMZ<@ &mT'+e*BBҪcLTٚ,X%\9H4HdF@N8qqq3PhL [d5*!t A@{5r.bى Eq VBHeA $0lER S~/(d=M*)Vˣŵl^Lrī)_!˴֤ffk(n_=B3Abo,vN2&]id-><7Sdp4L6[RzQA_6VԓqS]ZgzQ!ed HCk#_4 UU@"6 &Mhj[~Ke{qH6_Qvo3ڭPI":&A;chfx/,s:˺]&=_hHl= qF+;M[a?pa^\Z降-SDPNٙ稻IaKI/Ŗދ_AE+M`u\S{:F:D'/_!xuryݜ&\6V+n0 d ߉yqV|js-hVz[^կh _*svኁ,j)7{o]mS)hCP&C o F@:qxkS٭6= Ӊ>7L f]οlxSAB݆%) J$p{ycj{{L\JMt㰗nE֨ H}W^8 4ъ~pd߰w T+KMBm$, JNbGz]e|Ydh7L5B7yڅC0WG MH~vt3ǫ(@5}t%#)}bҵ pƣ_w|!aIN‘o3\BVWRYTRk3Ecoh[{NgWQy]cw^ljIp$aR 1yEY3s" DA'섦)k$sT3OsD P֞zx@Sb`|K5'3<:zZ^>y \5atOL䆓_$4ɛZhouRTfDMUQ|~ɷknO5M*(4`5Y~Ʊw7IY[v 3;ek=P3(@,vHEᵺu8e[Xn* {i}hM)Cp&D>DB7g5U<$u N"rW )UuUsL: B@1)/|ЅK=KpOls5C;'ABxbSH+9|<̙̾݋M . "иbڨϛ*FOܬoUOVppC8~매wr1kxaWIv.% f9sn6*W<ѳt>2vFplt;%뙸o73C`Xd f*P *P $E "1"@A30d0@Y3(ɩ1&t&%w_^Gm#b>5]Br{/ǻ$mV'@5bײx.9 yv\9<?ZwϭY̝8 w;պ=5 ma?sq洁?*1xq=lPX ƖR" cxzh86RnPIY)sΗdw~ 6?neITGT(ŤV@.6NdSo`vQ{4k5ƥ 0v- [#P M:Ӯšx۴8ąwwϟ' ZLr@6k XBOd+H % $\[  xj @kh8'P_^SLj=gH ꄒFsDpML|$/zD.@I#ж`.GD9o!2CMkjqP&C^&04U2F3墧*j /n﹂);]HRPa &DxI@!BPPV X1U4TS`< A,XDRH@ΐ {;Ordhi),`lMR h`,"RBBPp" b "$A 1B(F!HH2$"@"@)$Ĉ  0#FDVb":t\THD@AJtݯnLT4$p !U0\aE $J! -`q$MBBWLBTN8nI䭐HA@ DR]b!0,e׿t*(dH ]@RA{BCH*RcMũvCe( JV CAnlLq@3|?o:*:'Nk{ɪ<T $&@ T SJ@m m߹ N(r1B,a,FK#I@`A IȂFh~.(]~x;ҧe7n ]v]mM1oe3Rn+ ~H6_\\aͧ2aaT(Ȅv0<زV\_Ӌzs#vg-^s*ϟw5s)͞DtT]GʲzcpE׵[v=*^YAuOk>YlX}O ʴbPϕ̕A'4[+3*s"zL&{[v(L}y"\'j.Zmf@H&UqCkmӁ\bѾٟ+N&}O.uYmz<^PX9/BW:R#2xq1' ŝ%cbt!X:#;=iBeKAL$fff_Qn7t2; >^ dD(AxcL|K;{F6}SjrEPZ ?!5 @9hR3,dH7$ W$jL!F+SZ9 HB v+ڮ|^Mp@( B SxwS(f=^6jb "/+2@`yO㋹Z"Uggq@pNrd,֥ۀ)4V'T>٩&SxBۈ{Px+2 5M HAf-8N`5,6aXWam+ EE@2 myٖ2d,@c/b%j='beTi`iBc/i[ÛnH*zkc  ƦDb)w{YUݪ-A&b$"čDw>ΓՈ֮'>@@HBB! dDDJAA 8^:w_~t|N⚿jC9W.ީj /;wc KPaYd7 B\G?;6'x?~"{OE:H 7PEt}ț[<<ꄞFTld ܍>I~_Fdޕ*G;^i:߷ۆiy3wewՀk&`R{_gqZŰ_DUg :Q`d {G{(ECxv SJv&V𗻅wZ^+B/`$j݀D=twwm%H; ү;6Sš ۿοhsu5:D [f bWPPb> /k [L?yB!RȲ$"ȳ_0Ap6 0*$ W+Q@($X)>MP64"  0&/&.U`T~?}oF#i9fvAo2A5hCQ_b Ks,M/MMTclO]oPchf(&ԏRb$uP05h06e򨣎eIQL]|b-0r}ʁp2Wu]w LؒrWM.H/uPXytچc K_15D<#0cBǶwͷ-;JNR5gQRnUm &@>Cfǘ@} (f/`$ܠ&Hbs.Fu%`F6w݈R= d*B`@!$(R'wEiVEKmn<,JuiܫTˇ#I2? { dXJFchc dQRRVP c`dX$ 2H@M"HE47dQ`"̦m6(@#EH-2S{IyssE@՛FG`mcUcWE Ɣ\Pk@bD C$ePDIPIBV 8^4ШC&1&0chi !t](DP&} *H1k@1|y~;ssy߈{vVDA*i}|b0 hռ/$K4o8ܒ8'$I> (+F1'mub=EYo.{4hzhYumJDSQN=+ozxOnWApJKynծq)XN)5=#~X Ej͊a~.OŅ]j)`\pQb+`ĂQcB(A1E"(_ 1 @* H zuxLkֈDq8b4G#ƈDq8br!h00/"%P@ !(%Jn.,a) 2PsflHDq88h4G#ƈDq8h4G#FYH*( Jt ^/ !QnȿIR۫dAV ?/^>YsQ1}x{*A) (TK=^h!y% F'Y6D,;ZZw;ʞv:\R4H`xkDT$swXSrD# xH`(lwA y̧ѧ<%%?=Lɀ (@0 P= P395G" ̱ Kj+ 2].uԆ h(~ ^llDL-| qq@^y4fB IG\%dxaU P@`qKаPaB)`m0˛W|}e @/r`Ay62ECq{:uqH |7 pJ-FN-T,\\Q X\N~]&Zɚ!ugH44 QiS‹1 rr]JbĈU({KH&0 mL}{2%X`i$#&ö"Ʌ]C# p`QbAnF1PB2'O3}>myE&Ь"۞|_+\Ew@U57N>~<`T%%2R_҉'ZRS8gR_b`8hOh+3.MaI=DNyXy.J?7gL\(Θd~?O&{)!0]*68N~ >k*TE陥gU$$ K25otAx逹LWLP7QRPwtY%tL΂cCT<)x 7Mu9/ ጲXDis)N38ٸ\x"BH-YK^Az!MQ+hqW ~eG>4D%}X6Nrpozشq'mw;)I$I$I#p$I$L7|Wgw?B9 82ݩT37M`=7V S5~c-Me|2R'RE)Nrg[e''灥R@ː?"@] |dH@āȽ܈Cq~܁=dH ~,RC }*@ ~<$>6@Q zHD IH@`&Ć$}zN(PraR1Ϫy4"nѾ r`-=n9}@**`֙bi0d"!:9@\I#yz|w/cc*3f[!f܂9,7n %ȁ(ZMqH0Jv;ew!L(8it1NO }ϽaG9BS`C[(QpMd.lng'>"k!W.#߿!Rb9:_> is.'Z\ѯohΎصu/{rUZ@۽q̿5xYjэDii_!dy-" ؤD:Ʉ3Iél-?BW~=%< I2r pk[ݍI:hH^2^V"h41J9?|04_s-ØbFzYZ7;-ih|;мCɶ45fyMΡhp !"#"""dH^!kܢB,Q"&@SJIu !a)tV0j45hDF xHID[ A/Bj/^ pu,BՍEdUCtj$h]l"v,3FEi7QE09yE;F:HWp/HIss-%;4-Lռ(Rhd0@zW(BŽNӳ!ߴz!ɵB߮HHjBeZg6Ԫќ(s󏀢JT\fvm2 J_Oϖ5͈%% Ih0ܺdA؃t9Ǹeu~zz[+tl: ̏h2!rş|ZAط9W\&?zf8w8i_/f8"LtUif֘Gʑ7GT3xoYtZn,F?>{nϑ?"x 36fv={$=ā!~vY27(h)!\,9WTr0l  M pcyn0ɶ/=8B \wic_Tb@"WV4}*xBȀȆʞKA߱:o EL/'l+DOp{p u / `:9dB(-dΥD[ɡgb6bHq R"C95.2PK!C"PRՁ!=xEKHQ0R۩J 0H"PP#[A,ȥAKM,@ "B) EpI *)Q.YQ뾟qO~Ͼn7;OWmǮ)ݡͺ'BZ$BantUQ~.sDdrDw칛lP9@2~(c sV,(J K)$hB \{ā""@ `~il[Ao;@.)a !K+Toxȧ>'m R Eky}_ݯ005E ~N8A7(Eh6tXj8_EK/[|u*\Nm7aPEĬ"}f]S@$X&t0f&Ld/9 ehRsOr,t?ə] u~$P"ߤR(M_hOրz C-d `/e dxzJ߁2lfuooa'>,g ȁ^mS.\{fe۵G^?2#m3Dž,NlE>4C/Ob;ySԌQ*8I2VJ {>SO6cًhg_~}d 4FQYBSa5fmƅ%#T%#/A;kXeOxO,Y%؊]!^kNrHN ݫhf]spEz#Z#w(^0%Q(@ꆥw)H4qV8hY;j#G 9g]م9lN+7}}Y6b"9 "#0!PB *]zz+n xgC"2Ε smpꢡ]UP o j.F" P2,ò/^|eѷn?^?G @ )1r'c.x<.}3q[ҹm.g(+c 0M1~Io~kl55m>?Ξ+ /0sdJzy$nu|>q~n^֛+y[K.T9 `+ѧ,Tt*nIxg>SѼ 4K~`J|f`bWP_t2^Wؤ1zf `$~TXHENP^4 [ȕ:d(9J.WWob'g{K{KE *ž L(c(RB(r 'Xa)_Ńv`z@-` z5˻w`T9/Z-ym;>';h=tVìO`<'-'6h)"`c!P:|F087K8Vij`9w^c忳x؎; Ĝcpȁ8(U, Ō5k:OY<)=C_BYf0k $@Wtpm:Yy%9jH *tH_t0Gȉ`G rDACVT44AR?s}GI>n|o7e!C"Du/tDa1/S`/dY؛mv ) 4]EyQaZ#ƈDq8k?\0\Mx~q We}~{xp<9k~F_̷۴d'sRX(@F)UM9sPJ$U5F8>xɚ5$ntUS'3_|ʝ6IJhO]=r哧mZ~l 6ػ!qW*޲'=ڴD7x~~ji#FK._SݧwU4~xv@ ӱuwi5wmq,,l %*m,zVFK?A[KɾSczZgY .xu[]'l~%(NÏ[:DB^865kJ8;^w~o:e}Y,jҦB(@ "xmܱa|EynWI ;q4t[ 0|?N窨!v`ZbN, w~nh7.iC` d슑ƕh/z^mG9Xe_p煫XVn f-вG9'~pt`P~@Їb/b(TH0#  (A ȤUHȪbH(B2 $""ȫ">}̇ sN*HH {]{$E ƒ6-hU4,QHH d .1,B]bԑ.0@-+ H@ !u&Jgf\Zc~_ jZ ^EJ 38!YW5!;)/D]ZF,Txj{i /CYb~>ۗw%1/kOhF8;1;b*VYyh2}?{v(EԅfŊcÌxZT1a8UҸ1 lTM `q{Ք Xp:EUXC"C:${$f?+>Lf<009 şwM1y{`cwgb@"# ݈~lNwYe Ւɬr<ˠH,%)E βKXNa*j-Lj5Y"2,|;v?ik 5TKɸZRTkGn}ĺ_i깬\rGp&V_AAJG su_/o#bX'>gV"݅zt_psg nd(RbfJ{` ̱PK!f ޾|>CO U0qjظkOZ3Zz^+^3on-hҐYifhԸ֔,BD@WT.jG#L.0B3i7?5pw]GD. DC}gЀ _X+$DCi汊93 P`0 4PPx<#ͱ0 '")PC8"j ̰Opc6z})]2#xClnp '1󞈯>EQw(8ii欖w94 Th _]˚z( ETB 0dY*B* 7Uz&(]v$vؑR;m?G岠@DVĀAy,dOոb|=?+^ʎex!B@*  D"]1ҼCKWhlܒW!R1׈ [>3: 5(2Ûx7 qbCGzU$WE(~T宋 WgQ隖C{-@x C`Yḥe-ڳn>\<MvpDɎ+8i0jTؽ{'S`_lœc 'n/fဃ1Ќh}Bowz_l ysf +MtP`Y?}n1]K.`xo\Y.[BPG@ C5ʩopfm&cLy;]"bC],&2ܐZ]Q>Xp0 $'iߴWeĜ։҇cohLDdm>PID(\=_}K$6ߵDu%n)o79  0[6w p#`:@Hq*QkFl4ƀ[&2 VW ͻ"j{"9LylآgZ"ϫb/)|zq*w]bMݨ&8VC զHWrWw󾋚/=J"BAUTPjiiNJ O>F +! kcJ5-FD`0@' ^yA~M~whS=l2܋ .i9h >vÒ'-d7H/6W,- x ܖ~ R4' 6gyҨ=λZ~O&=1)~H-hQ-IAE:ʢbR4s;.Iu)uipAa)q}>*lM(.亊gd US,d_A|~)8|^ǫ4؅ɽ687œwS} Oh`znF;fqCS%#GQ J3d/mXc2DR[wD&du*q,+d-_L6CG<̔Nɣ} F~Ũs%v%%\9㚒5НozcJYcapl4gZݸ"*U%g4βz.V݃E>w+r)L󮙄ݝlxYQ/G'G&ž5v#4~*LUڸ؆cQr!= ̊ү({9A?K3 F#湟<P'}ח@0d~Mx'-'@2Y:bWQ(I]}s|~1nV m9 c":+ Sl- |,א}FD:T@XgL,ڒ{Y*v+L>5(H OϾHoStMDјsr֧g$>> ^Si^+_ ]03{}*`#" P($nHmCQ<-&H;f؀PQݼ8޴3#/jHGޯ=bP@T iIa2+,MXM1rjCk~TP4A Hp>t˯鉛EJ$lWϻuh_78= ^zׂ;VfP87m ̀B@)( 8k5JɞwUو9]vm2@n.2vGϧ-~\Qdfu|^2+蓑?mOQlɽa)]%yP@ț@%v[e,t^箛^" *_*v! ɒ i +?&ntȀ)eϫ9[l05V.?#ue8~ZOMN1TAӋ!o6)J]WBuGNcbac44kd*T٧7¾0iqIF0hfKzɕnۓ5cI0JiHks*9fO1pDK2{NګƉ/Ŏ]tÕ( f^:l$Kt^xb5,aOs $۠JMb9;ߖ@$%  <aRJ.:OP`f;j&[겪5IlɌuN[:Ő2~z%̑A5Fnquw{ ȥ16܄AL˚GwMoYe*(uTz?c9}7wf+ivUk j~:+X\s-r49_kE_{A6-vdźΦp{J.*[?YXiZK Ua"DOd^~'ǹL}*TEEPubOq3dL7LCQH>`H &i(sLׁ;&rHMĈb gWd@\_|Wz3QǢ,ж$Ь@"?;^ɟ^/ܜwZC!UUKa` 5u,TL4{d{vb-qfDUZ1,RwE bT l`F@H"_B4jjNEB0Z6Ƙ0"08!ۦA%bR)-M Fm,\E6ݚM8 pQ [b#,(Q@S4N2qDM$P8Ox0g~,QwaHAhd!U!#o01A?9rGw ڑEæ-5IgRA`b$ &즀"@L-A1$ @`"@`A=7_^? 3A+ѭZs [nM_h,A0 @C sAH@ CMK' D rBjfސ:Ԍ1XEfcD 9uB!" dD+@TiNw͂骞as5x ` '\ $"Hr+on@>/|* cػN*@H!"%$0DAxW@scS2A[30g$I !$!$,(ɻJ1 PW_{݊Ps AhHr6J^-,HU! D"wb) ")`Ns=o젠 $ t31v, )@ u"NEr^vBSZٻƂ&hDCgyG# |_ stIu*`Roi`l,|MF+sVTU(;:ϗ$ xHlul0v.t Ay!s}wΎd5||&Q4"zantejddUlz3)$Cz⁊_3}d c!HEh|G"zQ{il`NqL{ H=cdk )cMiY0v2+ؐɅTv@Z]+pñLwK{g_e9H{v+}ñ6]K-AвՎ\)xȴr(pzMeU|@b!)<+VO3N;؋=tZ Q>gHq s쎨kj…6L$Rt#ZQfa1ei[ ȫ? U BAKSL"Ҏ,n[]~|Jd"4 "2$I\6m8k)]loCִX쳚uwmd0&@PpijTUH0dha*! *HE!5Uzl]={[B eVI'vv\Фv"ܰ]z\RBI&-bI(= O5wfsR); EΈPKwuY5G"xujI-p9 vHPK,? OFakKjvY9,.haBf toM} | KRU: [D_xs_H rMs93JE33%N-Q}fj?чJ1[zBRA F E;_ Y6HHY!͵ASEhX/C@H rV%7W>BQ0%T_P_u߃P Ғ$1+FD x+cy?o?K@~C>ݮnaNiHz{`% "@ފRJ$I`EFAG3$L ?4#+԰W/D= @@}P<)C 3YEAy*9* !tZxDs]+K`3ԩ9\3 T aq$]0rksڪܩ+Vy ޭfȤIkg|VunnUsyDCعR-Ƭuy*e>ab`C5 }xsv$вsz.aJu, ;|:X || qŅ,K@Pr@[pDE,P #U`(QJUu/=?Q_*k*l&>k*pU}X&0oyj,eE`\e@ƼQ84gZד" KF#H|%0KX2HEskJKWIk5CE[^-veFew9*:ׁJ!3Jo2h1~>xЃ;e WoN*Ǵռ +R&HϷb6 l\_^k^0{PhهOJ1Т%h5-Đ\?gQ +0 P&p-"KY ] \0ck>9M{`Ov^\8@]uk,}<{3ȣmc훥Vpm_},x\]~;6?T,rTy&"UN6Y<院hʈR(A1Daw;"hǟt8򜯠W!UeW*%qF` %4OA!;,gޭ3ygc}|mşkXo΀Іb1 [Z. zY'pL'ʙזr>_h-my~~!v;^% N((Su%$xY!eo8@B܅F墔\,KY (B -ѠA4.oP,l$֪Ġ`N͑ a AVQuTeBAp iځ)#ld*4 ]f0@ .ET /Zu6KX,m!{c_y\+uP6@ J,%OJ^Q ϟ^fʼn mzNY.`h HOU:/2E)`^}R|剪{0qz#a>BÛ\yD ,N x>ߪߙT)ZNDD $X*?;s"lfXT$.l-@4o=Ӣ8~I-tLmv` s.m! )%q fhڜM ᨽ`7uo=sg/6L%9uYV߿8}۞!%BYG0,A, lF Rȅ.X"8#$ŎB1c, #rPHaPY҅]-ԆiJ,5 ڍHbb՞x*r!"兀4?jO$>;>u(ܞ)<>K).S1pF P?91qBks Ia,tD$ R1Il@Pj%QF$P$X"$,FI*!P\ (esԂҤ*%({znQ !y1J) g&a~a"E(A!EC$D$8Rŋ(Y$"1D, (A$" F ,Xщ( P@EJXHB؈o*"E#"Ȍa1)S?p"3g( B: f:i 7?m.x$3Ȼ"0eRrϑP-fY<g޽DbdXUH1DHEXb Qa@H #BDRT7̉03!qR7[qݶGߓ ^@NB Kp:1 (R_BdPtj`T΁ ]C82$/@w}*"² @;vj~R;V@3BC/?>c krypzd4 @ VH{>DA=;C3i֊feݝ:2DLp`Q KD"R@p!a pD# q srRTjQP1b#2 H %@" FEQB@)l1DE YRB,M!XtK`+JRlټ*B(/`aSA[yK?Or"r ! ޸=J&\j x/O~KoKw3{6 .JZqv`4}1ԭSQ ;;ckHpܩMNrbvL`Bv-y(l0lUH4BqVGкHIJ!U6!p2 i QII}ȝ/\3ir诚na_ɥ hs_mԸiP4qҀsa(I~gfpH^觡[F9My:[;_-Z?DeZ_wxZkjQia\m0Y2vnGcr*Ժڥqb1ЁVF~Ly*luCx31UhuJM髀b:G7;'}.C XC`YE0`B@> =4@+߀xRD?Tr5ײa)N]UUTkU=a$`"w/@ "jqy8PC"H" An]CqQX"|Oߺ 5̧{ڲY3dfë'nRY<]Wt ~Osjĸz/V!3zR/_ "D"c"!݆9y- #"H$ A "A AB@H_snqvD"1 &}Ȣ`[4'*(cУr+4Drv8G$%Lb  j8Id2"ibh A!mo>xQ1me`) z N~v޸<)μadPӣ~T-80AsT`(P:cgn9^_SmD+$TWiY[ȭBLg^ W$KfA 1Zi%Z#P.s!%  "Kb sIfȰ<m)4@6 Zq01u@8a@ާxAA(a"&9'8$b0"']: Ȣ m19WwP<>ȁN>o A%R oKD*z˩1k xeR `r@Rc,gQ×".}?A{d&Wlp9}PD Ւ$Z8%"Z=g4Y?>P dLjmd$9OOYP*ZL8ZfehJ7)p|+M0*y*H Z`]H֋_1`Đޛ^8OϚ􅘑sMv Fq+( 8Q)zRr15.PlPf['Ce&lVCgm?oY;ORt4o1x;}Z)5d ǐ HylY TT! [ 8D_ڶұe8ޘ0Ny8p(C?̭0r}b}>/tEAddΔ3}IY$R'ꀗ=snoŰwWz`ڱɚAw Љ%THWb3+tc+7<"bW30| =ű8bDC$N)8Ncmane+ @U|Y/흝u6K霟>qzn|x 'w4EF!L@/>/{ TEA#F.-D,)$ 4ʃs;?qm2y%{HWNs *jD 9|K:>I!ţۦ%J kQDdd5i Av9zYdfEnUdoD0))inAtاvHp]f@ӡاƽ]r*,L0}^@P/?Lpl@ =DK/Ay2ҷ΀$_^uJX@#Uڴ]K?'O0L^@B O)yp[Qެt-FKANf=H&S,0ҢR@C}~'àur@xtDG$A#th!R ",`SxD A@@@u} ]L[\~1Ɇ o* $24hAD% B4I(@j-J4ANcQ|*@G=[Z݇j3>jz^}An%UU,'K &u`ma>@E9@3FKu$AG#hcXiAP U c)9Jf'gQ"-ZZv,~!156@ ޓp9s=Ōf@ĵ-r'1` bQEha5"Dw=AR}fm%<\{lgrÆ7\nmPkݘʴTR~[77ytw(fTNU2sNgBE}6iL)Pe$p@;?0?h{Rdsya@+Kg8Ё0cE1,rg&1CFڬ.[HH٭N;ju]oѕ|d٢F*,HGm:e''}iOE.ښ04fƔ?N$Biq- ْ!_41`e/_H@ 2*]kEiD?66aZ9XdbSGBX+?|TC&n [H-nC;4ȳ8utA!rl"|#|v$oCj:t8Kw}س{jcmZ;100EkI>){  Ȫ}~͉LőZ2y0 " ;[Xғ7"wb ~_,鳎@\#5FC K 9C&n^_#)rH(o^r~ (}FYM: վ;́bK|kHKo$;ʎWA+tqe ]X ?5/wfu-@nl x10Q0L)~P{5=/~OiSE~w6];Ā08D!HBx/wczIO!rQ,aSbRi1aa !DAQ M!@D bY:@D$B2XZ !"$DbRA!юpw\32I"xo[8 D4h}*@#-<=kMUZ_wcrLHpDCob-БI BIAso%}pV s DnvF͂gsw|uXZ:,")؛" my9("$*VM={jGE0fp}8fⵝ `H3od@)K( :r$@<q*0VT}8\j2LD+ ^{s&4d+Oめγ! W@Iu㹌SP q#UmZ"&ev4@T=xCD`!E,%YV(.򶽈C}'T(t=J*$.4Cd 0L]/@ EfT.JF%R,ʼn$N裂߫~1V~D5Ѳ?[]o)_nAlhx"pU` yjDyB)ct'07rb< DZ0GhP902& 袰R PE9z0#"  v@b+H @Qr˜V8F$=xGB60ԁƇ !r0nCAEWckc*!T"P&}.ܼtPW.zt'DSPĨE̹ gz 0 c $D#d "H0%x X'_?6'Jݶ>Ҹě;*YN! "/B"}.mw\*(!+QSbRgHTHh" J^׍sP)X@G* $ 2aڳP  \c!dHv\oE3[lo6̀RH+bՔU, SQ 1 DMv KUGۘ~JkV_-]_^)pgMMrfI6Í3]ٳi^ǔ:<~kk\90B-瘹y$5(Gp(*na}5뛻n|& &뷶\{*yŗǜΡ]KSs9~4^RIR,RYŮ^z٘[I'} C4od(rzm/_felK'ĸ1T|nC-e y+.hV|iYjbCV*Jdb=ߖ[w:Dϝn:S~J&#Ʒ5,s+p;T?n~w--ءE9IT͚,AQhw#/Jv߱ xF~ T `2;ZQ55Ǥo]&]xSjȑQ#XYM?QOgDBA$<!"$ A9 ,ϲ>\>"hQD" h!ifcх6ۦ% + F gYjV5E?ͥ)D^-  bѽ/Y60g+i!EEEd-" &$\6'F%V/3I & VPl5;bFd,0% Y(ʪQ PHi |XE^!P6R #fXh1UM@eTk! X1.#%5QT$VMs)Ř^kF4Ih"vaˑߞ}f'gsF4q+S.?KɎX0xa!li"@h; U K"Āڔ AQ8ܙC0dXsߞBА-$ѠD@3qDwȸ*@s}>xm5Z~Taף@HS89͹(H:fde+YG r{o>WW0u@o%y;`"ׂi05AG)'3~gA;:Sm R`9X] Gfoat}yyI!mdlX!9܀ۓ' jhH("p#%qJC)` &9m@- s_nk)pRrW,B=IEi6 pؐ7P@Bl#4WE\1rZԍ0bd౥H(Բn!̄,#8H-H `t`J L$rX"rۑy  ڤ.Gb$bbDBu -2@H挃'Er7BE@.5Qyf )A0j 0!T,DP*.G7(I/A$lm]=B FP1YAuh7[ ߬L&yabK CtW{4#mo3<&l zJB7i01I0H VOSCQ̦ djTRHZYYdA!zdȡ!,4D (OLBE3"j^Krs{z`uf}ρNZ"n GjMSc&zzo{ʠ \4т04 J!r594T* nw7.#HHc DX+"! AE$c!$ !DV TdPd$I#20 Ԅ."T٢;$TnwY?f7DÆnH47AB7pfy7"k@#AdDH "B$"{ $ (H D]`aސꬁKd8Oث2y vN92*bBHAyh z0qD/U K{`6(Ir" C",:iDlHDU0@,Q" lW!?FTQJ,IED )~ iG*.]B`ӗY"*xjdU0Ypp 0@ @2 *8l(_Bјf|  1?BA5d }(O6Ŋ6OKa ccC 8MID(L!$$ ŀfDk$t`l@r:") \A@~DLw^zRLƑɉPss =;sq $pp+SB&7O-oF;x "!lr0f"zF{Gh&*V:k]rP16<=GS&1dZ(ID# 0+}^glHW۞fcLcHxg/!+]^=єbrC[m)nV ?ɔAp2ƾo,tjIy{-#%l^3͊O ~I^٣\8QL?3}b1}y68g5V _^Q ߎlHrZϪx>fAJ)b$<k~+둈zR׍ׄ~: Z1i 140/ٳn2tpd@oDeob5}3ͬF= l/%kͯJ97տV~pT[9vߜ#QAAߗi7Μs_$\,N$GCK4 @+տR.cMLJ'~bK̮ Cn1F(2 Mݍ]4 j =E@f$yBTv&#*; LAW/k^^}PW?]ʓt]BO(~؎{̲J>7zlpP `gpT97]a12*`H 7 `~*F0"5#  ]΋AF`H N;YD`lՕ`%@@i@h Y7I"h$.#PAmŀ2A+A!! fWB Zv4`,dǖB`숕 U,0.m`X J%XׂƖVB\MfXm,1KM5NwdlFL6RAJ6fUT`H v\̂N<^TEʴVH-b(ѓ<!5$i/^ 2YjOgK{uߙmm_;3q*0Qb !ORR$DD2jʌ-XdV^Ʋ3 ̄ 0-D (@ $ FJ^a@H1a U70 U"W("$T^A(BJݧ? 3._x!ւ6CHvq蠃 2,lfȢ+@ykzouT! BqArGwށewf,}^j$I# 1)LTI 8gQ0( &+AbA!$"ă!h8J q29I!"H ؃t$%z˱0P84䄈dQ9AHENE7-HȲH @(lB[\ ~[QEb\8R!/wNhR. B!W)Kz nFܢܻnQB+΢:.b?\4My 2luP)4L+u.l0 !D1b!'8 &`@eII%(s` 47ڔ;Xpo V0k DFQ_՝@I펁1*V*_6e Dk_>/hbLݠB ƒX;#xE$Z!y#bi @eHL PE-#ZsĂH  T"A2ͺ&3`H5 eF+AH"Iconoo@ 2!~$,wvu}zkƆg'o 혡!! {U{AEL*L$H$t@{7F1y|Xj,U-U ! {P !4hWPB,QC"Zw*6IzRmXP,.Ʉr^m+. D)5J&ij( ʅRCb)3/,[C.c$\ .PPT.X0& **D:2 RE00@ 1olB˴o+|쏛=t`vX"6֜5yFNJ]OEI7d2•"uP|NUf>!s3E_T2Fj%ry'X(78aUri@]iw˭7~l^A{a+7ϙ'X\%h|7nNsO/Q"knQUag)^-PoQOΆpK6xwk?<[0 lV0`@ciۗN<-,GKpWI(܌ ,X⦤, nV]9JrQEN\9FwN6Nulh?xTL!}H"EE" b^ ̨QB*,͉"%xT@1 zZbI$1 %8KPE )Ҿ#L@θ3Pr?swO!sHE%$""@+15"R k!mapfXJӧnD]=M^(&h;hXBF0B de؀ /WN L@V#]Ǐݯ`X:XF$X'cFӊPAN}v2yh6w'j$E (! @cc 8`n5   U!$Rb "Q؋(+qQ 7K9B@"lC3׶ g趫S$w>XEfպ5'wFYe%׶G[Ybw&^y_aaD-SSR>tQ=:ɏt8e=Zw' zq'aּ>QSRa ʘ!|hjIPpw^M֠zq"LCXQ缀`|d:#Љ86!YZHuඹ6iA,éRY0^JyML.j泚]sHs2#kCcKnrLݵ'}t1rJq<իųޅݑvIÛn2 N5CTʸ !Kkl } >Bܱ6pM pn鞗%5I(x!΃?:߲ap'&6WӞt$KDG\OV @_8$5܀e.%n@e|mxkAmpuX@LP-cPU7t橏 })s|Fg5HOH="I}kGF7ڇ]a(lRZm CQË3nb[|M=JڕQ$R' Fխur?eϼ*Ɯ mNh8`ȶ|R)$83.n`x\>7bɱHu޺vJ6bb RPҳ|FE^v2 ;l˼;1?{Guj[v2 *}M*9p3$̧D !Gwo[w4>0R \-e@iHH@zCT2 gQ`B&Qz݈܍`` A wy" .ۙ?< mk]`DA"30A7ޜuۥ4l}lA"J  ;a;~Z?+ϛfv[mo}ܺ7bLK}-!}S/v@8"&%7!J%g%9bJysu|EwU[뢀lđƄw/뎷WX[WؾMeR~ K[Z^ܻdN2uN2T_L2>JOy]4pVz~su^$8a͕U;>9@7<"ҟ{\eZ'smW;u`&LU%_ߠHI2S?5id=31MfU-oIܠtvӀy'sZ7,EkRn͈{2,?] KG.f=Snv\>G^P-[5Nz:%*:y#gmxE[Q'&Z ꓚuKy + do?Ia?G+M.+֢C|}ʸR&<_5qy~Y 1뀾+aLδ k0R/CQcHr->'&VSrݩUMqoʚ x` YlPUح/g' !~ŠnQd:Lc<8I؝n Hry&J>;RdŤ~7)p("YBAB"x.#<ǍI$I$I$I$I$I$I$I%UWt~xsޯ}~ dJ8N c ~Ʌ޵kFuv>uYyeo!"HF@lӈl(Ay0:+w#hW 6ͰUQ9&$yEw|\;l]S^_yŚAo|i}V&xwv<6>.XOA[js84x=0Z r Y H OV`ºϐYLEb@KV5} lzo}/y=vwt CXI @I$Hƨw!@?nHg"u~.{fO^_5ٛ+(;w0(ck(fIԊm7|k#ޞ~jFqa:,ZUb-\q6d_ yuӁY}lt QD՟Df3N"bf--JĬJjN^]l9w(pJt/^fnlм6-^UK5wn {.+.&Bk)u7֮-0B>Uv-f: (ek- Wȑ؁^IFd8G<'~#fڶX4|Vɒl9Les ?9 bhpnBT i,E,މ<sGnE$`uS%z /[z_o5 P6Et*ZJMW_Uk:yOgt3oAisa "~xAa,,ffVv ^tr_@ DO_iG^Rmוdΐ33{X&?=uO[9G`dz:NPk6);@kN^ZJ D1p#nSBya?{X W.Dsˡc|?(.{DQ>~ZߨoD.>a| S\):KWU.َ|t&{@Wy$@'̀2;UN؁<8}8JuA-$XV|Y/-  ֎i\?M6[F eriԝmD @uv9o+?swUҊ|| k$THAV,H )?dSh$MKVy nۛ-ܞƞq/S]g+ObN[9ZBُ׹Gx*N!q9OMpxUmX Xoǎ&ĩ$Hdӣes^;ꋻm)ͤ9<;NzVtlؗ#FS8uD`,ц>bb"0_CQκdHD$ (( 3XC=F9:ׂ!Oj<q- Vc(V?)Oe*b@ӹ 9P o>,n-Uo{2%}8K0x{JG.= |p[ɸ؁ n%HB @  H= ޙDn,h~9|gRTC-?]X>%Pe 8SU0엽MfilR"P= +أ*` d-LSǒ(ՓvS! J@︵%p`=h00h1J,"HrbFu?3 |v|v9{z_xq/}qkBP.BOu,@0B(E B!u% [4f"0r @/: Il qXd ,YKHlVRLs`*WdV]UmXLw/gL#"H_giTU6Sݭ:5=X a{Í߻?CqLO;q#m;5=2ܙd(E1_.-ijE%1>M5?!/#|(`H_QL"Z2_XIP4If2w.Gu80,U+s/F?@<^Oѩ*' 4 Xw{yw|ǦI Iװjn5fy1RP[B=7gswcL:|_)ͪqIt\>QVOZO] ('.3J+i_t/-J˙jAZiG]1v4g$w24ޫTPrX3q r~'ƍ p~;d͐9TGv{_!nOKސaNyCB$fH,mooK>dۼtdjrYғe;ՀWΑq|:ide)F(-KbۨnOP΃מE03D#,Ut Oqqɖ9)9#Q$vĀipV:d/ۧ!qm܉'UKߒmR?j(0ܝmhO9[>}kڇ@e~)EĩGXƼ8gZ82geulLMϲ#SYsv\jw7Y`k/ٵ&Ӊw:_yu@e6̋7X[K]U N-$eKmaFҥI6M%R1a9ID+*Z/ 3ӕYJry(wj_[C7/_/UGB]*[XC`^J.TEmXa/('lf^ _RX)0NGx3pg3dμ UfؗbKRyH >GyQf>eUS%+O97g  `(!o(&U)՛yCVfeVOq8@ڮ@5@zSrlZ""Ҷ@2w&> U`*ݳZ!@ 2n<qj~{3(X+ ܛ2Ѷ߫Eu/Qf{>(@<\RZ\jrL%m+!\(Ip0ٮWw&,VY-Z]J7/Ce”5$AށD %r2o/W!-5@W"0mĽl&=t(>0N˅=3&}J*=20]pDFD # ^*Ӊg?L%` -{6d,y[N>Wjn,ԙfߤ"& 0'#\*WFYY11 $بZM!Yj> /Rކ+KIPc?cfy)|Al6wlj 3)t$E:*  |p`lT2}~X7Z?4џrungT!.wvBuw0ᔠנK$o@Žt ^TRPKcq@jlbx (e&{]`G-7L{>xwvSMeͺ\43 wh`OE$DH0AD_F{/sN*hb,4I9 PA)nOb1?E>|8lטJvx ַ'9rG\IS&։IGidOܣo?R׽ąV(d0Ceрtx0iu#`, $såFgkۅSH:@m4A;J+QmUUUq_!0Cu_3y/)n^|HeybGF_ h`ݦnnI#@`">hhm>}r/l^=;P,$*D[V4E~v1Ì ^x/XE&.^>3,Fg KP@lf …&\Y-luAu8ܶM98mݐHW0'4SbvſG}-\fn7K)Bȗ'y 6*%1 p7%_ 2!폳kIVs$OL记v( 0T N}u۽?y/I ,& ǻg/XԎ bX}aY:8T?R嗾oGv5h֚~s,lވ`GLv#q*s H| thgQf, 2g Iѝ7ܰE>צ}d5fOH(~w3-iv ˥uB`Dn/_Q uq.#RC8*%gr_=-hqB 4ĭ\ήhh3kLOiuS66'`GwM;fEmZhQΟ௲Z4Z΅Ar} syO'a4xK64)]ߥ"hB~Mtgn Bݵ­WȲ0Y l(m4ވh=!^zWhĆõFxZ Ƚi 9]ohٵԌi'7a"WJaK~.of:Q pRKub2PE RwڭۿXLΦoMt3ATjc/SSXTqG*zCk)u*㑾" aKABz2, `H'L?pX~74D:}pc[qp^Rm- y-B#NQyz@vD8`#n'ߌ۱3zfڙoA]I}L'8(תּs+g5S%#'c|?( rn i\ZU IrY%x{B0bAǒ5 ײr3XҔzcNؚ+L,Ͷ:V?ϒ"TȝCPX kiq_Icy DEK/߈dx|I::!h;Ӊ=2 O "GQ'>Tڱg:s5S6W#nW9 d$ш ($W'qp=J\!I.C驥x8C4)KŻc;I FZ`XEll<0C9eЕ\k#//9k>CްSO̾.t=_콪 ̈ɦ>ޖa=3{OOiC5\R?e9C ͖w?(OIh:kԓus)AW  `ځ ?lRPt(K#xciS2'gd(bᤑs@7şC/c$xAT%y#0 k؞:5R3*InTBDhyyWhA/@s-ͿwPģ#U6\Q0{C" r;_ [.,)k{hl0uRf@#~J.YI1M\ 4;gHXIMՋś'@1QSyuE7jwV; ,q[g_ʹ]Fzrmp߆V8:كOd+][bgW`TW 2|!`ŘNp1wJPt51~ at$0}3`]aDy|1!XɯK"БyDa4`8;]$\g]C^+4$JIf~k(PoTaV#*t"BI+Scs:!J3NMvHD@P~Y& lprCH]ߙ}b8M! 2#=W-v&?C>!z{\ j* u9 ⨶*D;(e5h@AUOȟ}8`0RBGOHDH_.,BLe%t^1'O<%ܛb@-Mi'CdE3M2e*$ќ:-_½3A zh\emU,57d<"$e \zh>ј`"9GC_VZsO;`m}=y!9N(ׇĺ6L֔q\E8cQyFmcK6Lc䊹$O%f10?¢ 3|n~MD]>uD-yP>"w(9ΦNZQnjDNٗYU[ 6hap0IZ* c[Ek!$fY^NtPrW??ƨ9 8'A}RϑO(GJIfW a=jDRUzwEIzAf}AB| ֱ`lE|x#O#EiYt#?O6B6 AChȺ`f% e?3|?C @k\T1:eQHvϗ ?`.GdIt7P8 b@VHV$Т~1SީjX{M0μ?_u}1ճnxM6}+Pͳ]3p׊FM0  :t7a<7#/k??\L3Af5FffɩD0he`{l8i.Bv4N>,)i{5>N9:w{e6I@tZN.tvp⪧;o{+_Ӑzxr 8|0WuּsHm$Dl=poLf ύ D6zPv @E:\r Ef9 =30af M;xb]jƇ^uKmu0աKg7L*դ2O~0~ec TOo(DDKЁ!ZrBE< ͊zMJ Ww/.$}eJbNj 'G1ڧa;G {VxvM;̧ 镰&f%^" ,+…t ]qSEzj*z5Vb1GiMz?-Pq zJ?RzQ$RLB$f(i/R* ='Ag.1.Y(G)ӌUހ'(tY°VXc$Iub<'}(om4M1$ph*Ttex 4vvUoG$i ?RPX0+$I~]aJX%Fo҈A:-a]sVl%+,N7=:iHFy_.?`Qs{X.FѰH](FN0w.+Kͭ˼Dz?&zNy[N[nn9R03332M+V-9E}iNڬLÚ֗?NR^EmȨU^vʔ\.*+:!QLǧX ޔD,H!_D0gi#ͼ }f؜[!|Q"nXNq&PLtQEnpZmn%'kqKtN@Ulӹ )s .'LJ9vGֳFyĺUmCKC[{*ǛZzC[E D*9d #`]#@ v\hmM:_UĒs!F 7&5(bX`x[|(kaM4fiLHuWҀNM (P/jPi p kjDkfh-=Rh~ܕ;JW1F(u7Pb9~vicgPГТ]2{䍟dZIx X8" ]m:iX0tvӍfS>0a9XJ*4q(Ә܊"ONN Jx$h5tɋa$;}M&H*/߫nCNAm~tl%T=j>16[y98H8Ke<0:^)iR[?9WC-߇62D8H"sdfzbh:kcY#_?*^=|R99gfR]\bgHzP84®L,0ֹn |=SPd>O|XMwQ`bʳ~X^=r_+kۘtz7,?Nct$&ҷk Po:$]0&B{f0+1bHًj+n4柼J  OrXvC"b{V"[mī3ǩ]Tq1AL< 3Ötfmx2Φy1X]v`ecMhq,ɜ'%o=\]I9{ \h \W=sZ?Lݺ!BU!.ؙ\Wpə9߷)wl BV?߭a|Ԇ*c)$wZ](f:dzhy^E_=UȬPmuZǷqⶩ1v_=&s+}IW(YnۃI Q鬀aPw]$|bvM:ԂCXƲ^4}9v[*#CAr|-V$ g;Z*5"6I psĭ]W  3kESnᯛ#]$Z:'I9QI[GONr9j 8kJQ w 'D"q^?Jc$YH=sQ~A2^f;UVscо6,0N~KcMh#`RA^z˵]ۆz c@c4"\ !kgAWhmw$(9>weT4!JVļ!AƠ(Yh0xlRd5Oߋx-=w󺥲)w1NZQSCJ^fփXSb*l{p fsht(*-bp2+_u) 3V8#FjLV]:.1Z}r]w& c饾oqq%=GV4:d,D/]:XлU4߻F×0g%4:#; 7[u<1HF">S˴ii_F|(jnI&6uiZJYNtՉ,x]Zg&T% Y9[Z:zif T_g Q~jVN鹅1:J-F bYln "O\R\ܷ4FKAZ{,>+irh=~)qSȏy5ϖ #gd1 PVZ9?wߡ鵙vy[>)Տ;`]jm 7ǫtQ$^-xG9@{߃#fNpN ?44z5\V;++DKD4Z ʮ96dejy{Z(qKYƽ1.QXF_kd(jRwṔ޲5nU5ytg\vøb-FWzIbW[(F*pHb7WgdzmOg"@I|6Dd&j0i+yg,Dֳ֤|U.G"YF \[0`QmNaS?xQl/D^ruwHP;J^j' ftFjٕ-v&{<<ѱR_Ӛ<C {~++7wAi܏ (Q&IPȬ댰욨}.IMO5K 팺NUcG)}"R섁e_VzO. s-$o|@ǚj m\mȩqndlNu p wut jg.yߨ͏o8Y\RS- b'l4ܛ>̔܁6Z .Qte1oH.QM~)uogۥ aE:*vdH0DAŲh0%CCYʈ,x"4ȟ+P?B}ǿ.a>5Wn!5+ĕht2טO5Ozp׫l<9X8i^ilkRɩb?)[M>6Ră}uk\xbȏ`t,Vu˄!,Ԥ^i=4`9e$eZyi3zaػ~+e?tpqKG9{ P"Lˤ0ZY4e6V/4K**]_6ٞlw3 F*GB 4K~.:QŇg4f^XS磭Q)xlʱ(GQJK5ky"8WeTLi^޴&+>9!2D˿T$\WwsϢ'rm~G*$)h/w0פZ^YAkh"ʌ"RYHFJCufwrMd<(E_ 珶} 5rj~M4M-z#0Uxv=m]zcd&oH &EϷ/w( jf_2lJʬv"/#vWy|I~"dhn8UوYT?qhN\= Tl$R$΃bP)Qa\1`-<)9߳&JZILZ6͟f#V2Sݎ*Uj-Ì)i]ҔVv&lXj+#󖰋( jy aD.LyQ.WcVQ!i>K:lhQ.WRȩ=fpwvEp'5'ہŹǟfi}LL5ͷ V/}'-r}/ɗ\Џ&G|b7UM*TGod,mxhߪIڏTL桇.&EͪW;p%CTFA09vysޭZ`Y E͌H,HļĮ WSQ{2rچ^r5rKHwQ >vf PRW\pF"BY2?i5vz 0n_`}J~3nەUm^]qR F:2SF=0zkOlYI!pH%I:,uFW>߅uE6Pի$Z6!pP?D!p/{gWi-DL>ThL'nz[oG]%?a D ! s?|tu3~(BzDH"<:&H8Z_hqBsRSHeEQu&[8xeq.alj8T'˖j*cR~-16}9'+x VRbe#4˞|kΜYtFKd7{5PgSYru";tC+-Iuo=I̖PcY :j{8 rn>PNX̣]DJe-3%!v=䃦?'s<< R &InpL~1q ĵqI:Pٚ5~@6r36.t3S{GztGQFSRQ©M(*wڐ}ׯ4f-Bd&SeXb(ӋG-Y<2v/=<9)9%3KyDj{!:[3[SAV7aC󔘙WAZ &-UI$ŏ醤:1zSn* fj*!f,me1aU~Z4Pֈwif4lUDUӚy7,O19^ցpdzM䠔Ѻ0$#C|͆>j8|߷8M/*kɄIc>&;nS(b/<Ļt_* 2҅zG=۾cOUN,&C׈: d5feKb^o/zܲ֐zL h>^G0L*')~]qN2ﹴvDSR<fn>ĎKC5g.h[ه%ɛ!niC0X!ߺegHWdLVK QFhsIB+Y=M@4d~|rf DJHn47-GU :mr̓# sd 4Cŋq㇯A5˲S1[t1;*_,Ҽ_Mܨ I4Y q)8[Kl^>hiIS ^Ia s^RR0)=ބ^ٸ#&TՀ_n|IvHO'.\٧ %V 09ϷuNېDYqL]*,t @y 'K6!jf".i'q|:ʧ z%cαH52l%ly0P*ok~a>I]~ yU$s^@}]*Œ_z-4 R_T˴`|f C7` PK>i⹠22oZ09rM4Ś d! |#?z=翧ITy$yoatw2Yڬ}*vhAM'0jL"Ýo?icI[߲X"LK3x↊ѐPtCvgvY=8׻Y~eft%!o;_֌7R mJR!"˽+&5{_:%߮KaIM_(Mb.@B|V8·ץ9VfxK]^3>}"h jr78,[{7_̱l`M^D* 4w"wJʚ ]Up4iS'K& N#HրZΧ7 +r+tnnr6)l U><>*ء2D CE B4eo vG#I?CHPm}T[k*d3eC.aC*C))7x8Oǰ$X̻G㤵%&͓̚Xؒd*~M<=9x *$욐4`T%eo'NbR0]0_Zv܉6ũja%(o Ԕ3f3,w*GRU=^)2woHUhеGԳFSg! WzX^nU]iHf J:m/b7ٜ b7bE/(TGZ:i|pW~_b3L%ŀRQcLP?`>?^%R %NH "puaE V(ikL ƚGo`y2P 2Q?g]OGJN\|6O{' '>` 4I sH%ʶ>y̚NKNuoѪU ࿱B0(vd`Hv|wt;AO F]=汉UY]Y]yR{5'@ӟi֙fT$;i݄7Ax@)Nx ='~^rgL ovE@Co:< nzq260 ƵORi@ }+ X LZ156г0vWzP-o#*S /' 1>\ l-EU/C,j˖O·QvU.7{: WwVB~(5-Ƿs;B= ,RHk` 4vX@K<,;ZA f۽5CUgʔf=g>WȚ.犾QE[Hn $ӅAW:&2;uFwɤLM47n6n"; L%hymtqqvYBh޹뎮88.J+ey y]Q[_\E<$SGuQz@Jɀ'_=dBL?q~crs⓭X)&?zef 62.hal&/k:֚0^pfhJ ˂M_l߈mx?KI:xUq^@dDxHCu3*Kf%eۿy&p#zΝ[2rWFvƽT7ճnivA̸:s@A0_E5{+ \+<]3wxN}IlUg.ca6;+MJW F86Fi *}at_o>NLk-xSԶꉸ[xVTYQ~ONQ\KxPAE,-jiFգK<3U@qzzVV]ERՋeI װdMcVMwf7ӻlIV֠LP- x:ĽV,=@: `#sxgC^ fZ̑ularjQi'֕8s)l,iPɒξ k*$JA.q, 8kb8eTdH# U&QoՒx,*kLƢX4ciєRJ[rDq]خ.QUѷ^D> _'/4mQە1=Du0F'QyQ\T{(&E"˛jNa~*הށV|J |xyz[o˯11R! &[O|AqB.I~Rx _aǂ'|Ռesi @A +>[!2KB%f= l2u& #M SV]uΒ\._K]M :ҙ sv1{q^AcцIVkӔ@@LV0ZPho1Q7#mUר)2}a',(bnS¢V·D{&,2)AU8 }\똟tK1I,XW|`,Péjޓv^`9LcW_)"`H0p:_ǬT>Nq HDQ?&vIvqvWɡɛs8hLcË4mG14]Y޵׉ʺNiZkjMtQrd1(?ifb>/J#dJw8@uLbEdiFҌպ̧ YF2_[aq€K<>?KI8r z:x(8LCPݙjC0,q>tSBUqor4H-f,X;Ar59_v㻽tWe-)H60%c~KchkXRoɎ~l #!K>#nR?㍜]^y@$ҔӇ L/1>~ghfR]rEsSȄAn+7W08>KܶL^ݷSl|h5y<ż`w)넚CP|O97=K )kZH۶ ӄ9Rn^I.(1tnt X \$/R#>ż|w*d=X7SH^=(6^bh'7eْKcr2Rfxt(rl$kb|t(Y ̥05xP]Y& \F e?$rW]\o%g_^Fp WHZ~MP7]>W+JSˊM AMu}̥MN?)dR3 Y}D60(XK@?w_0D,eL !dw4 ok; 3sCbek76OrHaV umi] D8Ön֦-5Y9;V$6'ǥ/"9 x.r 7>۟ ,(q _:sƳQ]jC=-97ygؐzsW4|4+ս.&إ1AMo@n(Is\&w5kG־7s5G - ɟeİ\V6@Xmj+daϊ!7X)TaX岒,UʏD'ה1tnB;Cm $4nAyOўN{H ~{yq#Z4,R$RUPňao 8kS2#Djt<?{8C^e򓿐0迠iB1[ϰܼWȿ5#`R(=%y|T,R (wڒxpu&z )JPND.$P!+Rkmͫ `v?K [:</ia8pNDt]R؈?lG$bylȻujњٍ2 E}e"3ta3^vrFI@?~ɤ#=aqt0+O*ZulETo4;^+^G2Ao3ݳ=ȕmZ")T[l]tWZ=PTBV tK]vhhrb.snص' mg3asjxѓӒn$1,p<&vRW(]"b&\.f]k=+dd#n:rb'Cp|ܣ؈F{9:^ݗ*TBviZAˆIvwd_W{*OXcFg~Rnswe]XXM.I`;2U 1s"gbՇg d ǧ=N?3zVX1B }0FF^qnN7i ̐KDJ[5hO&4=b$) `(aQHW m ""KީdzP6ܠ +2כW p>=,;cj__b+ٝacԾ( U{pFO  XE!W3hwځo.Va]yw<78An&X5.>~BZ%EpJ­`"rw8Skqv{[25 &!7E8)iUC_XфO[2t?S(Wu&®D\??Yvzo8WK5gvA Zέ⫎ A$[(*E9(m=ۗqDHg5*qi* 8a ÿ!; Q9 C^ &/_߬.]znBg?ef>#D ߭Pմ |%qȘ-ԳuL5vqmbGܳ~lh؇'6y]N0RNvvpaWRNQ8;٣tHP+5"M BR^жKG*r2`-C}-FWSv->Mo^$熸;}3eԖYB~i*)3E URӰYd'bEWf.+C~n)Ŧ4T=[U} tߟ'd˝3Ms&e>@Dl5Fn1i (>\P|ޚ] $IhTn2e]Tr-E}TՅkRly`> رyPY<픵: 7ۤEPG3 X0#b;~o1PاIטe* lcsj;_Eucڊ v# Yy*Jc2EY恖k\ElAiwu. }Ɇ|3z3"JĴFm('\y@ӗa(&tML-σ|5}u*C7̻Z \qBu;71B9(f RA(&l便ZtÒ:>ݽIcVwء2]nvv8;yWLC<T2{w|tҳt[;?{y  J7P(*}"Ɓ+npt\x5pw-sVAfmR"|;R;RBٻO LR1!wCkvmZXFu7)(܏svT@$ui;F/DBŶ2cF~9]2)b2[q/q'*o e&ꁚGSx.XK`bA[-c(,BQL,[&j+KycNiLI}wⲫ&BtY녃+L*U 42=}=U'Ap6|Av ^ST؟}cp#4,[.˫”]L, SP>-6 R>gP.4  }}(&ȡ G+h @-Xdê>Rz*;!#T0T7լ84qS5JCE#rABe18GFd{b˨>Ĝ@.E#8=dL*25m4U_,JZp { RD-b\bJ`K酢>4#$F(l{dvZ5#X sS~id~I(-m@e}VnQgә(5k2Z ǎDHޕtʪVx3ݠ3ÇNLbVw sk/kGɏp349y)'6J/q]}xN.fTB\z}~{ίjm`T~f)! ywruKGfyyk^D9tJxHjҴCy,uaU`:Gmk.L:۾=x֒g3=hB)t/+X꽓e ۔^2 :5d _]pw3y =LOT1Tr:H ocЖTDbVk`cOp ׯNVk|K]!0AysSH+#5"l\_?7, ͓NH2nSpDH`6R쿮ܑp`)Xkm?ct6l%s("7%J'ߦ6EhlQ?,mjS(VYS T m|r:s?/=6z}NNGr.kTemAAdե$@r!+K^2wź9 "A 1)&vѶWDA5<׸>c?.V#tV[F00S؊?@#)AQ1r}tN|bYQU(#_O5j.7E%揿 \)Z:K{\߽;}GupDI">roX&`#,ILoӗ.^:S _H)}:9Jjn.j~ kg@ĸs^5 UG"d{Ix x('g}v84~)]J_ r&}m΍7o7ё1P"r n(pDBcHIt1#brM{*I~T߅ &i]07nD(0\(H6^O[7*7iQ3ZGy7l?};Ί3g D|=gIC]sJ O pxk~Z_dWwSv36*Jm[AV1,LghF]j ẁq (ouʏq@L{Cqx&CޢqS62esy'Hj@e } 5II8qHb 1#}:BP0,+1/%ؤ{v  zv E(kot.1Sc{{>-NkIBp@?;Oc|2fbB(32GP%wƎ>Pc3L4T(W2?z"W$tj%kv8­8 4E*[XqSJ^4C0r~^AUlx(][UەO3_!bs  xCy1R&d|9ѿȧ~T,H^~Zfn4BIܭw<(%&5.f)[1fV"uDv8]GroDlA/*D@k-"UĤp/OyK%3kĐ|M*Wg@9"NYdX@)/w(ΊKӨLkmC-[lJi循J) y e1CxQ^[ t 6ڭ@T-ژt*Yl%qZ4ݷor-h2[ÃbG168nbl&;{]YAY> WKfp7dAq$b$TVPAV[<] )WX?KZY|6n XhsEXޣubM?=X8ă `#E23x%t[E 1AJ np={ _(^q>$͓v!mL,W)NR9-̙=7*{|y>a :ިK~v?eZ&z|K' $at# tdVUjF /kPAqx?F꫍܁ }zӁ rݷ~VWz3 ~z{}I C\r@ٶ/3Z )d&<%ޜjG(A_} λɅ95?Σɂ܅93 H0Iȉ]R(Ňxv͡#y2;erKVQ3J]'~<U]M.*:'JLio@1 _.mב0mL2IF$ΫUP`ة.Azj s "Z} άs[ԩ6Í5x_1)$LgTpk# C_:ʕk/_h%C^[!d\&vnXtgQofVӖL;`9M^|x8V~7y|MIn{-.WӔȊ9P+)wwU>QUSf//>c<}Vr9wqרLf0-ś>938 76{9.(ܴ{^y5n GY8E7 ѭXllibkBS8Vq| S[xv]잫0/@g04y2%ul.m`u)Mu|WۆLܛ?'~5cϦVBeC6}VN s>ѡ]@qՇߋzQhr/Y8]82eg,pJ@D?{x{ѯRz6OƵː-XO2vHNĽt=/ω$NsCW *S^g >v15c&Cil- j/ 猪3jg1FeLS ^$BL)@)zKC<1=y z7&k=Ol2ϛgunIWNrڎhU=='﯌zv~>fns 0zI ;i8 "骮W$X篛o-eA;cuPa>}^ZzQh/q]"wG_Nϲ>q͋c3D\t ;|xfGYO2!^:x_W4!5f+ L~@C  RH @x1X_ #nX̐WVyljO}HHJxNUAjg`jc +)oTJ`0ƥ쪻 o=EŃoY?qt4Uu񯺢&{_W wW|ʝAˠaе.pDUE$yt|hϾIf5qd9C@j@iQ4B2݄uU3X㥞wtg0w huϿ,}c ~wSqHRuG^C~c4>3 ͢U Fn$Q[?q 1q8k)l8sI?Mx{j`}\Bǣz~;̅,{i6fZ-UoƇh;q9Dbyٵeـm?IJa sljrUΦ/atw{R-~AIRHXr L b3u L* }ँdYA)4ܢЊV"`h(aQV1X]1x462TWzG5Nyk%b?_}SuFf$bIFnYG!GʝY\Y2__,>c)~ LJf7WVSe5:"La3 "zGG ?`u׿J3!bCKYlT%*zfUB);G~ 7 %%2I~`v }JqǚjoZf?"=fc\<qJ3WQ#|~FBǏ|Zf']=) (W]r}vۄ(1B+58 E b;4Mq. ~?aOBaNiRRy2DL?d<ҁ1[oV>:{ӹp{쟞1]O`s@tgp&RV]:0mNPU'h $R6Ĉg~N.O]gh"*py1! ͈ P_Kq1? TT~wxV"=h$K\ypM;P~].妡X 8xgA]b~G!B?m Q.MQBi^~s7_X:)'104n`a gn'ۭ^~eSlvv?]%K,$PbrQʙUW @qzwV f+:SZ-rkM B+ؾJwneFʽ)J:V[ I& ӼƐܳݵP/H|PTzg$.p!V;fuN#7<4\ل]]&PVJ@u}_5~"n[N)k0!k34'hLiJ.X]Όw[=3٠Nhv!-c2 TӃk3?b9ڻ>eB% N^B<9^YO˳m(Xœ2$䚷 ӚgZ_;9ȿlnWyQ*{cM׫I %}a~}[+yscjb!` QգQM %Խ CF~oSg֟A7* ٲktOO|bzu8;hF,ӵ곁~>Cph9B=_NYd$qC90Q`=avyzZ;vo(e;,?iS9U {9/Jtg[S܃YīS{dpѾ&/F?FRF?}(h={0eY|#҈]G_~35vxm|7]ޏ|y=iyIG(b7w81n]А;(N,4hLd/b),I5 W牜mLC@DsHuԝV\[8cH 'y>r诚NchDwJpySG TD6O@y?(C!t-ϭp_fwє^URM S dc%*0ql`Fuk\i/䡿k~[`hl|gJI4A^Csjѡ3xPW\ zIR%"ꇀ1ꥥ`vj7FyV#/{}X[N :"psosˆ3ArdE"Q^!凚 quTpGe;߽:oMʥ4hJl4ag⊋SwKsNh%X4P$6|M!_޵{ M\5j2h+\@LDj?W50fO*sw&9En"*ESLb$oEY{ Ǘ^&'0{ %*DF?P0}.`JbUQ0~280; ?_CI.٭l2"^$8 3ж R&jNSZkjnDu4_-&YT&UYWFL^Enj_;]99OCw-tKJO1eV[->y=O[QizbMEgJQq {,P:`g!咖*9 R6r~VA1 Až1+w!qIhg(L<,OpbBʼnS>7ݐ7U^cM3 DhWd\㸺j+wʧ#" Enxg'Ai-6P ?؄qC,ODc/Lp#Cr-0i:z`Da;D=>!j)<`QZS(/OšjRmri8HR4a\3;$ws@d52m{<.IZ.ꦓdx> b`.tFe/ƦdNq686o9R~Y]e i$q nXMnV3c_=!ϵ*Gkg!U2.&9lT~_yN=wx4_x@䘈ϱ/㞃3y]d_|qԏfCeDn|JX9w R<{^A&X,)Լ DffuZ{oaAh"'%:Nn[$(hr/`؝YQ@IlHDvl9V\MQVZan 8ͻ7a wNAAFv0؁yq6m߹y0hw;#uC@Z OfS M䒳"mFӭGwe7X|jר [,:ysʓ@;Ǡa"ì ܽ`nj2`߶Y[X ku^Gi_^ܫ7[Ȓ- 0D Ȉ2 'BHe=?6gFN+ojN4i݃ziIGlRkYy =*pD pJ;4}QP٪yyFը(0ֳSE1:7.g R^|B8fCՁk :S?~4)P}NT R"@FlA[\(ѵd 2 ŵxe5nvo)azCd/ِRQ|F@Ԅ[Jx5pœ\u ^m5] GB.W;y})WҪ7(2n%)y&ж!krh{0jlb⏓4MtØ;5!#&0 pzF.p&0jaQȕ Fdڿbd㫿@QXQJQV2eУ͏<?Cȡ!Oe7UQpF+eQ.kJw.kS4!L}j~ m`— 0ncH?D_/OV#)= ңzf_Y*rqO/!G|`Ȇ/lp+~kJ[Cc 5Iw}iՒ-31'2/.[{8CkqŐo) Kf$ Ig: 1Θ^7\މ[%1mUlVH9XS-p .T`bZ=;x#$wΛ ]u_Ӵ܇?;~#agCW67?1n%?z$Jߟ<*EmbH\_@(9G1K~}\5+Utn@"eq,ef!,ϋmLk~oUݞHbwдʙyo`4kjb<'VPA7]׫ #Kp }ODR)D|әZw' ϱW{Y O'ZxEQ޲!1D0T,Z0@}R(.z\ލx閣B)b?*б_sdH\v F˗R(]q>we̞䓭l'IEfݖwJ :ēI5i$Q5dŖ(LYsh:u {W՚c6oP zsDn͢H rUqT}0cqyʏr AlY0et%j39& *Ӛ.]%I%':{BGȭuIN_`[W`jbɰɦrnZ.%cU39<:} >E^'gF$"HVcQT;RDA6¤}eMcjd%Bn8m'q?hU^mMn(9J 107ӆӶ|\lPl=-qu [da9PxPӥ>,UYM"bc_LynDj'fi95RsZcWߙ!dT+h`咴˓9j'71g} ҳ5W>߸ z&3.uX=:kfcOK:rWGB> bp⑇0'czciߍ;V'E`iAOm8^mpS>֍xqR=+o5$Bp=^ƼmŮ0}|S:TWSKCW9]nղxJ4J[Jf)7'm<] ưO*j9l^-GyxZs5*"(NS{ejzZE :CDFsݛDC~߸d5heMRhgRSw)#cg"O2?[v@&@Z6 :72X@NQ.މ{#bPhfe y5~漍6Re qV i%S">Q!@S挪,TL_uޔJ)vRS*&iPs, ՗7S(E 7jʭf:p||p]nj9FiJ~V}A*(H$#ZCuwySK"0d 6p'&Č}o(Ҟ[hIK|ý,.&Q HΧU=EQ<6yٞvz_ٳ[,2 ]p% 8tbd*P|,>7t_]]w3;{ KIs}%GCS"!+@&L$nF/#j,!t%nu>Z\zRIDjԡ}b Au Hi*0:&`[e,rP,;D`8NR\%:#VjM'7>;U3 s/xϜӫÏl %NpC5zE ZP=i2F141JD#h>bw -%. 'uaYM)RX^%~cZ O c-aK;{_V1-2DoaLjg6b>xr^g*1|BKAH2ts *yώG IVIw#|<&iÉw]R(on@O#0Q΂qGq#6P.jGORw6OHhUiιHЯ *$nIX\=c((E@_Ќ>rIakEXlJ͘છrhi t?dpҎkq&ꂤFmyCtW' s2u﫼9a,1ÊP$*=|6 iтʟ m"En_ &H3[#ŻB٨l":JfcUIBv9C!6}LEjxNUr ~8kbUZh:9Bҿ>;,>"K"E++4^6f33nb~jڎ=129oR58|'_r{-7R87{Kx >/3 #k͸LθwZ˚ϋ?'x݉,>ѐHz#B6gU+jO"; "BubL^,i{'6)HBsU:ꌯ+C '-鄦) ؈a?Ŋ՗XrVgMyx̧ݡ:jng^ET3ǃpH)Bj e9ׁm2-@+sM aZ3bګv7I[>q:!'cә2Rҏ SjC,0^A%|549)] 6vGtNL_5жb/' -lOgJIg[$37X1Y;1?aY,OĥB~=F_*pUGAizw3@[Ã9R̨G !}t_c+ʔAh1~H&HΤ}}`|' +˗c0rO'ͳc\[wÌkZ_)"B̮̳skxt۷ϰ&GAh:ZiuǕv+MwJo8m{:W utFӻ=D<,.ǑV体ȀqI5[sF,? U(~HLN8dq+įt;qg D {gSs`xw^(Jl:069fX>j{h^ob@[v(==+J[Cl22(Qt߆ R ^q~! ]Յ>90V}QnO3W/rqM[Pڞ #iQ]S!_o_"߆WUɨ`_ZeI"ȶ UQ'A)i(\Tfۻ$үB/ݵPi{/9D:ME-ջu%v.x⼅Y]#ONIgEBRE^]6Φ ˮh.1<ɕĀ%#-L/+E|7&?u2z#xFiM1ٳ8//Lx>SmGX%Lc~8(4V7oc:wT3Zg~^,9j1NÝOKlߐJca$η7ʼtx#k;{Va0>Ö5ڤ% j $ <ޞ}I7Ly_bygz C ͚BD3`_^@hwL& l~康MO뮡 0tz;ap]ESŪщU**4=%=E*XEe[u"OjR ed:_3cƐniBW G#uv?%k(^lEu"~f'ٍmwJBFs؄ 5y8V|,~(\WNMta%XOl- F0aJ?'pUm7Y1~eaؠ55&|ؙ 1C}(;>LfwZ=]oE UrFfX&Ӝ j$ A=VϦ(xr9=X@Ģn V"l 4I-v(jG"@+8߇Ӑ^2G$dd|ӦwGw .K l4"I&A>0(M&G1e67.O5zUM?V< jAՍ"gT29? ;X&ke{P RQ mynȀH/لr8ɱե?Hao3g~>=f5r Z]jaI.QtC!sKV ^+D6ުH-k$rz^2a2]L~S)DfZRQ=Ͱuߌ^s/z1?I8[jb :j{i5U0򿝉&B%[ac2_A#N6pE)C:Eyce`!cK@`jaO-8.?\.I&z_cSH BK6J+;IP $`)_MMTWnyܻk<ٻUd2 WM1l#xRq0 uDG}t2Hn*'XX>R{jq[Ki۠<_k{fo=Ϟ[]eL +{KQ~,ʻޗ+_w8Y[a|g&"2?^ISWgay9v[iz4ɡu|wo}MAuC'v&@&ŭ>ڙa)>7!ܗ97 j;8rh1L^%Y(IuR8ve65٪CchOAK~'[X)}_\OOȻj1$ v0*eD޹Z#p3%)qmmƯ:{;z;:N/@ 3q3 җf]}n4uD][_E7Oۤk.DY8ҟ-aGYV洛$ŠJIʴ\<5NXznM!NZ&s>͢r;-4²8"6% 𨍲9y0&1? @;f̜(⳰̉E_]+&vzErQO4`W *+F⿡ vGjϩ]9j/w91nO%B1d-K?es23r0d8@SU(I&xiX_ 'XO!`Y qe;1$!/Mђ;!V{':qp$oQPR[CX8ab?!E{ in'4j,E>;~**m1F͵ryE4lt?Qwܜ¦inFbվ-^J&XK#ٶQt:hWm"l' e_VJOj|QPpSQ9en4C$3_ H/{_}կfD\㷎ԫQR-" !`_9r5YKZM*UU*q:OY+l䎲cqK/Ză(G&\ޏܰ]"uH(c}pi,}*j}K!+(/Hy0G<G@~IJrQ/nR%g nj\TA\ot;(u^v*|GKnt)0bs \^dz5v9 k.ԥ@UD{|>0VΖ, IkYVH =ڟ 1l6jIf~݉/Hh@b%Cgz{?.p󕟎_h7J>ͫx,DͪWg :(_J0a]MAhz }k;H*Ū?T<p7kKVŁk[-W ^9Pi70LFiqb}i܋R^)("FM6@f}@8@?8u QLfTrE&#: (Ly Z2a~@OǤ1Җ@>^Mʹ/o /]1^+ $hDL?R3L/F}]b {:9q#ܜxqSeӯXxrr鍩)=n$:@aISC_W{χVN D`BEfc@7e}BFDuvQ?6q-'U?~,1SqA*`$b/j{z# ~&fo ΐ}aB8hQW\gŧJϿHͅUF?3;C8ϧuIES{VpL̄f. 8xLr?C^qWOZ#w-ŏjL~].Fб~@v9_U!,6dEԩc߀d$5_lC2KRj|?޺R_L_:) < LTka)~`(rҒa"+F[t;)( Эz}_]R &{P|V~jDA5&:YpMBAҩb6?bNG[t7,N&o Vxsl_ G5d}VYVBo`bP_IiW%/j&BW2v;aD@%sS/MJfя"`2M5腊עBN2a<|@7v 7.շ&Q;^yɴnװ^lB]2}0\ӬeJiRR (Pʆָ"e9CĦ L%㣭f)5Fq>4V_}zoy*yQiU/3,fxsFL9 Ab?bFNP:i0W*%ז){%gJ,7?V8?%d4(i`3<Ή.vnLa̾So'1ןn^?D8$W=X:^9%No ޵y6gXĻ>~=)W>D;vOL~b)CەV?e cJPMMuL$g0ۘ%NҜV 5 abi吣QQskb+IW0Tǖ !=z,Y߹չxmLWIGJ㕺P 0A~7 6I<~In%j#3JK-Eg}}j~; D!2`8ΐ]{OUo/(޸/&< a|*2$ХkWI^zC{"_<Q}lF&R-^AT~}:t$ w\ۓ ౲>Vw=pVnV Q*Ns# IMi\%5θY ۼMPu&>?F1ꐓ321o .5n_G(#YވTG2*y,Ķ*4gCDaT'"|[廳Ћ ͮTQ⇞ɷECu_T-Cp.U!_:5O8?$1cIz7Jtk2`|ox}m}]}~Ha;xR}%H~)f6 I5?4˧XIDqqI:^ 9S9'ih !꧋N^Z]m*fP5Vm{mҌO$DhGjr,Btg3+07H[#nla;%+Ə3kZ@cSBM"&2fpA^ϩ:B]= TUO5h4]LQb {UG㼃G`ÃPJ]֣ՒIç˩`ؓBQ9TW*J(dsF i% uY4жz9ԋޓ`<#ndݓĢ_n5Kj#7WOO P?5Ng5DB'Y" WO$+-AHͧ"!L:ѩ׍>nNͭd|y:/6Oi̪Ne+˂}@c잃=,+$DPhᩕS~M+r) }|'}( ;"yk1|^P:,|@~DO`{Kp*yjw"?{ϦOGkQ caiYN9nJ\88 ll5V~pƢclZ}췁/gȌҏW7 1Ʒ_#R,"9ӳR9HEnrvn]lاuu&6{JǧX ^͍~}[2;lHGF[op*l=v@egfEӒw8y&9_l >Vqw?4n|{ 1磌=݊#,/pуN*_L:vMy m%G_v^ ُrҘȂ~6S) pQ}2ɬ/B׭yvW#q*WʡUI J ꫌%ZLCg𿅾AT\N0QSFCպdTsmqV| }yg/( àQ`sÇbpi&8梸0-*B'7Z(J*djV8 ;L]?+Of#Mpz5QYt6シ"smڇAΠ!Ym1|IpGWQǿO@(}?a3M{jL;]Ě#FTxfSxm)僎bV"bN ,.eƐBWQ _"Wp^9Kimnr݋I#صJb1]~%缕߿PL-uq1O[Ug}W_-.ڔ }GDǎG4^VbMa[KF2[ziO Q:gJBΛ?8Zh!`Z ,8 7B'u6lb*Ot}Vݜd^ {l6/7VI&2 zC4{S-S!i9EUO՟@{@&1ρBYɼشaн"K2=!_RPCp  s=,Ή{{$D jb*+LK`mii[^q:Je5~ >[> Ť}b0, qݛLe OB@rfNx:Ŭ^]rs?AmDY׮JK^ 'Ǝw JbRͩ~AATӞ~zctiUf[jH܋Y䰓*g_҄z7nӱp=01Pϲ\JuU&=f_bk'C*dI5&bN9(2UbZ2:%J WZY:M$•_0Kbaǣs>ٴŬʝsH}_D{ۈGR(D#Q HŸb' 2Gx ˃m_3.e)Q_ow?;|JݬzY zK<QK>dX@[CL;Wxǯ 8 Կ໖u `ksa%Z`3n8ƽB>S%C;T U GтVlS8~٭6ӅBL : Wxdǩ>DYol:0 XrsNgQuƋX087[$vF# aL258& 10¬rv4rՏךFH{b+ag!݈ ʼ`}ݧ{{SMT8>ahY»/aO)TJn\#iӞRz8YEj#56%?%j[79贚sTE49D$6*qY;#_Jj>h \^űVۥV '۔[2Kxp?h`Ֆ%_8=nw)0tw mp%Ƥ9+lڕ&r9%d40z8'?s{{ 4iVOtZP/z *O^ xY1OF07&cKeF7P$_Z(be]d54aWY}mh'VD5އG~sdd^n_p&cvE)I4ϹzHV>:^ݏiqg75H U-IHIs,#*E(ezj<{ iW¡j}Um෫Cv򜭝O1ڝ.Ʈ wН<Zq+1?u$ٲv7d7פ^2Ͱ$u١QDWj"ryG88}1uޫeA/4t9U鶻q'glcYzޏq5ea} S˃XR4Zwo yl﹆]a)lڼBw 5?ZU~=:3Ba5v;s^)6=2I1jAu~vpEAod58òU!ViyŝF wib\>j֚9۪W+c+o5F2Ǩ䧎f5f1CCռUayEq߼&яJ  IC*9K-6ؓ |B3F9ϊFg+x6dâ"}L`'x FʀlݹZp$/I叅l̀EMW[#(K5X>ABc=ȣtЄ<_(Li}eU]P8:|Db.t(eZF;-ӏGB,˝\K\nYr[:D~5{`vT ?Z(}} n~UR(o?EJ|?J g.Od I':\dO=?⑭!Z't% 0.869Н28ǀ-g)&C9ʋa|MkQzłQcM TG/،0N-#\]Eu<* E"bչ.`Tز["IiƤۘ 3<5 3$J!ĄHrJ#JF,iH/aw$NUqH3QJ,VAp+9sEk$ktRc!Py*ϢYI9gBǓ8K'U͖41_7-0uG]|GZ㞜q1@x46F{8dQdK@TT%F"L_p<"&([CG\7^om޼HuJx0f!<w㉜o|7uuՋ,P>=qK4gq "s ( b$+ "QEA64.Ce`]HDlLPRcT#(9JQtrQ[Nh5R|;i62޲ݧc~Y6:umӨa"gEgDރ$wPHYd7C%GU<{.j^N5X'Θ*?lAc_NwuCňN3cv"r6y{)1C .{Yb&je^ʔna)ip&@W0#k=fY)8U*LU[$ Hڴ*Ԅ?jdX"E$̕x6Ӧhefeߊh̚5/Pڋ'KPG&xM\'+puI/ ؝5 =h[~W}}n@KbZo|x덅:z8 *Gz[dzHϰ ]:V{GXH9uڷ Xu&sαϿ\ԠSxW|?d5Aao篿#h3!߼׹ǩzZ? bu\gddl)ph{c@ƍEECUÞ[K2^~M^QFYD?򽮆/*O/Ugu0ի}DΣ4;dy:Fn~I-Ca(nۧQF5&O8I(T8mYlcr =m3s1W%&B_0xŊv8/+iC(|źSB\Qo;  MY4T0Tn=C~Hwds6x"2V55T6#ZK? 6ǪIEx,s_ֲx)d{>R'iξOus .o`NT}<)כuAo)5m>LdXy}IvKUøW?QR=UR mc302ߦ4i01Je^cZD3/ wTNϩ9UV:v=M&.7:Qv1_Ԥ՟2[IhP!w匤WH>E3E^xC"/w9a;J"A&ڹK~np/0$HnnbZC'=d%Ky˲閏2 a<?NCؐ/`ư* ЎͿx?XH26JlcMBJݺk _Bw7G<:?hKx^KwRIĥͩST0q'5HWqEro ,f{z8Gzx,{#J ;-2tbhH7b xJ톤\(_ҌvKi)5bLUZ8Ż镘r@K rxBؔ^HyIHۍ% "6n7xKq<"BnKQ4pF"FL&}`UK5 5^eQul{hKHMB1 +eCbT,`+tBȆށ8RWt% /6K+_8w wvS\S,h$svBMU3swTƥ68[1ԗ6Dknڷ68h;BrD+'?G _1nM]]?:ݷ]$&2Վ;fMuZf|2ϥh+CXAg>tNqȈGW/kj!FOzmBHvD]#>AjgU,vt24\(9pЬP\:;*[^1$},hU TLԇXjMAxܰi=fד#{{#jk *~HhQd'g LCu.RyHl_`0wSUʦAGME7mSJiW7p|$LFU͔~yqW;U™o\qHZt?rIcDEEjRTP DmRCAgESW 0Fru/8ljv޲ pD'\d/=r  %P }yƺ-tn| ގ;V]]A]1 Gp rc148K҃#wlcEEn n=lcQړ{-24=3H<9uk]ueb-"*"#[ƿ6}3l>R,ʵJwt1I θ̬,U1_})ge=Su.WZN>Y /o]zqmHnOhBTcd $k>uT5: uت\q;ꦯeY"|k-sbL5}I]p9a|j2$j7fOZSfZӖM,T:B )1qp/z0ٸgfi'>x5boe@U? $2̌siĠg)ݢ L'¦t<xE_V:䁚)'{1qb XU 7Vy_ [BpNN1{K{wH*Z6?S: A8Jo.oQ2.ߗԨ{KBR;譚v=UfVjWHҔϼ|M[s mG=n h g[, sO"S~gtDՓB+0`.jd/k>ׄ@yB%<ˤSi偝Y-xwx@G0#_{OZnQtqu+c48i7/r?0؉TB]q'%H*\u-<|l z릐-c=-ISS}>yfrIUsN|ɨSYUt.S21d~#},?(8B8B itMF.!?bIK};6z+1LLP~L L8')fx;hx1u\.mdԈ|*q25? R|~*@rx|Jq +Dv<<4+ %_ϋaF:3NƖ?*B O'{Du@VyD.]вG p0m6" c&NP#vN紐mu0{w ݃.P2%tB+Ԏmg]HIČMbY Eg߫ƛ80hCpPfHDoخ5SU&8 MA'CƏ>'CZfx\tWّTrwK0.n"e6JHrdOpX~7 >8|%e۪ "r)̚21SA򞞔 *>OzKES;mk4:ok3>E5ͧ;H ew*:1i!RږI[Nsg5%%N'֮X%1zuOJWlIc5e.!+: MOLqg^[WwS npT [r6} !9¨1|ߖꂞ~~fR9 uZpϷ`L'7B)J1!CF=3|uo$h K&BD*JPC5v %h.6I`Dh{}'*%77"i1g ^0?fXģlS_1yw;Z&@#_/WsV)UwVt,'^4>M&ƖS:(1[h7" "v~Y)h ?uLW+DEC*L#\[f/ c<+a_EALQI%x*L `$/T}/UHQQB[.G hswc?ly89- sLϸ4ʲFʖ-xUo)y*lI{|ӫkVF<f ۙ,/VI<۹+@!PL*I3u2r$>;AZ\ࢡ,N:`U5\E{=\4npRIu(1W/P}fiwYu|qLj$P7kJzg\ P-mY%Ұu&5 }Vنk+[l|ϸ?}ŅȎ'l">Gk"ߏ7{Qtk 5 "zQ5-kw,^7* ,ӰP Qo[ǭrHdqLS8|EaټkL\:Єs1wW,_.TNɘ*9JnT$ęʔ,'豤–]ubJ1kis0]8_9*s̿Lj̆W8]bIS(UANqtN]=GQsjHEQ)K!(z+* :Aݍ]| d3s[X{S'v6P[ ,$!of~:pD`o8R 4im%#j#pV׊bDI㻲og#)L9Va~tԴJHI_>Y^xmf7#10іWĒ]?wP|Sh^XP,Nr%H"vIK*^{H5Q磖 Yjo/wRvw)$a*e d.u듊#%ZN;V\7| &"LZLUտ/xuWlJ^)h(τybx:A"`5j7i)n۶WeK2:4V4RgY{2G;9x҅擅5VcwBP$1̚xbrma2Ԕe PsGK4a4z_U1(=Ta'~]t#uEnjN[[TqD 3xgY8 Z(hzdj$2+d(ms[ӛl=GnW U#y7/ˮW$H=$3"zYy(rg$~nw_yY{c-Ps{dv1G! C ʌ{+?{˓ޭw`TcexqTC$:|W-7O bI.j09%.fø$TǑq`b͞DV!GQЀ+g#=sWke"zre#s]7}{aQf lvxX11Ù,.@XD@@L*c %6zsͲ1Q(^d(' K6q2"]7%px:/{Ĕ uLܳWjo8-FBx"caI{n)8Ffj%thI?7/z YChܪL~OTZ"xv%ߊ7fG$N]<XΡb40rmzq5AKO:FSB(Ø5$IM:`⁊RZ7j9xPX"gӺԨPIxpWnTĒl҄צOyJ쯙f)r5XYB%Ñac<QisHY{?o ?6YᑈT-E<~oU*RF!ͺh3)Lj`]>XtN'DPeAJPS}[/sqð85~z|ԅ²*}ꉎ63z zOl:|5 7g!.> P8t -~՞Y$"~)㨫v՝s@y J ;ONΣT,t*}߬pgr' ^{(Zn^;t=@v&EP,V W34u4p{5x%'U.S.i~ZچnpDϸY>ms s  ltIޏo>bؕonA՚9bYDVt<&i}5^@d8Fa؄}D)]Yր{SA8w'_Uc](w7`U7a ߳ˉq_K>Wk'Ij]UѽP:bo'<*oSq>vUJW*E@TŻ}t!$J~LmX?ݶw+8}̞X :XkE|aCD 8L`GNowՙ]dלM{h4ҽe-\X,_, 4u!?_ db)'+씯~zad<%P 5πC}k/ 8~9i),<2@dyy./yj L'hgd.UMt^}KW]H/#cR=,%\O9J:%3i~[v=oN9iuSYOBUT/ .wdsb淛rӣ-Ź!1$%I@ۋ\(;d_GକDq/0SLN9~ozFV|< HoS17 oG co*լ!٦+-}B5uFJqDvVvS%abД^ti4~?3nĮr ,ϼ? x 1-z)Ϻ8TS-I@6 D!lg[LtbA0W4zСBT6 &iAh' qd}18 `ګ 9nGt*j.;SHbJ[j KP_m˲ ge;E)ySTrqwTppmߘύx@U67~_럣_+`JA-I)D%3;G2xK4YeJEZ捉,!y`Mܑ j3(THb HcblyyC|bVYs kՆ~+Z'Iᘌ+[7/6YS|b"h_ :MWo}sSuk{)vU ꋝA5(CowPllyLlcNVz,t0T^bg(fn0=2B9'0;H/=-3 tFlu,`ViE"еPv- _b4>:U1fPWŒI5bodLK!RWٸPOI4v؉~^W?U^wSRF.vk]ϝ_{(7LIOWgJȄzcȞN~^u*a?b."]D8д2 Mf|/ܵR-Oz-tm?yi焢@6%WYq|VT_I[)~XN)lC~Eaz~ˎÇF䫄> D)w?}Яy`9PhW\Hd:C$J)s0 &/LzgtWy~,ՕΈ.`$ĝv7:[{yXf=,-b s-){t3T,20%Juكss䩚޽"cu#w4RUx8YdDw>˩?XփgUwme3#ĹM#mݮ'uqh0*'_쯁c[^'#ewYĬBZ2i)Bzr2E4|HOe Rӑ$oO (44B> )s9WNu|Z`W 8 bR'1a)}8B8VAi| 0>qQ$ܥ"X/&Urr"0ZȚ >"/y4vqZG>zʭ)DZ)p0 Ta+kȒ0<8qwÔk:{MqVmi8;΁![I˖/؆;e]c^1Tȥx ޱ ϒoYa4X̩*fB_.]Xq7zg}[E~!pg{גA<  D'#3m`JZf}.p`i?'v&lnY dT5>8vR1'F7GG*>&|\V/ba/ ״a\4 H;cl'yja"9]Pz4Nn$s_+l1;mD~ѹj#].pJ3?(AN~c?#˿&L9tܼtyISȖa5p F؞Sys #E&$oϏQٙ}~ROr.BWwz=ZQt1*nB35)5;ro>pIH N@\*ǞQmقTg7cp{H7p}U\{2i<ʊ$oYE_CRmy|Jq{AޛRg?Cok px 5u`wachi:ƹTozAN[ OR䪫> ZIa`A/5&"b,#}kT!5I|R/ԣ3e`]ΑCö?{'̽;LeMjU" <b XN009p=gUVyV)ϵ}, V_(^@xp{ uY=W+zR %K7:M`k*mQ-DTozm 7q>EC⻶d9v`/RRʫdĸL}-J*_ٖ2#Y|N}` ݀H ' ) ݼl.ѵ7o۵c-sPJ?{8l窔eQ6col{rEzɬ؅#vh*>Scq:jB4# TGgakthFQ߯JKP5yr Jꄏ5 JQI\$n~|cwI%_})v3e=> `; [B 7{47;5Y']ԭ锣,+9*3OwMiW`ET/9̂wg.\%2=mϒ>یaO}Td^zcӿ}_+]Fx< ,KeW\$N7R48 g wu*caD놰)!"g*A*;}V9N^ G`wI:I}d[UUk *LbU%s̔ѭ7}'F܋.g_O Z0Vh`yT+Q9]x:i`I߶S1ihAK kw[MdI9bV0xa;?s靆~($-y2ёKyeౚ)YHخ) wL7D&0wF )(Ŵ&E_F]GV +[R6#HE]hҼI QԧpsqI0΁2 1)Sʀ*e Se7e}g/o}9E6AT(r t#*ҵ18 ` ~F5  ~VKt$Cű5A~;[ڕj;&89N!T11+^ PC9J`lvT.8K rԑW²tcc6N1V|xvA|nmRra=Kk1nſ(7VIufU@Z^RCN\{Rxz^Ub a͝;8~MxKnhm[ݛaźѶ,l}6☖61jNgxn,6_~Cei2~]PP]Vcβ:1VuX2%9Z߹Y\GiQԕ鈈XoKq;\ =6f,%u):jI]cZq!HmGw)_bj\v@"]<\Y +s`ۄ@ҫVŕ$[xE;񊝳Cx+.nZ6\a>nOܕU[NgG_.0 utv͖ E S/=0匊p%Mae^fo0z>*\^9ݏ 3/槾ZE`|x ҈]@DNhc)uޣ9Bz}T.Zn]cU~J(&?p8 kMǿ &6H9}!DLwp_OQ`@hp8 kgToEI._y-1pn:ͻ+RR:1Bb!2LWSW\:7y&Oc\UjԨ;/BJ<}pft7?^2YM[+ ,C~;Տ1(NOx'AlBm>j[bo#,Th /d2:]-tI0.yO{ ^8׫oz I~[p(O=o!xq+&*aV4._|őIճz퉫877c ¬eIyP^)[ z; >kH0+sxtühY|6+@ AТCN% 7R Wkm^yy&Fز{NR,Y/rsE]Fn>Y}w2l{!NVrcuCDgk/Zɡ. ˌJ Bݒo݃2~q3MstmK)ujJ[⎖*Jog- &^C v/2Zp+Yծ~>p mDn-qWK{&Y*#i%3 <5L>6Q"]֌`3u,: #R*ŋ.zdU(lja(3fo%w)(#% ]7^+'$X,A0N-rMJb:aDb|QcU~1PPa@4a\ջBizbl߳c$j]*e)c# >Cx6fvܼ^'dm'ΤvmBR\WbO} V X=LlԒ}_eQSy_S-Yy oo$4̔GŬ<8:vqiv"g TvHVDwz+|L̓QYA5W"rf RS423p*Q8TVv6r}|OJ6j-.|%Ft[? mbL'^0󠪏UA]ACY70ɋ}I/eɋQOj61L+$C|\E@>,#0Qlc6ʄ.bvP]E@) QZ(=PrEul({Pp_Ztzr HIL|%vm[5ʗ,/É kMʻۼ<%>ͥzWi1B-yBD N,T}/x<LHp,V3!5e b|:/T'/nYB spTJK Hrh8zHucU4hN/O~UYҪ_zŒu lj%H9Kf-zP3/ڬzW2ӈ< <67fUC岺GȖM'K_W{m<}b'Ϥę1̙ȹlJ|>O71;XgSJy}<&q^h 52U}Aa +l>$%PJqYKŎ[fؿf PpGF>Sj^™.7USʚcP]os]H6Rci[]&Y[C +`T33V\ A:]*No|R%dG0A\h}Qt62Sj-1'~fY0ѬXl  \-TM 3UB5}mGcI[6{1t(s'(.&hd/m01V3&61N9a6*H FK De :פůA͘=~n3۹߯'|$x>`qt^CFQVD ULE&.$"K2}B-,-ז+|`CƪMH"c"mF ʽsNP}Р`{=k[YIht2O XPWsS!|}cE< KAdX p#:`;;Ūoy;A$Ym >Te捁.c<}{Eݖ Ӳ/cS盻4гv3firϠwu#J݀mu8ѫTSGW2ݺ0f bןܭnN&}0Jk`6h ݦGKכTx0)ޤn)Qsnblx{M'. tqt%D¼$gC G4z^ug׎*\[h)lߎ~.d:X5h_^ 1Wze/Ҳ[ 0{O(6yv޾!>TZUqldqP ~T_! pSS?=%54Y~e/g CL's yks^}JeXf},XhheNSbghU+*կ[4EJ [}TIdtgW-Ysv #sQ{D97 1ɸGmz'&IJۧ3 bH_ET%l"sjr]q{v -K:=ctyłNjOM:f憾:;wX 1grk,[ %`/z*Q-iNmj6AeۻgZ@ ʒ"c/hzNkhS`};EyQ ûE4ȸE(W+S5.R@z\\Gtn9G 3$ᪿ}LOuh2ht\oxՕ#BRce"EAI#I\[Ł‚gE61U:kiFkJM+J3\= [v?t^IN}}'Fe0`@=_Uu}uT(v4~o&_d:j?ehKvl"s Xu'!`sh~Ŷj6#R})Uכ9cͤ1` P;.h_ A34*zLqPf*#x-K~C1bˇyHwP(UC=*[bſAvU;6pV,3r 1кvkD8(Ovd>΅DqPױ0?Pͨr+ZDoѡDQl<' 8)u{$M8`x [4 +S֊-[Ku8χFC6$%æsXfճN-'{?oN?,S o'[-VSnEUc/{3)YՠAXd$mKk %Tlɩ!g`,+afﻛPDlũr9?9}lHHXTg.Uxggq5T?ʡVwcSO(yFm5sVoGFHJD_Ej%/qb~jݧc9fY_:'%DˉQD2@z~oTRsyWw8f(^8quSIPpN[RQ:Rk]vxk[@]*$!ǷGNwFhb@Hz4 XPx 5 'xE^*<-Y3XD]u. \>]~ ;eq}ª»P*=qp)Yxf2&=#~^ 9(b/L,ށGPؔvt(h=FQwd&ĭy@]>뒟ĺPr'<&3cʗd5n~9Ve)*`hN(9 _NЎЗ xzཱི l8hlBhFN7>[tdu(ȜP*nNhSa6Hլ"aBX_>NR*)ǜÞjOa[|ҺSvd`dHz-Sn6otՌ.E bn,*躼eS턤htljn2(bv`RbH@Ħ5 U@0'e.閞1K7P6&}QCfLWQ'K#ty^g 9PI^ȁn v]Ϙxeƃs6[򶑖qlC)䳿(p9x8:GLLEkN+XYvӥxazJg4IW9b:rbx\0O6}/1R"'T̢/c0(@1JJ }  ͪ!p$5iE|Yfdo5FUF$d{~7DS<KEq\96ĽeCxN]웱ըJ\|ڜlRl|M 8X"o̒]׊t?Ǔa]AnipKpT,U1,cTvc| RP{C U:M:%n-Z~-{ʚϐҳû0f֌UV:C$;lh^sM<ϸYj Ѓ+ABЦL7lo["[`ʔ~ci`35W5gkqsI*./buVM՘?XkW Rg5>>)\(t+.'ni?;=݂ *GWAˑܺ\W 1n.ٓeG*㞷 g 6tbce7%ᥞނ"$MNL}$FE@}ƭ3S2Ҷ 8N5EB w)qOd?g M'zX`+8,]%8s(Kh s7_p# l:F)~㖞ZEz'z+0噅%AйSҁYNu[tE~< [Y 8~:>q(?D6o%LthRî Ҷݽ3Un`Uj2h>?Q?▕#ϳOJwj G_|-g)iKK7[9] %^j=hSKv%Tߞy׆BkpYJ8;p?܅vuVzO.&HL@A#kg\Ĩ\NPƜʙid94(HHBe IFhSV׎f`s$ (86C\`Ѵ}ty}nB !{w(ߟ6?_\<-)8ΤFG*Fk) %Xw~Ot[Sm&ͨ|j3N@ή]s$"}bWekwճ\WPD b+(L^Ș]Xj@ڮ)+c67:pi;gYL&m}#=GƨMKa5'jV=7!K%j Pl7s#g؄lt #0ͤo윾}pف;Ub&}نt+╥J&9y9m m8#+o䅧]XgIOuϗ',V}]{8 vӯi(ۇq;ٶY$ޱV%RBfk@n;Wd[vUlGOd]1#L!w"MQCEd6^@~|)ߌ+a[afnm_q3D)_.M+]r_!ݢ7*veHs6o-;=Uc`X8; K|^_XeU&MQ0ݷhm-N_m5fY n,{;Pw%Ees=&K2$VHQ Soy {UTWqNwv ݯUAbgׄ"$CVPN G7ݷ"ŭ&ŊmIYUo1|.5x+5s.{v`~w~v"Cbk^ WKJ"Ht4J@&k*apyHSiREކΜI~:{#Loxkǎʒf}poe}1䃑8HNo_m.1-5>G|vg?NjPM$Uw `[A$#t;dBg;'}Ax\cASWy׺ȧҔy3^W ╦4ϼ|᧹#m^ ,OO6ߺ*J[ӼΑgfoTt{18tjr^^'{+ aɤI4|oUHyH掯P*n',+> *wLՂH82m#܈zkHKcaXNT߼|AGI?eh`Ex ~} \j¸#6.51Ӆ}]cř`xSPSOwGU!;IB&r9Rx.9Id:YLVnſk\ۚ3]/J OJ&)לf8&Fˆ~8gCe(Ya(0u0*4T,1A97 G#ۈ߳5 Bp}P<"_kv~om%qS[U_r|$me6;L}uA3+:߈<B}~UEC>)DHYF9>$Z_!: ZӛjE;'a~oΖZɀ"*E.KY/ƒu.,bʶ{n3%$)݆ͣLSGA:լq"GWXʳ kgO OW}Mj?ߟϗ?o+6Yiog&G$ II!3?&&iCJ μSݾ\>[CqwYaC'=paXaݥ"P0E}dnH1] =ݳ+! 2_^jr"P^?ߑmB;GVe,Jёpk= ^-un6Ϣ8=!m ό0g҄-.v^޼^.kpu C mHiT:b@P eiyu&j<{@b:!\] KON&Wؚ|J? l@#T Gzw>pعI Yt](>WS_U񻫨ѱ˶(=FJ@U^{(<;rO)Rἐd##*#ݍzڹ}J2Z}bKXaWWG`.fn(yqvk>3_g=ɓSA(zB]?ITزs}E8:+(|]$v?w,R7oU37DmO.c+FʧRfa%)-!]Ki^@GՏz+\/8Uxۖž/ :wIJ8s>-&b,+%;t*[[|o,)*#9:&cʽ"*y0J:L/HPۓW-pȂJl+oJ{=T>-e`~ 0#Z|톈^F{dۑ-ϞXv`;ö4ܒ3-=5]A85䕽JB@mm}%#l:Oo #G))]H;#}UՋq?cQmX;8oڿ]}HBf rSZ$ccvYUzZ#2wGJa3CyѨi>}eJK]gK/z[JRQ"!{Z 7*=npe჉U^xٓj7%ǁg/Y:n5,7?J~o(2BoAdp\Ǝ VӬh |ΏʅrW(~劬#2n3-4a_{/ ۹PMe_X roli⭾<ЃaϢ~Iϩi}s(WU׃5S|Il׵Grp= 8GG]( yLUEGԟ y4dϽmɆX+[C^(/Zro?0OU= ߗbcjѣиEq?Yei;m-5v,֣5j =iӐ#S(/ԧ1r )_ `ZWA~7h4:5U YWr(q9>%hpx˳&ִF( s.u,1Ñ/ۏH}o96+L\ż>*vkSHz~ _@|B(r|'w [dY0gM8Nxj񷃄3BX=*FL/T*~*6]KemŐ͙! _CBbA7S*-섴mՑxՈ$,T(p ջi"܌9̍#^g$Tl42ϜS݂#ID-_uxd4v! b"rI/  s, f]G~3=,Adh]Caɴ01CW]*L#f+widN#2מW=Wݑ hM;蜊b?9 0YIԚ?0G=F4u:+!ZxӍ"rK^[)@{cho K&={]@\`޴['|fBhyW v3#Q]uo[aA;J0۫bLw}qIO+`nA$Uä\PͲ%M$Bc6 bOocSuqWLү@l2郄פ=nK?Vf ΩꝽ}-Ú ۣIms?k?D(U?v>ater3n 2Zº[]}A z@)LKg0܊A؆[c:ܷ%w>;5f{Z~o֠3"sqG]GŲ3Ph3xt߿h?cY)<;ޏ[7#7ok1n~/.|*آ5Cđh1?./gZ=JRI}찶J1wpV":SpL~O9UW-;gӐG1_U_*JR!x#QE|fg fS[WIK[<9痎li/άg6Ilӯ7~/e)bofzHt)؅j(/OBʽ WΑ`V`)LN4eƵ??SrJ:%g XTAO=N V=9]R:w|h[5KDg9zwhģWDa79hH*Fpط7ХÚoQ,%]AX,Q{.DfOF)a1B)osg@HY|c ѺQ Ԝ|ۈǢܡ,y 6ӄIJźՎ(͋4zҙD)֡yȶ˲tnLȖ_ܻFIڂE[_>'sk$aeȤ/*JɃ_됆jk?)o0уX-rX, WT_=W)+ra*EkGn.e29Z}ȥy\]=G(7T@Aزjvv.o),B&[w}ǵsہRN(U0RH*FM"PbH6~-VEGG>⯣" okaܛ'ktF佯r݃ ;]7;o`ZBm}a{\ GG5z9K,8ӫ4\5J[HjIXwѩc$WPWwU8(F]wUPJ ,|d{Pj2%$ Wn;?H 7M煺/K^LǺ4=w=]z)h?Ze/BŔw!Ë;51!Q@L+}؅O^LJ%ad ,3Gqe0Ҿ?Э)]7O €m+6ca,:@MuJjDyX+i ; ruWx+5`^$7daHC:ZƠ&[Гׁ* iĭ}̡jKzߞ-`O,}ְhj E1Q= #nH$ժLƩB^=o>ε`v|rt&ib06޾`QwƠg GA3rLѽ RK1Uծa6- E]Чj6PG D^*9X4}FqEwhtFiR1X_8b^+<{yF"`ry %%wI|gcp ).|k G{(@B9,(H O Z*bURHpCG?ٔ?y13m-]x?kÀ b#)@/Sr2Q{ _igtʹ#a=Q%E r+&`>I~xϢ1Lw~<ϼAe.6P%*^$L]O=VgI9T/\oҫeW@i-WV%~o7!Q18ᨬk9sP{uϵR,a̕rW(~iI_l>^Z,7S%0Zps7яCK{P)@*)uÒ>H1 \x"Gq2M M ~IS*wC2[.FOw|?`0a] \ΫrCPV?,5`qSkg./^NEN2J@1>_} $C~ɨ[أz+C۾yLRg=G[}oͲV馤,M3ۤ :Z&=*'Zk2Ys͝?s`m.|N)?_+mhtSm5ƦY:<DW{6`T 호#Aam54̲3eٽ)Z &3@‰!X [NB!dR}X?le 0Z> }OWr(gn:rc+?'? 2׶rj?q |[-~;?u^JڼfUU?㈮eOtuP'YRȋcDd>ݰk+7襥/D"ѱ'o08?E+!̌?1,~{7;>l%B)V BӮEEjOLD:WJӲ3.CXop=Y,|ē.ЁwBy}t{cRk6łZȈ~ 9$cԽ.Jg"Y? V(ʏhL+z)k#%1maf.FJ'RYPѧqW:Y fߓԜ-#++a.O;dyy76Zտ=J8#F 2'I 78N6ءe%4rԇfZ2'Y?1*UÃ\.=~ln^nO"ڳW|Z?Uů2E=yu ̅ǂDeڪ*\ ca25OAif ̙ڹ1N>FVMhzc%MI`|XAA2M;HA/|t"?Vf"yk-lww.:?bEhAM/ʁ3JRxL9(OOc7E!\},E79UK#ҧD󜜿;FHq2/cwV[XYT0vT4R}শu<hS֠~3{4ЊnI;vѼ^6]R^"ȢieUu~!e}w( w{GEmv ʨo1O\XVǬ|xaE.o;e J=./~Oqk W~ujcZ ZB %mJݴ 糃ɼGU[[x ["u\Y1CRgA _|mcAzbD !%b +0 ~ CVq _jּB fl|!5eZ>%}&%n?>W\/ÇbX Za%qiADN_jÌ#ғ7>qyS) :ӄjPWzj2Z`jp.fUJH"_;+'9#‘c}ݰ63PVc]hVVV3;:) *oE2bRZt^N)QS5PX$G@C˃C3[&__Lk&iY =t\c:K,~ ;[,6 ,;h Wz}Otͱd&v> Ja~VC\Q;L?}B1iS).o&iYmtw  yД,ܭOYUۗFm;Z.=<'e%-4)"k{H^Hpݚq9]paf Tw*W7F_ Q/3K0PLg-a5DT OǕX( g[^T>qAEA(/Jcz]<#ByTRZYY.Oyu=FV 6`uN%@N5=y/̥+|@?}J֎ a"oԺ1!s\d{oz'7<@ }De=Ow>tT ́(bY#^*Lxz̘>,TS"7Nĸ"bO|6JP4jD ,7 }7uAs8X>NX ?Z{L-4"K늸oP*џ&)Rpwbl9$0YZӘ(RZ9܇ }̡ooFgjAFZpYH E=XMKaф:SN&ݐ̞;N&dfP7Ϛ$} ap9r'Lh}Pcao1zǨ{@xib/6]•j7@"e7͕ԋN絉,00'5Ȃ%ƃ ~)H:{}7yRY^떂Q_*bZWE5<yDtZ9";^Է I'Y)4O?{-F+Acwь`45oJeQ]Axͬ ncM)l}5{i׍24j"ig@s~zH3Ttd`+LlB+5tRZiL? Oٻz76%ÎtLZ+ }%VL60~ /(g^;Ꞇo7mͯL5kr3D?g tqQ2 zfaV7$J.~]d" <~  }ޙx8aϯ'J}Fn1SG\ߟq ѶGzB,L x |H2(SvrIZTn|;˥Q;}}"4@A66eBs{ư#Tk$<̷=˗MJ`ENuoڴ/heIqnp9+*I@XʗU񴪎Cyh~O:+sM3_)3Yk+dl72 bW%;Nj9H;MnOu);$PgW+G)w>oq;*=uj‚*!Ohnѕt.(UgI<+RD1/cӑ" Z/9j nzR SE LoG``O>Y#U r/EB_|3B>l :v=՘Ng(|JkfTl%5x tLl9p?"2# _L4h;9/D)oKGӯG'aOکM;Y]#K̖C%,yNA3}MXZy[P$ޢT2ycB2Gy*֬k)?-dGdYqb}OG TE9 * %4hïM5u.fqV,}.Uo^nNi2 :u3xTi70Є]o}ri>G|bHє9 !a3lJfJ% o,{&* R ]خ;84"&OWqSCx;hq+Emݑv\DR'z؛~}Df!~ ]}GS#EJ i'"\$(be;أژ{qI=%#;{4<\q=#I?:U;BmZ~h7=/5 OjaKj']R?.B"X̛vJEGCR+gj|;vzGHvY^2C]C>1C$ lшAj(H1ЧPejqM{''1$mIZTl/kKQh<{4T6KQ7i"y1{Bc~kg'ڞƧԁL$ⓍԄ,L ez'nB%psXB(#{BOx3WbU]e 9gaYwMKa;wt~1`{ߩ8wa0yS2%a,Ť:ԧA?a8 tܢ-ߺSp}&íƩ#f~`1A3{~ pj\eF):cA&;mD35h4]QhpbTk/)Hד%lyu~{]iwzݖb~߷QFꒁR @(K-UҢ=Ϩa,tPz;KΝoJ;PQ{n6$A2s19(8[Rm"$;|#[ E/dj]_U} "w̭^gq+}"6Qy2!_S<<0uѹ0ș$f[J.織q#'sWЙ5v'.ARB{~Nkdf*\:3 ˿9mOc|Gϵ?G@fbEfͣQ}۾$.OlR;?O17yxD"bw͟6\LoĊ-5JӤdLe_WL$ 4HmdN5J:>G:I#N/N^U@ BPX$20\Dg͕tXDQ6A+|E$q]&ں耿9ڻ#5OISK BsFH1:}&f*}=]i6Σ̩g5)}":W-Fѯ@*J soy"r(Me+(h'W{(+*I7,2ch(lD\ o1umb]$৷e1lߠk4 ekO5S@6G$u%Pz@`ޞ/Tx"^@\~E <&%WCy9_I)t,pT-|QY/+z#ҀjeOkWF?9/7OL!jS HD ""6WNo-Tv"R8i҃oz;Bt⟼0 WtWi^j9K,:SWS]qM!&rv%^-]m#E0yIxspGԦn 5 X@t~SyF!%V!/) Tp xHI_@zpb -oέ8T\Ue309)7?VQTھՌpᠽ`]]m^Hj9S?}gcCl%8b+>F\8u ZbX:\}g*ll  I}ʆuM:!1x͕q(h%.o~T}uMaWz5 ړH7IAaV$.γ fSZߔ7GU #I^Ņ)`ȩ0ə(Mʺ!+F* $^QI˺.6]FqeR҇CF$:=0-tͿ({C`7=RZnWtbUY9ɦv0}LbXڌXzeu¿W[]e8v$ŖoVD|I`9jFL|Աn>o@UwbnMNuYՆ7!9P|$S|$9N؂Yw xWv}W]9ҷ$\ߪ<9q;*k߅t38E!L3)0K.>A4)955:+J쨭G(ê*OY_'kMII4p3z c!p@sq\e iĀNR&Wnԭ_AHad2`Y'z f%}Z3M]0b"WR]K#_mU(6ቐ7i0+t1RN3 bbPwTU{>´Ө\\{ ظv+ʬxzp"+t|t.0Z'O]GEʼ~ܙT "$Q dq 18P#v' 9CwgLd-Xl!2&C\֡R|SqzIo}7WtJP=8lsq(l ^rd~>OVJHzl 9nkZ>"w ҀIu?WbO͆8amxclp[qW:6zCMl!~.J[upAB9 yIN~ťmC6&I5f@"C% gYfN-]Ȋ{3ɈnEOk-*Y(0 k,c*HP_~;rW7̞>7w~ hs9D,yTm? u*Um9XoC5&ۊ.߬ochX#f@;k5g3[g}]ir؏xR">xkWgV1{Έ))!IZ}4\'\'iؾ^u;kJu h>{\13VK*D{t%e3鞖sȫ!(EY%Cז)h =uHWT(*3C Ѝ:ֻεg37^y+L&ͮ T$h%'!\vɧ/n%?t8~ eOxϖsk=4x,9TjůJ'зKL^i8/X8r' |\;wOA(Ou l*ʜB 86fȤ@aMUԶ4Q?.KʯR>&W HHUIzy/ a>\d啂"MR):N51dCYiq e8iAXQJ+~韝Ouks%2㡼FؼF>Y/̘lޙkP4,o ʳq`:*/rdY?Ŋ7!q:'`ϮQ`4~^< YMGQ˙k4nhy}9@Ћ /R smiϘػJoI |tE(0X:vrd2$zXK}v(EI?1弐pd)bQx[ `sjt1#}*L6>=wf SfW2sĭ BlXC<6w z]Jneo1?\·c<5A:}^u?bͨ:{ʆ:SܰӸ]nvۭ!6F\"wGVi@þ,WΞ?}ZƋbU4W256J'c6E=*k P.REP' ^Shb,;5afJpHhs4+2 20 Hp?k76tgl|KHLYtvSD9WL3H޻ 50;#&ad4FcVʬC\u} ^.Ɍv.ʞ.W^*;M!8]UZDD91x਌B|{6$r|-֙ X'֔$AR %ZezXZc{KIuz &352}9 14(QL,wR fœG掶DAFY*6sCW`нi,/(gB^Mʭǐ0ލC?{[7WDcy )? US5\*޸;F,b_4?Óa@چg p@ 5|+% u}9o6d|8Dҟ[0c_ Z>:sTk$ugp縈gydd-< LƖ31ٖ{*w%0n7aqXy`n׾!P7#ƈ*A4،T*!͝Yوub!uf=l]ФG e6J4G(0k4)u e:a4_xGk,OtڏZ仵-{gDnj^V{6oZ*3/3Kl5:/iԙztxٯDۢΟ%^ DIoќ &0彾yN崄  % a@_u ډ2b 6'3~n£?휿u{ Gklw:!-aVB񫏍Q9^긓pO'}(̅dfY6/SYe:_@ G7ڔͬFRª2С&`o,x%oQ븮nHT Sc8~,pI酣w:RG g1YόNK Rزḱl{|4'>I5v6'\e)SS>ȏ2:Jt{o<_s ~= b?SC 7e|~G-(g}p{II73X2܋߶B:ɋ*l6XF'{OEj>Wu3|g1+9o̲"[CFPuD3+Dxh8~dVocښSKɟP_r#H4- u_#A %j:`D";P Lf<g=@?Bʥ,srZ.[6!OtEwWXD/j݉ N@Ɓ Ə`Kx``ݨd-ee%1)@)ڇ1 d!JJ{Tp2yD}9R¤H낋k%; U\6K*qjf>'$je+R_E({>`*dEx{ٽI =WKqA/tP6$u"]n}C6;YXW?rA`ţ'OՃ4ƿ;iG.$n4e |t18ieнGu=LOܢ"s# ^新iШgC I@3ҜO9vZ<ث|3혞9ؿ")LR|D>* _;>?p:{ɤQ]~,lrWv 2($~ ģEG :4,rb$>[-}6{WQje7%ӨȌr?w U$mr\w!8W`ŒH "zԂY2Vmgj$⸿)Cl1M,-ZAkQk|@y_Y*xWÌ[KK Z皭2AKC%-CbvA-W͍}xՅA#nу{yh %8l"ٰ @HpP;@:(q@zsBKyHWc/@#AC3~λ5$>Hڦ[ARm}@ l.QPl[#{ֻ;I/Wڌ/ u/zڄb(?am/7Os{횒vD2JMjS~;M&Gӈ) zL(wte&= PzsMjW+Hq٧)YPD/X~ zZ%Ly됯= )L`Fd!] /?ss w5/(TިYAHKX.&/sL2({wzLj Ox `t} į uBt0Q1$PENc<(ɉK}x՛NRNsqCϩ2AJΦ+?<_/gPD}0Y"MdmbQjͪ*RYr boaun8 C`#kCRXx>/H2nD& (}s1.J &'=Kْ3QNjh:!ggifdą/e"\+캿Ը9YTLW'WKDs6g3iD=MOASMLLbn9%w6'>sio[8B JT ޸t,LٙrRjޤСf*s}ЈȌ^(9~D7:ٌ(?0t|uWJCp((܅^͍%)0U^>|[/x9qN$LXVQoaT lO"b4W"nE_wQS1W9ETt3i%mAbR@C4g~&!c.zayM5EM:V Ű6+JßxAEȔsSU#F'=}x7XAW[ pj:_,p r(({棲})lJbU Ee AD饋o.P2p볘uWlS?ldΰes3,E-fϩ:K'@Z HlDsg@Cy a`^b\' _qtf`+%F?2:}$ŗ~ 9GA*o=eFJ0i.a~ ;ҵHΰ >hi-_jR3D*Gw<~h ABE/ѐH -F5*-@90F}`8bf ,:\A"*pk- < P*)ȔwK*f/C/l GU􅎶$[%gUkXY?Z5|7C%ԘSwq֚V4u q;l%}@*.f"H6x+'H#!Jayp7O`bbRx|.EB]%Ɣ(cE c>HSy9x""yx1faZJ&݅{DF8PR%ɤqnMX2>I l1aԨ-m=I +4;xam6l'ڼb3Ow/Ty9S19'rcvY?6 *f5,F7W bEJ㯕m bC"e[8!<&X$b=?b\Aْq]ih!}#iO;A.U9бdt?_0sxv҆IR[PSޥ,azV}Y4E@QR H1f8;P99j^ ĢsYNK?KhPx4l -1b\c,O!ꖓNumxxA]k?a}͗YSj id0J&}H ;f+"T,9bbu*Ê9oCߤ{#6\9BSJpGwTueUW[GO0&Uz{w0J"1i11C!Gԓ{0 !D&gon^E+ 5Z/ajent+<ykb1?K%p+g@RHF\vѠHZ|ЭlP[VA"K0%y~Bi^13 a%Xb$p7Oh$ˤyⓊ0QOl6UHRg~N-nVj(P$6ݔVOKBȝpeRX5OZ%vL[z7JkUE2clW|Wy/A|g[.zKY/|b9^4|G_SVN< F'0ʋ=G؇] o8IJh)D'Iӫ&qm{_^V}n9qk"vGC6b@co,$ 󻷟3v.hS iؠÞ:A7*1Sa؁2X6,ahy^ȲiߡhXg##ce7k S 'i:DUMOC_Yvx)4\B..aN*k{<=BF[r,r;`VFj1}*r1:٩羴wƪ3бs.ѮܐԶ4b/)C>r8 h/ cx2{kr!,F4kӜVwu%Z:HRۛ9SEDhm8lr[0Puۺ&DwWp{(ul6n~UrdJ#$.U6 rrnU8;Υ'M# y#Dagb|{[;}!.=}SᯟڞicK*vͤ5hzk . Vq. (9Klw+Z;ɮ4Nk{NCc459mzvbPok| 3u 2$cS|O2{m, %ZhRXD{;f!Ѩ E77uAG<G-٬~U^3!{3LO ~zLA 01&)*嶤hg/B7:V4]1ʞm1qtm_yU C9?e*eb!MŠ;`P,dU|Xi+gҨz|em[ O;@;^B-/dMnHx[}m)ǖYxs͆d—;4 g=4*ש)g|cZ(,L."Λ+b)@u elA *YcrJ * vIA-Y]+N&޳Vu^^kl$ YU }{g_ȽE/w\&ݹe T+^!i=m+qj6Ƙ_O/3]u'Vbsts 8QKX'lG6Ax--Ð@vbU4Dҕ$`Jn lRd_͡aEnŚ^~v$P1[ll S$JVUvŭ8q(Gw}vp{yM|M5TPC Y/LSfNG$qDkm.¢}f eE+1' e~7OE Jq<%8rɆ9kmBU0";*m: ׶q];Ei O;_&'{ӏ+(;HJFw%=^Q LS7?PSrm'nI5̕M >eQc4˨/r`lvr[[K\&8X !hv*;"yI.j*rui^"Fz4}UG{Edkx0YoWæJVBrC x]dz?HM|!wfPKIH91kЩZN/;~j!e,ǙbV1I]bCXU|YzNWHnb4.Ǵ|))N/%9YZ^WMX ~;7^~glSv:i1f $R\j2 Flا{O.[2"EL 7 P>{|ԯޮ k_UUL1,`# `7ߴ0}2f"wzCWxPNKyX5D/A I_+XrcP7HK~fEX]zs vgEk'64)ݔ(pnbJ@>tGAPN"՘ٽPK:~ t* ?XLq65F<+mG:i {4ѩ Ǡz? joufk!Ԍ6mXǕuhS{;=ޫ[lٰf`Fww?rޮ}> ӕ&y&rjv fGT&і ŚDexz-rV*ӄas!NA`R @:TA,4y*5~::xN["8vT92C^Yс49T\tc8Ʉ~_ 6U7½.Bu98p+SwV ހ V=`o=7cMuyI BpSb@8oF.4 傓.jY"A df^YÏQԉ_OTOL1Q`|D ^ Ak3_1WX߀\K(v;VtāolA&v$in!i/JÌ]ufA@gJHLRH8,y'v;vN¿'ސp|(܃eCݘ؉W99?oe y^057a\N}̔}fr!~LF-HjDL{خc 4q[<%vUeŜ>t^PƔ,J_>ܱm2/?%Sk'Zh6Cf^[|kڼU*}>e*JQ2 _DoZ[wWӵDKV)+>;yi/p0Y:P&$w|+^Jba̋+A$pr|5o%3)@dkԜN!?Zq3.ܧT->N7|S7 \BmmqE!QDH$`2Hh}_}T:[*KtkVr_k~ԶL Vf\] DZcѱRFL2LmNd>mب8[roLrKSɷxY^wׅl򎳋UqDi# $Rg*êvU0~= z&YW] ?󀵩!c\|d+N>'9azu{ @ot5 N<2ʣثMkF!QZť}P { L!`dW5N]gzD#W_):y *ևrx'—Qܻ{J'!)0!o(>d#J4_k.a`KcXZ?pq800i |lGYō-F z`-jB]i0!7"$*5BJ6{h!'e{ߤNR46 1Y;/1zĽ'E0gnW2 nA>g2}Z6+z~~ZIVBʜQ%J]JCd@2rb(@9'5k2xiN,b@qfnFgbZ"*I1硻=>wLXpvh?]Ʈh+6+}&˜~O "=6njĜ9EI"XU(i[}E›aHL>yX+a0g~$˾D25} 𓞷ݩ(y($ D65^l~S5y/2M.DPU`y M  8ū!%2;5ZY$!deHˏS" ^tL˰xJRRno$jHUV33G{LVjHO_zV%;:3C yT3*ś 4ד &} e{36(IO`-ջ0a|0"F"5A!ȝcV>eDYu:b36)Yل-;mo@RPK6 [-& p?BRqIJ_Аcs)&p;}m~rղ]g:iڟ2^#AHk2"@ 擳(ťe\ _&RG,p#6 ۰ջ/AJLV0Ah%YeZ Abj\3I2|3kMy!0),`m= C` ©"cXvz'PC. ۧt]S#:~"bš |q{{rȦ ~Gyo3pﱽ|3sy9|nB>|VsȬsjczj^ eքhE@cC1$tB)d2PX`;ÎK{[RC4~s˓+{㾕zPbeWqߔzFm M(S>C:}}&pۙfg58p*|CMՖt**L9wWv!XmfCjABΦ$B) Һ٢nՠ(1@kJMH4mt"%6n>RT]޷ƺgjV#n*@]bU#5)袢]{ʘN5Gz vrU2P)=JÐ! _y)QCމr:4QsK[:|!gǯ*TkwCm'AcQNtlDiQ(EPzh;Ickܰ{EUﭮeJlP}AMB +ﯭjF|aAo&Wo:u޽{᭾/cT<+yUy"P/wQAgτ n>)=mxy5Uc]|aTkm_>9m޵T:WE/\z+CL66TP|op}mΙY*D}wm9(FsDg;CN3ERήj \)/^= 2zw$Ttw:"EՅvK@AP iETW|xkj{r:6cXY@;R>[7/|{涬ek:[n2o|Swπvۋ'>%/j5r}QZM|4k)E&, #`LVZ⾻϶|ۥ۴{81puV^u@OT_. %jV@͠Ɓ ͛j>q]ϼ;|t%Դkf{/}ϟnva><U;jjA H6e@6n|Gݻ Hk0UuׯG>f2 67JhR]UJD6Ɩ6 ;4&,bF|"|$ ]I4s8]V/]W}WfvMU35=RHH@ *Rb֩$PT@H"P*$R*B%E%TTQIJiITR TJHH*PФBB$%*Q@HRA") m *"Ԫ((*$U)J PUDJ)D@ RU"EP))UI(B"BJ%RD*%UPT*UJ$UH)T(Q@RA"%BEREH * P JT )IBAH@P(R%U$PDD*%T)RQTUBRAJRITJ *TRQ$*HQ JATTEQTTT0LLFP `&L0&Ab0&Sbb4P4ih0 <`PIAdF5?I3Sj0OI꟤F&xɣBcH640OI'df螘4 LH&L21224hd4d4hcTF&@ Mh01h2`#P))$M14LOM 4♑OM&i3OSSOMFM'624f#$4i~M oI+gmFO5=IGZصM5404:^hRxM-\_nkuwx4M^G:XVVIa  Ƒ֤vk\Yޭ?Cg'Vx7Tҝp":0up:}YE83(pPD+"JUᕥSh-aw?Mg86הɔ랿guEM(.HIjr/F){PYm>X>EfriZo7դMzMk2i?^x3I{j|->mo೻3~o98oSg;~eѓ h¤"T*WVR$KLS)W fCSG'D;63ˈ5o j|Mm9N_U(uw`^F>mo0pޣ`rr?ٺ:g-m=ᾠP Q6?;ɴ?KiikNos{̈́ʙ3]9'99)g;g!; LFv0:CiJHh~a?̘3t0L-*Sy0IB:ʼ/G&NN ۇ"aB SyM4pP•;a]Q2sasv%$ L( 񌙮勵8W8<O(9 Qj sq_O.22眏#X~g|6TO{}N䢟GXaJvy2x>FOzOnG|J?FB^}xb(BA|'lD# Z\/~eUpx\p9qk9oog}^?v3y*z@_}ϕXd=/_jyܧoYy^[83[nJ*! o*j_> 1)u1[jk*wrܚ镏v>W$qwZi:C|/(k4^4ݎfWrSܶtFYmw/ԩ {8!,˝ݖ٦7wϐJlQÿ:+2 3NT0r^s@Q4g #2͠jZo*wp7IX{i_(g:;z @Ʈ½{j}m-rbr !˲8fd{7VP!M,6q‹]߀s>t#sAD<ljwn8ҿw,db a/@0xSvG CA`D>p"Ɉbn N=rhs Fuy^[>3A!ԘweNH Qm]!ʶTh?j@<75HGI1"2)8 cVh=](sh:lp&G*^hDN6.c><+zN@]B拧,|9I5Q2{/7醤gMvum0"P,k%W6}-t;8œL"1!vGjk \# Vi5 R:ݴه#XTFvvRRsj" Бfaĸ?^ wY~xMDȪ7[ґv?}&8qW}NFQgͦMџg,qޙmgLիQYc~()s{3_"?P2BU@9V}JU]U8K*^`?j}(iXC@ `>F%DgTp>,)/6]O\}ܚ fq 9#`mjX5ttD 7s,|ZWj3Vp/t ՘|$ %,21DږffD錸^%\0eWVBºHvHCs9 SFItb"?Mmf:?ǞrX\bT+@펐Tە=hiR,.g߷G%OJO&xJOhd<3fI:'UN,GaoN[$|=*CؼM°XBKoTkY̏TY,L#$w;.ppqP<RxkP`*Z3ks}9u- DCO6i5!AI(6%G_U}fJj[.oF|5*ZaoF˳q=c66t9Mɔ>#o4G):`5M!DDDO@T<(!A6٩n װ[L'~L9#p@H&_'0?`nP'Ħ?zd !пd֛  ϻ!F- ΁8? jdQ"w(ט . j' cŷ;s0|WbIED-Y8[1}@Äa\pVN5cc#&VhՊ5wl)M/O^x B 0Xr\~g-/QGdtJ2 wZnGd]I}e=ODb de|D8^^7>XܑӴ&1dmtcN%@gLp;hG22]~sTUЙ9z3htB39ZRڴ|t L'&Uߨ}x?3o>{!}v$[>`}W⚦>(mDsr[5z/FjG|LdC1Rdu^,cv酙-}^wU#~0Џ>wbw,%]_t*$6rL%ImFIw@`w1AְI* cQ;ruCyG-l Yu|TR@/n͇ 9#;PA=U}-UVn!xZfX2.8#;;)4_w{{ɥN7mwh' S~,yzrį~dGbC~ =^&)(i `:NuTs﮸vuc=7A1S=n5g-׹^T=9o]Py+h 5O>Cɗ7`᧸1 CԺzLYȉP7.n'em{Ti;|A(nߓTַ|碠t}J4]/][x{hH(80 wz D Fr~M8y3n8")?Z939bT 2 æ)0 @nF!PcWc$1S|8&~9wyNI (rU)+bU=Mɜk#CN118;JYM]g=6} Dž| v= '+0)Æ&3mOT]t%}4#j5M.PaZ9{պ&8,3(DŽOe^GW˲ -H3 ~U9~ߋ<+j~qqpAE#W9Fit p>sp'Jlqusi|X>9aZxCQB>R G%|_ՙc3 XcJRvC}mh"1|>-b#`Th"zCsc!:)ё#jAA3:GkTt+L@@ NNe_y8òp <ձ*[; ҥ+8J̔ LL\% ؂Eq2?WXۢlMyC(Q 7 Kbq>R4ly/7O|TnaWppT'#iZ SP{[ +ŅjY3>șNGǠ*+`G|v=iUH_A6k3# '2t~~slԠz>n g;Lߜи4q=3:o;mr[&t8p|LqI9wGSl/ij!٨'cn\eC ӗyogWO}g/e8oޗ|=Σx`'&>l;L=[pm 'sx)}>Sn?ů !P 95ȁ[ F8ј2diFOůQ~/ϵƻMqma12}e]UdT4> D3E1D_!eߞ '?M xy13锰JE`u*X7t Ws\ʩxE[,Xk?+'ւ!/$xĄM;s[ݥx?K{X}kI$I$ؖI$'՛{vUUUUUUUUUUUUUUUUUUHTXEQT,UUUUXUUX)AHEQUbUV(*QUUUAEUE`V* (PTx91Lj©'Ĕx# 9qVJzk9mjFjKV5EI EOߥ?j*VBV"։Xc, qlIhT +T`"0+ bH(d"V*őH T 6;@uO @֟kXi^g`Bbt~QݨHwlX!K$/6V&CT.PqJK0@ATX2>x/Cg6K8I+FDA "w!>}L̝0M@/+H[Jށ*loۘ> -/QVܑd.|<xi 94i|n,:"`=LEOOUUQUUUUW!?*יqa9Kqi rGI UQUV*0Ѐ ҥЌy-ɯ1Sp?='^q. T3ie9 Q,k,ɀ \,ѤMNw((ӫ[09ٲg珳>ܝj*a>@m3'=$'lP?2K8{bSPj Rv7`W@BCABBLEF Ƞ_ *~LF\J} cB+sdrzsMQaPx ضS0l6kbNb-ⶑ6-l6ɘhUHbH"b,1"!MNfmᖛ/|l>@'>Qaj$$X'I'(l}Z['ə6IbAL Mj۬[B)N5C|t`i `6S/7M֨=Xi +^|`u m{qyedގԲHOVC w<Ԛ@ a? RODvCG,ľ4II u\'B-S 0y}N:&9gOŁ@SvL-I~||daœÒf RW=K5'8Iv' >;2>jƽ=^g|x=̇~G3PkHpa=a 0^e-/][ ԁ!$ #ĕI"zX9_'Hp2Em y')?|;y~0b2J n* ]*2+]'!YY<C)$ηA̖Nb 0ֿ\9=('_~.h>_?|9'ɞ'?\ 2>36n> I :MOh7 "|/{pohXxQj2^%&QsmZBnJքܢV DN]_r qd;5)?׎}oe/vxQ8{mn UgAZR)КiڕZV|HOB%zHuD{V@ϝl ARF]d1 T(R $8d GZLS(TNcw4' zEFnNV$,*%D!]a(}u X\x5sPf!5@hMZb : 1QfSBɈ"kZeR- UIQݒ~wY6I,l 2k&%HRVXKqbc ]UCঀݵmՅ$"@QG)lWB% v^WP9P)Ty(n E(@a!S+)`p2o @1a!a!Tr1awauB1^.}aIa8佄X"O/;0@3Jnb%l53NߔCNSL؛rSF̓C2[!1y9?6` 6D@DdAd;{ChN$gy9wrrPi$Y-%9Q6Bjľ >)ˡ&⣓Jl \]z.D7ړ2!/Wc]-|ل=s^.)leI͓ EaP9fBCЗ'dhR^:;{sҧwКd^ $_ZQXgA\}Ϟ2ZR{&d͟ <ޕ2vҚ3E|_]$ɒĬF(ªQ9jKhG6q~Aq+ RKxAO\\bS7m7qhw>'M-eQIRHCplg-VT!87K&p[͢j-)1v?I픝ӟp C )`rk}d3tp6Yq?&d9\ʨm~ܖ><6Wi E(IVhi6 Q{[׎+fy@0`k1Si8Bȣ[=A DXWZ\7)8`aSv׈,@X8lFP3G' A!6S$d")ٗn]'QΟIv5Ү]X\C͹``"UQdmmUUUUVO|_>̥ z7/c[j|~V.5E>7tTQQ1OZ &3l02-岯Q?Zw6>qu&Lw_ /aCwطAg%$ӝW (^ھW6Ҫd(_Dt;;3 aQC:MMq2I:9n PO?{ 51ɖ]UuKV}lJ+ڔXkb8ڙoD: $ϋ澆r +9P&#c}þo^Ҵ#I:j*s3;fBpó-u{ ˬjmT7GkMs'k#ue!tx snIdx-<1TjXL)x+e#xY1('Ѐ -xHN5z `:rя@6\h>x'bD:@F|@7- . p,8olOWMx` ]`8F*"G e~90;?A[Pr1 M67Q vaKMrA@qnNq(v#ƾ[ChRmFjVx k0^TLQBF?ml&jve Hi ߧ .*tNxT1`c0Ԍ U䗻oxUdtqH%J߽sh+^ֆ 3퇑Sm%ŝ[B&j1=0~UoCм/Ć'Ke"Ȕh[?JJ$o#W6Nըn2Ѣo-تx㵵\`+M+ pF,Z)r9)eh깑Ϟgۡ;9{Z=D~Vqy!m5c4DofuJ-^5ػRoOME7Sj{ZvwV᧲m?y{#i < Q4(9aau;pz u!@m5@9SX6DRPƠ`!DѴBTQe?tBfUqqJg콠(XNƽ̗tM L܉I;->$V:vn zYy*/ˆīB֚49 5\P#au|m_5 jH??;, SVg^P@!SD9D'!FDԵʐI| #?LuѰlCAc)a }4Rdz "Naqa'k1>㟰=g\V03}m>Qo9E"&1֍|!ɻ-pS8YEprDZO(J_Yـ{YJ֔/,T JozA"tƜeU ~(8~J{[G88.$R8 vMcǑ GU~ o IJ\v|п^'zZX*-9cXΪiaZ25)ll2|B5!SUف䯘R,f+$bl `ĆͱVfx!CPmk97!fyDŽ %.w*}X#=6oj "> hD)Rdá*Ud1=gY 9Ƭp1WcXZ N];݋ژA*#N71̠QZ :Yhf)_n#-b`PPSD|eSZ9שh! Óл΍9ͥ0m((1 7ӏ8 _-?"VU6 $v~f/l{pA`;QIYK WQ@Ꮸf"Ħ܅@1?P᷹ W~Ћ ߝTQ4 k!5G6RcF/jWS N7͋õep&ɋ4:.k UAE3PY;֜>چ_X&LP8F0е4!<}P,~d|Fe3aTX@$hIفO=wV^3鎁K"XKxMz)YA sf2jY;7&e9Ӳ1*Ƞcur"C#sWAp9%$.L[j`FȰcgiH6i視`@C$3yo3rLy{IqPpD(SC0](AivhQ `{O3tAiP~·d)۴c%ގ@=^8-}* 7edRmgˈ:3 @ ,wGp9FL"QoL2k2Bt6) \?l5۩ S3wuHIΐ-EfacpLp|3 09,#bf:=b IFk;:FKr"\ؚ-w6(JtTe _]ٍKx=bc/pd y?n \8˞C(G͕_3-$G4i%?~H3`rVtF>~MSJ{R$Tj&!e X|Ahj $ټͫkiD+W6ٟ4MJJ@HYBVJ݃ l.^xz!Omy4r,A,2~G ̘>|Pl r~KT3U_ ;;6>@ Μ0("S+zcr22#ZwwmM6Lw 2'دڌCG.;b͸4pp5y>\q])/3P5[xԵ€! u5>Ue[~QU\G9RX<<ݿ)QX}TmwA tnAk8m :jzJPh[4A^p^Vyȝ(?ӻSX߭zz,~CٙW`4/tݷDOJ Gk/y}j<El-/k}ӧL.s~e0c#fPdK-c,$%,$5&߇JD̏{?=;ސ栈۹g\To ~htvF!@,$ J͑] f.oh' 2*u$/o9 ݠ) yބ._?lDI-D9 ^kV5H J1aXt8sF"gHehKޠw 15P諕Vʵ6Ё@5.k8SOPB#+Fښ$wJ*`}T"1FAaO;ɃTMz,;"gb3% $+Ug{%*~gN<kL |.K-MC Ȃ tdie#w21\iOfB-vڌY t`4t!'Lt!͉6z/ 1X~:尰dY9jQ*ҳf+j~cJ{J6Zg3?dvwFkbMIs{)9)]t-[VaN4xϕ}.Vxܙ ;ۡZ$ɍ0v&\vӲ`yĊ&}ѻ$D(Fh(׏0.㉕W(%UI_n߽rEv>ߗlHc.E΀S*>eVײ-pر:񕫗G&9CL3M`2izg  [H^Q~N۽3TC۟<Ӷ@Sa `L̠"1dοU;IdaSN K% 0|BO6&Ol A=-$07 h{N"r Wznp\P^pLSQK1@' c`&Hزv2+1iw;O|g4o^W68ʜ{c niȣ27R:uQih# _d #xQkSU)i`LD|©ABvH-Bש)g){7TƂU:ߌ:IcR y"՟Uos)cpX0O+t%Nz(746XPdN5yg8X8J!ODQ󁁇OДt-]Pڳ0X;Q֟x>,{_W\VH%xz$=78Zf oy8x⁃+qMj"IYɵ7 hR DoA -< sX_Q+@ãOZQmW;ӝzjj ]C8CXj]O%HRQ]sb#}q}3C|0qp@Vbo\.ẇ B<;U!um,LOɐ/N97Ƶ#hjqqZ< ړ D#;1.` YJSZy5@"  uukit[g.5'qYaā%,vs. )qu Tec[`4 $O6>?@"ߙchMiqvT&j+9JŨRW>L"m ~2T:έ>yxѺA.zH}m/771:Onຩ s &?N#ETNҗA3~Ƴ(iOӞ W>%w:g q_ˡelA+UL_? 癵ﰍЌ}; H{U;k7f}t?Lo.tOL.׹u}+Ȅv1YeԿQw9>OFtlj(MكEb obX89(jJrIM@:#kO3뎀jKYі1ӳY}jgu͚N&-ͷ^9S >)-BqJ !^wj쬠$:V)¿Yk>N_ \e : @:$IQѲb(J4U:rQ[/* 1B-)Lڍ_336?po,FXfvƦJ !0ʿF*g78/9H(s[*q0[CR-_rA8dvԮt) KJ†`ϣ\H ^c4D*b0Z3 ni xo z]>iAy( rHY ׁMwcy!̄rX94>HsirJ'Pj/o+,M{bUkgQmhe.41~wըjtxB?c5no^ءebnTC{Q>\$+lre-3{1Th; #2׺Z!ewBTr Bkcq\eWn$OB? b>ʇ%BϜHt23}3ʜH1Ո@I0Kc!cnSn=˅Ӿ[Z]wnh}o/~ߌG-|>C'~W&Ҡ'ȯQCaN{+w/JS7ߦS;Gѕ.ӓ Dh#E41aX:Ɓ3e=H`{`Yo5L ynJ|[śẫCNYISzk@M#n?>pIzi&3>b?*K6˔a;&Pp*hm6OEd7?)2NvKټO;V>TJwojٙ Qy=M;)uͯx.Ug:3eقwdyB.p9z~.vlezweұxa(o֍cڷC8`P|k*XgS#[ndVK)O<38ⲛh`0Ƅ:p,r\} ٺ<8&ԢnF[VQk \N▓jMNPN՘&G%HO=E~i.K=3(ث^[ sez@Sd <jjj1n?7ԭ{j3{l# 0O}$7s\,IS5V DdߎVDvK_wTVRzՙ\T)84q0 C(}$?L>魰‚'75:"y`\ow9rSAg$Ya@vje-SRC(pf>'+BnFS੖nZ~vN󱾛IN6XJ :VX8i>I̤W;S8`,A&nd|w+WPˊdfh}DvEji*4,uCհk+ws+6o"iUh\|EJm$`S$U9ha`bf Qlj77{WJDTM}{/->>SL؃k9ڝk>f-6І2)U謥`xt܋űGj|R%9v껤Ku^3uK 6bp*Zh\ )sUaWK p ßfP2O|60 / @`ޅJ=yɿ{ǘO`3iiZ13&.ōW\ůʋ;7'G!G!87"~c2W!p?{7w= :nrurr. ]rAFk]6~V*p?)xREkJԡx 6I UE(Wsоf9x r5Dسޔ\>ޫI,t/<)rJZiGΚ'J ]Zt)=V]-$?%^Aa<]0gGsZi~r 'x=QeQF6ĭsFDv)c{ ݢnQ9p|#16$ i N/Fnc?{ՠ49e\]_ce=6hU )ӝ/`!v.A-$؀9)qX?W^apq^DR5!uHw_eI5'=y E lR5Lk|vb7lnW9\ cm>ѱ_k2Bca-MBtL @ %€A1Z:-ZJ3ZsNl!5[?(="@c˧0MXrkl  "a2$ \c-cYWmv[;яwg_̘Ao H0/$bLZcIasWӰEsWOTr=g uj?#4+(iwvi h^ggǩ?fӴ4DSw;>)GHMf~zDLϤ)@y.{Pžo [BOYr [=7NB8Wck+Pu%a`C"mn/e N) oӘ_JC-/W[m~A:j\@:($lʍh"Mh Vmqb],Wmsm&)(U xDےN[lQ !}9E"$y,/wkO 7$l; r-pv pZK>Dy *Ű2>A< Yf)GQzEfwY25| _Z6h`&`-Ԕ}T: |@&[0Kz-C*5. V ``3 ,WKm|$(|ag$/: ܄.Wy[+I  ;Wd/Thg`i"$jm n1rgRY"6:ST`tw_FeT܃ EȢ2\.{鼥Qbl5n ~%z *Gd \ǟqʻSWkY_BΠAtV[Y%)H9nzDC}-r&l|w>F#GG蟆|281VB@ cE+wwd'Qpv-sL|z}lati)[Ok z .#}CdLZ?tYKK/NVd"2jBO(xY'0s_÷$_.OoWb"} <eHç&wxTJgΧ]ODOӟ7t@Տ[5N*&:O ; x'u'=3bWPGwܶY)o,)%^͞J_'Olnt(/F͵a{ۘ2eYm<+Ef>kKyW˜Zmks˽K=4$yZ]-ic*fLqj~qI;S뷻9nޮ_ZGIjn GrIZY #3p mgf]-ٹ2;?5;r?DE~π7-ƿe24U'G⋏B"F`~^"0K4Y}WSbkC_b7cƩ\pQO@@j{SmmՆDkQ%/j.#`_:8PGG=ꪟ3 \v6o'4|,ݔ~ﲮyLz@[H!7sH`3~)Lgo(-9bP$c+efytx-w%$jRqm@]jZsE"%CO x.c]dAw߬oCdKXb)ܘK2cSn<;,x0\Oujт;1XoS˓&ڪ?~ީ$c|#u7]G (a/mE(D3<1c bcv4):f((CiˌX4/!BڈD*.8[ugw0c (R8izo2sv}` <7ÑN.s~5>ɠ+0q20xFQeeF:% F ~-Q>:~c#\WHiEg"[WhdJcG 0~]R_E,ZI2W#xNGNuyѷ9mvbĴXG_VŚH>)=EVi cN|+/xFz9qɜ׶xԪ=Iny;/ӡEE2^F '(=G zK EUWG#))M2/hO?bW_wh:xw89!iS!zrk`N3orJ2ީ k3=$tY%OyԟT 9!Y!n Aec-"U:E9i۱y l 2U?DGyENfY܌ $kFU|RXV9Pocf]Ф8؇.ʓa!Kpr}2p"H!Xl1,F**ZY6Uiъl̬ ooyo,yO$'4p\:N[4DP9Jr~Mv T 6dq!Y4<˥8ϭܚ]ae^G\fŭ[OrBhoOJ+R:ׄTV4 Ts3oD#UUwErUAi}3^ L(EU:DU攽= $ IkFcP£QȒlRU&݇TaAʘF"#"/(JyV1Vr$%: &~,6m#J:0r$XU ZP!&eI?sKRHUM0(2X Q>QkS=[\892uځ a'mܹmrBǹ_4.0@OڮVr`um1F뉖jTUߪnR*_+f \eH%QM)}CPKfrv8DM-9f31qKm/7j) \*4n8ϸ͜vyfE@8=CwKVf/waqo \^ċь8ʆ0z}avPYp`{?͆CǎU HUAzg0QOrL'ojߠ/0WST!8h@ͻ*aM텓}97x?k' 4ޙ?gPXLh)|F`O59B9U6Ȕvz )$"m|  χ;/b~#E$4:a V$Rʄg@R{Zx[+,RXضѠڔ-vjh*,y9Z*MF_=SsW9RfN҇4 be'bݴ>AEub81;RRK+9k֞Isux +15}I(ЧS+]B%G>y ‰fյ2HQ3|fӿk~qnkp]eN8k_/N>^Zxy޼x>39գu3_wNIKgz9okl-JK|Ψܷ3333-s3333[.<󙙙<9s;k>O u@& ճ-[6fgb΅1,V*YؽF,| =HI%9QYhȆa/L:bADDDA1F:ŋ!}S@q0*:8% an=Z]SǦė/VW<lV,pxYi`z0ї"H*2&t @Bj\vɱ{S|#ВF%/,^[+oV{$T!mn{iH v߽g"RA.y^ iu%ct~V|E(OȈIȡU Ba \)Y%,XeB$QAPaFĦqLa,pIqy><8,Jdm-!jfR`7ۭn}!B%ŤߧmZf2Lۗ;t blC@M)e iju;;צ<\&Uj_:AZ!.([x{|eL|B65 1dzb"*g̹_MxTπH?NG}7S^!|Igc4lA >c'/xNI)'$|ȤQ ( `"(N lHnx'exzPvjm)ljjf͛6l{#`oĚ~U`UWǸ[UubNwAԁA3YQ pP jJ8jNmi5Ze&<"Fa.)[dIԽx$Y:BWZ(X/|2N3Ki Tlr-2-Z6>Ig]kc2tyϟ;&+~^$q^6AߒwZY~;mH:6 L"YVXQEA k-GJS cweF:24 TGH(a׊ IB,.%;Tcq4z,xH"졥E]i.3AB"h8 ~|CTq/Thj.v^з7mEU9n"A7t6qpTdD 1zdH=#$訁Z_Z(զ0&.Ȩ^&P < ܫo~&h~Z#C/Y_z& KH@Vw3icǕ(TC"RQ=+Śg ae(_t֛bX̍Pʔch!sqkyMz4gq^ʨ0˕TajFHSk_fºl(u$5uuѳiY,v+ip9^K[ɨxMoO.m5*]}Ęj 1l_V%pT.҆erQm-kwkbH,To^q9nV~V+z$UU\˂93s⪊eQ̸+_*҄եUlH`/0%S*rr,|3:IC+ $U$I#bXJ* |IyQxJXѶ 3^y5 KgYs)ۛØkS2voN9 <ӌ79ε7- 偑ivkюKfՙM]z}9D'؏ WZqCSWJUSvkΰ9߯'Rng^Ik4Ō9r @GOWG:8D[(`jPJ4՘4㩀@{'^O潈@*aҫDBJ˜W)RN)ۖ%+9g^nb^})jWm,)_,)S]^JuR1+즥~Z5_ɬgh볾P@~[,NǷ7os϶'*Ygro 炉MzP;}80.ItYnd̺9E'4 F}M[N yNg:gv6qa¥􆽼|yهNӤsuCץ~OUy-jӕhSQ+S-8b# =9p{}8<w:F Ծ;pd}Xpyx{C<3vGC׮;ױON^uG&ɝp埄G,}j386هg IQ",_ܔ WsU|h(ZtZ t.;C{,ϲe۰ 8XL~cDLEX(Wk D+|i+bϪ-$oQqASIFM6AᦿSY@8:O[J3ѣoGh`z3x:|&Dܐ Ǝs >rttxydh'ٸl@I}ᛸOcO 6ZYןCu6np0ȝxkkG"&KFx۪4(.,%: "J < 6l'08)Y2H &jR]Ӻ,4$ ![,52QV1<w;ߠ7`28gxШ uQ F6x?=[Y/0炰YZLTB JLwj0R* f*@U' ?S=a7ߥgOMI>"n,/c-6kM@uݛ/o`lm&D(`چ+w]7q e^4WLFx=֖ H A1kҫN]SMje DnrQ hMnT]7_wkP œ%ْ--i R/H AVd KQd+ZΙZ$Jox))^;3_pO>8ٜi;fJP@V`jz.@:qw݌㍺=9Ohyr R8Y7!Dj5'U-Ѷk1G,gUKAmVrȂDI |AH@,$"@(A4ӮA':TϮϭ{ߣ:zxW)TYf"₥)Ye.QP,ķjkN(Zc$gĝ΃[=̽grByξ}pήj3>8:dL+R ¥DJj먱%fۨT v&Dϼd6@ά-%uDQj,bQIgFGZ%|3O>)fiqS 3 b}㱇曤0oi4撲JÎPP7h;'%Etк~E@¨%%T $Ӧ)SvxjlEHBQ/QII)!0$wdPwP g*e V+zWl,B(1;\xO>oCE1{2n9~G'? eda\S%翝dꢀYѩ8ޞ ax)n{koBky:=i(߇L=Yw6:wC>`ӧ^5p֔'WVW]z;7 -+BwBr(5=w4zz֎&rk"̣}C|;)uk[*~H~#-41ew`(QUXgYbQ+UX;Ƕz%N01„ܧ VTUTZJUju5£-g0Kt%K %{tUuRB;l$ _8Ô"^'$%$$[+a&E=G!H)eHNScQҳ\yu~WH-kVSu fAEV>KB5AqM%`Kmˀ%C^4&OzpGLTPL~డ1P9{|;zL@>C> 8QRg-w#b 'օ[7pJg٫ mĮ^ 胩0oBi. :O$,%EY(YNq`U$l:)Huf{{8a!kZ>qUf̈́ . y:1c!xJ{>dmřBtEj8Ip}C~W|ǥ3ې@Ƿ8zפg\߫ldM-J|uɉpOR͑d M Y9E,BٺVA]rݺKasFtY-(`Ċ^*5S]!ǿ~ɓ'{ 2}b0O< wNO\ל3!9>ܴYĐô?=쓊CٝwC˛8NS:ֽ57@úxu}~𪪪*dQ?aD>xWl0N꾸b޲RR 㳔"(*|3k&w3$z:(ºNL0Mׄ״R${}:@@rט|!|թ?@0M-zA0N0zmp߾u |N|Nap~SqZrB\$P0u18B4VfS 9)ο)I@g$X,Z3Μ-9O"d2JKtBD"@x`-ӥl-g۟?u_dChdE\>$ROGyOȌNs5t'\ 2q,9GG<ߢNP,!xD$%TDxn•R G)Sj0|#?gۻ[n2@2G $cFA$?}ъC<걘pF Yl!" HE$$dUI = ~iWJ4c!@YIW+ÀCmB8`iJ0+3/Y-!glڊX\/ Y 4V2TX`C-X[Ei.&3pS< š8v0vۋq-n9tL.c,v70Oo8~n />AfK ܚ$AlҍUQ !SS Hk%|$9a@6;a7Stxg73;B `FKI l |Y%"֩) +A#muZq"ȯ&- dP=MI5 9>z&É$tF.nrs{;k׎Wwslܽ="g|P;|9cw?|˯}sF׳f}L~~7w{PBMv)oYuڟo' E(-QXUXUURI$Auڸ''3q 2jsj!L!R0RB #(IQAJٴXh\ձ * /T1RIP]AeZ9&[.]YI a~zqk;4ZaXpND%b4&0P:=x93O5ѳlTJOÇszT ߁G.Bq)q_䙢@x8xǝs[1#g<'zaV*b"o>$aT㓬}hWy˔JXk< rsdy=HhCf9 VGFfs%XDBH`%BrFR%KZ_YX|R8CEE@ov^8_~I$\|yNx[?G/Z جӯ~0|kN8u',(]!\qnb}Gx~Of}.83_(Ͱ> |I8<1IILz$ p6=syVWQ2m/sҚ'(MT$wmo"!ˆ6fCn*FRN@ `BC9_mE6sI̧* *{<;}G[]׋F1AW/{u܄PeBGکocIZ9M ʍ{Bkq^G3q@JL|crj0[+j ](& `e^V\85Wtfvfć!PHvaz$qơx{g֋^t0=y{|Wǹ`*2QYVIOD9^Rxpoíp+x$ҴZZ)jX_w>(zI0YbTGV<{U A9UC ZKW73z8L}>3 9;i҅ Tm)"h ϕP}mFGVfSX:Zh+єr~[S@3raY2( WjR)zIiQ0XK4M &V޴B@<p)(2(B)X '4YPjulRl ; 11LBB=e0Awb)yUN{=;; }5'^Y;ÿdo: c[3 l?vO 2p@ HN>sgC!gp:O&,ACx JbQG)("w,'0־T@~s2qQdVFMR![)ō~ ̛di?8ZEFc_?CWyuZ4՟$p]+JYiu宔4>TJxwHw50OZJj{ǯn\X/<{C;̣5PByNр1H1!'w';;N08:_k>|=㊒^ў'B1TQ){$,.#  XuDuFJ3 Q_QzrR}jm^@!E`*v@V S?O NfBaJی50(JőV1eX ,A1jQo r_'ƻVlV"]M4|Sj Z-Rk{v7> g``[L:3a%E/-LC Yhc>Ff SIF5za\%Ҽgs{zj|x$=l#<8 N'sS;9éРң$ 7n(DIJ`&2BG awϯ!;q<ǣx~9qsǁ~nI 9ӧђk߶z{n{;û|x iuůfquߛx^=DӔo@ʜаOI gMLJ>dܝ<#12^/噥YT Ŋ> 60de`H{?\{*>k3?7kzwǞ{@st3s5uרn02TrbD8{\iYiqOK9&~>A4 W/{ہBaUZaJeBQNB6 ݥgӋH'>=}qߟ?Epi7׾BL T?}HϤ-ggG.=GIDUZIke&ܐ"޾IJ"ʧ{qN;7Q<|N"Ҷ]Fg(l2wH{=i;6t+߉r듎.R@<y;B#w'klW>FlV1o~n߮|v2(π'مH1lҴCEgnTk!57Ua}ۀ`HHm1#Bei!RE(R*]nOz>;zs u0|7FB\MDzC\C;gyv=d3u+m8YJ@),>z"b IŌO`GNKw۞GXu?KS: {qrz >I|tp)ǵٯ@<;׏N֧޴svgn͞0;9ߏN y9ߦzrg])Nv835=:= 㽖IJ9h ζ^t䝹<55 rv=9lv/=d񐱊 |\Y)6o>;&y*aq ۯFu:sz3ÂgZw-aoY&},vty&ijy$4^s.,>) *г$Qd%۱!FoC:)${Q0DqQ4#eR W) H-;!Z !BN7:_owe7:Mb}&a )oZ,ɳj(|=s#yA|;ߎb^B?6JV@R>rAUj׺&y+N4pjĖ[W7`@/($`aft*-ݛ-)Y\>{3'ٞ:Kw~ӯp՘'>lԆf.~ @8u;%:H%J~k\X` _XcC sU,D""D@"Ll*" {)ޏ|`u$>|f^2VEbl96ۭ)*ؼ(!+R) @Y #*# +IRp,l%u@&}Gh ?OArVPP ܞuGs7 9O07:-U W>[wI ( ꩑RB뻞Bǽ> 0uMJgts#V6t ӈn;&EjYȶkdk =efT!ӯo~'Tq+~B%HXH8TXRo2|3X^BE⩳jx}ϾAKhvOmETS{hO_9㻕6}_x"lo,ܶTK[SFgD7wQ\֋b۱B/!)@@s5?\ *S=ԓCxPf֩_HB,XY(M/ _X,bV*4Z')/~6YjlKJUlY . S)#IZr]}[(|}^lȘ:ԓ5;ߋ|pLGqAK!чǖ+饆)lyKB)RQ"2kۭ :0WE({Ϲ|i^O?]…yUlF\0ڑ=Pe)p2J{?Z@0.vey?L'!.neW$7v[ sHVJB)Zt%'^Fy>Vmugֻc}NS՝Be =<0 P/(4>!EMQĖ,yݻxjի/嵮ti <6˟f4M[N8I֪!l y [F/i>'BlGNKSˮVZ1;dLh1復6j@?m3 O+f$Ż@!Xo"T2r} >>$\_y1x] NC|#s S\[SC46\4mis_qoXoK{Z혪c2]`EKxwV;.P9;frO?LnM7Ff@IY^ղp9k%TA)k#62q~oBb\Fn(J?+| -FGP͸`a{Bn4̏psobrZIPouD-aşHeX0~77MΗ6~b C0%$H*}x?>)mK"e> ;ڿ;]եŲQ:h>wif|~Cw'6[[wMVIB+@+iq3'P͚}Q%r6uGa^Y=f l'ȇތpX:!搶\Gwp% V[>1յzZ5O4exo`+`n)l S4}>&X%QvOS>z;iGϿI@М@`iq{O2.uޛ{R/4N;bafcb0VP6sE$!S 7 'wqv j@)jք8F]E$o0 5Fmc}IwFXBp >,'{j{,Ȫ={/;߅=_|<݅*׮"aFK5z4٣b'ON, @n^c}Cbjg%ÝMt^1cykUg5H_%AA4T%DKF $1Ӡ3T'u5BU0 ߧj1) YaDxtRC4>WkRݾAq~}!"x+ & y.ېk߂ T3th?O_]Ub} KsI"X hAΓI5IJmbk_z˧vZpr[CAJdo@QXi`cOG.sZC4?:c^{[o5S0X̯?zt]P}˸Z5K6&1^{{FJq:v~pJjrRc+YTsj IR;*@ e^\P$>#~4Wp.9๎ڹw\δUTU}b4"s+QO8*,qi+|4@xl`+pYk2.$o֐Zp)CΖTgSw cǢrS;tB$FvdwOhn;|[ⳟySuM_ E(T_Du6F\D͝=BO"gZTu7)wǦD$j*6.PX\{||]!-^Vs;pTc&^6h{e !?졢5TKZx蝰Is#[-޸nW=b0|6d!T Eq4 Wi\tcN0HsPĀ4N t6ŷ5כ*SE"DQ|cl?cBaK Ӕ ʒ'u?'g*"Xk|d푠s3ELwGGF]+tۣlB;,:no uRr̹.ˮ>PW>|."wC^Hh-'T?s }$Uex4}2դfN)SuPpl<{gY$w AV Zi P&ᰧ3͗'}`^5Uņmu]އjДW&BY;by#K Q+ڧh]_mc)܏:rDenJm/ZoB`A[Vy"CvZ.dW#cr^^m~ߍ"NU|Eͫб&53$~C}?_#dicҩx8 _ܲkvu"/hYFC^ɴxحYj[&gW"bS/B=NEݫ=Qblj*%&G~DYQ`BFtg!LBgS7jџd(!UU}7 |NN5Vk֮3 2:t Ԗ.7ug :i XA|Ab,@hN@Vzlz:Cen M ͹h?8L?xz~tMx_G8 QSIۏ:|+DEȏ_}> ΁gIS%Ҥ.u7@!x*vİv>Fb!Ε˱&:\N9T V[7..F C )qB} *R698XVIg_P3}*s8y%.ѿ9N&ѽCؑTJaO0JiATǛA-! %bDp>8ҞF!Q/5_%NjOq"$ w=$]C{eqK(stQ_KDx\VՃ ōib#|9e$\mgRۢLB#*cA ??GegbtͫBdKQ25"f-ضeJG-L.XhŷU{QuS W .m MqӐyJmqmKުh9_!}J,` ;C9yD%& -]JE ăo!;zT?eipzu8z6'dŐ?޴5'i=խY!z: P6Q @yg%К6vw%q`$O#*7IT< _:ɟѝ֞P{ JճMs*N~{ne]?~?p>i%|f[vhbUoz? c׳,Ru.s'(Gr8$BVs+9 {+. ,_d割'},FV!8ޓy}M]3/tѱoX;>mc!x h"ue?,0wyzܯX/^x3;.5@h 3ɗ+cA@,,>L'vIdH@ X*D Bw]V+_[3 e UbR'Y'łD1$l h8.3zmP;kG=-T# ?̽Kl,Kٙ+F͖4N'Ϩ&,8QNX[el6_ΰ9w-F3: O5ܜOߤ?H)GM;Soi9|V8M_/YUj "[ 0;h_r1lq3\hu3티ԥ>#{rLk*㗘o a[go*2iHS ef",D/ܵRt--˾3!P$Ci {tW-,c"m 6 1Ս#eĈt(0㭡 WEΛT,y>1 &ep~>7NfmR""P[@,{vxz:lVTrźDBuA-5)X ^9,?`"")HcK0BdHA۷vk`j[OXOe@YḾ|W"FRõЧSpF_<ZA1LIQ=!o{:思=}wFLzvKTXɲRdYM>\:1޾yGg(gAeY?#ޱWZ5HE׶0h5}6[@b;vbZBH{?ޚ+:utns5ֽxyw\*kW<1{:Dۖfosw}y5ɔϏ\'Y>>E Z9^Α[fowz-ryffoyԒI9s `L }0aqÜa3!`pKK< G:|ǮHZ7ƙraߘ7w,Tn%_vO?URz<%]3ADQ?EP 8EV<<ʩ1)P-$t7 㮆#4m6<YSX79 @$ShN&KAʁ͇Fg. AIrޔ75ՊUi! FgB)@HB!t "!5QBQ|)9΀ KBuQ7f (1E k[O]3ٝjyl_ÆYAG=.5g?hlmMϐo=.{4eߞ\dorqwr b&/]|juOcGnaMr:?1utf)S98z7uO~ًh^ݶk~g 5sxz7UDv] +io}}{|k]wˇFzε7sn=hgF/kXTg[(3WR~VG&YT첒aɓf] $ §Y9 YiVXzsْk}| 2xnJ[2+jz޷WL[йL+VVR`—4dO+&AȎҳ(KgEUhI}C`OV&R(D2{lxkZ FKOњEH7,Wjz9c^:;;ˈ]Fvm{XWUݧ${jAz5Lj-TaW@|nˌjB.geLV Tp r>VI4,93z붋@GksLˉ%NTHہ̀%AF}C՝Mxңg;lj$㑢`$\JF,eȤGͺA]g\H?g>Dc+lcw -Czk978UnclgiT>2z8sczS|XkW{k=r-'YvѶv/7UIU 6݇Ae&d%aG lIբ-.A"Yv PY%[u,E.W㏳ZpTƏ73֫y6[59w{νN$?a<7G A)BLT~nk[{T$}Jh'K q AX#^0S!W>.S;CiNnt{`y^!CTC9&9ŗT-ⰸHrɋȍZN0]2cݑhIcRSRdMoPGIoF$=b#$D jNH'rţr8?љ??:VԮRZM\~8+zkpSĦr/<Ւu<[Eg64^,!u4^~ ȫJsm>}n|q~;%5uIrδ,,^Vcر4UuDgI4:ZWK5Y0<{ZYvL-mn=#YçM4E¸Ѱ;,j&P0߇At'_po['J՛04ە ы!FeDŽ]"[V73%" 6 iɐ$m vKɾ(ofzuάBF#%Ȏ$- Tϑr!"wZXl֐Nф7Jy,'ڋp³XXj= oS upfCL(zHDs*W.Hk 66dU \Yʴ1aJګCU 8ҩƊf؜eRة̕hLlsJ8(s'Y5Ѧsl[b펲yԆ [,l(fo!SYlH*DZ!BRQ#J5Q@eiDik -DcY IdVTV6 +U# %, bDf FR@Q%)AS %@q^<{m;O_oI|Ty_paDWDEУ=篭wѨ}q\)U#* ( iQkgoTEfml+SikZ mfm`Ƒ #UܐWul B &s̏U@=Lz]p圙(PXpF}иNn{H9n.&ZH*L]'\<1 v r[j/hLUqռ0C֪؀ps:F~ $^N`}_9`Ep* qP%^D='O̲"qpAO5 |>v|gz׬8 O,x *`d:]1 n@PQ W%I_m,g}TiQW.\*̸`Q=oaܧ5kOB[h0fj LNؚ@~mxnW87L_P5E3$nscbx39L?.-r#w4X2/2ٞ̉( ^Õ+Eо 8QQeֻk;^yjL[א>U+ڐKV%4?!Q1ԟ%Ժnڜ3xWھW8F<#>Qb`ǟ[lf5)n[|cv$zCCз5E徤aj_Zx ߄0PNB@S1j(xJ+N;XL {Okq칬>s`6$o?\2*UED8P ,=7Ciߧq;u6ԯ m@5퓟CDCuSs;2!MNWt̶]#ZJ?wBb5h<@'w;Tz(_vA#32#4tK҅]GճI&*],L7͝ՁN K }C[d+A2i#'5'wZL<3W^IʡW! ۜYŏ Wt;-Nd,ۥR2BfvF}'1E9e(V#^LDz,t6Ewd upx (P!QQ3܉[2꽜?) –,aJۜq1l(rAbr8S{Y? ;JfڐcQ,\OY5}'ۊ&?]&ls쨞\zW_Oطm3j=~Ƚf}J ݢ"nҜRӎ>/)>K|pLiF.W>y =#t*G}[-᭸ |&yD-0$Csa3MrӾ52ϯ]C!cfTX%0T\8uF[cՆI;4F7]6Beڡ,.܉ E&RtgMp[9]֯du{+\q'Zw-=4^_=MŹ$X $>AB(ZP\k1qdz7Tirj 2[ &*6m$jj4HЗ:j*"PRDS:B}Ȳ5iHEJg(-;8΄Os}?q #ӼQ{|:B,qe$d@~840L(l@{XPZl oN"B #QrIЌV=3 h<[~0Gds>F/Yd,NJ(~rOy| |rg,!:INf~ON>ԖxiM.O;=S Ohaw9>]y+oN/}TLN:8vє1"FM2Lgin7 _@@oWW{r{"O}>s`s5@7xf6^Ϸ{v wa{& øؙЧ׭`)fsw j$S< 4s?yZssm+W8 u)j:HP}ũ(eoFZִoB$6lǨnЙ^eJ2ߜEzC&,jD@*[=eqn9TDED@'n?p_Cw]Vvqю(j ;LC Kͨ?T',Y|\9=#Ϗo Ei/@5( ŠS_*U; L@S_Q\cCVΝM|T`mKaw"2kPψ}4:?~Z(] p)D)OP%lݮjΰrʏaֳuU$?DB^ՕAY׋yp>֧n1 ?36I8C:ȓ4lOY{XQ8P. HUxnbyaI"SЄO_U="rS٠UuO'E7J~./dB[mQ[|%)8"wpo4:,r֩GxymS8Gx P1sg9"ׅeю X`'s/p,)m;/lrdPO FpG gڣƪijVǜ;fz9@,/۷Ǵ>폐z4l8ĵ;* Мͤ 6fM 5 w5iH~X0aCf # bmpjB *ڽ4.ez^`_h 7l jz/[7ƻrϲ57DF9#kQDM=>Ҭ!tn"n7|h$;^l3f6:]1w_^En v'}bǽ?~|fZwz)V#*NY_v1CGG^A"[|gx$ !$5Mq{F=96R^Wq)mha*Q{8]PǪ"$AZq @u@2BW9X}ڧ ٵk ot;67O~q mVD@ #Q (O zn\|zT:GT` UC>{m$U@3u9iT;X]cd5/Վ,$9N |!{b&hP_z0 Ez5 c _3im;X`_,d"(*Ҍy#}u=rch<5W\'2iPM%r; Nq>%^dr?7}!}m&7-u6Ol s(uS였3o@U:BdWzMAϓUnz gH+0 *pP!^iߩ4'!voX56bl8W2#Ѿ֚ gm;A 9 aD@1>RY cު,4_#)˸KTĮ'`$vlp+vSq}Âfl)Kg6,5 4z|YծC>Ò9m#Wa$u=$nBҧIhJ3~So.μ)x+l6 Hp2lvZ8?!҄ x;|e9J.*X_~Gg/،<_Eo?ru>;UDb)hd*{|o{|1zu>n67-#rW}E@ATo0#qsaq3.U78$ly7F "t{@y5goz6MA,U0*;2L5/Vwׯ^u;9ӎι睥|z4|ja}|=QY׭88`s9xfN{^':'З-n  lHN\Nh8MU5A%5m٪{;|wjHs\d }h&k}hQsN^ˊkCsWA~ !oe0ذƳ*_,ݮ9݌%d3Y:t\^?Y٦:HĚyZW~H-j7:UUUV)8ws3|jHo\UUT`e{*&~HYt+ߧP>2{+dmExal_QB w MmO(70/.T|-pVh^k^;ô-H. BR^6F#3e.]-º'MıCBc5'uc9U)e(^T j.˚O+\B, )>i!eWƖ2x,"roܾS8xb g9l*Pu@{aoIJ.Xr_NnuM%aq3P!*eHy؈Q4&/HA򝌮sZ9+L΄D$fכh.|=k s!W AE;Qi"{Ԯ^KNv`csU0Bcf/ PXIT G]M='2I ;O=u,óã(H9)-]^6uQi'M %zoٱڭj~T<=l;}f.wU7425/%(eNW~ͷsεx=R4 :abg" i{?=~cg 4󸐛4DuE_/~M N$FBց{b.05 oAL2ڰc*\Wg*K>B'̆'ӓ .)"KA*mؑ.f3 \)xtj(J:L+?9=F%rί7'yz^VŊ7`K8M4͢koBNbIJB rnR#8"(ݞyD4‚QÅx'&9b PW`u@st-[~?/O2<ϏpLI$I$II|`qօ~c㷽-fEUUUUUUUVI&*3̛7?G# QdC@EcV6DPCsoAENyUx]3Uˎw7hrRaj"&?rtAbJja]ER#3Vl t͸1};>sq{@Հo]UYdٳlћ_(A7"bV&I$I$*NkZ83w{PGoƢ) RUKljrLᬝ- G> jD~d<B饙'Wr7528Y`1Clچt xħ ۨV:<@rgˢIţs +-Dvo9/q' VRUUt,NwWػ afbd(X ݫO.e>cku"FF(0|{j.`s`itG3}[wU\P HqzF=Mj<'|YveT#UHEL]VJ=QxWDQzbnz?0H8J~kQ&g 8=#B >y8VC_'|It*4yр BQ]*XGtC^oo>V/tmJHZ-8 knGt&W*.k\3"e|[;= :ޯEcA>ADhW!}aG6֥+ x#LCCvgVOR|k$aVy{͝A*mwޙ),7cv WB^ &3›/Xl@Dr)djݙy5|d\}UUO%\KipÑ:d kT~,69F;ާ{!pYa4z%>[xM̧;pQ׆P޺Pt-5]}\1ٝO* 7Oر'ϯr\Ol+=nOcU@@z=@96H dN \k#%e Ü!/aRf19:o۲{E3n䶨U `ޔ82;$ f-S@S-Rgl4B\)7Pu _!Ʒ pFQ;)eF@2 Ԡ3En[-d։bm8{qG~Pߥ1/2l&1SyMwZeܣ Am_jRyĉZ#;52rAMnܔ'/C1(e{"_yO jD5s7W뾯}G]׊{o-Gˀ^F76k q  #?O\SҠ|-TMSh$ Vcx=+9PD7σ:5!1@($v0 DZMƒwj΃£36ݘ( GI'5x1zeCT^ +$4LŔ>əVndU`Xe~h2LKE9RdP H]Lx W {P횕|=8 IPۅƧxq4 @=f$XwpgdhNì^!o23Zی/ˤ%& C!{.9ƒ#Ԓ%?mg{cyy\o GOee-=]Uf[4XwT:_'j?=!Oqw[<%Q۷;!r BnAGuWw^ 3g* is.Zi*@Ta26,a Nw;#eE]4d[E)eM$!%HwƊeD;o'dV cV߄ƁS| ~PWЬj2s G;0Ox+~(8ǹbQu$bL}g ؕLA?|ktpNvM)W.I 0@  *4þD ZI$'={ -ηk0}ٸ4%KN u׹}.7qQ'b3+P"w)p Kz|hI i܂-7=+u5{*TșIJgyUI"4[qhrt}| Obm~@Ɛsˢ{mQjY`)KS*O6D, DN!8y eN ?^y}\_T oI2~) Nvi$ Д#V mF(NfhR)(1_)w獻cSK$e @o44E2ҜeZ 4Cvl( C H AŠ t>xq'0d G^eIP$LiBC< " (x>]mzNFG‚[5N CNO~6dwբ;@π Km{GArDWT*M$*p9s5q]s9 As9 f0YYj32WJO!{{{(գUnAJB A O!~[NYVh5 M-"ҹcfA%+Qoj[ eCbuU[tI[ 4u)H4$g-t#Gio մ,_]"SG4oa^|=)ӫO_tדc3|M[;ge}XըqژHPo~IXU+fH;sV]5 $qMzߏ\KW/tJMwhDuq@xoU{._恟^ @A_߯u;BNB[|~4Djeq!)Z-,`b~y3ܝcamP=p;Jnnǝ7(mG&HXF?tW<fd9LމF )K#q 1\ W=r`ϕw;"h@)QR4\EہJ>6zBi `|4M:@Y:9ZCҁe5(0766雧&Y-GUE u6Ղ(OYU Y5bݐ6k@Lz-|zVHD>MⶾBt KD Go󪭦)8szD=]<:˓5NRS9ANqaj4SqwVu lY6.h]B|]` `A@@TZ\dJϝR?'UE!J`(EH9X>]Gs$vNs1^up<핚fUeV=4ۓ~xz"xc+,TMPR'+[J ]y^h>yZ>/'Cx=]V" k.z1IٗbB;ڷ֢s֝_ߴ?!wݑ'W]xCN>8:H{)n?-3}G57׀z?J_/C#gߔԨ>|m,E7>Z..P 6 <,UBj)y[Pط+r</X@*l?ߔM;HnQ {?e8y>s s1"XK1fc Op?!Q4=.㢁wDž1JK$oytI=zG综xN v-@5Ϳy~[4 dUOa;nrsPG-}ǐUOXT"~[NgdUrn.?pd}4+-!~5=1EdtCY*&IZq҅c,\6Xe"\wF+CoLSݷY1xa(moNf^ͳF >M({1|>[u]_kݨO̓Pw?l쟧+ڔ4hQI l B}FL6}zZ/^-kfk@q28bsMM%LØiqLblIΒnTWF}:ȄKgeoƽ!v 0w T `v5o "#) am zaZ\^} zZ!sb(_m~B#JIݥb~w(B@Rru$ŜWlEUgd귾7kG|wiظ+-ﴥ%X2cS~C kSÜ9Her6AGAVl&E,imv"Vhed  A( C1L̽;% 'lP-֪Hb41RM2)fvC(LHe"r;_eeuˉTkO#ޏ6 {(&fx3SߖR"}F@a[c#n!t7);_*syt\}⛮B^Z@@ 7S%*Dh^^w5JksZff.HEU>Ynn_鸤AScEzfA PvY#*Ȁ-P[u?T&0`E@TX1t!/zþp\=oBSGє(b98 PMl \p׀_TZNpHfG3K9lc |/b]hzzH_Nqؑ#VfwO\5vd*dAuW11"NߒЁ8b g>wQ(9u80k2n>}]ٖ4t0ȍ)[\xy1ƝEw噆J)~/NDhϮpB FH_{o $2Qkb0Gw)k p7.,kAcq,{ϪM V9V!=VTS=TlX=$=d; 9Ov;Gƈ/tQmTL(U681ICDM@RԬ!?IO)&aExCO*Q5s#]2le0L\ /+dvp@ԟ&AçUă mIS TrosQ r_܈澊ic`6m&6zjdK7l`W(IDSѵdg=d c #7/ f"^r ʤàuwi@Ӂ 2 L慱Ęxi.Is;K.QhU2} ]_K?~ wgQkaBjbS3ZX? u,eln]GIymk$>lglBMR:蓯+0ˈ Q߱cp>M-2YDN {yv\JSD~ &d5txlmvGu:z0pK6(đWzY8}XGgBu~ul(#!+!>FEQEV~CV13Ce* IB>U(E}#BraΥ$ZqPh*U/ߠ5QOh橙 jN3r& ,& ٥_{KE\MFﭢG>:ɚPaI/.:e=Hn60B֧;cCn9*5-N0`Ū$\z(A[f~}^meɬ%;r a28 G@6DYMpa.$wdon 2 c'0ATN*5DӲB c#&U#WGZUƚ7%:,0I( q9_~$GԽ!q_~1c%BlPkN.^1qOp;(M8]!Eg&Ä'bM{xl'ey4"w% |CrpIyYEXM$fQi=m ]XBI1Лڑ(Dvd=5q KkH+!dX78w mzf; H g^"){.*w1jM"&3uz?쿙{9>ǎ6>65Kn7sH;uwX'gm߶#*QUUCuCMN=oNE1E 5z#RENqi 9dJew<ԇ3ߚĞ~ 7a~'OXPmٻop}k+Oߏםmb]xiO@siZXN IZ6Ek3E<S0_jV6'P, ^yl`8$wE:n/stvE քaOބx.@`@*F`f W@@1L+'OwL8&gSRbk;}I*MHXfPnᝃPj 1F?Iy''Dg8GZ!6/=|C"g_`~Dr E1 s_mZj!΢XG9w9c]Wb/c2 Fþߖ=žL%cdH79NKgx}Z!!9 ;nWZR<[+=.@`'dͤϾHISl s.w)-֥˦yB4f,=C#4M@g-}[lTdW܍t~Nv[e@"nSSX忔Wd/؍'dtz8k[9h@9w 쬍n4H0@pw4xދ(h}֕:SS>si0-YHH'.1:O'89v Z15iytPZuV`Q!:-U!c),օߢ=!&3\͝.fnųĪ;-W zlq6SzxA(?Xgkwjkx=LmOT{ G,5L| 07&;\VZj'q5,oJZN, {Pw L{Era^~z}lF?/)o@I$UUUP¯}J /'#eP*  %UYBlՇe;/mޘ̢&k~? F,~NCi|e +/ZDR {vS*)ՒŹrzv h R]4S"ژ?,חcS4>x0M3(fiڷ ڶ{ڦc(*3Y/Uj<Ǚ/pf?ל^bv@\"k]kݻޯeD#,O[>j-Tah@r|rNЬ{\N4Gݯ4FX{An=Y^ttX!D+r >|6wEWS1k]ƪڧ/j3Ÿ,JrRm!+Јqh/C$&Bmĭ欌 2zPfkć*G-{S=@D52"Mw1=[ ŏ܁D0EGhD15EPlqǕ>yd@PQeX zP ;thѰ,wC9| ;zwJ."Sʫ7*UUw\0*,av|jj(?Laᵎ3yU|lI/!#TֆOZ9kIҙONa4NQQ)ƸҋeYb[}2㋂Asg~xyS$^rpbS&``/uc[.p]P4r?DmD5ﰼ8Ȧ&% e<a3U#GEx7[0-c2\d;rcIߔx*++k"^ e1/ 4oh7@bZ4jꎶN+Z{H8ZD6r3:Om?Nh.`K~K.O֟RX+գ F>b dp }4-uB 猠|uTI4HwS?l^GrpR0(Bjcbv>"DTl*MaqĞ6\@Y} =?2{ ]D<~kߊ"'0]&ɼ}1_d@DL@H*!%ݠ'G{ Pcpjh@*Xa(lP+_pcF RX 5:8ϑed%P-jF"}/)4u F[Mh.AY j5|1Uy֮qi<P Nn2~Z(ْ#>yPn|T ,)]׵=,(/wx!p0G`~a('U,SgJdp7*;R)?uC4ʻn vp"V~<*ZPXZCLiIKve?!Xc| {3A{$4boy.nCS4B? ='۞)U~lN ^Fo}^>d`ƒiYӣaL#N]K: y/ӹ:ΖO;DS:??}OkWNCF}4o&gO(xxބ¿!BZh@xY#UOPHŀ[t>ӎz9'>ɳ/l^wxr|{fHBjrF{?o]f*<<(Oo1d_)CQT5nSdOw|wN.}x/9ږ!  HW(6ڭ,LB܅9/H¾?XOH9a% nUUUUUUUUTUVZGn}R+`5H{NOtyfmNZ8>!okmbd92Pzxm<$WRm{C[G;Ϊ睿y.[HՃPhC~Z q EC{_ i`WTS$I|KB3ϻo=B) ߷ӈ;#kWm{ 垒b'zb#x/1Y Ǐ\,`$$r }jgDOS7l.pnGT6W}BI~p:t_.7Kұaע2)ITp7B*?04 !Wi Lz'{`N0աohJ/V4uB!a ~^s "mD%Z 8yh`f5i!2 HFc l27B.rbLLPg7 `s?mW%Z@Mn A3x) %_PW1iW졨_ \gGZrYz*GP8[~@ u9I6kf-8 b MС:""BU~ױϵf_Akm6Ma^ |ݷyݟ/w9sg=s9f{9s7otyPQ5Oׯ/Un+3~ë B0 3W>G_RzX~{`'/ľ?10$q'v߼mx""~ߏie,e}+bQ=Ա(0nYcNɨ?1>M~iUF~g_J VPf@~])e,@vu5@g)UU8`Ljț~Oas=aaOaxq,Q_΂S&H81ܣX990lµ{W nԀRaL2T<*H8:]oI CڵHFNU:flp5z6MEGP˼M ni nkoT:46_#tiom]>Z>7E  *Y|>>V1cfWͥ9w۩&*_kH1Ss(I'|<{(Gsu`Dw}scS]hq ߇{߲d6Ʋ_ bdޛyNɡaMtyf/Gv="kmCϕ/=%,<3uAo{AՒvBQP|x;# @ ARΤ`($8+f~{Og]sBxBxL q({?#'vS[e֓{:CaUtbo "p*']ٷgtlzNz27`KI>`v>ɍu4x NŒ4hϐ~KռDW\^nneckMSUt ;hr]cƽ1z|2˗CB$vA8_#o2I$HI7_2A"HX;K(Nh CjTF0*2 s?򧵽l6sIo~f##B17 ӻ1@~>U#8ܾ~ Z~KX0,Thõӱ<ػ1/k|mnǐBLA̰.Ʊ,j5k=?kyD ^!tQr^B'(請feFd mm66|8H(;+1b[Ao6pzهhTd*Yvlܤ}WYH`hM8*>1c~3L_M}u "2r J@W2P1Uhc P|"ϩ[,BJ¼kN;t'ZX0YC&v^8gi6~>Gѩq|ow.7*aZ&szCߝ 6)2)K&Qca$oR3CU xy@q'ar*_ͤr8;FL#ǖ@1Dʅzc_ߕgrA%-r4H8 &kbok:X39G{xQZq֏V8Xa$\X$ t2M7$A J6v1"how Ȅ@a 5Sp_K~:SΏ%9MyGp_m2Ncd=͂ۿ'\cu}#Wz_up"uK13UэLa%l8l1 :?#M P uׇt]/mK 6_k޷.1_r=s G+d1BTKu X^Cy,rj I= )"+g_?-Q-\am|ay/Nt98 %5sq~6ffD@6llnO͋'cWӸvs;ݤNv`wk@,hq A?b"r!!H ۷;"2 M]&G=Nν!-}vk*UjN_arsn2f޿W~J Y\2g6|TA "ϗSxW:PI!B2*(`DZT=Uf i 'yސ\&k)@:,N^ms᠔/FyվGZ?Z3Z\ےqoߖ#KIx^$r%DB pZ>TH⺷Gxun#0C{:{\0*|mS\(0ԢDnT9GyhX]&} ʇ{zUN W/ba\a^UeyapuyuUUUUUUTAHTY%'Rf{ eGPc% gQͧԩ~?kelmmFdus>Xek+8퇝_ }><}x/x'p=\NWsiǿ^xK`tR>2mQ !e _:(p$ JF`'haUZGSiz/5uia6 h2 O$^I$A3hZyG~n2?weO,I*B^JQI,nSbkD=ZkJ|5\1JH"#6X %ݘ@ EF&xlzw㯚 C{i?ϨRF8]L1ڳUjF"/'xqܷ?-&[|ҟ}jۧ-H9]]%A" "*J"Y Z[8g۹MhEDd9{hxߞolJn;v ;0'NCB$U$C!'IxT5xs9QOtśg*x]'HvSvHo-[J@EF XT#łUEm`ΜTPb**(ܸkhPe+- "aD" UE6KkJiX(VSCLMZ6f;*Cm01qt[H{*S֤r@{J%cO?r@:j3\?z>sťy˃ӛE88JNM~K_Yק,bx~wBJb}m AޏEkJw6D@!G5I/s/ 8W0cnt.CKPTEyp^4ʣn9{&']{ f t0W`H$Ϛr8F_6|ّؤL[\ڔ:bE+l$(@0D%onۓ#! LuGqe^9 S3oLଫ6V/ 'fgQr̐[˭0񏶡Nh=b. @"*.CSS凮 B\ jFٚ;E/tCDM* d._xWeZ)D }־CiםyTjs35Bc և_t޳냸x]%?] &bҽȎss:=¹A7EC&al|;駇4BIrT 6D.c2GO\w}f4~]%uD& ;>__PNMDPD=luA3ݟ5D٬mkmvKƴ "2{}u9b[6Cu~j|xʛBJTAPnj`a jaʡjG7c@$Xp'?_Ex,u8;z U]{S9}?uU:KN'_2 yP,5#oS;Gnvcw gRn9A6 pWWN~1)B"07|7XܩǙMBHDꢨcԻS ;UޗF|aXojI9m8=D `/_ + /ȿ$ }>d\Zm;\E&І%"dGH2JQw?4w}Fb_+ΨukX˓;ngrrp4GeO_JIJ_*= Kz Z[0\uqN(kxpOEESH&BPx| RTDiy"CODZm Xu~XDLTmur'E1Y}P?B7&"1"(#SI%0j;ud0ϯsawtE x fFeF΁>VϸPS㷃m7x%=U~QwASA!9o$SSFܙBN""0RUAVEQAa{Yk9mY-2„YY 9$ 3YZAAAAAAAALf5 ((((((()ƲY*Vc11ALf5ef AAAf3ƲSYk+1AAd$6, -°48s0g~fp!.7~䇟ZY?k;ckucca/us:TU UB ;ZDI4">ƙbC$xO>f?`i=u;e02gI d?LjB)!! ۵`3E3 fL$& %UTNBp"P̄/0?w7 W eg|3'3'55d>B#*D>I|vUUR3 "B0 UHUR}LG,-1),j "-r1Db"Zs3 mkjcaڝm V Va4Zq}xT)$MRe9A{nyN:fl{/3b'5/2\9)R W 0c?{_ݓ7rx;ÌdC/9ZǥZ 7fU4%c"B1m.o!ޓ4eOT*St* nR~0ʟS 2aƎ{Fl?05 }>- p:ZDr"^0b$}I$9O*L2*L2a?S2}0?=(DPU?-!%Qh $3a( (orOB)?x!8mx&.UUUYdRI%X^O6]d M+(T"NfB;9pȊձ8z̲%+Y@;Y|;Q5 i.1y"}E m}m@l7]_'@m{[(y<:Sģ?܌ $$ZA_ɓoOfCtFT\ag( *%4ZgJ7E pŒq"M(Uc}'l=ˏ}Xn$hٿZy Ձg}RK( z뫐$2jfv“:w ~kNU!/^XfQB}j1c}}08{,T ط=/(BW~34v2n?+<(Y[ CbInJ'=EDw,\Ύ@=/A7 mz7‘]%XQnd|xDUJnE/2Nq1ÁTWDN5@# s5š. D܋ۘ\ۮe.Cy5W-QYS]"G6X۩+Σp}'.@(*wݶo1r:~<=iȘ훽oח9xs=I0@nM{ۡ먜7EW5vֺPNo-7uX'u-x{VWPSLuO=_< Gy;'R1aXa"_~ ϶KyNc~;@"f6Km5l[jld8_v;l3<<)z۳jVMDDUETAEiyer? 6)J4RJ*kN: (P=*-Ft?#T5(: 04M;3HY1.3xBm(b"EQ{UPH;tu<Ϸ&Ī~88>[mS,l(xp<#S8r 0L3VuhSCt>)v5?͸_U\b t? Ls Znd<˅7{E񥋏n86LFۓXef׾ ;02X >t() j #w^wݐ0D=Jiw+ɒV@aǶDxR4Y&VJI+R )T8Mv@zBUgm:S[m}6q:&NIMᇖbC>G, p,w]1wAs[b &|[iP~Mr8Z8nNےc5ʍ%qcxe@eo:ƙx?ʙZd:\E  FX$\ǚ8./+Ħ{%Y! VHE4R-e3_"ej~[ZW 1}轅~ØW4Wz¥v_+% hcO/y 60P(c|ռ6/kU˛nn CtOnC_m_jn¹T}o)'1!!|p|Q?!zާ~Oˆ**yY>`n]/wU9ܟ8oO4@'$$T@ @)a.@Ez<OH<:>gLg"IJ1f"p@" ́ |ڿWcJa* /@ N't9¯L1 m0!gV 2gw|Pa8}O&r2V %hY /UJ-$53=)j-Jd\{'[?⁏-pƒq9p <tZB0>M"Eo(6@W&K5,Ѭ>SSyΝN39l"YQ>_ Ky*H&fp[)OXld@[dq-W-X#Bʍ}7&A ?&٥0vb` tT D&7 L=뿀OD5rQߧ9> ux߰gS_T+xsSLa#{`Ջ'm>%"x[闁"Y`"` j[͵mX˜;׉r7%ܢ03sUQr?3{C7|6R?Ym{"u^D_mi4|=|fFC=4Ao#֢r?09KUUUK_  ^OMK-DŨD_&I B'[@`Dյn5`#~y_f߳'pngWΨ*^ ~"qu;L0^lmMN~ߖY]cr fL*4C/`x`Ŀ! GD1 Z:z :M>x"3iЄŋ+158^TF!\" :DZ7L51g&]y NMVda5ȁ8*ַWA-%)D7FJ^B9pBB{>ǯ`Ͳ:%lX_`rk {?T,#?s\ABg_)`HxY@(x>IP `3&s R"e~a= OLK":.Q4;5މlSmDMۗTA ɐG 02*AFmr]m}8kMXV u,VEs )wn"!$2J⿿p*~߶ug*'qJ#j1i &6_hA:eTij ɦF9s>ۂz;_~߁3_ng_%ITRueZ=^fc/5E%C啕꽓bXfAVy?;32?Y{o[瓐Gk9cGk9ʩOD0'Mz߱1'}0 O.{rۈtdurtm gׁ~*R/0DPڎ=ǫ,*0?/O{|(BG6U*F$#=RX>Vş| VdPβgﺚM_*'0$uuMԒ #-۹; B )4RfQ nr]cw<=LԖ 4⟕h 8f0Q5LqJd+qxZ{}z6Ml3sW+]ߍ_3yps-tJX \)XFPmw:#k-O}P;Crp`wy6#@zՇ (W薙?pImO) bgA;U,,&DOt;'UJH zV/k=mHZY9U #ʸ0CJ _d.h|DbtYtNh  s9 s )5!cAG yR@snPsk4$U3Qbo[ TcW[z6XvUNRkJ${rGH:.z{,{^MlxZuj k]#bġ3ckK=;Yd7/;YS!P*NKCICN*+eTtՊ(M &%y5}҈ADjHM@YՃ5BOĴ@,Cr {gA BTVG@Tx$&;׳o=N[)%q}ew_Ϟ.2='yJKuPk2ĽHbG6흦!20 €)k'L|I0J/$Z 6!"w9n]! .$@CAy\TT"Hozwc?\ JGu9M> HIԀjUo~;3*a0~G]4`LHc;GynszC\騢Ow jyؗ[Sb$ַ `{Mg14׬7| xqvr {[^?{:>ۻD8FAS>NƲpu@∐;8IP<\EwHATuO trxT:ڬT,XQ gρ^5IDeIm4bu5hGc1#(ۆRF`Pt$.][NuSg՜9G䍮 h\;~3 D%*Ny*XTqn'UtN=؂@KrEOȪ)%ݒ41TYOwy;=|+x qכwp[y !(B!ԷyDSy{C~@<Ԫ=|S70\#Q@Gʆ2RRqdߏx>#|R/M%0 {rgքrfJȽOi|3?4|N#MD׆DZZg8vZU둁yщEZgDbyFk#Z =錬i^ʽ EE[@f5ְduMǔMqU a"teu.16-Ch4Bt`*[ػ8sy VQOEܔg=s7z__~{jŸ[{24hk{ٔϒOM ^ԓ-#Buc㧏{i)V0@-onvi؅w*N_i=Ws@\:Ov\an^Fܾ4w/'<<蠜E٩mPM?rJ1aECz>ږT\4$J"+ P ԴQ!E"=0# "P"QT&@w3}OFNۡtz>ՙ:Ehx/1?y7 BgJbñF3׺ PFOq<0\7Tt6.rk+%cwᄃЈ9H!u1 njwQ;a)i> I.ʎQ:m؎8-a% ¥D Bn&kcU,C(9coӺ[4+EjJ,tFK:7iV4ZRA(>uYׂ #Μ[fAX&;VL'n&zV$Br+L6,O =f\Eol.;$,8v$+C{@8 -X U,_O%Y7z @ tXX ,F*+#o e&-T L\!KBƷ t|Œ"xt[CQ8sc{]LqM<(^,2S'@x@  $`=bC" E:~!Cu=sk)tD9p~鞳Gؽ17YqD^AQu2h}iMyuR э1 ~^6SG~yzNR8I S<aTHP EFd.Dwѧb'8CWz݆ݰ8`]ٷhwi Vͱ-SQ3W28 $F};d~/.접1 #R|{ጪ =;336lew*}?-7qiV.u^_jg &D _ߧܦǚ+fZDۆmmT;z>IVi2:؞Օ._kjֻ,}b!|xf?Dr']nYo}΍Z,Gwl:?08ɾc P湰xAf2YKA ^TNo#1x`=NevD=07"lǫz{߶\!]US([(<NF vZԎ˧?~ݛ#a > ?L~ ot@ 6 k]ACv "$rv|׽Wcz -Ss" c wޱɞܠU^(z1=̍NY7,35idO T.,ٹ^J%GBhd)'3$ͮnlvhy*Mp/V!5'"f%ݵ<~MբCf. DC':n%aNZ15B[дCA\,vqE^'i BMƗ{`=lI/25{ 9u4r sq]y:im;fa 6$d<㘄%D}em2Whb[coΩΜFߓ&!;B {/L;;r.fji \MbD@Z[HLNrr@vy/e4}y~#ۼo^>~{SXȫ6dfcdU`%`fw2B3DQGi{?ҞX?;KҺ>Ki馎lѮ[) ih`dfb* B _S|8["+P\?Iu[@G/gƆ}aDp"P@8 v8A`3Ss|`K;l'ucNGJP6fӚ Jp{M\ZsٛW02KS`&{\bHSF{6r_a%G^K>^f6W^fbN AiPY8WQ /|Gs fS@oB&ow8]&@P%>+ i1sYt`\*rMpo >]g~ TL8kU;,ֶ flj"'ƹ8^//+"33e6!nێ_?8~,J7gsuACu_%6좛;?B"`ك#c?8.Y8 &&@gPaL J@'PU8HɄ3r@IȪ-B%ohybMX!?St"9_9rN%AQpL7n#}xm(wRgevq>}F+0F}YL*f(a @GD$6Ub q]7d&gV/Y kkG ۺBI'[ռ>o7?=+:Ƭm RGλZkڤ ;}P>ĬXY"Nc“MqoxOÕDw ezNy{B%F'UX 4d(Q!1bhHz4d%*d$г{)ކ OaQ  NsHeV4;3ߒZ(u .0,NK#  U^N9N !h@pN'&P&{o}~9ipYPrDUUa=UUZb)cw7}[m j+SYl^3uEx<(9{X(ffYf[Ak*jvLA` z`DƇ!~'Qfj!$:@mtXl)iMJ6nȶYMlP3v=D g;sGS~-і`k$$BK5mMW鿷x/KsM)(`AnSrs\g;JZcSnK 7Ôlf0}< *4!6U}Vs9G(~gqrjUPgE٭䃵y=K)8;i18ct.c]`1ʪ"oUd"EL.faY"Pɮ؞C3f3vg@&;hqV3"[1D\ڪ*(! W}gt8br%erwW"}?,$e{~ezȣV+Ʀc*nk Ρk9uyP@Cz `G76U?oH0_p9<"2PNyLRW#>UeUE`b\P} o׼xk~$D[ cٴ . dwȧKqUaPMHWM|RKՈO|ɡNDH*߮vhvOF>GKhH2f#+CxP:ѭ> Epo>je7 /tt5 $`=Jlu!Ntqw׍s9i:gA !<1vQK} ZɩҲʔsl|_n5xsszξ7x C΍wͩLzuۍ^޳oomz^kM->?J Բ*^KFAp}^[etY;_1898lyB1EʪX N!uJNVY(jq B5 6$Y 8h ]IkO1QbCC1 XRB*I#JA?z_s=Tm&m?+{+GbndGirH&2H5=3DD؜*g/NhIk12ɳfcklָܫF6 l]T(#a#6Gp: njahDCZ 1Ǩ+=U`8z(P%B_No.ǐ;: 7؂'" k7NeŏaO9/kUNfB"c-mwU7XۡLCsqP0֎KJA,}h(JR/.Y0v!Mx˽7=ࡘKU6{Oy,'LtaRWlܜk> 62h~֚sur9=;t4إ4: ;ȞӒlhudUcW)#ϑ|ʑ$1"Ty> `+7)Wx7tC@L )Z:'zͫ%Dui ZIny^Ļlc{ :S>Nh '<ъɆ?^aT諪?띠hcuwkA&!1bP7 ds26:#v/n8+5 !U/|͛)i&=+2G 6&-K!so,,;aqD($9?tmĺc{1jvy Q,1n |F@jj]]% tm'&ǃe3pϏIMF̩\RN, 006c>+ƗA` ?Jڲ87_U0 kXkɷX=af_`x V[P ~5j8cap'زR24('tC;=(͒> ['p Բ=1a€BOe>fPV:ٺXд&~ P`k"֍اkٍ@ >Crjš?_CﻬwM9@{{p؅ "TaAq\Z^) wC ^toO|+p;[aGo'`?Ү N@#U;wt[t kcȪq.(@1LHNz+ԶUI!pqgMğdvq@\-UW[ ,>k*#FgKt_Xf68TѥF]oUsYiJJ\\ ( ?޻Z:w_EBf N@>;;aV0֋ݭ'I`ޛz˸4YFMN1p9LHy#ÖHg\,hH\-'DsW.-lR CGH2?ng>ݙMJJ oVA{NkBj?4PeZ6R+t,ԽW{tae y!=Py(ק_\#9ҳ4FH"sڠ!X+G4_N,Ztf?9j+ ߣ帉mjM=G[=CV&p6eԴlXO[[ J_Ä߆!HdӚLNVEMmDҸEr 6DwU€&pDX1w̜8%PQB=N"zF3NA}6@΄ )bXܩ1wg3_s{8N[Kq[nF;:Nri}w5Z@:!ٕUUT1ֺ.w kn'/{_|^BK݃QiA䭐ۖwN{^we;d;P[<ѽ䮳ޙ˽kN&8K|`+k K?1gDR%P/|D|- +N>$`(],t8'iJB3[75n"L%[%s;/ Xd E2*"_Nvڅ!]X&Zc'B[΁f:A_REjd1+`'>X)!'P p>?K=C5'! 9{wS>cfbxUr8aH愞y$A4mxdΫZ~{bko_-})hM}k/(2Հii'瞒xj\7^.!jYi(u_˧v:8LOUz>2 +*@)3|^{I z{[ějjaQ T2ɵȨ, I_ctt2'̧y$ t8 s4xlsBaށԄ{!s\ ۩:qpDH?h(jWe;eKp,ދx`0]gzis) udOwlvIΪ( uw4'Kx$ uѹ( vǦK938zӏM(`(% @(޼ݤ_(-P[:2pF}ZT;@.'"+lRUg{;(TVj[-& Kf/rU|!rl~Mhe`zhʕZ2Ƽ{LcqA>Eg¼oߘ% :[eѠn\̍r+̇u.ĻfZjw/\sk(~8i=PwJJO|(B(S=*w /qO cM6ROY5̩}P @@j/ ▣U?ث`\t1ֵ:N?voJi I J1>o2}uQP %MxY)xNu@HSb_?Q*08 IVx y3߈A- X|a6Sݦ m&30IѮ+TO6:LƳIn2?ig"/ (0Pnu?*y@; ;ګiN1XS#ե7r\_6(/{5a7LOL۬d%d~;ˀ}j}/sh$™n:k˜,o0w<94d9Fw,dS,\SB8O/6N[ci*r< EQ^iočMC ʽ[aˍ*B/],!G-m-MX1RPsK|FaI nWVKXޕ&KGZX6\#'7#7=)]aNFSݶsgMd2FI>j_RI.@Ϸ]i u d_]'$jzCP&PE\a&Zihw{>wޯ ,5\4Y禗%6-4v%'Pa0 =vK*g녡 h2u !U:f ZLc/e\N V/ -J}_%a´Z_b!%!mXLO F'¦ҿB=Xoj}ނ_.oLٛfvJ_s[Ta{j1ء@l ]ukGW#H V^yJ4 C|SX REYU LqRUF _-&sQ˔$ -F1h9]\;G2 ^)h0F"y~B:k?NQd1bR5>GufmXhcHQ{|1LG`Wګ\g'?J8}.fEGAܕxJ{uJtyHT0 ws۹!Bƾ;[$W(MSDCm-l0)xdgm>VףGtӂېzⓘk1hg#ɯ% L>]"d*(9^UQ@(',%tPINgRWqp9?_IpGo{[m~q%!Q EDU@ P @%+L,$FV+ږCt?smpӺyZ&|w fUX<È-N=5$Ma[\v)JʴX->D U> /7/3x ƷXҳ -(ByCfaF&V'K,c'E(̊Dk.!ZOaV-4IW)3&F7j<09b.*ntChͼ5)s|hjm4u\U:Exn K3 j5HTUf񝝬?skXQC@%OO9-O= TWTq&$FV 1g42* qQ,TcxbGR6 (2=Eayկ1ta1,{dL5lR5O4+(gA:T#vo+:PҠsOh4Vv/Txy%YPP+ϊ}FUM̘`{ y:9}DŁ &5w[LBVe&g{Ev P-N X=X21Aepx'H_e\L;|▝0b!a͟ 7WXek%1#obLz(4>]]լVy?U0a@ n{ o.,HUY:F(c& d Z YGJ$'n:58D%?Dc{ F"NN}s{a\mj @P;L,%f@$+\J \P,!<",0ٗuU}֍'TC+Yc^p $QX,қŽ` Kh>?kox"]wXoOᄒnӵSXW p7]>NN'JH*#r UD{O.'.$k\ۃ;i xBBR@Pp/\@QED7Wou,Y<d?]ih1):t˨k3Tnpn-$M(P$@ &S?O?BWu1@?̖QSKpq tK fx#4 g{0gm+Bu1w3yҧDb؉auG-c=y´!|0ع5آ^.3Q=Kl,Vc߄0b}׋1/uW5~+Mu)飬Jmi˫ȚFpn@kN܀43=&)CSs&4`Iuo攍nKU)kyDmQlFnvRC֦5Em5^+yW9S1ۨӢzǑ;Cz^Rq1#\9gi{ba!A=Xԑl7WheUIlXz&=-2rbJV ]"ʪ8LZýrt!XCLR_]k1ضssrpÜQl`|-TUuo~N{5*41hxHM#K|-N=fz{w&ffffhֵkZffff2O0aQP=執=Y Y|m9މi(Yz^=SGٱ]O0(}3A'D {xNn}zmk5:bf\Lˉ T*emm(&wNs3q'\UVns ̦}?.I~*nZyG</:uEEkι1H$Ny!:}N$y Cy'_yX÷?J"IUܝ Hd? 5[JEظ1wrHAR"Z 3kJ߰kj^ʈ3!ge]ֵh}N@$`jUA,*lnNjIutN'l _oM!J8qHd;-$h([ڳ9s+ +ˈZ&4(5:aoEGAɧR:.[T*|k/wl1TXW9s9\riɠUUUUUUUUUAUU_jmlڴUUvLyU^C~smN"OӄDå\mFfh#F1̪j|zx]a$H ~mbfeۄm n0 {qfwJ–Y<2Y&*~@Uvl 7>.e2Rw[unThKT`<w%|YUSST/:>w DH_xO+A(Yste$L b*1>ѳ\?r2$Q80"p4Y.XS Jl7q08 ()5_N~1JȂ~+UGJ{j<ߺ?Wscm^W_;c<|G|ܟR.f3I qו5E!m>I$HEL Ȑ*}hO:>/9%.?}ت)6?`Ɵ! 0BRbR:1 a$[m6nznG(q~@N1xۮce((lV r `s'|Z/m&LfkɇP96 7IK # &!0wMP3Xd cNa0{#d2|e83qɾp&'ɰ6qpk_og k:f^7xYg"F6wHC"ѧ1f'>/bCYO>=?}3E,ѭkW35kZֵ:֍:ֵU3={{mm*N"Rs7VU^|Pܭ@7\@ːٰ -V6/$j~ռJ\~&nTűxo!Id!vLf 7=!) # =^Vأ4{!P%ϏysYfNgS"sF4",2jstg&z 0,TF.NKƩ׀gK$804} `}SfB2hXBK]%"g0 كL4JPJca,zpW%U{(͞(4Q%:`Vq{a!*I`q̢8< %\PHLNeM{x zK#n>[ߟZ2 ȺI$)hTݶoW<'^^z:>A`Db A˜fv+aEQX+ʴ| • 'Fh'@h{bZsB'{>Ml:ː*z6g{w<] &/Z}l dtƉދfS%۫TXTnPo%"i2 xbJJ>EP=䦊+Ѕ n?hޛyr,h`ia뙩X;lS,C3;7gN·F< Kwp :VpS_h  mPPt˃2Crįn챍䕼3Bl:Mj&i|{l2 3@D-a|CΨVTp}Su壙eMdE{6t=E4^v+ήxFs5S%:o5z<&5'O F#Y^K?UX;FFUoPcfb+~l"=_v>r$_ڄO%=z$0)Ǔv7jB8&e 4 pvWU H=ws֩Cdr+w/w_x-oµ^cae:s7_IEAĮ ( U`hh{Ԋ! Bgc*VuYij}6ŐhնϾ-E%/ ~~hB* _Z3 aXO *~9: \ "ř92ILFWv"Qe!E#!E|/'eKj%;nYDHvLN*z"LX 'NClKXc7cxKtSş"1͟ fvfXQYX%1Q(_b@$?`NIZ,dŒ)U`! MG 6pmŅNNŴb62CH Tqlks->P5s<OC<_k{;U 3a˦o¸p(9t,'-H  ivpgT"@2Vywמhu"cIza0` 2jkGjMUR,lFguԼi9 35;k2! Ł`ѫ6+d5-wAy8D,'D:CCB5ٳg#՚h2)Y!¡:!ɾ%^ؖHiT;Sh?#(B((-g#?U()`ә-C\}fJ.G,TYRٵoͬIniٿ+Bymċ$d"*- J̇34汚Q VH(%j H1 چ6eEL]9G2'n&U5J4DZrI$$*$XDV2bUCl2 ~[KeGxOLׁ즔w;ud$DrOl-c !-L 79P% $f9h@3Df/S0hr:~cdW*cJU{彟&&ʬY]ٴ~L9v|9]i*vql֩#> J# 1&6WWg,"VYx%P';w^2/ʡ4ڽ9ccaԏGqV2~;llQR#!ArTIPX1 QcFX2f7$1I&L /ƒ e[IZ͍6hђx(t̲m&dŘFmm[3S56̨ѩe+e#F6a H Au+>a !lGoޡ#6D$==>uv9$h>@R08v$.,h9d\Hl 3f9'BЁjmpZ;@NuÜO@1h56B5}w$\E'&Cq,54zyuj/Fۿ7;˷@$޻[ *!f4˃vӧMLeݓ@#Ӌ[~?nBreW&h"⚔:S*V#z]>o ~RN̈"@8Aз^hcvLc *ڜ*3e')jX=&[E!U:P2z1"V*2VDodDAl6[g{wCo<ϣsc^ɸ 1vcS)A|DOk?#~OY2"~= vvy;URݡD~t ?nvQĎ׏UV16*< tlʹ +xG)>I:Y&lzo$(BG7@!Ȁ 0?>}7۟bANp}7d}m Ȝ%!I>'[~މeUtQ`䊣PQ@9DଵvTx@D,KW'" FUUQ;$ڟ.7S!1eIk6cjɛ2+EdAUaH Mhڦښ-Q$D}[/? @"""X c(Z JH)+VH2)&Q`Tr{˖݇2,8zbȖ+5}|l{" ,>.d;"YrG2eCsOKT 8ŸhFe>}@w)Q4Don(Hȑi$e)Tz r$EH0rP:g!j+Ŏ AФсH*Ta5aو(9qa)`T} d|;l1XԀA P8gY*S0ѣ"&>x"Pc%4xV: L!x8,$oƯ%9);GK!ey ].Jj,?>R 5 NwEh⎋AjQKDՋfaF\~Ԙ_vf^ ny=<5v$aޗQ1=Nl,\QtA=+$F񱂴&6ݾ=Vʏ,ׄG.eKI Ag6QrJ8#sߎ'Q?_I&&s6Zc C6ɳ&jI.%j=ߔ8Eq^DO @*O=%q1IjD3=lqKncr˱X`gΤ `鞏D3}rMk/zN믨 X P** _{'y+c[7G]?IooҠH"JBvdF6~6p V$Oע''>/G=*"u/S aA ( e(~ܼaP. i)LQvglr^+ ۦBJ0\S^ tcZ{+1k6äVϕ~_!99_xM6ٲ6LԜ5٬:ʨ} D "$U~JUUA!b)`\x|zqM>._QEQEUUUQEUUU[ ?$?ؤ#Dڞ jl( ,H?1D$, HIARV YVG(SqHF1& 0QfI8ldٶ]83&imN U j;'YH`uFA RP $R*#c?/s1e h#0IY$DM QpaQLOr9cwv4+7?ګ^z>(z0) C31ӸE\VD?`2lmERY*X$I&-,5hҡH$h!RQhh($?Efؓ\GJ"=rU 4$iAGQI?fOda @'Wu_MXH?1LUҎDc0G,էrqÉ ;f\& H{*2mN/ԧ?N{}v!u+eف! $T d1(C#6.`pؑgN1>2'BQ& : 9d0)S%~(dJ8HJ)L%Ј&iE#@$M`>m5+Sr%K^$ O“_dh2{}O~ $ FBGtŸX$A<ÚkL8.ᚏ] 4lJ 5؇?|(PHUQUU~2o377ۮèsxusNe홙aĆB B2a!4:$4,bM` %%UKvshd>&; CSNYR=\5'h8cN*V뙃zh81@AHAk A U`9p\0=}!ڷct&jYCO/O3z+}r;oD ; KiW T<ѡ,*:/;vci~&1E/'1snzV#k̼x]aI9uiTe+t1zpU6{A SE NVVzϥ7-9+#ѡa|ldUM ~nǘ*z=Ew[m@q PHH2[bǗޅ]N@_Ԗ-ꍲN@o70$eV%/3O)Z#U}ie-W%0tz$L~,_=Z';*Щ[Uq;1=-@r9J_6\oQPh. @ S |crt{>i.ƘRH{_Ã2O]XOF`T\vNz `ׅl"0l8 D(X܍qƥZ {VZ|!d.Pa?^jszvVVm9&nc%(ȈfK)P6$]z-#C{Sc4- W%\0UG9[&5V:T]MNCfIvפt jqyt^IRƣft q#f`B)X:ᅭT*{t6*`}%~ '|!b8|g排k᩹LDpL5S2dM]6j I]f 23><d0Bk6K0Ͱmm"ڨ۷ޕZfFӗ9s\:ŗQƗ;xC=o{xDՕg1R|$Oa9[ r H;g=^N붯TχMh9SB2yBp/L oV&۳64${~ M)?&DM)Q*DvCK Ø_ BɁރ6| Xa?"6Ê,)cjL@í qT0ƔnD+֩@k׽=sBE$Y (L[G%4$ u%Iyo-$,ٺѾ'<i g.7 @H``q2đݾ-6cH-Tڙi3YlٔJk0)0Q:}ݳ\ɑ3?O_޸@3 -3t^^jȷ)j /MgsL} n#2{xzB5/Ə;6W* gvw h/eK]9WR]OYH\K~ޠب'x79ZBD~J\iK1}__%2; \߰BBhZhB3YI'BnnP |f|hs,{&x3c;loR=!! q g \$Lu BEj18WJDއY{y$߶|x!}\? I'D'c'niz,!!9CBpudIP66NL7!,ɞ09Bk!5h:8URH8AAx j8Ӈ}ɩ!Y9d;,J2Rbpq!&Py4i0=9<"> ]zˢ2{ jd&d6q50PMzF/0k)&B/v d*4rfC4TG&8!Gq óɬxgzg>|ǂ8!BT;Xxcg`Bqđ\NFNS\%/O'>$/nvxۀgE{ %W2MYߣxsxq_;'^hwpB9햜u$@" E^{yМy|[BQ8d=<4ytMS'V9h9>(:;/:;x7<l=sr![&)awv̷Ӣv.畢M:j,f*Z4$P 8co]{nt3烄sYӐӄQPU"})8;߆ӃQ܉xZfuΟ4Ai [RG:]s>P&S !TX t$&Z)ɺto5g7<櫓umR@j\))%yZIF(5O8{?((u<+FyjjP e`밓<.))@0,`u╘88sVR!g+4))drHh],c*33333333333uKk޺PҰfiߦu#y~D'뭍+EU m@o) >z}~f^A[ˆRͬaP$UHd, d2DmKJ?Gyw9eA1Ҍfh\ؐ? EDV}(h8OFFgX}?!܆ Auxaړ?<wr=3jч*ƞsڔ8<_ oe?9{g~bj0gŒ<?{aM&mI̥A5Q]\r pZ8 FtJ60MK3Nv]ujF.r"-"_ A¥۫4zH%W+S_?#y2 Ǯ?gbMn!m&Sp|hz:ts|'59әDet,c/HttY64a׹Қ`0]BN,l3wݺKpYM,xgTp&L5̜9!x?'8;AgWy92j{=MNs}s&wĚOxuK> >Ydxm˱<;y,=~/AѧN=,*Bu fl yrkD=lSԚ눈)t=MG}vs:!,BzrT8:b/B2Nȳ=SzasȘlۍws;أ:x/S%G=N MkD?w e w?gcFP~aAlT 1 CYUT ()P(HIl8B$VTvp6dMm2cOq>6k{Qنњ<!#2ދLgE<]գh >*јN6ZB^Vo%FX`O T$ i"ԕtDA'wx]f3\Nݲkok[93`ia(9BXk\{줆1jGxZގ,wp 8y/ !FsHZbQښk1q6[ZY&Ř֧|1]d&9:y2 4,p9W~Jd,Ȥg8gcŃvA(P& WI)0CAh$mGtֻ-9k6ąN@aPHERvr+(m.i]0 tI5k:h6HNz8^Ƶz .:٘55=ѺZ: >=|^ߩۍCQ=k2w>$~Ǟ^=rtv+^hß>@8t0 Fxg=izg~oN̟K=M3jSE) Җ\oes_ 'G{o|0Hm&ux$㿷c`6珉)q)߳{e> 38SS|w) 'K/lSf<Kzs[DeiӹWO2ڢ:<kHxO׫_UUm256&&C~O[z QD х$9~_͙-5oh8?_^\(eYtpe<^!?*}a(\""?]q2FGܭb\rװԠD30lԜqpy3>K#B. ,$6 R_VyD*=OU7#MZ@i9;󢾴ZD6w@gA7w;uχ~'METUF°_\_u[6NCw.9o*}^w}6Oӡn'WAx)˹)G 6ewe6jd#͗YIB "RM2C  JA 0 KP;e*'E X c P+AɴIm&\kSiJ đ0ʑ\Zg^g=Ok:]Ovn%[fFB+lX1;8Dw 'դi$"=Gwyw_PͶrw>V3zDOl*e=ɋi19E$wt;pO7#3T\ _7IM͸ǁFv Ev+ >f#z=4zv X j}׉C3@?L&˯;Lz}HHfQIqCP*z~{;JO3@OѴճaSS^%1O &}93?k_cx~>BQ{%d|V0`E~?MrG!vl[[F9GwZs7{loSs`o?{? D) p# 2s3"4{P iD,3^]}(9(!55tV"} ڔ ]Kep)y%?@FaR#ȷW qC߼vϏX}ރ7z1ZeFWAf|.m{weEWRW$xNnٿSOwje4#4dj<_9Oar0όɼx.)<Ŋ6a@bVB}-IN;.g)qJHis@]O`%`Q }*{\te8JKO) n(_'[.˕XC]|8w/iİe3ܻ=TZN5z?g )b1R͊K+Bxv5Cŭ@wxDk9g!Cï`fȄm(7n /92]i'Z?viQɲ'C4x2'lBإv҇lZ.zj<]}w]߾YA DCL& Ӣa4XJ#AcB[`:֣ua/JUo J(*:A _Z p`X g'WT88e$oCQ+Ǿ^L#ֈ%q\;%bz6ֶBZ Â`>'%j Ű@t)/n@] Jd!P6Ë-OuyK5sW??zbY*fDAT1+SttY{rCP @Ш=_gIp=ժ_lS5$ p"߯|Drt{!efd/d ҄]=`0, {3„,-:pҽ`q =PuIߞ]d"S5Dk|wQr;:b%n*fj[Q<"|?Ǯ"H,ߢiC^];:mX/n^U%:%t(̨lψߣERCezixherzg)вD~Vк[Oڱ0~_k xNC= W@w%{T(s]QjJeQUUORO׵v騟oa=x `ngyP2$Tg9\-Dm8>t$aH!h{.7-k߲R=[/^^ D)]Wf֩AIlg]/=,Xq Ȗڳx)" ɻJ @/w >'Z/}W^)*"HR,X%[dYI=yr&=\J w6ރv 9p CDIɇn ہg7ke$!@vPP֓i!y/P^?mȻh( a"N3mFL厍+Í1 i8jFjM1ʛ5&2(6%fh[VHʜrk6ـa h D,QZV٩reXr 5[+""EAb!MM60N9r8Ř5XShkV.4\1sm63K[CY+ m6k1$^_Vs @@(7UQI' 0l㙕G:s]ֳmH.⻷ 9Ʈ[i7Ӝ[,x4gMZaH1HXfјR#}#rx9* $$bv.EbȌ0A"R#Qb;7"JwͿZhtXPPDB#ld{Gq@]CAהX|ZH&uz͟i`$d|qN,r }, X k3Ij=F/®;e#jxPT/EϺ~89cm(НiӤ%Nc+i> \7d,iB7g<N{h 2 ݾ``j  `hSlmY!d9C :X,&춵G@N:ʄҜk.{H;FIO .8EIWKlЅB4WjN2+,ZveR(FdE'>*(_h{/Gy# }_wt|MoY^v; zռmlxC [!pMPEPB(C׳_bcxHzhM YX҅No敷q4ヂ+`ڱJ%$c} [vhND qR6dLO|r^ RNŰdIþaeTUE[D E gvBC?( op @`ֻ9ۡ Fg=:cG_С4 j<լ&e&meEj k'e(ٱhmm@MdU$$`i"I[kcliYZ lB4 A5fُ݁-T1cv~tB/?&R1l Zs*znOj-;Ҧq-lձ:%s+AԲ0['};T槎FהiNs]xveWډsKѩ.<O&%VvK *Őd ~ ; P@1&oC. !dJIl㰁ؓsy N0;:8`Ň|%'Gn֓lN/_QN;C$ݜj#[ !iɫ80tq00&f9Û=kqpDB5SM/g[͙ H TԐ .xIzeu$BfNOLJ?s'zm;U ,~;!"bH:TС-[,ljfe&Ԍe_t{T5eib$?oGmfNJCXS0 +R]eQi?OB$ 0'fahJ)Q`TĐÛb,j') 6°^:V'!RB `PtVP(ǨGT?o9+m|tb-c:iIu @tY:s2E u;6L C=_Tۻ &cle*67-KMS2ÛeSh1,ke5M54Es\jʹ5Eڗ22r61mab*E*T *6mX,jji,m3cij6Y3$ecX6&փomoOl/m'6Qlɍc5cdlG2UȶkY:c_@}ZRMC8`LƯR(]|>ɽ DGZFx1iJa$?O;+„HѨ% <-Hή !^\c,GO?G/|mQ9Ҏ A:Iems"&OPXCsAEoUBJ=T2MY׬\|g%: VAH!?)~}#xf1P#" G},_[)wñ)@5u8VP8" ` ""(*Ye:S=ۼ>sqtAf&8x`YV!yrkg#R D K*tCʛڭ]*Y}"[/fPȵ}H=Gޒ*9-oR=#`ljMCKćL4MϵX2=W㎬J8/@ʟ>j'1cIf%57 eLM90Q_u?nXXy–Xzo)!yxt"9̩ T= $ !;)1wI2SOb4 >[\w~_G<(_4]ip"*)5s>V28f/I#{j|)9*Ȩv?YhnB"Y֠"(<-c6k l1EZ-̼P TbeFg0;7=?'ˡrzQ8DS CQ 'c齕5Gux|6*9TN/ڒȢ D:ۛ;tPSLB8=7 Xf o2i+\TzcRH"]P61򾨗EQ!M'_[rW}MMJ{_( (tLOLe~hIl͈P6c5nۙ6XFP@E9/;ϙ5R桌 Ǣ=`[.~7DBy;]Wj7dY c}B&vȆF^)$"HI!6F{xQ# @]E|"AWg \%̘cv." Y wjy ⪖|\}2󩍏Z<@q EyA0efnVu.d@`ƅָ+L3_\dS o -:-x<R m !ۿZ#-u]Hk߸ vRјp~oL(NMIDϦq @oJ6K'o WsqB 9 TC(x)l؊Tj9G׺_kJl2X:J$  }˜bZ&a]Y휯vF96j+ xacJg1Yھox>Dmwwkd@bz }gz $ XUUuUtIrl{ժQ7?3L!w Q? >;/|گk/?Xe_cQkr&ų|tb޻KˉGC(z#)`~A$l c4N'Sxʴ٪[LlQь "2A z<[sn\Bw?[fhqA! 4,cQ-F FB0P.` *"@?(TR{4?qa !CÒZ)ep"LvI'(` @ 4]UHԔuJ0 3EÇf 1`0bP`R,+QM%k*Ia*I$Rbh J\8.?WMC4+8@ztOf6Wem55sHQ(b1e!PB`͡"3I/_Uۏ&%XXJQ !ـ[ SRCL(D B'* (Av0 qꃶ9w}CW- 7X(N}O~|̍l6R #~KPTAڬ>:O95XXdPdP7z-_{[ilE T`x(&P ha(h,E2h: +$# & @ˑf! S0b(U(SC Ф XM2* X* d$ ݘ͚mI "!tVvDߢDOؒ ?%*bV``)V8$ ?a[H@!pdIgh'8&g\` H I4(# [ `7 x]tbq$J_3M}Ֆf͚Lcd[W,`Ec!K+d` Q,[VfWUhflY^\-- e$')$"mmfFTw^3Щ @u.W-hRWJUC帅F&W~ Pl|펝fo h5톴~iCiÆ3iMnɣHhѫt =#pV.m%]Ddet_ wPp">DMd+'^{hL>7 DW  "@Ax1Dshf˺>nߛ4MBc5 nJfǹC 4bUB̺$6Z5*O=#UT=6[2kIO\kƍmg-B}}Z@F~"Y+tW||<Fv@HKڬewAjJw+xÇ(vvˊҘ1Z˲>qKjP"ܒXZZ۔cF:F{|ʭ:yQΉ9{vvc/bv\=PQ7%Ѡ2jh͛k8u zm|f3f=rvr>jem]'睺sb49~xoAĦ,=#IJ*63U଍r6NsSV`]ONG|Vh JmhseRM7a% @+$UtHy7҆.Z;ؤYiwoFg;->XjhFVj+/ p9@ P B]p{_ 4*/j,l1p@ DC$ E kJMcjf!8G}UpY=)"{@C`^Oo1ZM5aaL:-."b 4;zo)/ d{\fo% lD_zS5COAh>^uW m};j!D@a=H,. &UeEUc-F<s|2C*HHkP])ta A„2$ ;ǽ;ed,/0HpVt7~=ʎ{8F$c V/m"/p6$S`Ub.%\sb.ML]I-ѡMv6DR]8M?vMsRC|{X$ H~nt4;h$,19j%`٣I; tb$lW,876a'u~=CRee5n\OޛI _s|ň>IgG^yC$gZAPftMȼ`Nq? q5ɤlK*BV1(+qCLO, 1qgxp$_YWʉ2ס:}rI[kߜ+='#9sjXB@;]/U 6K=s1=[FD֬Vilnq\`H``ssP!3 H pDM""ʒQv@$pLĨg#f&"˒نa 8I#!!@wt Hh8QZBXf@չ4YYfG4X4Rڶh E "L`S  4K nXe4& ?(VBba$2Bb,e&RM6h(Ѵ!欤X҃dKfhn!їPP,0 لͤz'S{@X|i]%BY Jc1dޮLfAMjU (1R CH BH :eXahVҋr Tm"037p0!4@y8rERm􈛉57s} &HE@O4nMalkf1FFDOGvY2mksg 8H!&:Y&$P!"K}P ! 9L9;N~^Bȧ9hIY?zeyބױc/܇/}siNwwgaךQw6W+t/}snVB_Otq8O &_taåTww>' 6 wx;{T*;75[Sr7FTVA 6 #w:P% %'Aӕ8~wn3/;)O1+"$ DqXÜs@s%멈l5'HD`$HVEV0@3rvh[LFbT *1b*AE`%eY $*9@1`c&g2P մeZl֜W` b"HQF1,T6!fƓPf:RA% PCG2m_+xϫR+Օg{-n73k4EIfQMn JkJ;T/B+uf0 P(c)dd.Ntj]hz5WZI,L2C&CDoךN<ؙ5ieQܶ`s7=5SM1XO0+b,HHŁ/(r.F-Ɂ+٢~DaFH Dl4=;c[#њ͛mk e9«+XfŸGOm~P]Eɘ66hkLͳHfhl3-mfHl5fճf* eY٣FXL͕1 e0e̘fV&eō%abfQLM3 ՛M6m(fmMjѪl+e45Fm-lɛ-lCk[FF,KL5͚٫ %NGVeeXƩ3&f,mbFeP22Q_KG@{T%=>Xtv=>AڜrJ4l"_n))x "#d\V՜p9>zyy*3IÆiX8ڹgv5LjѴff[dͱѭS`K$CʽLn"08ܢP+tRz/MڥI3p77*UP$zˮ8h|y2Wz~̻^4h9k?c} 0<$QDdD@dMRJ3,EI*J3ݸK1}x*ǔ<{gRQtr0٫m`@\U&[fZHR@AHơYPB(&&@10X̄)EH(XPDJRd,X#)K"ѶV$JTȖ2%R"JYJ P+H(H?HR[A tc6c4:R]8hbiMJ49fWpQ<(ƎS0 "H@ЀXHQYņ82*Ѣ*QCJ #Ӕ+*lNg^ۄֵ'= ' ˣ⍩fYs30"OLR/~.l-#6vrdf+>~İv%? 3qi|g=Jp\InwszI&6i&0}IFQUk% N ԉP/;%644~#zw [W1VCїDMg_ՒZ;3N/W<7؈\T+TYQ#WF9+ɇw={F_OlԑoӁ ;[}!W'9?$FZ@9E5}aZa 呔86$<W_sUʚvh,?l^q;:ݏgx^=z*%%%@8/_N1oA>ojOjN;Mml}d$9[|/v>_zO!} q!0osayu$B}'H ?H8Tz16q9On 06#X"V$IZ9z9`^Zv4Q!./@dDkh&9A:={Ygl2=t&~R*e'x;|~CMk3Zqa,ѕqrغJt Ty fR(jb*-DvN֖HFl(cQ),XyX;Shek/~rz~'[L34R0Fl^)7}/<ρ۷}bŻ_P 7.kkV(0XUo{< 6-,0_lMQc} 2RQ/܍q8R( $XH!dEPlfLl}NִT}y^lڗ٦*zȌ:NFGhNx"pprQb`,GuK\)Clj1)3* F&'Oa.a:[cLcVj[,./R!*J,Ts*rfMfv4(lՊ-ĉ"%T `uYh#."D\)AM ]g2g)# ,41LŚml=CAa# EՉR)WͶ,ff+fKEr8n`슌F(ÏQ ."05́1ob3ݢLD}^>3oΫSy?5vW}=ϝnf:.}4[9^x0q-"ӱYOn7Spo:,J3 )2 ic2`;ZN|dw b0tD3]˥GJЧ(/:]j|Կ~ ed]ŕ-[KK_kt#n@s5c7YˁBC?,lD1AFbsNQ=>ܷ#3ԫG$q7xq3A"'7/N*Zyz?M6fQqłFDc)#=uY(&KEtm8Y~^yD֓dy& np.v/?3az5~~o=OwBqb 20{di"€=2]JDK8f7嫂V^, h!f2/[~w:sn۞/Iee83`,gUOK(!Aa!*!{âno; ?KdV$g& ly|(Dk܍auҏ? ݎu~Ze^+CO9ҏpn^f܀d\ܗejr'Oݺ"KlU~Q@s[߯ӦXTM"c@=9=r3ԣReGպ%|HD'8zT!o'ݼ#;/d tJ$V2D!MTOE P''?VS>;@'b8mDzJJUK,|2/cyaFob$8KI*zJ<ܔf߳!,2) @0Wc࿥Oɔrde#aV9RWO )uB a=Pi!$O|fRhDN;AWnjfYk5Sɳfbmd͵M6efZX*,DUc`YXhV Kk2j'O^[l 兹dګeqXfڌV4d1KK'ԝ?\{?7B TU3Pohv*,3˓"R *$ . 9K6mնoK׭j'4UWX`#H)a)ouy9&NUX{#[LFV4s Fm#$x{UۊeGx&ii*lH8MO7v\DLHk5aAXE_5 E@׾6 פnr|T!8I6 Pv`nrMfeo7ꓷ,~=mSQS'smTfکb?Gl-Fɵ,6*6+ ? 1q/]6NUuf/.C%L9M%Yo:h䝌vmRLɪzR36ՂWX(f1 \:m!kibL~L*zR|"f5Gnw2 3|ɯvܙGJ#lnW#hS.AN(rܲ U"D=N]†3ʬZ{58)/G59;׷GHO_nk< >|--~u^vU9/}4DU"c C- 'D;U~c 6{9(~y.>]'G*yx!]ŽWH(@(PH3tY/4oJ]%>TZT?x6jdYɁ­!` KYSѦҥ~1=5S|Q9/5:N"P{_pHIx7Y崿΄1H ПUZS~6$Xj躳ͫ?ٲi EQno:"v=KQ8: ʵ1 06e}*?b&r,r˖B84\Uy.an^8e5> i+{-ibvM50s?݂4͕Z/R %yskf="t{*T j QQEcwksvר չ]%n/L c~[˜jfͿwn1ȠȂ+҄?lk=~mh܄4k+uF,XCT,t֚ZۇZ1XV$H6LH+$m jIf7g|66h"1+6(0m+A0E[Zm* dL33`"E`l "1q`ҙ}fcc36fK1LԳj1T̮4ֺ "k|n y71]s") H ݿ~+K20Ɉ I>J01>ґtw3|殢^ (ddWK䷼$臣; Z 9P$P(kaKV-^g@1$l&i,YR,bTAaU*`ld3Jj\fL/?<%oxߴoI ~?o|-o~4)TZPU/a`!<}MTY`UN`ӾnLg!n"v rּ@U 'ڠ]ʍIM R 6fGU%M(V@ >K76y]A2X K 7w &D!/kD\|j6zFd_[J{ֵ_1WtL@R d-1Ff㬛W i04"ZF3Hcǃ{sl/׿C^ת'hʽlQI6IfZ)&,D|wH' W39'@_& =ܴ+%d,jeJl n:&`k`XdVRLT5@D}s45VȎlpϥGvϾ{˲'/u/Pyc=,|EgHW6.YNvV)0ƇKrZxc8uOU);YS $cP6d# F%BH30d? +PPD{CXď<쾗 F ]S*u}E(L櫆=;á\Up+=K}W<-eC'lf*ƍm΅Suo%efFZ#)0'A!lUHАD(@P2?!?gKӌ۽ڤshsYmZƦ)ləZZ1elmji2d[G\? 1iI-6ImmY'm>{1D,YH2v*js]|κU J{;̄Q }@i?UM4CE#"H$ VVsS3e8MܚIP#Y0eS `"sւj 茥 2n$.Q|`S:E@>' c.cdL$£ "Z0'n!23 IealUHf63`ne-(HGQUqn]rZ:"]g4EX~IA2y;!]8mrg< ^L 3SC07;q8w~uotxt>A`4 8( ~T*:scՍCt h(cKH <#+A+BA+@3x:.'"n,d֞?/N Z|GNq3>fY"ۂ_?Fr7ՍD eGg/IEV#'[PQ lJFWI;CᄉMIc=9V'u>nŌ LXE΁L %ZΞ\^z=&ĺ{W CRX{3|hsVʅy;oiDÆ'W&Dzj2Ng^ߎy;~ub>4ru!2pz59N;n^S$FAxmMܖr336_W͠z3Z3R奺|lzG9k;_s9ή֤s5Gg,ɳeIw@oZ>pWx^@csׯ^9:^Ldv;qna%.:xyDCu0ic1SٓISv\2C h.(ÛyvYTvl)Fh+Tj-{uCj,ZCM^XZ]%p-m\38w*R]-;6hjQYϡǦ=of*G!(fITѓrox8 ]ps7gɷq͓'~Τ>H/^UbU &"0#;W2D="YOa9ˆUW%%D) ^`$%&tgU$:̯򢬓Hʯ^HɽNORB@]Ӷ߯I6gn!,=uFY!R&Y!;tao#U,d[0s=_"F挳) L)(f5)۱FZֱnOpA2~Re0p}!~sLoqޟDs7Sij!G/X@/[ާZ^//$Hgc.mmь\$%ÌZ[i@!0㛚6@ɸlŠ JA'̺FіYF$tkrܪU.!A+8q i,P]Tj]q"yzqcu;/^oxkcgj55;=9~;e@Y6d,H38¡(L舄/EaO g|;xuas{BDDMO?)(*F^L~P2#Za_&-s;m wu;>Mo8A0!%QX0Gru ~C"r_w,peʊ>1a"<$@GdK3&GRCG#*=+6 =Lb`2.aFQ_ {A XQĥqAɧz,Li^艶˞&ii&#g~Mi爴([GG <#9#$2ls1b!1ֵ뉉s\I.NyZܤlr2s3BDAr@cyēbؤ&M|͏Ͳ 2MOHȡ)[ 1 A(T,q4S 7IOofdcB*biKd@'O?Phs= Ib40dB#% )"b-2]!^b(R@NTRw;u'&Gۚ|nOVbXρrLzW[m2 C+L"~V0S,VA> Y'\ 93+`jq_Tχ(8DzƈtP  mHEoBCt0@~I$o3 z~[A bfݡA`fIC ;CDDe!0/)ciC#DB&EceUURKPA"x &fI[JʌDHXB":Nk%e&͖7ǐ0EȠ,`4]P$q*F"גE1Y `QgRPPM=p*+J?w#_(^˯:QR (I  i!L{/5>b}/[c(dmUQ2h#F%Im)eͬѪ emfm[jf2"1I܎H-ՋfLlb՘˞"?([iuv0O>_'Xwj%=չPɣS5[ R"@q+H`< %P&* ݦMjnNG 3XF5Mk)Ðz{Z̍$bR$e)bC I<)Zy-ܜ8K"xViJP (FҮmゅ|gx{)k˲)"݇ףrHI~_F Tm块FW5c̬dU֡BTr9$}E2 1ҕ6ZDw8B %""?,E eyl}؆j{˅?TCޫrjԷSj[YG ȿ$Y&-"6 .O7J'K_ nm]7gގ;UG|^xڕüd^6fpWT>!93PiYO\s$&xU)h֓e\k*:86FY4+x "vx-Y9.DUYDzv/rM75'#({dZq J $ MbHNv93k\SIrq$`N7(8t歫Hif&,NLȶ$(#$dQ"Ȫ,F(cUU6m*߻og/M'HWӳxLHqY%{Y ў.Cp p)MA֙C@gR@5Zyf`0Rh'ntCN'`ιwE4X[jja 'xg' pku"kvL,it=:T!oa5Ϊz8ZT L܂!2b,v4"EIuf*uޛpK67d"g /GMΎ;`o?Wzfܪx6ۮKsJ3U>][&9Wd!.}ָ[ލ.kX=r4 kTQ4x78bb^75VÍSL);ě&ݣ蹢o|i}EfLtʮQ,T/ř$dXSvh&!42ԩf0q08A giONgvAU׊x8٥|F" 6̤.uXnҩmIJg=hF ;}~v<lu%z@^lj3lO vʩO):8O{2@;]Z}ϯ &[yW˲283 pw_f60٣wˮ$ y^7X2 9v[.6w7zckeϷN'xqMP"  hm !E^L[mI![mo?~j<W!#/! !$O~Wn . _qK ;};61 C껟yL #b(9J/ C?-imi#}l rX^Y(«+36ʮJ$cl%a aLPXD2+3\sQ/_ҺDccؽLvf ٝQMM=vt<#EƔʹ#8f*D (5(BRPhI+ 'ͦ.sF6fi0D-'h.eÓ20wAJ N0 }vኖj41Xfٶh*ea!k̜a+@hJr>͈WVvRΚ^y;2wI6?F*UKWvzA\ DF|Y_iLHd? ( x>IcXJ+4FCSR5tjLb%+I#15 VZqc9*j {Ӈ)tI a+@Hш1(ЪmXf\2 6IKJtԎ3Pcke.sflٳdpFSφJORD[Ʋ]k:0Ѩ,Dd1ww.ZփGS"hQCa69$d BGaC< N UH&d2D`QO=7{랉!ܿKs1g~`Qg36H8{v8DkΔHlBGQ`p;e)A}KxK{*} DjOkK7Vۨ ~ {Hm)u(0DU%e2J¡RLa+$'(U6%u}!`% +Z{.gzčׁ (& &C3q{9މ%ƬDN{,2,ibmmH@("bg6F**#Y`F""(d?;QW k#F( H`EXlK`G[lm`'b=m>m1$;Wgxq3<D0j,GC )*mi>pU.5"G0{3C2!ы@zJv׷:3aˇ<c@@h5&fɓ˜dlR$$(J`"$Ȅ@%`ڈ[!JZ8K)eQB1')SInBQ"J^``#vɄV!( hT[2N ,A'ZT$$!%'FmX  BzRa6i5k%c F+_~OfZg=p:((\/Gu@t)q7iP,TC63M99c%,@bH%WݪD< `Q, խsՖ0ضLn4ƵEG&Rl8Y<d2?]sylup($b VA ٣Qb7oC Ӟ!}a@*Ib%bĠ 2$ DQEV!˵q(KQ⒏PY7 M[gI͠SWxo2bu"4a4 8=aqfhCuBZ4Bኾ nvu \OEYWh?鏔2Y)ZԈ'dK ~&"Td#T\7QLt r.oV$ $ :Az7@ĜQvG m.ZgVI yi&Jg.|GE$ob@O r(Kfa1»<3T4퐟N@LL1ixWE8 ۔M1M3cۑSFL)./yiSxu\Qpixdj1FՍ3)i3#ej [-3{ 8U~^qw bCg t`_D@A,HcR P$F{[r{|/UI ûN6".dj=+s&雽~6&33lafm%~)ӲuyM-:O]c3 Ij]q\J(RY /.nD` UBDeOY&hl~:LOpϭ6aꌠc4UOaNEvgW#3Kqu3-9]qX$3 &,62.n>R,/s+8O'0MD0϶e5!_P1}rlOmv&{&0(0HUПI#4^[8Ϙ8Vyw` .VP՘rGo~>_&0b6}GKi5<'Cm'DY"I:j/n/> xOB9pEh9.cg&;JF؅S]"a@hr*#<I;}N`NvI~ֆڠl9b~% >L[l'tcW!o=(~ҧPb*Ir;Ԟu*E1ܫص?l% M@wi~m];|wL.:E= dƌU@;>Ma'gHeOk!W7՜ip}Z9:⏓4b'T%J>po3_UgH%ɗ7q.uRD; ڢ"!~~q{ߨb?|Ґ+ a(r3BZh?+B#!5ʨc~Ívۯ/QzokJiFݹEG4.YՕs-B $'mbr&xefIa $l}ky@jR'_](;.0L3KyFu"xS*Xaegw9oqx/,!Cq?6ƕ:W_Xv>}gGFKq;_K^K7o>~zܲ?n{ lnb:*M*Q 8Q)KgMi#iZ4(d lTibKcU9:!w m_RPb<A"/N:xD[p=R{. p]nr<}0#GzH>w6" s߀|G()RנI{+"nܝü<Foc]kS]:baW}|Ͱo ;]{j+PA",XA Ht>\==/>ǧrs.Zp^->>='O:QT_yW Hgo(€e`i/bra6aqـ'E¡+8!32/D,d'ʮ&'ŅD6;ZCD^RJ12@F y(bPUD4 v(ͤ_ix\YBM ,ׄ)60#>NC8چ2z ?ԴN;7 IS}ms }<nm'$z؎ N "Fv/Ki'=;+\ރ;RP P6w~@1I!B2 gp^K'yI"Ȩ80(U/0(CRPnwo> o*f",!/N!Ml^SNT >OE m8ur㉇aҶZ䡤:O dJI *j|44rVJ~{2.[oP!ni^ l]{҇iEqj] 1ׁ*lvVk$?J^;ᝦhfĶG+hb-[v 54TO6)ڙ:)/SV|?PW7H/LDk÷e}Ϸ?6/o ^) .V>oWnk8ޛ7<קT[juKʌ]ռ{WO2߱_6m!?y0m𺦈v \b0Ϻ-DAM+R#{tůlĽ*bRՉ}M{#?ãNx"KEk@WҒYq0Yh_oj+zNG ̝0 5bEfu)JԎ(}L>_iCBs ,ѼˋmdS/Ff$.E}mv->)$j>LWfi7+mjB\ya?YU6}0P2X>\o!_=SکgNcU4#Vg8LfʲKV̑Ni˂O90 ;wF,/~ l{d*1n>I"94GfALlֿ51ā7 fZ_,I`LMG/!Z&pÝ}mTp5^O0g7pz+Q2HM;e*A;F>zSmw&vogزia{5sz /.~6(&jhTT~o+:[{sisx(RXJ{$Kg,4I}}ߚiB(nd&ƹwf贲!!݆O~3{1i,< Wr] <|SEt{*_O8ͪi1Bmlл"{d.{Qk",2z|ih.CD#qWlQf'KZ̃]Յ~:7DsyȻlkv5 bVNYQ"&UċIXpfP8-I4- "OU8y dK!'>ŋ/2T J|dHE DE~] M+, aX4wɠc VK7920:P% ԫф&|*4sɰcx7wL4a{~5*ee_wu{ 5gz_$?0atkI4ޑ'-v(f"'.vv} x ?Rob=sDE]<|Ţ*4+,'bm1rd<=FK)NKN.J e Y61@DUE . _!fs|h-lqԷ,sLH(L{]zUaʩ:Yw%˰yx_7#lP$- r)h'C%U Ařt+ `'@EɎXr/ 鬃/M)k|Wva5WAM.g[-q6 WӤC1M'PvF?+{a/tN#u.S<|vr?vf Dlbd+Lkĕnmt}(}K8TȬjK:!օdB-xre4qcAӶ c]ư2bucCٗDD*N4لQ <̗1:ǥT  WV3S"-vF.k&9ANؑn&憣0q9'n& 3(/xĵ^:I#O)9n϶X"䎅|DRIRbR"AL'K7ցO]wnYBaB/EuZ(py n,HN/n2I p'OQC&jh)YT͗'+}~6ΧaRCA0 W'6mܦG+&N r="t KH#fL&:`-b;vv*1?:8 U?Zj"* ;Iߺ^οQFyWF&Wx:%Y}1Qrn؛j*9#C8^$-BD~j'wspf h*`K0V^ͬZc,RċNj.}n™6 y~ FPL{P?'uG~*bSV WL2H" eTB9.xMf *Z}ԇbSJ[RWbvޯ?0w;gE352TLAR(ƙ=J=ߵiFydԿ=S59)u~|Vzܑ?pmd(2$0t^ԜAyQE @T] rXU cHtwI۫o$O,{'G8~ۙ$r%3SԔeis&A6GjB~:{iV]xSPĽTYc@p,1bϵC78"kR$wf>Vg򿇄srk,fXb؄5lEr;{%?O U$|WCAUS.ayml]s:BL] 7Y04']^嵀{\1o}ҸzÙlvDKi5P8S8811Q ɀ+A NB?^/4p6I~>yA2ԡk73jtmH~[˝xg./)p0,]![᳀FME꼪 s;3BVB}=v;lG>F4#ƛMUYْ6y;žKiP/b+?,,F10Ȯ.cOk["v Skdҹ%;TtIUܗ \ehN[ ]2F0 !SJOOJXPGUhVÚě@oeTb*+'>@t赼*BK漁zF7VÂ= \ײz-Ϝ:"E2󟺣 "9` (i Ķy 7 %9m_9JVoC`\+ins(%/:!a *~,e:QZ)XsQ^=fj?1Pcw#чIpoz0=_VtwxA(LLngڌN_L=g:w]hF]>Kyʼn`i[qv!hͺ=W*Yظƅ->d !@կIs2",۔@+6$CA#zyWvbM(쁓R 't%)1peH ɐFMaoZkO*"e;GC*GqZ&L٧yfS/ٙ47jXLq5ϺRmW] 4J:;׼V/ #zOR_H*:,KӺd' 'q+L &郫l)MًE-?#7ޜn3jx2h)q731S0J멈IbV=M XhaPp*<\hM;pZLq>MR &XXUqm7bt-vN>mYJKe9٬}yQ-pQfåDJX19. Pc3>5-@N)bhXA=b[\]r4[p6SpOW[rW*՚pw`2ʐ堅f@h/@ၸ.%>t{zh^]t!nn3!6dǶDnx:u, @!xvڵP"c1\{A• @lló,젚zionI;lʿtl:jNC)Bn.88.ěOG~0@!n2֨CG0@9y}=pι9o% GFp{oݕ)׶$MkS h2YT@(+G,pAv>vOeG(R}/C23C/!"p=_ W)85lH8`@d]دQ\"$- Yr~|!vz_4tf_{5]{׸K ~]~5TZ1r 5 `uWz?쏿8w?aԛB F3*J/z_ڣU%;q<Š$>|ǵ0=7GGO m_^vT"(ɮtu26֍M䙻p g&})nJX1o':jO-)E9ջNMƹyMa `?BM ᖯaʻ{DmӧNW) DNt`1Vp/@ܼ'׭dc j1Cf{dݡXUy3,u4|2GX3!l0쵦?6Ƃm9V NxޓIf5D0{5%c]h`d"ɧ?Z~ib(ZնM2LF8̤M*5 W%!%J2^B;yĢc2+piߺ ';qCbJcAc;[-w(kppt } V^k}hذ/Dݿě,8~sH]yhrS%mRop:S}6;W gpw,\rzdYp]O](QP߈zҶ}6Ɠh _RR:b+L8ߌ 6>ҖFe$iN@LiYal5TR^Y5ʯOI/ΝlFIsЗĜT$2¼#SGSz ҵ=쐚vl;?c9EzRw9A{?°o隢\=c5ߙVS\s-),? ϨNuU"(:k-Wݏs/W4,SDng eŋ@&5qϥ@1p}6wa F8Jd/IY4PJ ;oR*RPBQ|X,Bq9d88T*\NK ~񃺫X]gWS]/dijMלs,\pMsQC6_vrU-BvdE޻!+R r/Bt*5k:#ȆJxx8gذlj콟ytL`#B_Bp>[RBEdF!Vl V[GcCk.r(Ÿ"b.ًnVzj^/Qrܶ Ȳo |ze[8yl19 ޱ0>HOgQM#`HxK{ɇ) -.V4CPW;G' )k,&LifFWh~hVz:TuԽ6O ibvG]O#=uA:,(ڸt J|1-$:I3Q_k`_oȴv?Y0ل$"Vܥ3e`HN +.e([D~h| bqW:#_'fjel~%t4ʑ<!5[>grx͒EscW7eJq^JvݛR,gW܉)6+R(وcV~xyw^ AʪA7!"d t H=eDXg@ >A^n~w ꪧEWñ !tnrN7R$kwa!.Jܣ+èIfOEO&C:%S{jHV `l6mVGɱ * 3oDE`.%ށX1ހ Om@տkWC \Iuˡ.Z[[ncpX45@/閚3fKs}-E1'_چx# *#!GPV4/z)f8a &'ܽ@vQ/|SZ0diw BN%'yQ GA+%sҭhx)jH!Qg0w(6?L$HC~<ụ?a/i< k`#^#GJFQ_|]^D[ʙ/ݦZr%@u=/(A {5F>f#@cyQꋛݷcP{ͰK(g ťJ0>cIcjA$^|KE2ΈǾ@H[0HspYrX‚ฐCTz$*⎊:`[׆HHDEf43N|75գ;97aT.)>bF?zԿWf܉`)j9p96bkL#oh-J'H;v-5.@/P`Pad$nIшzZkf},u@(.\#0X*`97fQ)Fr;NciFq `uĞ7WU/~ߚ=Y WpMkjyO)gbg-伒c/R_E}r0,|'5NagN-o9_*35DK̒S}j] d7cFKZ?A:Q#بNQxq]8X%lܕPSXTݮ8otgR!w 9$:ӊ~ =nrV[kI,@&ph$cR9/5@o0DŴ&bR)jEs#}3;Cb-.{mBȓtFDUոV(\.iGI3.wV1Q4?#9t-!b:<]`6CrS)xȄvm}a!5oAҏJ[~k砥E25]ǒ ^u$ZilFO:F%5Hf[GBygg“5x3=evAҡ%S(V6;ݒC>+F O Vnn ( $udcw&dWlaȑM%Fݾvy+<٬Fǯ8ɕц6XSQj~` [V5Nܮ?ȶTJƛ mDbמ0jo.t>̺1@FL|ޡ.$]\6} juLE:[ԢUξZ}`1ts/A:8Sm> /+:s'nom֝Rk \:N#s*':;"\9A/uLY=q49o6{٬=j*+ tq,NjeI!51M 5ϗ5&uͰmJJ#I'拗v[YA>Ia8;e[zBQ#lG؟p|OB̷(*zTPz(b2O}rȂܪ\؇ PRC {Ω B.R$".x@Ǵ{tiRL>pj og/u/ΘXh[$!׆cqs[cZW_3CEm QC#Ѩk a3IɡCfS󡯝^snMRփ,6K B>E&D~&kf"^rg{2 %#:X|qjyxۂJ"Y#MI\S̲ccfzZRvvoJ.txӐ‚iq0.K 4eN$?: X37rLk?=$UIn \IE`ܯS sjH$_Ѳ[/JAm% rSܣ߮dY?עjXU &del/Cbp+~`# 1D8Rgrmpsc 3yg\D3tY𺔚郵x$t5\u4Շ ٛ}hޝI&7)B(ڈ;_`-YAgF٪ީ"x/ / i l $>Ԍv%c1#ZR |փphBcVєKo\a·dz2oLJݞ_rf S?2(}pX*_6ks<#Ճ8Px(@P -JL*vFh(iTtűEoԩgT@ky:s(ܲPu$;3o^-+K8 CP rd .mjC]n}wP/L{{lN;G}N3Ix$AoUPb?z+jP (EJX$(DjZd 9vZ̦ݿ%_$хgsEG%`w%U谌r)c]P{HexVr`8I`7)ׇP)* /Z؈M9㆑D8v۷G#sF%И4g bϕU"i'3(Ag֘sGr^'^ P:@idl~)Y$[ UlHd lBג YHK]WDy3zzBVPaGct'f5SFsi<=<iKRF!MMW8v?}r;@k4h(B!IF2`> $;HgC$0Qض wCZb9ULY)kbMi <"\fBEqy &vϧm0Wn[>rt׶v SְiǔϻX#IM%o6s_$6]c?qDܻH16χgdMJ9;54;]3;]Hm0 bax:_@{{F w̥wV3q#piq6va쌪ZMZ|S]ܧ毙 疞 KAo^|`1<;s|NxǀOP[IȋsYA̯/q+(h*o Y%yۡs@1X]СJcrcBFi/.P#Q_ jSl_ayO2agdn2152J[O S9Mg/fjZV#6GaV@c6N BӬOniBlt#\vlX.}bH2E@"J:nXD,pK;f7({-6Tq1M \)qcw*T>nn-箊P@)j ˠ֊YE @@}5Nofd2+j{O^~SFW[>:rkyN; !umj 6RPBs2IGgY;b~@mn,&R:۔ TkYY-vD,0/]Ӛ_$jgCKb3~k~ei!"dM[+s4,)]wPFđ `0^݊ӈ &k%WB;!f8g+kV 7#V SZVdd\ [{jZWTXDu߹+hmpxOeXKY>LFT/}i׻/u3'6l:Za17%M:xw+Dp}Qwʐm0<iMLAw/+ozlC΃J3izÎ3LND\d 7G2ߴL Y#8e0ȁc&֢yYRR2^y9m~ɝ<83UY `E&`uI>Y8K1z`-R;ܑ T<a)Y\Evi+@:Q;#D䐲?޿, @?^AڨX}E`Ω+oFW۶!>#+%g,P7CQ+NƱ&+22c>qݦz#/SwJD; 5q+bh4ގPe7''e>Yy**2+m5W-Ωr#=/D0%ASIs7/Px^0)iɋ"~p XZ";Q3z)]7T3$VWhP+\1زʏ>"Mӑ3Xۆ?lɓ=Э< E%VH-nhܵ{d&MZ`S_XԌ %Q~HVS1"( -daX 75*H[=Nէc"u?H?y j8%j7-9RxqgWs-͔=o {(fceg=l9j*eΧtt8Y{`¯n@ާ,j^<,'BWx8VYRZ_u]y+^}ߖMa$DRLG_ufJ54,H!b|:VJG,|9?+ [nldǬl|tզۄt$A.uh\H@mӞtCio)@rm7yc9u}Lm+)q8!Fm8pra 4vcD*C: U:Kpl=b-w3A%B!9pt ҝ.Ҏ|gecaDzHBȂ9UЧpϪq!B(֐4g,ys˟(m1&1݅йj!u7k :hS9]\Ѵ<{ܲ*[97<|l%-,X> Q~/MwU?Oac/+Wjdvo(+ cOs"CMo(IVfp?U]tΟ4jֶ)ӧ#Ѐ yJTkD<[ xf~c񎱢̘^q_YH?Y-ΤJ~I-csnQ2m l*8YYM9@a:qfozdå |E]][֤5kLQh峟=FgLPLu^d)HО5+2L&oU=L(}uQ$?`Kw%e2{W7$j겆KrmCN3*r g.a8#H/\I4Qb0AS0 -$W,]Gbmx ͣOu|W4pn(ޭ*<7,w`[AaQ1F?ܐxLqCD:cNWRG.4By/@M߹zG{}I (xh 4Ds#<#xɔvY// sy`T[ 6~dR՛[z耲ÀwHS dXJ[  l&P`d^A?(Md4{&HEgXAQqUL:,N6eŀXm|HH8\q$߫ f :TwFO7-.v^/0PY Ö3%< KO}ڼ:ȋl@(kDRGהKvq_ں&1}Ȱ3Ϊ*lvsDr:3e'xsol|p1OQyiWfr/# r45+\?t&܎8-@syz0zD;K;N1y׏8򴮉Dx (N q{aF/]3Z3 t`w nn/-Qhe}j t~Cez  ޹!4<8,,@W'Sצ[qFTInH%&ll0ЫAs[jBV։p07u"=>(V~YGXb>-BZ;AvQw3 ӿ29󎾽= K j!IPo7Ś_3b}Ah-B9LrCMwSH xQjtX٬5?"8 Oo>P<w$ 3?R߷Ol<4n\a :ş1P-F-)a2F3WΟ h[jw+$FŬk/ L.K)@ѽ+ ٤?1?Av|o璪