From 4aa2813ee4888872d468009ff97b4edaf7b99152 Mon Sep 17 00:00:00 2001 From: Dan Smith Date: Mon, 6 Feb 2023 15:04:31 -0500 Subject: [PATCH] Squashed 'externals/coda-oss/' changes from 3bcb3d874..22a7eab30 22a7eab30 need C++17 in this branch 99daeec9a latest from 'main' b9ea37bbf xml::lite::Validator can be moved (#648) 9cfe9a4a8 Merge branch 'master' e989b0910 createElement() needs to be virtual (#646) 4bdaf10d9 Change xml lite function to virtual (#645) d17b57a54 Merge branch 'master' fa00a5430 move debug -g flags to be turned on only if debugging (#644) 6be8f0a2e move debug -g flags to be turned on only if debugging (#644) 44ab72854 routines for simple writing to HDF5 files (#643) aabc5818e remove more C++11 work-arounds (#642) git-subtree-dir: externals/coda-oss git-subtree-split: 22a7eab3010a0074ec244142bba80fc8656ebec3 --- .gitignore | 6 +- build/build.py | 27 ++-- .../c++/coda_oss/include/coda_oss/CPlusPlus.h | 14 +-- .../coda_oss/include/coda_oss/type_traits.h | 14 --- modules/c++/except/include/except/Backtrace.h | 1 + .../c++/hdf5.lite/include/hdf5/lite/Read.h | 9 +- .../c++/hdf5.lite/include/hdf5/lite/SpanRC.h | 115 ++++++++++++++++++ .../c++/hdf5.lite/include/hdf5/lite/Write.h | 80 ++++++++++++ modules/c++/hdf5.lite/source/Read.cpp | 17 +-- modules/c++/hdf5.lite/source/Write.cpp | 115 ++++++++++++++++++ modules/c++/hdf5.lite/source/hdf5.lite.h | 7 ++ .../hdf5.lite/unittests/test_hdf5write.cpp | 93 ++++++++++++++ .../c++/str/include/str/EncodedStringView.h | 4 +- .../xml.lite/include/xml/lite/Attributes.h | 5 +- .../c++/xml.lite/include/xml/lite/Document.h | 2 +- .../include/xml/lite/ValidatorXerces.h | 4 +- .../xml.lite/unittests/test_soapelements.cpp | 65 ++++++++++ .../xml.lite/unittests/test_xmlattribute.cpp | 4 +- .../xml.lite/unittests/test_xmlelement.cpp | 4 +- 19 files changed, 523 insertions(+), 63 deletions(-) create mode 100644 modules/c++/hdf5.lite/include/hdf5/lite/SpanRC.h create mode 100644 modules/c++/hdf5.lite/include/hdf5/lite/Write.h create mode 100644 modules/c++/hdf5.lite/source/Write.cpp create mode 100644 modules/c++/hdf5.lite/unittests/test_hdf5write.cpp create mode 100644 modules/c++/xml.lite/unittests/test_soapelements.cpp diff --git a/.gitignore b/.gitignore index e1ff9db154..7489cb720e 100644 --- a/.gitignore +++ b/.gitignore @@ -2,8 +2,8 @@ *~ *.pyc __pycache__/ -# Build artifacts +# Build artifacts install/ install-*/ target/ @@ -20,6 +20,7 @@ CMakeFiles/ Makefile modules/**/Makefile out/ +CMakeSettings.json # Waf .waf-* @@ -51,4 +52,5 @@ project.sln **/x64/ *.vcxproj.user -CMakeSettings.json +# Unit-tests +TEST_*_TMP.* diff --git a/build/build.py b/build/build.py index 31b457b7ce..15c720768c 100644 --- a/build/build.py +++ b/build/build.py @@ -897,12 +897,6 @@ def configureCompilerOptions(self): # If you want the plugins to not depend on Intel libraries, # configure with: # --with-cflags=-static-intel --with-cxxflags=-static-intel --with-linkflags=-static-intel - if cxxCompiler == 'gcc': - config['cxx']['debug'] = '-ggdb3' - config['cxx']['optz_debug'] = '-Og' - elif cxxCompiler == 'icpc': - config['cxx']['debug'] = '-g' - config['cxx']['optz_debug'] = '' if cxxCompiler == 'g++' or cxxCompiler == 'icpc': config['cxx']['warn'] = warningFlags.split() config['cxx']['verbose'] = '-v' @@ -934,12 +928,21 @@ def configureCompilerOptions(self): self.env.append_value('LINKFLAGS', linkFlags.split()) - if ccCompiler == 'gcc': - config['cc']['debug'] = '-ggdb3' - config['cc']['optz_debug'] = '-Og' - elif ccCompiler == 'icc': - config['cc']['debug'] = '-g' - config['cc']['optz_debug'] = '' + if Options.options.debugging: + if cxxCompiler == 'g++': + config['cxx']['debug'] = '-ggdb3' + config['cxx']['optz_debug'] = '-Og' + elif cxxCompiler == 'icpc': + config['cxx']['debug'] = '-g' + config['cxx']['optz_debug'] = '' + + if ccCompiler == 'gcc': + config['cc']['debug'] = '-ggdb3' + config['cc']['optz_debug'] = '-Og' + elif ccCompiler == 'icc': + config['cc']['debug'] = '-g' + config['cc']['optz_debug'] = '' + if ccCompiler == 'gcc' or ccCompiler == 'icc': config['cc']['warn'] = warningFlags.split() config['cc']['verbose'] = '-v' diff --git a/modules/c++/coda_oss/include/coda_oss/CPlusPlus.h b/modules/c++/coda_oss/include/coda_oss/CPlusPlus.h index 388cb8fd59..018be14ae3 100644 --- a/modules/c++/coda_oss/include/coda_oss/CPlusPlus.h +++ b/modules/c++/coda_oss/include/coda_oss/CPlusPlus.h @@ -53,16 +53,6 @@ #endif // __INTEL_COMPILER #endif // CODA_OSS_cplusplus -#if CODA_OSS_cplusplus < 201402L - // oops ... try to fix - #if defined(__INTEL_COMPILER) && (__INTEL_COMPILER_BUILD_DATE >= 20151021) - // __cplusplus is 201300, not 201402L - // Enough C++14, at least with our std/ work-arounds - #undef CODA_OSS_cplusplus - #define CODA_OSS_cplusplus 201402L - #endif -#endif // CODA_OSS_cplusplus - #if CODA_OSS_cplusplus < 202002L // oops ... try to fix #if defined(__GNUC__) && (__cplusplus >= 201709L) // note > C++ 17 of 201703L @@ -79,8 +69,8 @@ #define CODA_OSS_cpp20 (CODA_OSS_cplusplus >= 202002L) #define CODA_OSS_cpp23 0 -#if !CODA_OSS_cpp14 -#error "Must compile with C++14 or greater." +#if !CODA_OSS_cpp17 +#error "Must compile with C++17 or greater." #endif #endif // CODA_OSS_coda_oss_CPlusPlus_h_INCLUDED_ diff --git a/modules/c++/coda_oss/include/coda_oss/type_traits.h b/modules/c++/coda_oss/include/coda_oss/type_traits.h index 5bd920a912..5c92c1d321 100644 --- a/modules/c++/coda_oss/include/coda_oss/type_traits.h +++ b/modules/c++/coda_oss/include/coda_oss/type_traits.h @@ -29,21 +29,7 @@ #include "coda_oss/namespace_.h" namespace coda_oss { -// workaround missing "is_trivially_copyable" in g++ < 5.0 -// https://stackoverflow.com/a/31798726/8877 -#if defined(__GNUC__) && (__GNUC__ < 5) -template -struct is_trivially_copyable final -{ - // This old Intel compiler has enough C++14 for our needs; see CPlusPlus.h - #if !(defined(__INTEL_COMPILER) && (__INTEL_COMPILER_BUILD_DATE <= 20151021)) - static_assert(CODA_OSS_cplusplus < 201402L, "C++14 must have is_trivially_copyable."); - #endif - static constexpr bool value = __has_trivial_copy(T); -}; -#else using std::is_trivially_copyable; -#endif } #endif // CODA_OSS_coda_oss_type_traits_h_INCLUDED_ diff --git a/modules/c++/except/include/except/Backtrace.h b/modules/c++/except/include/except/Backtrace.h index 6978895260..42cf6ba6a4 100644 --- a/modules/c++/except/include/except/Backtrace.h +++ b/modules/c++/except/include/except/Backtrace.h @@ -42,6 +42,7 @@ namespace version { namespace except { #if _MSC_VER #pragma warning(push) +#pragma warning(disable: 4619) // #pragma warning: there is no warning number '...' #pragma warning(disable: 5264) // '...': '...' variable is not used #endif // _MSC_VER diff --git a/modules/c++/hdf5.lite/include/hdf5/lite/Read.h b/modules/c++/hdf5.lite/include/hdf5/lite/Read.h index ed57dd12bb..09a8502ee4 100644 --- a/modules/c++/hdf5.lite/include/hdf5/lite/Read.h +++ b/modules/c++/hdf5.lite/include/hdf5/lite/Read.h @@ -28,7 +28,7 @@ * \file Read.h * \brief HDF File-reading API * - * These are simple routines to read HDF5 files; they're loosly modeled after the MATLab API + * These are simple routines to read HDF5 files; they're loosely modeled after the MATLab API * https://www.mathworks.com/help/matlab/import_export/import-hdf5-files.html */ @@ -39,16 +39,17 @@ #include "sys/filesystem.h" #include "types/RowCol.h" +#include "SpanRC.h" + namespace hdf5 { namespace lite { -CODA_OSS_API types::RowCol readFile(const coda_oss::filesystem::path&, const std::string& loc, std::vector&); -CODA_OSS_API types::RowCol readFile(const coda_oss::filesystem::path&, const std::string& loc, std::vector&); +CODA_OSS_API SpanRC readFile(const coda_oss::filesystem::path&, const std::string& loc, std::vector&); +CODA_OSS_API SpanRC readFile(const coda_oss::filesystem::path&, const std::string& loc, std::vector&); } } #endif // CODA_OSS_hdf5_lite_Read_h_INCLUDED_ - diff --git a/modules/c++/hdf5.lite/include/hdf5/lite/SpanRC.h b/modules/c++/hdf5.lite/include/hdf5/lite/SpanRC.h new file mode 100644 index 0000000000..7d6582124d --- /dev/null +++ b/modules/c++/hdf5.lite/include/hdf5/lite/SpanRC.h @@ -0,0 +1,115 @@ +/* ========================================================================= + * This file is part of hdf5.lite-c++ + * ========================================================================= + * + * (C) Copyright 2022, Maxar Technologies, Inc. + * + * hdf5.lite-c++ is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; If not, + * see . + * + */ + +#ifndef CODA_OSS_hdf5_lite_SpanRC_h_INCLUDED_ +#define CODA_OSS_hdf5_lite_SpanRC_h_INCLUDED_ +#pragma once + +/*! + * \file SpanRC.h + * + * This is a super-simple version of C++23's mdspan. It's here because 1) don't want widespread use, and + * 2) CODA already has a View2D. + */ + +#include + +#include "config/Exports.h" +#include "coda_oss/span.h" +#include "types/RowCol.h" + +namespace hdf5 +{ +namespace lite +{ + +template +struct SpanRC final +{ + using size_type = types::RowCol; + using element_type = T; + using pointer = T*; + using reference = T&; + + SpanRC() = default; + SpanRC(pointer p, size_type rc) noexcept : s_(p, rc.area()), rc_(rc) + { + } + SpanRC(pointer p, size_t r, size_t c) noexcept : SpanRC(p, size_type(r, c)) + { + } + SpanRC(const SpanRC&) noexcept = default; + + constexpr pointer data() const noexcept + { + return s_.data(); + } + + /*constexpr*/ reference operator[](size_t idx) const noexcept + { + assert(idx < size()); // prevents "constexpr" in C++11 + return data()[idx]; + } + /*constexpr*/ reference operator()(size_t r, size_t c) const noexcept + { + const auto offset = (r * dims().col) + c; + return (*this)[offset]; + } + /*constexpr*/ reference operator[](size_type idx) const noexcept + { + return (*this)(idx.row, idx.col); + } + + constexpr size_t size() const noexcept + { + assert(s_.size() == rc_.area()); + return s_.size(); + } + constexpr size_t area() const noexcept + { + return size(); + } + + constexpr size_type size_bytes() const noexcept + { + return s_.size_bytes(); + } + + constexpr bool empty() const noexcept + { + return s_.empty(); + } + + const auto& dims() const + { + return rc_; + } + + private: + types::RowCol rc_; + coda_oss::span s_; +}; + +} +} + +#endif // CODA_OSS_hdf5_lite_SpanRC_h_INCLUDED_ diff --git a/modules/c++/hdf5.lite/include/hdf5/lite/Write.h b/modules/c++/hdf5.lite/include/hdf5/lite/Write.h new file mode 100644 index 0000000000..3a0e4c7c25 --- /dev/null +++ b/modules/c++/hdf5.lite/include/hdf5/lite/Write.h @@ -0,0 +1,80 @@ +/* ========================================================================= + * This file is part of hdf5.lite-c++ + * ========================================================================= + * + * (C) Copyright 2023, Maxar Technologies, Inc. + * + * hdf5.lite-c++ is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; If not, + * see . + * + */ + +#ifndef CODA_OSS_hdf5_lite_Write_h_INCLUDED_ +#define CODA_OSS_hdf5_lite_Write_h_INCLUDED_ +#pragma once + +/*! + * \file Read.h + * \brief HDF File-reading API + * + * These are simple routines to write HDF5 files; they're loosely modeled after the MATLab API + * https://www.mathworks.com/help/matlab/ref/h5create.html + * https://www.mathworks.com/help/matlab/ref/h5write.html + */ + +#include +#include + +#include "config/Exports.h" +#include "sys/filesystem.h" +#include "types/RowCol.h" + +#include "SpanRC.h" + +namespace hdf5 +{ +namespace lite +{ +template // currently implemented for float and double +CODA_OSS_API void createFile(const coda_oss::filesystem::path&, const std::string& ds, const types::RowCol&); +CODA_OSS_API void createFile(const coda_oss::filesystem::path&, const std::string& ds, SpanRC); +inline void createFile(const coda_oss::filesystem::path& path, const std::string& ds, SpanRC data_) +{ + SpanRC data(data_.data(), data_.dims()); + createFile(path, ds, data); +} +CODA_OSS_API void createFile(const coda_oss::filesystem::path&, const std::string& ds, SpanRC); +inline void createFile(const coda_oss::filesystem::path& path, const std::string& ds, SpanRC data_) +{ + SpanRC data(data_.data(), data_.dims()); + createFile(path, ds, data); +} + +CODA_OSS_API void writeFile(const coda_oss::filesystem::path&, const std::string& loc, SpanRC); +inline void writeFile(const coda_oss::filesystem::path& path, const std::string& ds, SpanRC data_) +{ + SpanRC data(data_.data(), data_.dims()); + writeFile(path, ds, data); +} +CODA_OSS_API void writeFile(const coda_oss::filesystem::path&, const std::string& loc, SpanRC); +inline void writeFile(const coda_oss::filesystem::path& path, const std::string& ds, SpanRC data_) +{ + SpanRC data(data_.data(), data_.dims()); + writeFile(path, ds, data); +} + +} +} + +#endif // CODA_OSS_hdf5_lite_Write_h_INCLUDED_ diff --git a/modules/c++/hdf5.lite/source/Read.cpp b/modules/c++/hdf5.lite/source/Read.cpp index c4f567658c..325111a4fe 100644 --- a/modules/c++/hdf5.lite/source/Read.cpp +++ b/modules/c++/hdf5.lite/source/Read.cpp @@ -56,7 +56,7 @@ static void read(const H5::DataSet& dataset, std::vector& result) dataset.read(result.data(), mem_type); } template -static types::RowCol readDatasetT(const H5::DataSet& dataset, std::vector& result) +static hdf5::lite::SpanRC readDatasetT(const H5::DataSet& dataset, std::vector& result) { if (dataset.getTypeClass() != H5T_FLOAT) { @@ -64,8 +64,9 @@ static types::RowCol readDatasetT(const H5::DataSet& dataset, std::vecto throw hdf5::lite::DataSetException(context); } - const auto retval = hdf5::lite::details::getSimpleExtentSize(dataset); - result.resize(retval.area()); + const auto dims = hdf5::lite::details::getSimpleExtentSize(dataset); + result.resize(dims.area()); + hdf5::lite::SpanRC retval(result.data(), dims); // dataset.read() doesn't care about the buffer type ... that's because H5Dread() also // uses void*. However, the LT API has H5LTread_dataset_double() and H5LTread_dataset_float(), @@ -74,16 +75,16 @@ static types::RowCol readDatasetT(const H5::DataSet& dataset, std::vecto return retval; } -inline types::RowCol readDataset_(const H5::DataSet& dataset, std::vector& result) +inline hdf5::lite::SpanRC readDataset_(const H5::DataSet& dataset, std::vector& result) { return readDatasetT(dataset, result); } -inline types::RowCol readDataset_(const H5::DataSet& dataset, std::vector& result) +inline hdf5::lite::SpanRC readDataset_(const H5::DataSet& dataset, std::vector& result) { return readDatasetT(dataset, result); } template -static types::RowCol readFile_(const coda_oss::filesystem::path& fileName, const std::string& datasetName, +static hdf5::lite::SpanRC readFile_(const coda_oss::filesystem::path& fileName, const std::string& datasetName, std::vector& result) { /* @@ -94,12 +95,12 @@ static types::RowCol readFile_(const coda_oss::filesystem::path& fileNam return readDataset_(dataset, result); } -types::RowCol hdf5::lite::readFile(const coda_oss::filesystem::path& fileName, const std::string& loc, +hdf5::lite::SpanRC hdf5::lite::readFile(const coda_oss::filesystem::path& fileName, const std::string& loc, std::vector& result) { return details::try_catch_H5Exceptions(readFile_, __FILE__, __LINE__, fileName, loc, result); } -types::RowCol hdf5::lite::readFile(const coda_oss::filesystem::path& fileName, const std::string& loc, +hdf5::lite::SpanRC hdf5::lite::readFile(const coda_oss::filesystem::path& fileName, const std::string& loc, std::vector& result) { return details::try_catch_H5Exceptions(readFile_, __FILE__, __LINE__, fileName, loc, result); diff --git a/modules/c++/hdf5.lite/source/Write.cpp b/modules/c++/hdf5.lite/source/Write.cpp new file mode 100644 index 0000000000..ce140935aa --- /dev/null +++ b/modules/c++/hdf5.lite/source/Write.cpp @@ -0,0 +1,115 @@ +/* ========================================================================= + * This file is part of hd5.lite-c++ + * ========================================================================= + * + * (C) Copyright 2023, Maxar Technologies, Inc. + * + * hd5.lite-c++ is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; If not, + * see . + * + */ + +#include "hdf5/lite/Write.h" + +#include // std::ignore +#include + +#include "coda_oss/cstddef.h" // byte + +#include "hdf5/lite/HDF5Exception.h" +#include "H5.h" +#include "hdf5.lite.h" + +// https://raw.githubusercontent.com/HDFGroup/hdf5/develop/c++/examples/h5tutr_rdwt.cpp + +template static H5::PredType getPredType(); +template <> +inline H5::PredType getPredType() +{ + static_assert(sizeof(float) * 8 == 32, "'float' should be 32-bits"); // IEEE_F32LE + return H5::PredType::IEEE_F32LE; +} +template <> +inline H5::PredType getPredType() +{ + static_assert(sizeof(double) * 8 == 64, "'double' should be 64-bits"); // IEEE_F64LE + return H5::PredType::IEEE_F64LE; +} + +template +static void createFile_(const coda_oss::filesystem::path& fileName, const std::string& ds, const types::RowCol& sz) +{ + // https://raw.githubusercontent.com/HDFGroup/hdf5/develop/c++/examples/h5tutr_crtdat.cpp + // + // Create a new file using the default property lists. + H5::H5File file(fileName.string(), H5F_ACC_TRUNC); + + // Create the data space for the dataset. + constexpr int RANK = 2; + const hsize_t dims[]{sz.row, sz.col}; // dataset dimensions + H5::DataSpace dataspace(RANK, dims); + + // Create the dataset. + const auto data_type = getPredType(); + std::ignore = file.createDataSet(ds, data_type, dataspace); +} +template<> +void hdf5::lite::createFile(const coda_oss::filesystem::path& fileName, const std::string& ds, const types::RowCol& sz) +{ + details::try_catch_H5ExceptionsV(createFile_, __FILE__, __LINE__, fileName, ds, sz); +} +template<> +void hdf5::lite::createFile(const coda_oss::filesystem::path& fileName, const std::string& ds, const types::RowCol& sz) +{ + details::try_catch_H5ExceptionsV(createFile_, __FILE__, __LINE__, fileName, ds, sz); +} +void hdf5::lite::createFile(const coda_oss::filesystem::path& fileName, const std::string& ds, hdf5::lite::SpanRC data) +{ + createFile(fileName, ds, data.dims()); +} +void hdf5::lite::createFile(const coda_oss::filesystem::path& fileName, const std::string& ds, hdf5::lite::SpanRC data) +{ + createFile(fileName, ds, data.dims()); +} + + +template +static void writeFile_(const coda_oss::filesystem::path& fileName, const std::string& ds, hdf5::lite::SpanRC data) +{ + // https://raw.githubusercontent.com/HDFGroup/hdf5/develop/c++/examples/h5tutr_rdwt.cpp + + // Open an existing file and dataset. + H5::H5File file(fileName.string(), H5F_ACC_RDWR); + auto dataset = file.openDataSet(ds); + + const auto dims = hdf5::lite::details::getSimpleExtentSize(dataset); + if (data.dims() != dims) + { + const except::Context ctx("dataSet dimensions do not match data dimensions", __FILE__, __LINE__, "writeFile"); + throw hdf5::lite::DataSetException(ctx); + } + + // Write the data to the dataset using default memory space, file + // space, and transfer properties. + const auto data_type = getPredType(); + dataset.write(data.data(), data_type); +} +void hdf5::lite::writeFile(const coda_oss::filesystem::path& fileName, const std::string& ds, SpanRC data) +{ + details::try_catch_H5ExceptionsV(writeFile_, __FILE__, __LINE__, fileName, ds, data); +} +void hdf5::lite::writeFile(const coda_oss::filesystem::path& fileName, const std::string& ds, SpanRC data) +{ + details::try_catch_H5ExceptionsV(writeFile_, __FILE__, __LINE__, fileName, ds, data); +} diff --git a/modules/c++/hdf5.lite/source/hdf5.lite.h b/modules/c++/hdf5.lite/source/hdf5.lite.h index 709cc784cb..fce6fb7c0d 100644 --- a/modules/c++/hdf5.lite/source/hdf5.lite.h +++ b/modules/c++/hdf5.lite/source/hdf5.lite.h @@ -60,6 +60,13 @@ auto try_catch_H5Exceptions(TFunc f, const char* file, int line, TArgs&&... args details::try_catch_H5Exceptions_(call_f, file, line, &retval /*context*/); return retval; } +template +auto try_catch_H5ExceptionsV(TFunc f, const char* file, int line, TArgs&&... args) +{ + // "Hide" the arguments inside of a lambda + auto call_f = [&](void*) { f(std::forward(args)...); }; + details::try_catch_H5Exceptions_(call_f, file, line, nullptr /*context*/); +} } } diff --git a/modules/c++/hdf5.lite/unittests/test_hdf5write.cpp b/modules/c++/hdf5.lite/unittests/test_hdf5write.cpp new file mode 100644 index 0000000000..0d99d11050 --- /dev/null +++ b/modules/c++/hdf5.lite/unittests/test_hdf5write.cpp @@ -0,0 +1,93 @@ +/* ========================================================================= + * This file is part of hdf5.lite-c++ + * ========================================================================= + * + * (C) Copyright 2023, Maxar Technologies, Inc. + * + * hdf5.lite-c++ is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; If not, + * see . + * + */ + +#include +#include +#include +#include + +#include + +#include "sys/FileFinder.h" + +#include "hdf5/lite/Write.h" +#include "hdf5/lite/HDF5Exception.h" +#include "hdf5/lite/Info.h" +#include "hdf5/lite/Read.h" + +static std::filesystem::path find_unittest_file(const std::filesystem::path& name) +{ + static const auto unittests = std::filesystem::path("modules") / "c++" / "hdf5.lite" / "unittests"; + return sys::test::findGITModuleFile("coda-oss", unittests, name); +} + +TEST_CASE(test_hdf5Create) +{ + static const auto path_ = find_unittest_file("example.h5"); + static const auto path = path_.parent_path() / "TEST_hdf5Create_TMP.h5"; + + // https://www.mathworks.com/help/matlab/ref/h5write.html + hdf5::lite::createFile(path, "/DS1", {10, 20}); +} + +TEST_CASE(test_hdf5Write) +{ + static const auto path_ = find_unittest_file("example.h5"); + static const auto path = path_.parent_path() / "TEST_hdf5Write_TMP.h5"; + + const types::RowCol dims{10, 20}; + std::vector data_(dims.area()); + const hdf5::lite::SpanRC data(data_.data(), dims); + double d = 0.0; + for (size_t r = 0; r result; + const auto rc = hdf5::lite::readFile(path, "/DS1", result); + TEST_ASSERT(rc.dims() == dims); + TEST_ASSERT_EQ(dims.area(), result.size()); + for (size_t i = 0; i < result.size(); i++) + { + const auto expected = static_cast(i); + TEST_ASSERT_ALMOST_EQ(result[i], expected); + } +} + +TEST_MAIN( + TEST_CHECK(test_hdf5Create); + TEST_CHECK(test_hdf5Write); +) diff --git a/modules/c++/str/include/str/EncodedStringView.h b/modules/c++/str/include/str/EncodedStringView.h index 38beb310b9..1fd1e99ac5 100644 --- a/modules/c++/str/include/str/EncodedStringView.h +++ b/modules/c++/str/include/str/EncodedStringView.h @@ -110,7 +110,7 @@ class CODA_OSS_API EncodedStringView final std::wstring wstring() const; // UTF-16 on Windows, UTF-32 on Linux // These are for "advanced" use, most "normal" code should use the routines above. - std::string::const_pointer c_str() const + std::string::const_pointer c_str() const noexcept { return mString.data(); } @@ -122,7 +122,7 @@ class CODA_OSS_API EncodedStringView final { return mIsUtf8 ? nullptr : cast(c_str()); } - size_t size() const + size_t size() const noexcept { return mString.size(); } diff --git a/modules/c++/xml.lite/include/xml/lite/Attributes.h b/modules/c++/xml.lite/include/xml/lite/Attributes.h index 17c40e4102..8b354844bc 100644 --- a/modules/c++/xml.lite/include/xml/lite/Attributes.h +++ b/modules/c++/xml.lite/include/xml/lite/Attributes.h @@ -31,6 +31,7 @@ #include "except/Exception.h" #include "xml/lite/QName.h" #include "str/Convert.h" +#include "gsl/gsl.h" /*! * \file Attributes.h @@ -330,7 +331,7 @@ struct Attributes final } std::string operator[](const xml::lite::QName& name) const { - const size_t idx = getIndex(name); + const auto idx = gsl::narrow(getIndex(name)); return mAttributes[idx].getValue(); } @@ -348,7 +349,7 @@ struct Attributes final } std::string operator[](const std::string& s) const { - const size_t idx = getIndex(s); + const auto idx = gsl::narrow(getIndex(s)); return mAttributes[idx].getValue(); } diff --git a/modules/c++/xml.lite/include/xml/lite/Document.h b/modules/c++/xml.lite/include/xml/lite/Document.h index e61422d30e..1d53fdbab2 100644 --- a/modules/c++/xml.lite/include/xml/lite/Document.h +++ b/modules/c++/xml.lite/include/xml/lite/Document.h @@ -104,7 +104,7 @@ struct Document // SOAPDocument derives :-( * \param characterData The character data (if any) * \return A new element */ - Element *createElement(const std::string & qname, const std::string & uri, std::string characterData = ""); + virtual Element *createElement(const std::string & qname, const std::string & uri, std::string characterData = ""); #ifndef SWIG // SWIG doesn't like std::unique_ptr std::unique_ptr createElement(const xml::lite::QName&, const std::string& characterData) const; std::unique_ptr createElement(const xml::lite::QName&, const coda_oss::u8string& characterData) const; diff --git a/modules/c++/xml.lite/include/xml/lite/ValidatorXerces.h b/modules/c++/xml.lite/include/xml/lite/ValidatorXerces.h index dc2cb39390..8942aaf57f 100644 --- a/modules/c++/xml.lite/include/xml/lite/ValidatorXerces.h +++ b/modules/c++/xml.lite/include/xml/lite/ValidatorXerces.h @@ -120,8 +120,8 @@ class ValidatorXerces : public ValidatorInterface ValidatorXerces(const ValidatorXerces&) = delete; ValidatorXerces& operator=(const ValidatorXerces&) = delete; - ValidatorXerces(ValidatorXerces&&) = delete; - ValidatorXerces& operator=(ValidatorXerces&&) = delete; + ValidatorXerces(ValidatorXerces&&) = default; + ValidatorXerces& operator=(ValidatorXerces&&) = default; using ValidatorInterface::validate; diff --git a/modules/c++/xml.lite/unittests/test_soapelements.cpp b/modules/c++/xml.lite/unittests/test_soapelements.cpp new file mode 100644 index 0000000000..21ecbfdd86 --- /dev/null +++ b/modules/c++/xml.lite/unittests/test_soapelements.cpp @@ -0,0 +1,65 @@ +/* ========================================================================= + * This file is part of xml.lite-c++ + * ========================================================================= + * + * (C) Copyright 2004 - 2019, MDA Information Systems LLC + * (C) Copyright 2023, Maxar Technologies, Inc. + * + * xml.lite-c++ is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; If not, + * see . + * + */ + +#include +#include "xml/lite/Document.h" +#include "xml/lite/Element.h" +#include "xml/lite/QName.h" +static const std::string test_text = "SOAP Test"; + +struct SOAPBody final : public xml::lite::Element +{ + SOAPBody() = default; + SOAPBody (const xml::lite::QName& qname) + { + setQName(qname); + } +}; + +struct SOAP final : public xml::lite::Document +{ + xml::lite::Element* createElement(const std::string & qname, + const std::string& uri, + std::string characterData = "") override { + const xml::lite::QName asQName(uri, qname); + xml::lite::Element* elem = new SOAPBody(asQName); + elem->setCharacterData(test_text); + return elem; + } +}; + +TEST_CASE(test_overrideCreateElement) +{ + SOAP soap_test; + auto a = soap_test.createElement("a","b","Not SOAP Test"); + auto b = dynamic_cast(a); + TEST_ASSERT_NOT_NULL(b); + TEST_ASSERT_EQ(a->getCharacterData(), test_text); + TEST_ASSERT_EQ(b->getCharacterData(), test_text); +} + +TEST_MAIN +( + TEST_CHECK(test_overrideCreateElement); +) + diff --git a/modules/c++/xml.lite/unittests/test_xmlattribute.cpp b/modules/c++/xml.lite/unittests/test_xmlattribute.cpp index f94a136536..011bb79d1c 100644 --- a/modules/c++/xml.lite/unittests/test_xmlattribute.cpp +++ b/modules/c++/xml.lite/unittests/test_xmlattribute.cpp @@ -1,10 +1,10 @@ /* ========================================================================= - * This file is part of io-c++ + * This file is part of xml.lite-c++ * ========================================================================= * * (C) Copyright 2004 - 2019, MDA Information Systems LLC * - * io-c++ is free software; you can redistribute it and/or modify + * xml.lite-c++ is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. diff --git a/modules/c++/xml.lite/unittests/test_xmlelement.cpp b/modules/c++/xml.lite/unittests/test_xmlelement.cpp index ccbdde0a7b..a9890ab004 100644 --- a/modules/c++/xml.lite/unittests/test_xmlelement.cpp +++ b/modules/c++/xml.lite/unittests/test_xmlelement.cpp @@ -1,10 +1,10 @@ /* ========================================================================= - * This file is part of io-c++ + * This file is part of xml.lite-c++ * ========================================================================= * * (C) Copyright 2004 - 2019, MDA Information Systems LLC * - * io-c++ is free software; you can redistribute it and/or modify + * xml.lite-c++ is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version.