diff --git a/CMakeLists.txt b/CMakeLists.txt
index b063bbe618..51843e01c0 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -24,8 +24,18 @@ if (${CMAKE_PROJECT_NAME} STREQUAL coda-oss)
if (MSVC)
add_compile_options(/WX) # warnings as errors
add_compile_options(/MP) # multi-processor compile
+
+ if (ENABLE_ASAN)
+ # https://docs.microsoft.com/en-us/cpp/sanitizers/asan?view=msvc-160
+ add_compile_options(/fsanitize=address)
+ endif()
elseif (UNIX)
add_compile_options(-Werror) # warnings as errors
+ if (ENABLE_ASAN)
+ # https://gcc.gnu.org/onlinedocs/gcc/Instrumentation-Options.html
+ add_compile_options(-fsanitize=address)
+ add_link_options(-fsanitize=address)
+ endif()
endif()
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
diff --git a/ReleaseNotes.md b/ReleaseNotes.md
index dd7dd197e4..a6a8c326b6 100644
--- a/ReleaseNotes.md
+++ b/ReleaseNotes.md
@@ -11,8 +11,15 @@
```
# coda-oss Release Notes
+## [Release 2023-??-??](https://github.com/mdaus/coda-oss/releases/tag/2023-??-??)
+* *zlib* updated to [1.2.13](https://github.com/madler/zlib/releases/tag/v1.2.13).
+* new `mem::ComplexView` class to make it easier to process complex data stored in parallel.
+* adjust compiler flags for clean *CMake* builds.
+* wrap common "file open" routines (e.g., `fopen()`) to support `sys::expandEnvironmentVariables()`.
+* add header-only [HighFive](https://github.com/BlueBrain/HighFive) HDF5-wrapper library.
+
## [Release 2022-12-14](https://github.com/mdaus/coda-oss/releases/tag/2022-12-14)
-* removed remaining vestigates of `std::auto_ptr`, provide `mem::AutoPtr` for the tiny handful of
+* removed remaining vestiges of `std::auto_ptr`, provide `mem::AutoPtr` for the tiny handful of
places (e.g., SWIG bindings) that still need copying.
* `xml::lite::Element` overloads to make creting new XML documents easier; see unittests for examples.
* try even harder to find unittest files in various scenarios.
@@ -30,7 +37,7 @@
* Utilitiy routines for finding various files when unit-testing.
* Removed C++14 work-arounds needed in C++11. Legacy C++ exception specificatons removed.
* Rebuild `waf` for FIPS error; added more debug options.
-
+
## [Release 2022-08-30](https://github.com/mdaus/coda-oss/releases/tag/2022-08-30)
* XML is now always written as UTF-8; the code will still try to read Windows-1252.
* `Uri`s are no longer validated by default.
diff --git a/UnitTest/UnitTest.vcxproj b/UnitTest/UnitTest.vcxproj
index 8caaa20fbf..5f55f6360d 100644
--- a/UnitTest/UnitTest.vcxproj
+++ b/UnitTest/UnitTest.vcxproj
@@ -25,6 +25,7 @@
v143
false
Unicode
+ true
DynamicLibrary
@@ -33,6 +34,7 @@
true
false
Unicode
+ true
diff --git a/modules/c++/CMakeLists.txt b/modules/c++/CMakeLists.txt
index 34495bbfd0..bbfaa01162 100644
--- a/modules/c++/CMakeLists.txt
+++ b/modules/c++/CMakeLists.txt
@@ -18,8 +18,8 @@ elseif (UNIX)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wzero-as-null-pointer-constant")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Woverloaded-virtual")
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wold-style-cast")
- #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wsuggest-final-types -Wsuggest-final-methods")
- #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wsuggest-override")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wsuggest-final-types -Wsuggest-final-methods")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wsuggest-override")
endif()
# add an interface library for unittests
diff --git a/modules/c++/cli/unittests/test_cli.cpp b/modules/c++/cli/unittests/test_cli.cpp
index ba10dfdee1..62fa2192f9 100644
--- a/modules/c++/cli/unittests/test_cli.cpp
+++ b/modules/c++/cli/unittests/test_cli.cpp
@@ -171,10 +171,10 @@ TEST_CASE(testRequired)
parser.addArgument("-v --verbose", "Toggle verbose", cli::STORE_TRUE);
parser.addArgument("-c --config", "Specify a config file", cli::STORE)->setRequired(true);
- std::unique_ptr results;
- TEST_EXCEPTION(results.reset(parser.parse(str::split(""))));
- TEST_EXCEPTION(results.reset(parser.parse(str::split("-c"))));
- results.reset(parser.parse(str::split("-c configFile")));
+ const std::string program(testName);
+ TEST_EXCEPTION(parser.parse(program, str::split("")));
+ TEST_EXCEPTION(parser.parse(program, str::split("-c")));
+ const auto results = parser.parse(program, str::split("-c configFile"));
TEST_ASSERT_EQ(results->get("config"), "configFile");
}
diff --git a/modules/c++/coda-oss-lite.vcxproj b/modules/c++/coda-oss-lite.vcxproj
index ab34ea98a9..f50ac4a193 100644
--- a/modules/c++/coda-oss-lite.vcxproj
+++ b/modules/c++/coda-oss-lite.vcxproj
@@ -421,12 +421,14 @@
DynamicLibrary
true
v143
+ true
DynamicLibrary
false
v143
true
+ true
diff --git a/modules/c++/except/source/Backtrace.cpp b/modules/c++/except/source/Backtrace.cpp
index 6b8e24a622..a6a326415e 100644
--- a/modules/c++/except/source/Backtrace.cpp
+++ b/modules/c++/except/source/Backtrace.cpp
@@ -57,6 +57,10 @@ struct BacktraceHelper final
BacktraceHelper(char** stackSymbols)
: mStackSymbols(stackSymbols)
{}
+ BacktraceHelper(const BacktraceHelper&) = delete;
+ BacktraceHelper& operator=(const BacktraceHelper&) = delete;
+ BacktraceHelper(BacktraceHelper&&) = default;
+ BacktraceHelper& operator=(BacktraceHelper&&) = default;
~BacktraceHelper()
{
diff --git a/modules/c++/hdf5.lite/CMakeLists.txt b/modules/c++/hdf5.lite/CMakeLists.txt
index 927e11d93b..0efec0c88a 100644
--- a/modules/c++/hdf5.lite/CMakeLists.txt
+++ b/modules/c++/hdf5.lite/CMakeLists.txt
@@ -1,8 +1,8 @@
set(MODULE_NAME hdf5.lite)
if(CODA_ENABLE_HDF5)
- set(MODULE_DEPS except-c++ types-c++ io-c++ coda_oss-c++)
- list(APPEND MODULE_DEPS hdf5-c++)
+ set(MODULE_DEPS highfive-c++ hdf5-c++)
+ list(APPEND MODULE_DEPS except-c++ types-c++ io-c++ coda_oss-c++)
coda_add_module(
${MODULE_NAME}
diff --git a/modules/c++/hdf5.lite/include/hdf5/lite/Write.h b/modules/c++/hdf5.lite/include/hdf5/lite/Write.h
index 3a0e4c7c25..dea204a7f9 100644
--- a/modules/c++/hdf5.lite/include/hdf5/lite/Write.h
+++ b/modules/c++/hdf5.lite/include/hdf5/lite/Write.h
@@ -25,8 +25,8 @@
#pragma once
/*!
- * \file Read.h
- * \brief HDF File-reading API
+ * \file Write.h
+ * \brief HDF File-writing 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
@@ -51,20 +51,20 @@ CODA_OSS_API void createFile(const coda_oss::filesystem::path&, const std::strin
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);
+ 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);
+ 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());
+ 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);
diff --git a/modules/c++/hdf5.lite/include/hdf5/lite/highfive.h b/modules/c++/hdf5.lite/include/hdf5/lite/highfive.h
new file mode 100644
index 0000000000..6203344c30
--- /dev/null
+++ b/modules/c++/hdf5.lite/include/hdf5/lite/highfive.h
@@ -0,0 +1,75 @@
+/* =========================================================================
+ * 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_highfive_h_INCLUDED_
+#define CODA_OSS_hdf5_lite_highfive_h_INCLUDED_
+#pragma once
+
+/*!
+ * \file highfive.h
+ * \brief Utility routines for using HighFive
+ */
+
+#include
+
+#include "highfive/H5Easy.hpp"
+#include "highfive/H5DataSet.hpp"
+
+#include "SpanRC.h"
+
+namespace hdf5
+{
+namespace lite
+{
+template
+inline HighFive::DataSet writeDataSet(H5Easy::File& file, SpanRC data, const std::string& dataset_name /*, TODO ...*/)
+{
+ const std::vector dims{data.dims().row, data.dims().col};
+ const HighFive::DataSpace dataspace{dims};
+ auto retval = file.createDataSet(dataset_name, dataspace);
+ retval.write_raw(data.data());
+ return retval;
+}
+
+template
+inline SpanRC readDataSet(HighFive::DataSet& dataSet, std::vector& result /*, TODO ...*/)
+{
+ const auto dimensions = dataSet.getSpace().getDimensions();
+ const types::RowCol dims(dimensions[0], dimensions[1]);
+
+ result.resize(dims.area());
+ dataSet.read(result.data());
+
+ return SpanRC(result.data(), dims);
+}
+
+template
+inline SpanRC load(H5Easy::File& file, const std::string& dataset_name, std::vector& result /*, TODO ...*/)
+{
+ auto dataSet = file.getDataSet(dataset_name);
+ return readDataSet(dataSet, result);
+}
+
+}
+}
+
+#endif // CODA_OSS_hdf5_lite_highfive_h_INCLUDED_
diff --git a/modules/c++/hdf5.lite/unittests/test_hdf5write.cpp b/modules/c++/hdf5.lite/unittests/test_hdf5write.cpp
index 2d0dde8502..7a4412fe05 100644
--- a/modules/c++/hdf5.lite/unittests/test_hdf5write.cpp
+++ b/modules/c++/hdf5.lite/unittests/test_hdf5write.cpp
@@ -85,7 +85,7 @@ TEST_CASE(test_hdf5Write)
for (size_t i = 0; i < result.size(); i++)
{
const auto expected = static_cast(i);
- TEST_ASSERT_ALMOST_EQ(result[i], expected);
+ TEST_ASSERT_EQ(result[i], expected);
}
}
diff --git a/modules/c++/hdf5.lite/unittests/test_highfive.cpp b/modules/c++/hdf5.lite/unittests/test_highfive.cpp
new file mode 100644
index 0000000000..1b6ee28626
--- /dev/null
+++ b/modules/c++/hdf5.lite/unittests/test_highfive.cpp
@@ -0,0 +1,396 @@
+/* =========================================================================
+ * 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 .
+ *
+ */
+
+#include "import/std.h"
+#include
+
+#include
+
+#include "sys/FileFinder.h"
+#include "types/RowCol.h"
+
+#include "highfive/H5Easy.hpp"
+#include "highfive/H5DataSet.hpp"
+#include "highfive/H5File.hpp"
+
+#include "hdf5/lite/SpanRC.h"
+#include "hdf5/lite/highfive.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_highfive_load)
+{
+ static const auto path = find_unittest_file("example.h5");
+
+ const H5Easy::File file(path.string());
+ const auto lat = H5Easy::load>(file, "/g4/lat");
+ TEST_ASSERT_EQ(lat.size(), 19);
+ TEST_ASSERT_ALMOST_EQ(lat[0], -90.0);
+ TEST_ASSERT_ALMOST_EQ(lat[0], -lat[18]);
+}
+
+TEST_CASE(test_highfive_FileException)
+{
+ static const std::filesystem::path path = "does not exist . h5";
+ HighFive::SilenceHDF5 silencer; // no need for diagnostics, we're expecting a failure
+ TEST_SPECIFIC_EXCEPTION(H5Easy::File(path.string()), HighFive::FileException);
+}
+
+TEST_CASE(test_highfive_nested)
+{
+ /*
+ Group '/'
+ Group '/1'
+ Group '/1/bar'
+ Group '/1/bar/cat'
+ Dataset 'i'
+ Size: 10x1
+ MaxSize: 10x1
+ Datatype: H5T_IEEE_F64LE (double)
+ ChunkSize: []
+ Filters: none
+ FillValue: 0.000000
+ */
+ static const auto path = find_unittest_file("123_barfoo_catdog_cx.h5");
+
+ const H5Easy::File file(path.string());
+ const auto i = H5Easy::load>>(file, "/1/bar/cat/i");
+ TEST_ASSERT_EQ(i.size(), 1);
+ TEST_ASSERT_EQ(i[0].size(), 10);
+
+ const auto r = H5Easy::load>>(file, "/1/bar/dog/r");
+ TEST_ASSERT_EQ(r.size(), 1);
+ TEST_ASSERT_EQ(r[0].size(), 10);
+
+ TEST_ASSERT_EQ(i.size(), r.size());
+ TEST_ASSERT_EQ(i[0].size(), r[0].size());
+}
+
+TEST_CASE(test_highfive_nested_small)
+{
+ // top group: Data
+ // outer groups: 1, 2, 3, 4, 5
+ // sub groups: bar, foo
+ // sub-sub groups: cat, dog
+ // sub-sub-sub groups: a, b, c, d
+ // data: i (float array), r (float array)
+ static const auto path = find_unittest_file("nested_complex_float32_data_small.h5");
+
+ const H5Easy::File file(path.string());
+ const auto i = H5Easy::load>(file, "/Data/1/bar/cat/a/i");
+ TEST_ASSERT_EQ(i.size(), 10);
+ auto actual = std::accumulate(i.cbegin(), i.cend(), 0.0);
+ TEST_ASSERT_EQ(actual, 0.0);
+
+ const auto r = H5Easy::load>(file, "/Data/5/foo/dog/d/r");
+ TEST_ASSERT_EQ(r.size(), 10);
+ actual = std::accumulate(r.cbegin(), r.cend(), 0.0);
+ TEST_ASSERT_EQ(actual, 10.0);
+}
+
+TEST_CASE(test_highfive_nested_small_wrongType)
+{
+ static const auto path = find_unittest_file("nested_complex_float32_data_small.h5");
+
+ const H5Easy::File file(path.string());
+ HighFive::SilenceHDF5 silencer; // no need for diagnostics, we're expecting a failure
+ TEST_SPECIFIC_EXCEPTION(
+ H5Easy::load>>(file, "/Data/1/bar/cat/a/i"),
+ HighFive::DataSetException);
+}
+
+
+//*******************************************************************************
+
+TEST_CASE(test_highfive_info)
+{
+ static const auto path = find_unittest_file("example.h5");
+ const H5Easy::File file(path.string());
+
+ // https://www.mathworks.com/help/matlab/ref/h5info.html
+ /*
+ info = struct with fields:
+ Filename: '/mathworks/devel/bat/Bdoc22b/build/matlab/toolbox/matlab/demos/example.h5'
+ Name: '/'
+ Groups: [4x1 struct]
+ Datasets: []
+ Datatypes: []
+ Links: []
+ Attributes: [2x1 struct]
+ */
+
+ TEST_ASSERT_EQ(path.string(), file.getName());
+ TEST_ASSERT_EQ("/", file.getPath());
+ TEST_ASSERT_EQ(file.getNumberObjects(), 4); // 4 groups
+ const auto objectNames = file.listObjectNames();
+ TEST_ASSERT_EQ(objectNames.size(), 4); // 4 groups
+ for (auto&& name : objectNames)
+ {
+ const auto type = file.getObjectType(name);
+ TEST_ASSERT(type == HighFive::ObjectType::Group);
+
+ const auto group = file.getGroup(name);
+ TEST_ASSERT_EQ(group.getPath(), "/" + name);
+ }
+ TEST_ASSERT_EQ(file.getNumberAttributes(), 2);
+}
+
+TEST_CASE(test_highfive_groupinfo)
+{
+ static const auto path = find_unittest_file("example.h5");
+ const H5Easy::File file(path.string());
+
+ // https://www.mathworks.com/help/matlab/ref/h5info.html
+ const auto g4 = file.getGroup("g4");
+ /*
+ info = struct with fields:
+ Filename: '/mathworks/devel/bat/Bdoc22b/build/matlab/toolbox/matlab/demos/example.h5'
+ Name: '/g4'
+ Groups: []
+ Datasets: [4x1 struct]
+ Datatypes: []
+ Links: []
+ Attributes: []
+ */
+ TEST_ASSERT_EQ(path.string(), g4.getFile().getName());
+ const std::string groupPath("/g4");
+ TEST_ASSERT_EQ(groupPath, g4.getPath());
+ TEST_ASSERT_EQ(g4.getNumberObjects(), 4); // 4 dataSets
+ const auto objectNames = g4.listObjectNames();
+ TEST_ASSERT_EQ(objectNames.size(), 4); // 4 dataSets
+ for (auto&& name : objectNames)
+ {
+ const auto type = g4.getObjectType(name);
+ TEST_ASSERT(type == HighFive::ObjectType::Dataset);
+
+ const auto dataset = g4.getDataSet(name);
+ TEST_ASSERT_EQ(dataset.getPath(), groupPath + "/" + name);
+ }
+}
+
+TEST_CASE(test_highfive_datasetinfo)
+{
+ static const auto path = find_unittest_file("example.h5");
+ const H5Easy::File file(path.string());
+
+ // https://www.mathworks.com/help/matlab/ref/h5info.html
+ const auto time = file.getDataSet("/g4/time");
+ /*
+ info = struct with fields:
+ Filename: '/mathworks/devel/bat/Bdoc22b/build/matlab/toolbox/matlab/demos/example.h5'
+ Name: 'time'
+ Datatype: [1x1 struct]
+ Dataspace: [1x1 struct]
+ ChunkSize: 10
+ FillValue: 0
+ Filters: []
+ Attributes: [2x1 struct]
+ */
+ TEST_ASSERT_EQ(path.string(), time.getFile().getName());
+ const std::string dsPath("/g4/time");
+ TEST_ASSERT_EQ(dsPath, time.getPath());
+
+ const auto dataType = time.getDataType();
+ TEST_ASSERT(dataType.getClass() == HighFive::DataTypeClass::Float);
+
+ auto dims = time.getDimensions();
+ TEST_ASSERT_EQ(dims.size(), 1);
+ TEST_ASSERT_EQ(10, dims[0]); // ChunkSize ???
+
+ const auto dataSpace = time.getSpace();
+ dims = dataSpace.getDimensions();
+ TEST_ASSERT_EQ(dims.size(), 1);
+ TEST_ASSERT_EQ(10, dims[0]); // ChunkSize ???
+
+ TEST_ASSERT_EQ(time.listAttributeNames().size(), 2);
+}
+
+static void read_complex(const std::string& testName, const HighFive::Group& group)
+{
+ const auto i = group.getDataSet("i");
+ TEST_ASSERT(i.getDataType().getClass() == HighFive::DataTypeClass::Float);
+ TEST_ASSERT_EQ(i.getElementCount(), 10);
+
+ const auto r = group.getDataSet("r");
+ TEST_ASSERT(r.getDataType().getClass() == HighFive::DataTypeClass::Float);
+ TEST_ASSERT_EQ(r.getElementCount(), 10);
+}
+TEST_CASE(test_highfive_info_nested)
+{
+ /*
+ Group '/'
+ Group '/1'
+ Group '/1/bar'
+ Group '/1/bar/cat'
+ Dataset 'i'
+ Size: 10x1
+ MaxSize: 10x1
+ Datatype: H5T_IEEE_F64LE (double)
+ ChunkSize: []
+ Filters: none
+ FillValue: 0.000000
+ */
+
+ static const auto path = find_unittest_file("123_barfoo_catdog_cx.h5");
+ const H5Easy::File file(path.string());
+
+ TEST_ASSERT_EQ(path.string(), file.getName());
+ TEST_ASSERT_EQ("/", file.getPath());
+
+ TEST_ASSERT_EQ(file.getNumberObjects(), 3); // 3 groups
+ auto objectNames = file.listObjectNames();
+ const std::vector expectedOuterGroupNames{"1", "2", "3"};
+ TEST_ASSERT_EQ(objectNames.size(), expectedOuterGroupNames.size());
+ for (auto&& outer : expectedOuterGroupNames)
+ {
+ const auto groupPath = "/" + outer;
+ const auto group = file.getGroup(groupPath);
+ TEST_ASSERT_EQ(group.getPath(), groupPath);
+
+ TEST_ASSERT_EQ(group.getNumberObjects(), 2); // 2 groups
+ objectNames = group.listObjectNames();
+ const std::vector expectedSubGroupNames{"bar", "foo"};
+ TEST_ASSERT_EQ(objectNames.size(), expectedSubGroupNames.size());
+ for (auto&& subGroupName : expectedSubGroupNames)
+ {
+ const auto subGroup = group.getGroup(subGroupName);
+ const auto subGroupPath = groupPath + "/" + subGroupName;
+ TEST_ASSERT_EQ(subGroup.getPath(), subGroupPath);
+
+
+ TEST_ASSERT_EQ(subGroup.getNumberObjects(), 2); // 2 groups
+ objectNames = subGroup.listObjectNames();
+ const std::vector expectedSubSubGroupNames{"cat", "dog"};
+ TEST_ASSERT_EQ(objectNames.size(), expectedSubSubGroupNames.size());
+ for (auto&& subSubGroupName : expectedSubSubGroupNames)
+ {
+ const auto subSubGroup = subGroup.getGroup(subSubGroupName);
+ const auto subSubGroupPath = subGroupPath + "/" + subSubGroupName;
+ TEST_ASSERT_EQ(subSubGroup.getPath(), subSubGroupPath);
+
+ read_complex(testName, subSubGroup);
+ }
+ }
+ }
+}
+
+//*******************************************************************************
+
+TEST_CASE(test_highfive_create)
+{
+ static const auto path_ = find_unittest_file("example.h5");
+ static const auto path = path_.parent_path() / "TEST_highfive_create_TMP.h5";
+ H5Easy::File file(path.string(), H5Easy::File::Overwrite);
+
+ const types::RowCol dims{10, 20};
+ std::vector> DS1(dims.row);
+ float d = 0.0f;
+ for (auto&& r : DS1)
+ {
+ r.resize(dims.col);
+ for (size_t c = 0; c < r.size(); c++)
+ {
+ r[c] = d++;
+ }
+ }
+
+ H5Easy::dump(file, "/DS1", DS1);
+ TEST_SUCCESS;
+}
+
+TEST_CASE(test_highfive_write)
+{
+ static const auto path_ = find_unittest_file("example.h5");
+ static const auto path = path_.parent_path() / "TEST_highfive_write_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>>(file, "/DS1");
+ TEST_ASSERT_EQ(DS1.size(), dims.row);
+ TEST_ASSERT_EQ(DS1[0].size(), dims.col);
+
+ for (size_t r = 0; r < DS1.size(); r++)
+ {
+ for (size_t c = 0; c < DS1[r].size(); c++)
+ {
+ const auto expected = data(r, c);
+ const auto actual = DS1[r][c];
+ TEST_ASSERT_EQ(actual, expected);
+ }
+ }
+ }
+ {
+ H5Easy::File file(path.string());
+
+ std::vector result;
+ const auto rc = hdf5::lite::load(file, "/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_EQ(result[i], expected);
+ }
+ }
+}
+
+TEST_MAIN(
+ TEST_CHECK(test_highfive_load);
+ TEST_CHECK(test_highfive_FileException);
+ TEST_CHECK(test_highfive_nested);
+ TEST_CHECK(test_highfive_nested_small);
+ TEST_CHECK(test_highfive_nested_small_wrongType);
+
+ TEST_CHECK(test_highfive_info);
+ TEST_CHECK(test_highfive_groupinfo);
+ TEST_CHECK(test_highfive_datasetinfo);
+ TEST_CHECK(test_highfive_info_nested);
+
+ //TEST_CHECK(test_highfive_create);
+ //TEST_CHECK(test_highfive_write);
+)
diff --git a/modules/c++/hdf5.lite/wscript b/modules/c++/hdf5.lite/wscript
index c8c8b5ef60..32be36054d 100644
--- a/modules/c++/hdf5.lite/wscript
+++ b/modules/c++/hdf5.lite/wscript
@@ -1,6 +1,6 @@
NAME = 'hdf5.lite'
VERSION = '1.0'
-MODULE_DEPS = 'hdf5 hdf5cpp except types io coda_oss'
+MODULE_DEPS = 'highfive hdf5 hdf5cpp except types io coda_oss'
USELIB_LOCAL = 'hdf5-c hdf5cpp-c'
options = configure = distclean = lambda p: None
diff --git a/modules/c++/io/include/io/BufferViewStream.h b/modules/c++/io/include/io/BufferViewStream.h
index 45bc468189..beb00d23a2 100644
--- a/modules/c++/io/include/io/BufferViewStream.h
+++ b/modules/c++/io/include/io/BufferViewStream.h
@@ -61,7 +61,7 @@ struct BufferViewStream: public SeekableInputStream, public SeekableOutputStream
BufferViewStream& operator=(BufferViewStream&&) = delete;
//! Returns current location in buffer in bytes
- virtual sys::Off_T tell()
+ virtual sys::Off_T tell() override
{
return gsl::narrow(mPosition * sizeof(T));
}
@@ -73,12 +73,12 @@ struct BufferViewStream: public SeekableInputStream, public SeekableOutputStream
* \param whence Location to seek from
* \return new position
*/
- virtual sys::Off_T seek(sys::Off_T offset, Whence whence);
+ virtual sys::Off_T seek(sys::Off_T offset, Whence whence) override;
/*
* \return The available bytes to read from the stream
*/
- virtual sys::Off_T available()
+ virtual sys::Off_T available() override
{
return gsl::narrow((mBufferView.size - mPosition) * sizeof(T));
}
@@ -92,7 +92,7 @@ struct BufferViewStream: public SeekableInputStream, public SeekableOutputStream
* \param buffer The data to write to the stream
* \param size The number of bytes to write to the stream
*/
- virtual void write(const void* buffer, size_t size);
+ virtual void write(const void* buffer, size_t size) override;
/*!
* Get a pointer to the internal buffer.
@@ -139,7 +139,7 @@ struct BufferViewStream: public SeekableInputStream, public SeekableOutputStream
* \param len The length to read
* \return The number of bytes read
*/
- virtual sys::SSize_T readImpl(void* buffer, size_t len);
+ virtual sys::SSize_T readImpl(void* buffer, size_t len) override;
private:
diff --git a/modules/c++/io/include/io/TempFile.h b/modules/c++/io/include/io/TempFile.h
index 8e80e054be..b997bc948b 100644
--- a/modules/c++/io/include/io/TempFile.h
+++ b/modules/c++/io/include/io/TempFile.h
@@ -33,7 +33,7 @@ namespace io
* RAII object for a temporary file that gets deleted
* upon object destruction
*/
-struct CODA_OSS_API TempFile
+struct CODA_OSS_API TempFile final
{
/*!
* Constructor for TempFile object. Provided a directory,
@@ -49,7 +49,7 @@ struct CODA_OSS_API TempFile
*
* \return The pathname of the created file
*/
- inline std::string pathname() const
+ const std::string& pathname() const
{
return mPathname;
}
@@ -58,7 +58,6 @@ struct CODA_OSS_API TempFile
TempFile& operator=(const TempFile&) = delete;
private:
- const sys::OS mOS;
const std::string mPathname;
};
}
diff --git a/modules/c++/io/source/TempFile.cpp b/modules/c++/io/source/TempFile.cpp
index e23bc29c37..1424aac29b 100644
--- a/modules/c++/io/source/TempFile.cpp
+++ b/modules/c++/io/source/TempFile.cpp
@@ -22,8 +22,8 @@
#include
+ static const sys::OS mOS;
io::TempFile::TempFile(const std::string& dirname) :
- mOS(sys::OS()),
mPathname(mOS.getTempName(dirname))
{
}
diff --git a/modules/c++/io/tests/serializeTest1.cpp b/modules/c++/io/tests/serializeTest1.cpp
index c3c37d2527..2037899aee 100644
--- a/modules/c++/io/tests/serializeTest1.cpp
+++ b/modules/c++/io/tests/serializeTest1.cpp
@@ -44,7 +44,7 @@ class A : public Serializable
vec[2] = 0.0;
}
virtual ~A() {}
- virtual void serialize(OutputStream& os)
+ virtual void serialize(OutputStream& os) override
{
os.writeln("Class A");
os.writeln(FmtX("%f", vec[0]));
@@ -52,7 +52,7 @@ class A : public Serializable
os.writeln(FmtX("%f", vec[2]));
}
- virtual void deserialize(InputStream& is)
+ virtual void deserialize(InputStream& is) override
{
string classType = fillString(is);
string vec_0 = fillString(is);
diff --git a/modules/c++/io/unittests/test_tempfile.cpp b/modules/c++/io/unittests/test_tempfile.cpp
index ae391a26d6..60e5398c29 100644
--- a/modules/c++/io/unittests/test_tempfile.cpp
+++ b/modules/c++/io/unittests/test_tempfile.cpp
@@ -41,7 +41,8 @@ TEST_CASE(testFileDestroyed)
{
const io::TempFile tempFile;
pathname = tempFile.pathname();
- std::ofstream out(pathname.c_str());
+ std::ofstream out(pathname);
+ TEST_ASSERT_TRUE(static_cast(out));
out << "Test text";
}
// File should be destroyed on destruction
diff --git a/modules/c++/logging/include/logging/MemoryHandler.h b/modules/c++/logging/include/logging/MemoryHandler.h
index 0bd91982d0..6654333183 100644
--- a/modules/c++/logging/include/logging/MemoryHandler.h
+++ b/modules/c++/logging/include/logging/MemoryHandler.h
@@ -52,7 +52,7 @@ struct MemoryHandler : public Handler
getLogs(LogLevel level = LogLevel::LOG_NOTSET) const;
protected:
- virtual void write(const std::string& str);
+ virtual void write(const std::string& str) override;
void emitRecord(const LogRecord* record) override;
diff --git a/modules/c++/logging/include/logging/StandardFormatter.h b/modules/c++/logging/include/logging/StandardFormatter.h
index 0e11d3d30c..798082e819 100644
--- a/modules/c++/logging/include/logging/StandardFormatter.h
+++ b/modules/c++/logging/include/logging/StandardFormatter.h
@@ -67,7 +67,7 @@ class CODA_OSS_API StandardFormatter : public Formatter
StandardFormatter& operator=(const StandardFormatter&) = delete;
- virtual void format(const LogRecord* record, io::OutputStream& os) const;
+ virtual void format(const LogRecord* record, io::OutputStream& os) const override;
};
diff --git a/modules/c++/logging/include/logging/StreamHandler.h b/modules/c++/logging/include/logging/StreamHandler.h
index fa66e54b5a..49d12f1aff 100644
--- a/modules/c++/logging/include/logging/StreamHandler.h
+++ b/modules/c++/logging/include/logging/StreamHandler.h
@@ -57,10 +57,10 @@ struct CODA_OSS_API StreamHandler : public Handler
//! adds the need to write epilogue before deleting formatter
// and then writing the prologue with the new formatter
- virtual void setFormatter(Formatter* formatter);
- virtual void setFormatter(std::unique_ptr&&);
+ virtual void setFormatter(Formatter* formatter) override;
+ virtual void setFormatter(std::unique_ptr&&) override;
- virtual void close();
+ virtual void close() override;
protected:
// This is necessary so this class and an inherited class can call a
@@ -68,7 +68,7 @@ struct CODA_OSS_API StreamHandler : public Handler
void closeImpl();
//! for general string write
- virtual void write(const std::string&);
+ virtual void write(const std::string&) override;
//! for writing directly to stream,
// used for the bulk of the logging for speed
diff --git a/modules/c++/logging/include/logging/XMLFormatter.h b/modules/c++/logging/include/logging/XMLFormatter.h
index 7eb6556152..b6d8e8e834 100644
--- a/modules/c++/logging/include/logging/XMLFormatter.h
+++ b/modules/c++/logging/include/logging/XMLFormatter.h
@@ -63,7 +63,7 @@ struct XMLFormatter : public logging::Formatter
XMLFormatter& operator=(const XMLFormatter&) = delete;
- virtual void format(const logging::LogRecord* record, io::OutputStream& os) const;
+ virtual void format(const logging::LogRecord* record, io::OutputStream& os) const override;
};
diff --git a/modules/c++/logging/unittests/test_exception_logger.cpp b/modules/c++/logging/unittests/test_exception_logger.cpp
index 375b4b5f47..f85d8cc54a 100644
--- a/modules/c++/logging/unittests/test_exception_logger.cpp
+++ b/modules/c++/logging/unittests/test_exception_logger.cpp
@@ -45,7 +45,7 @@ class RunNothing final : public sys::Runnable
public:
RunNothing(size_t& c, logging::ExceptionLogger* el, bool getBacktrace=false) : counter(c), exLog(el), getBacktrace(getBacktrace) {}
- virtual void run()
+ virtual void run() override
{
if(exLog->hasLogged())
return;
diff --git a/modules/c++/logging/unittests/test_rotating_log.cpp b/modules/c++/logging/unittests/test_rotating_log.cpp
index dff0bc97d3..6f0c4f7251 100644
--- a/modules/c++/logging/unittests/test_rotating_log.cpp
+++ b/modules/c++/logging/unittests/test_rotating_log.cpp
@@ -60,10 +60,11 @@ TEST_CASE(testRotate)
log.debug("0123456789");
TEST_ASSERT(os.exists(outFile));
- TEST_ASSERT_FALSE(os.isFile(outFile + ".1"));
+ const auto outFile1 = outFile + ".1";
+ TEST_ASSERT_FALSE(os.isFile(outFile1));
log.debug("1");
- TEST_ASSERT(os.isFile(outFile + ".1"));
+ TEST_ASSERT(os.isFile(outFile1));
}
cleanupFiles( outFile);
diff --git a/modules/c++/mt/include/mt/Runnable1D.h b/modules/c++/mt/include/mt/Runnable1D.h
index bb73e94bfc..406f9903f1 100644
--- a/modules/c++/mt/include/mt/Runnable1D.h
+++ b/modules/c++/mt/include/mt/Runnable1D.h
@@ -25,7 +25,7 @@ class Runnable1D : public sys::Runnable
{
}
- virtual void run()
+ virtual void run() override
{
for (size_t ii = mStartElement; ii < mEndElement; ++ii)
{
diff --git a/modules/c++/mt/include/mt/WorkerThread.h b/modules/c++/mt/include/mt/WorkerThread.h
index 0cf0ce2dd4..4e865d0fff 100644
--- a/modules/c++/mt/include/mt/WorkerThread.h
+++ b/modules/c++/mt/include/mt/WorkerThread.h
@@ -60,7 +60,7 @@ template class WorkerThread : public sys::Thread
/*!
* Run this request
*/
- virtual void run()
+ virtual void run() override
{
initialize();
while (!isDone())
diff --git a/modules/c++/mt/tests/BasicThreadPoolTest.cpp b/modules/c++/mt/tests/BasicThreadPoolTest.cpp
index aece0cd81b..56b9903012 100644
--- a/modules/c++/mt/tests/BasicThreadPoolTest.cpp
+++ b/modules/c++/mt/tests/BasicThreadPoolTest.cpp
@@ -51,7 +51,7 @@ class MyRunTask : public Runnable
{
}
- virtual void run()
+ virtual void run() override
{
sleep(TO_SLEEP);
mSem.signal();
diff --git a/modules/c++/mt/tests/GenerationThreadPoolTest.cpp b/modules/c++/mt/tests/GenerationThreadPoolTest.cpp
index 26b873c5de..498ab6f25a 100644
--- a/modules/c++/mt/tests/GenerationThreadPoolTest.cpp
+++ b/modules/c++/mt/tests/GenerationThreadPoolTest.cpp
@@ -50,7 +50,7 @@ class MyRunTask : public sys::Runnable
{
}
- void run()
+ void run() override
{
sleep(TO_SLEEP);
diff --git a/modules/c++/mt/tests/MTSingletonTest.cpp b/modules/c++/mt/tests/MTSingletonTest.cpp
index 0488595271..beb1719e35 100644
--- a/modules/c++/mt/tests/MTSingletonTest.cpp
+++ b/modules/c++/mt/tests/MTSingletonTest.cpp
@@ -138,7 +138,7 @@ class Calpurnia : public Thespian
~Calpurnia()
{
}
- void doLines()
+ void doLines() override
{
//__warning__("Caesar, I never stood on ceremonies, Yet now they fright me. There is one within, 15 Besides the things that we have heard and seen, Recounts most horrid sights seen by the watch. A lioness hath whelped in the streets; And graves have yawn'd, and yielded up their dead; Fierce fiery warriors fought upon the clouds, 20 In ranks and squadrons and right form of war, Which drizzled blood upon the Capitol; The noise of battle hurtled in the air, Horses did neigh, and dying men did groan, And ghosts did shriek and squeal about the streets. 25 O Caesar! these things are beyond all use, And I do fear them.");
}
@@ -154,7 +154,7 @@ class Caesar : public Thespian
~Caesar()
{
}
- void doLines()
+ void doLines() override
{
//__status__("Cowards die many times before their deaths; The valiant never taste of death but once. 35 Of all the wonders that I yet have heard. It seems to me most strange that men should fear; Seeing that death, a necessary end, Will come when it will come.");
}
@@ -172,7 +172,7 @@ class Brutus : public Thespian
{
}
- virtual void doLines()
+ virtual void doLines() override
{
//__status__("Be patient till the last. Romans, countrymen, and lovers! hear me for my 15 cause, and be silent, that you may hear: believe me for mine honour, and have respect to mine honour, that you may believe: censure me in your wisdom, and awake your senses, that you may the better judge. If there be any in this assembly, any dear friend of 20 Caesar's, to him I say, that Brutus' love to Caesar was no less than his. If then that friend demand why Brutus rose against Caesar, this is my answer: --Not that I loved Caesar less, but that I loved Rome more. Had you rather Caesar were living and 25 die all slaves, than that Caesar were dead, to live all free men? As Caesar loved me, I weep for him; as he was fortunate, I rejoice at it; as he was valiant, I honour him: but, as he was ambitious, I slew him. There is tears for his love; joy for his 30 fortune; honour for his valour; and death for his ambition. Who is here so base that would be a bondman? If any, speak; for him have I offended. Who is here so rude that would not be a Roman? If any, speak; for him have I offended. Who is here so 35 vile that will not love his country? If any, speak; for him have I offended. I pause for a reply.");
@@ -190,7 +190,7 @@ class Antony : public Thespian
{
}
- void doLines()
+ void doLines() override
{
//__status__("Villains, you did not so, when your vile daggers Hack'd one another in the sides of Caesar: You show'd your teeth like apes, and fawn'd like hounds, 45 And bow'd like bondmen, kissing Caesar's feet; Whilst damned Casca, like a cur, behind Struck Caesar on the neck. O you flatterers!");
}
@@ -207,7 +207,7 @@ class Octavius : public Thespian
{
}
- void doLines()
+ void doLines() override
{
//__status__("According to his virtue let us use him, With all respect and rites of burial. Within my tent his bones to-night shall lie, 85 Most like a soldier, order'd honourably. So call the field to rest; and let's away, To part the glories of this happy day.");
}
diff --git a/modules/c++/mt/tests/ThreadExceptionTest.cpp b/modules/c++/mt/tests/ThreadExceptionTest.cpp
index efc5ee9853..381171aa78 100644
--- a/modules/c++/mt/tests/ThreadExceptionTest.cpp
+++ b/modules/c++/mt/tests/ThreadExceptionTest.cpp
@@ -38,7 +38,7 @@ class PrintChar : public sys::Runnable
/*-- std::exception --*/
struct stdExcept: std::exception
{
- const char* what() const noexcept { return "std::exception in add"; }
+ const char* what() const noexcept override { return "std::exception in add"; }
};
void add(sys::Uint32_T x, sys::Uint32_T y)
diff --git a/modules/c++/mt/tests/ThreadGroupAffinityTest.cpp b/modules/c++/mt/tests/ThreadGroupAffinityTest.cpp
index 9d47da780b..32d3c63c01 100644
--- a/modules/c++/mt/tests/ThreadGroupAffinityTest.cpp
+++ b/modules/c++/mt/tests/ThreadGroupAffinityTest.cpp
@@ -43,7 +43,7 @@ class MyRunTask : public Runnable
{
}
- virtual void run()
+ virtual void run() override
{
// Print diagnostics from inside the thread
while(true)
diff --git a/modules/c++/net.ssl/include/net/ssl/SSLConnectionClientFactory.h b/modules/c++/net.ssl/include/net/ssl/SSLConnectionClientFactory.h
index eb5bfb72e8..698d14e3ad 100644
--- a/modules/c++/net.ssl/include/net/ssl/SSLConnectionClientFactory.h
+++ b/modules/c++/net.ssl/include/net/ssl/SSLConnectionClientFactory.h
@@ -100,7 +100,7 @@ class SSLConnectionClientFactory : public NetConnectionClientFactory
* \param toServer The socket for the new connection
* \return A new SSLConnection
*/
- virtual NetConnection* newConnection(std::unique_ptr&& toServer);
+ virtual NetConnection* newConnection(std::unique_ptr&& toServer) override;
private:
# if defined(USE_OPENSSL)
diff --git a/modules/c++/net/include/net/ClientSocketFactory.h b/modules/c++/net/include/net/ClientSocketFactory.h
index d4b59ab9ac..237d86c764 100644
--- a/modules/c++/net/include/net/ClientSocketFactory.h
+++ b/modules/c++/net/include/net/ClientSocketFactory.h
@@ -134,7 +134,7 @@ class UDPClientSocketFactory : public ClientSocketFactory
* Sets SO_BROADCAST socket option.
* \param s The socket
*/
- virtual void setOptions(Socket& s)
+ virtual void setOptions(Socket& s) override
{
// Make sure we're set up for broadcasting if necessary
int on = 1;
diff --git a/modules/c++/net/include/net/DaemonUnix.h b/modules/c++/net/include/net/DaemonUnix.h
index c866bb3aa2..94039fa9cb 100644
--- a/modules/c++/net/include/net/DaemonUnix.h
+++ b/modules/c++/net/include/net/DaemonUnix.h
@@ -21,29 +21,29 @@ class DaemonUnix : public DaemonInterface
virtual ~DaemonUnix();
//! Start the daemon
- void start();
+ void start() override;
//! Stop the daemon specified in pidfile
- void stop();
+ void stop() override;
//! Stop the daemon specified in pidfile and start a new one
- void restart();
+ void restart() override;
//! Parse and execute command line option (start/stop/restart)
- void daemonize(int& argc, char**& argv);
+ void daemonize(int& argc, char**& argv) override;
//! Set pidfile (file for locking application to single occurance).
- void setPidfile(const std::string& pidfile);
+ void setPidfile(const std::string& pidfile) override;
//! Get pidfile.
- std::string getPidfile() const { return mPidfile; }
+ std::string getPidfile() const override { return mPidfile; }
//! Set tracefile (file to redirect stdout and stderr).
- void setTracefile(const std::string& tracefile);
+ void setTracefile(const std::string& tracefile) override;
//! Get tracefile.
- std::string getTracefile() const { return mTracefile; }
+ std::string getTracefile() const override { return mTracefile; }
protected:
std::string mPidfile;
diff --git a/modules/c++/net/include/net/NetConnection.h b/modules/c++/net/include/net/NetConnection.h
index bf42a8a8da..3cdf6b535d 100644
--- a/modules/c++/net/include/net/NetConnection.h
+++ b/modules/c++/net/include/net/NetConnection.h
@@ -116,7 +116,7 @@ class NetConnection : public io::BidirectionalStream
* Close a connection. This releases the writers/readers and closes
* the handle.
*/
- void close()
+ void close() override
{
mSocket->close();
}
@@ -138,7 +138,7 @@ class NetConnection : public io::BidirectionalStream
* \param len The length of the byte array to write to the stream
* \throw IOException
*/
- virtual void write(const void* buffer, size_t len);
+ virtual void write(const void* buffer, size_t len) override;
using io::BidirectionalStream::read;
using io::BidirectionalStream::write;
@@ -151,7 +151,7 @@ class NetConnection : public io::BidirectionalStream
* \throw IOException
* \return The number of bytes read, or -1 if eof
*/
- virtual sys::SSize_T readImpl(void* buffer, size_t len);
+ virtual sys::SSize_T readImpl(void* buffer, size_t len) override;
//! The socket
std::shared_ptr mSocket;
diff --git a/modules/c++/net/include/net/PerRequestThreadAllocStrategy.h b/modules/c++/net/include/net/PerRequestThreadAllocStrategy.h
index f555d6e3b8..c02cb530bb 100644
--- a/modules/c++/net/include/net/PerRequestThreadAllocStrategy.h
+++ b/modules/c++/net/include/net/PerRequestThreadAllocStrategy.h
@@ -68,7 +68,7 @@ class RequestHandlerThread : public sys::Thread
* Overloaded run method for handling a connection.
*
*/
- void run()
+ void run() override
{
(*mRequestHandler)(mConnection);
delete mRequestHandler;
@@ -94,7 +94,7 @@ class PerRequestThreadAllocStrategy : public AllocStrategy
~PerRequestThreadAllocStrategy()
{}
- void initialize()
+ void initialize() override
{
}
@@ -103,7 +103,7 @@ class PerRequestThreadAllocStrategy : public AllocStrategy
*
* \param conn The network connection
*/
- void handleConnection(NetConnection* conn);
+ void handleConnection(NetConnection* conn) override;
};
/* class ThreadPoolAllocStrategy : public AllocStrategy */
diff --git a/modules/c++/net/include/net/RequestHandler.h b/modules/c++/net/include/net/RequestHandler.h
index 3ef3795962..8859f5d98a 100644
--- a/modules/c++/net/include/net/RequestHandler.h
+++ b/modules/c++/net/include/net/RequestHandler.h
@@ -79,7 +79,7 @@ template class DefaultRequestHandlerFactory: public Reque
virtual ~DefaultRequestHandlerFactory()
{
}
- net::RequestHandler* create()
+ net::RequestHandler* create() override
{
return new ReqHandler_T();
}
diff --git a/modules/c++/net/include/net/ServerSocketFactory.h b/modules/c++/net/include/net/ServerSocketFactory.h
index 7b6393a0bc..3074d37647 100644
--- a/modules/c++/net/include/net/ServerSocketFactory.h
+++ b/modules/c++/net/include/net/ServerSocketFactory.h
@@ -127,7 +127,7 @@ class UDPServerSocketFactory : public ServerSocketFactory
*
* \return The produced socket
*/
- virtual std::unique_ptr create(const SocketAddress& address)
+ virtual std::unique_ptr create(const SocketAddress& address) override
{
std::unique_ptr s(new Socket(mProto));
@@ -185,7 +185,7 @@ class TCPServerSocketFactory : ServerSocketFactory
* listen().
*
*/
- virtual std::unique_ptr create(const SocketAddress& address)
+ virtual std::unique_ptr create(const SocketAddress& address) override
{
std::unique_ptr s(new Socket(mProto));
diff --git a/modules/c++/net/include/net/SingleThreadedAllocStrategy.h b/modules/c++/net/include/net/SingleThreadedAllocStrategy.h
index ac16fafb75..4a1314f129 100644
--- a/modules/c++/net/include/net/SingleThreadedAllocStrategy.h
+++ b/modules/c++/net/include/net/SingleThreadedAllocStrategy.h
@@ -58,7 +58,7 @@ class SingleThreadedAllocStrategy: public AllocStrategy
* Set the auto ptr.
*
*/
- void initialize()
+ void initialize() override
{
mHandler = mRequestHandlerFactory->create();
}
@@ -68,7 +68,7 @@ class SingleThreadedAllocStrategy: public AllocStrategy
*
* \param conn The network connection
*/
- void handleConnection(net::NetConnection* conn)
+ void handleConnection(net::NetConnection* conn) override
{
(*mHandler)(conn);
}
diff --git a/modules/c++/net/include/net/ThreadPoolAllocStrategy.h b/modules/c++/net/include/net/ThreadPoolAllocStrategy.h
index ce7fc740e9..767e024503 100644
--- a/modules/c++/net/include/net/ThreadPoolAllocStrategy.h
+++ b/modules/c++/net/include/net/ThreadPoolAllocStrategy.h
@@ -44,7 +44,7 @@ class ConnectionThread: public mt::WorkerThread
/*!
* Do this in a loop forever.
*/
- void performTask(net::NetConnection*& request)
+ void performTask(net::NetConnection*& request) override
{
(*mHandler)(request);
}
@@ -78,7 +78,7 @@ class ConnectionThreadPool: public mt::AbstractThreadPool
delete mFactory;
}
- mt::WorkerThread* newWorker()
+ mt::WorkerThread* newWorker() override
{
return new ConnectionThread(&mRequestQueue, mFactory->create());
}
@@ -127,9 +127,9 @@ class ThreadPoolAllocStrategy: public AllocStrategy
// AllocStrategy guarantees that mRequestHandlerFactory is initialized
// by the time this function is called
- void initialize();
+ void initialize() override;
- void handleConnection(net::NetConnection* conn);
+ void handleConnection(net::NetConnection* conn) override;
};
}
diff --git a/modules/c++/net/tests/NetConnectionServerTest.cpp b/modules/c++/net/tests/NetConnectionServerTest.cpp
index 545bc10d06..bcbb46ac10 100644
--- a/modules/c++/net/tests/NetConnectionServerTest.cpp
+++ b/modules/c++/net/tests/NetConnectionServerTest.cpp
@@ -50,7 +50,7 @@ class EchoHandler : public net::RequestHandler
~EchoHandler()
{
}
- void operator()(net::NetConnection* conn)
+ void operator()(net::NetConnection* conn) override
{
char buf[MAX_BUF_SIZE];
unsigned int length;
diff --git a/modules/c++/plugin/include/plugin/ErrorHandler.h b/modules/c++/plugin/include/plugin/ErrorHandler.h
index 727a81584c..be7ca3c8a8 100644
--- a/modules/c++/plugin/include/plugin/ErrorHandler.h
+++ b/modules/c++/plugin/include/plugin/ErrorHandler.h
@@ -52,15 +52,15 @@ class DefaultErrorHandler : public ErrorHandler
public:
DefaultErrorHandler(logging::LoggerPtr logger = logging::LoggerPtr());
- void onPluginDirectoryNotFound(const std::string& dir);
+ void onPluginDirectoryNotFound(const std::string& dir) override;
- void onPluginLoadedAlready(const std::string& file);
+ void onPluginLoadedAlready(const std::string& file) override;
- void onPluginLoadFailed(const std::string& file);
+ void onPluginLoadFailed(const std::string& file) override;
- void onPluginVersionUnsupported(const std::string& message);
+ void onPluginVersionUnsupported(const std::string& message) override;
- void onPluginError(except::Context& c);
+ void onPluginError(except::Context& c) override;
protected:
logging::LoggerPtr mLogger;
diff --git a/modules/c++/sio.lite/include/sio/lite/SioFileReader.h b/modules/c++/sio.lite/include/sio/lite/SioFileReader.h
index 8fa5133344..446476dfc7 100644
--- a/modules/c++/sio.lite/include/sio/lite/SioFileReader.h
+++ b/modules/c++/sio.lite/include/sio/lite/SioFileReader.h
@@ -125,7 +125,7 @@ class FileReader : public StreamReader, public io::Seekable
* For simplicity, the final position is reported in the return value relative
* to header start (always). This is done by calling tell().
*/
- sys::Off_T seek( sys::Off_T offset, Whence whence );
+ sys::Off_T seek( sys::Off_T offset, Whence whence ) override;
/*!
* Overloaded method, only works if this is a FileInputStream.
@@ -134,10 +134,10 @@ class FileReader : public StreamReader, public io::Seekable
* yield 0 as a return value.
*
*/
- sys::Off_T tell();
+ sys::Off_T tell() override;
- void killStream();
+ void killStream() override;
protected:
};
}
diff --git a/modules/c++/sio.lite/include/sio/lite/StreamReader.h b/modules/c++/sio.lite/include/sio/lite/StreamReader.h
index fe0c22b755..982b8900fb 100644
--- a/modules/c++/sio.lite/include/sio/lite/StreamReader.h
+++ b/modules/c++/sio.lite/include/sio/lite/StreamReader.h
@@ -140,7 +140,7 @@ class StreamReader : public io::InputStream
sio::lite::FileHeader* readHeader() { return header; }
- sys::Off_T available()
+ sys::Off_T available() override
{
return inputStream->available();
}
@@ -156,7 +156,7 @@ class StreamReader : public io::InputStream
* @param size the Number of bytes to read
* @return The number of bytes read
*/
- virtual sys::SSize_T readImpl(void* buffer, size_t size)
+ virtual sys::SSize_T readImpl(void* buffer, size_t size) override
{
return inputStream->read(buffer, size);
}
diff --git a/modules/c++/str/source/Encoding.cpp b/modules/c++/str/source/Encoding.cpp
index bbe3a0a5f6..86a879b0c4 100644
--- a/modules/c++/str/source/Encoding.cpp
+++ b/modules/c++/str/source/Encoding.cpp
@@ -198,7 +198,7 @@ std::u16string str::to_u16string(str::W1252string::const_pointer p, size_t sz)
{
auto retval = to_Tstring(p, sz);
#if defined(_WIN32) && (!defined(_NDEBUG) || defined(DEBUG))
- const _bstr_t bstr(str::cast(p));
+ const _bstr_t bstr(std::string(str::cast(p), sz).c_str()); // no _bstr_t ctor taking sz
const std::wstring wstr(static_cast(bstr));
assert(retval == str::cast(wstr.c_str()));
#endif
diff --git a/modules/c++/str/source/Manip.cpp b/modules/c++/str/source/Manip.cpp
index 516f43f354..444c897321 100644
--- a/modules/c++/str/source/Manip.cpp
+++ b/modules/c++/str/source/Manip.cpp
@@ -146,7 +146,8 @@ size_t replace(std::string& str,
if (index != std::string::npos)
{
- str.replace(index, search.length(), replace);
+ // ASAN error: str.replace(index, search.length(), replace);
+ str = str.substr(0, index) + replace + str.substr(index + search.length());
start = index;
}
else
diff --git a/modules/c++/sys/source/OSWin32.cpp b/modules/c++/sys/source/OSWin32.cpp
index cfde07d35b..9fe5e7f153 100644
--- a/modules/c++/sys/source/OSWin32.cpp
+++ b/modules/c++/sys/source/OSWin32.cpp
@@ -148,11 +148,15 @@ bool sys::OSWin32::isFile(const std::string& path) const
// 2) Not Directory
// 3) Not Archive - we aren't doing that...
const DWORD what = GetFileAttributes(path.c_str());
- return (what != INVALID_FILE_ATTRIBUTES &&
- !(what & FILE_ATTRIBUTE_DIRECTORY));
+ if (what == INVALID_FILE_ATTRIBUTES) // "if the function fails, the return value is INVALID_FILE_ATTRIBUTES."
+ {
+ //const auto dwError = GetLastError();
+ return false;
+ }
+ const auto fileAttributeDirectory = (what & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY;
+ return !fileAttributeDirectory;
}
-
bool sys::OSWin32::isDirectory(const std::string& path) const
{
const DWORD what = GetFileAttributes(path.c_str());
@@ -183,7 +187,7 @@ bool sys::OSWin32::changeDirectory(const std::string& path) const
std::string sys::OSWin32::getTempName(const std::string& path,
const std::string& prefix) const
{
- char buffer[MAX_PATH];
+ char buffer[MAX_PATH]{};
if (GetTempFileName(path.c_str(),
prefix.c_str(),
0, buffer) == 0)
diff --git a/modules/c++/tiff/include/tiff/GenericType.h b/modules/c++/tiff/include/tiff/GenericType.h
index 581c06905d..9d5a994ea8 100644
--- a/modules/c++/tiff/include/tiff/GenericType.h
+++ b/modules/c++/tiff/include/tiff/GenericType.h
@@ -127,7 +127,7 @@ template class Gene
* @param output
* the output stream to write the member to
*****************************************************************/
- virtual void serialize(io::OutputStream& output)
+ virtual void serialize(io::OutputStream& output) override
{
output.write((char *)&mData, sizeof(Data_T));
}
@@ -139,22 +139,22 @@ template class Gene
* @param input
* the input stream to read the member from
*****************************************************************/
- virtual void deserialize(io::InputStream& input)
+ virtual void deserialize(io::InputStream& input) override
{
input.read((char *)&mData, sizeof(Data_T));
}
- virtual unsigned char *data() const
+ virtual unsigned char *data() const override
{
return (unsigned char *)&mData;
}
- virtual unsigned short size() const
+ virtual unsigned short size() const override
{
return sizeof(mData);
}
- virtual std::string toString() const
+ virtual std::string toString() const override
{
return Strategy_T::toString(mData);
}
diff --git a/modules/c++/tiff/include/tiff/Header.h b/modules/c++/tiff/include/tiff/Header.h
index ee09bc445f..ed9da4f1e9 100644
--- a/modules/c++/tiff/include/tiff/Header.h
+++ b/modules/c++/tiff/include/tiff/Header.h
@@ -96,7 +96,7 @@ class Header : public io::Serializable
* @param output
* the stream to write the header to
*****************************************************************/
- void serialize(io::OutputStream& output);
+ void serialize(io::OutputStream& output) override;
/**
*****************************************************************
@@ -105,7 +105,7 @@ class Header : public io::Serializable
* @param input
* the stream to read the header from
*****************************************************************/
- void deserialize(io::InputStream& input);
+ void deserialize(io::InputStream& input) override;
/**
*****************************************************************
diff --git a/modules/c++/tiff/include/tiff/IFD.h b/modules/c++/tiff/include/tiff/IFD.h
index bfb8b65556..706309e8f4 100644
--- a/modules/c++/tiff/include/tiff/IFD.h
+++ b/modules/c++/tiff/include/tiff/IFD.h
@@ -195,7 +195,7 @@ class IFD : public io::Serializable
* @param output
* the output stream to write the IFD to
*****************************************************************/
- void serialize(io::OutputStream& output);
+ void serialize(io::OutputStream& output) override;
/**
*****************************************************************
@@ -204,7 +204,7 @@ class IFD : public io::Serializable
* @param input
* the input stream to read the IFD from
*****************************************************************/
- void deserialize(io::InputStream& input);
+ void deserialize(io::InputStream& input) override;
void deserialize(io::InputStream& input, const bool reverseBytes);
/**
diff --git a/modules/c++/tiff/include/tiff/IFDEntry.h b/modules/c++/tiff/include/tiff/IFDEntry.h
index 31ecedddb1..75552676f3 100644
--- a/modules/c++/tiff/include/tiff/IFDEntry.h
+++ b/modules/c++/tiff/include/tiff/IFDEntry.h
@@ -122,7 +122,7 @@ class IFDEntry : public io::Serializable
* @param output
* the output stream to write the entry to
*****************************************************************/
- void serialize(io::OutputStream& output);
+ void serialize(io::OutputStream& output) override;
/**
*****************************************************************
@@ -131,7 +131,7 @@ class IFDEntry : public io::Serializable
* @param input
* the input stream to read the entry from
*****************************************************************/
- void deserialize(io::InputStream& input);
+ void deserialize(io::InputStream& input) override;
void deserialize(io::InputStream& input, const bool reverseBytes);
/**
diff --git a/modules/c++/xml.lite/CMakeLists.txt b/modules/c++/xml.lite/CMakeLists.txt
index ee70ab4070..ad13e57988 100644
--- a/modules/c++/xml.lite/CMakeLists.txt
+++ b/modules/c++/xml.lite/CMakeLists.txt
@@ -3,6 +3,7 @@ set(MODULE_NAME xml.lite)
if(ENABLE_XML)
if (UNIX)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-zero-as-null-pointer-constant")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-suggest-override")
endif()
if(CONAN_PACKAGE_NAME)
diff --git a/modules/c++/xml.lite/include/xml/lite/UtilitiesXerces.h b/modules/c++/xml.lite/include/xml/lite/UtilitiesXerces.h
index c9d78cfa15..ba587a91be 100644
--- a/modules/c++/xml.lite/include/xml/lite/UtilitiesXerces.h
+++ b/modules/c++/xml.lite/include/xml/lite/UtilitiesXerces.h
@@ -303,12 +303,12 @@ struct XercesContentHandler : public XercesContentHandlerInterface_T
XercesContentHandler& operator=(const XercesContentHandler&) = delete;
virtual void ignorableWhitespace(const XMLCh* const /*chars*/,
- const XercesSize_T /*length*/)
+ const XercesSize_T /*length*/) override
{}
virtual void processingInstruction(const XMLCh* const /*target*/,
- const XMLCh* const /*data*/)
+ const XMLCh* const /*data*/) override
{}
- virtual void setDocumentLocator(const Locator* const /*locator*/)
+ virtual void setDocumentLocator(const Locator* const /*locator*/) override
{}
/*!
@@ -319,12 +319,12 @@ struct XercesContentHandler : public XercesContentHandlerInterface_T
* \param length The length
*/
virtual void characters(const XMLCh* const chars,
- const XercesSize_T length);
+ const XercesSize_T length) override;
/*!
* Fire off the end document notification
*/
- virtual void endDocument();
+ virtual void endDocument() override;
/*!
* Map input string types to output string types
@@ -335,13 +335,13 @@ struct XercesContentHandler : public XercesContentHandlerInterface_T
*/
virtual void endElement(const XMLCh* const uri,
const XMLCh* const localName,
- const XMLCh* const qname);
+ const XMLCh* const qname) override;
- virtual void skippedEntity (const XMLCh* const /*name*/)
+ virtual void skippedEntity (const XMLCh* const /*name*/) override
{}
//! Fire off the start document notification
- virtual void startDocument();
+ virtual void startDocument() override;
/*!
* Map input string types to output string types
@@ -355,7 +355,7 @@ struct XercesContentHandler : public XercesContentHandlerInterface_T
virtual void startElement(const XMLCh* const uri,
const XMLCh* const localName,
const XMLCh* const qname,
- const XercesAttributesInterface_T &attrs);
+ const XercesAttributesInterface_T &attrs) override;
/*!
* Begin prefix mapping. Transfer string types
@@ -363,7 +363,7 @@ struct XercesContentHandler : public XercesContentHandlerInterface_T
* \param uri The corresponding uri
*/
virtual void startPrefixMapping (const XMLCh* const /*prefix*/,
- const XMLCh* const /*uri*/)
+ const XMLCh* const /*uri*/) override
{
}
@@ -371,7 +371,7 @@ struct XercesContentHandler : public XercesContentHandlerInterface_T
* End prefix mapping. Transfer string types
* \param prefix The prefix to stop mapping
*/
- virtual void endPrefixMapping (const XMLCh* const /*prefix*/)
+ virtual void endPrefixMapping (const XMLCh* const /*prefix*/) override
{
}
diff --git a/modules/c++/xml.lite/include/xml/lite/XMLReaderXerces.h b/modules/c++/xml.lite/include/xml/lite/XMLReaderXerces.h
index beca1fa5cd..52b78befbc 100644
--- a/modules/c++/xml.lite/include/xml/lite/XMLReaderXerces.h
+++ b/modules/c++/xml.lite/include/xml/lite/XMLReaderXerces.h
@@ -82,7 +82,7 @@ class XMLReaderXerces final : public XMLReaderInterface
* This method returns a reference to the content handler.
* \return content handler
*/
- xml::lite::ContentHandler *getContentHandler()
+ xml::lite::ContentHandler *getContentHandler() override
{
return mDriverContentHandler->retrieveXMLLiteContentHandler();
}
@@ -92,7 +92,7 @@ class XMLReaderXerces final : public XMLReaderInterface
* It will set this internally.
* \param handler The content handler to pass
*/
- void setContentHandler(xml::lite::ContentHandler* handler)
+ void setContentHandler(xml::lite::ContentHandler* handler) override
{
mDriverContentHandler->setXMLLiteContentHandler(handler);
}
@@ -104,12 +104,12 @@ class XMLReaderXerces final : public XMLReaderInterface
int size = io::InputStream::IS_END);
//! Method to create an xml reader
- void create();
+ void create() override;
//! Method to destroy an xml reader
- void destroy();
+ void destroy() override;
- std::string getDriverName() const { return "xerces"; }
+ std::string getDriverName() const override { return "xerces"; }
static const void* getWindows1252Encoding();
diff --git a/modules/c++/xml.lite/unittests/test_soapelements.cpp b/modules/c++/xml.lite/unittests/test_soapelements.cpp
index 6be98e7d46..55de517a95 100644
--- a/modules/c++/xml.lite/unittests/test_soapelements.cpp
+++ b/modules/c++/xml.lite/unittests/test_soapelements.cpp
@@ -52,8 +52,8 @@ struct SOAP final : public xml::lite::Document
TEST_CASE(test_overrideCreateElement)
{
SOAP soap_test;
- auto a = soap_test.createElement("a","b","Not SOAP Test");
- auto b = dynamic_cast(a);
+ std::unique_ptr a(soap_test.createElement("a","b","Not SOAP Test"));
+ auto b = dynamic_cast(a.get());
TEST_ASSERT_NOT_NULL(b);
TEST_ASSERT_EQ(a->getCharacterData(), test_text);
TEST_ASSERT_EQ(b->getCharacterData(), test_text);
diff --git a/modules/c++/zip/include/zip/GZipInputStream.h b/modules/c++/zip/include/zip/GZipInputStream.h
index 1994d5467e..783b6241fe 100644
--- a/modules/c++/zip/include/zip/GZipInputStream.h
+++ b/modules/c++/zip/include/zip/GZipInputStream.h
@@ -58,7 +58,7 @@ class GZipInputStream: public io::InputStream
* This is a little tricky since we do not know the
* length of the read.
*/
- virtual sys::SSize_T readImpl(void* buffer, size_t len);
+ virtual sys::SSize_T readImpl(void* buffer, size_t len) override;
};
}
diff --git a/modules/c++/zip/include/zip/GZipOutputStream.h b/modules/c++/zip/include/zip/GZipOutputStream.h
index a8d471569c..7f137d2cfa 100644
--- a/modules/c++/zip/include/zip/GZipOutputStream.h
+++ b/modules/c++/zip/include/zip/GZipOutputStream.h
@@ -46,13 +46,13 @@ class GZipOutputStream: public io::OutputStream
* the call returns.
*
*/
- virtual void write(const void* buffer, size_t len);
+ virtual void write(const void* buffer, size_t len) override;
/*!
* Close the gzip stream. You must call this
* afterward (it is not done automatically).
*/
- virtual void close();
+ virtual void close() override;
};
}
diff --git a/modules/c++/zip/include/zip/ZipOutputStream.h b/modules/c++/zip/include/zip/ZipOutputStream.h
index 50ce6a1982..a49c3c4a0b 100644
--- a/modules/c++/zip/include/zip/ZipOutputStream.h
+++ b/modules/c++/zip/include/zip/ZipOutputStream.h
@@ -76,9 +76,9 @@ class ZipOutputStream: public io::OutputStream
void write(const std::string& inputPathname,
const std::string& zipPathname);
- virtual void write(const void* buffer, size_t len);
+ virtual void write(const void* buffer, size_t len) override;
- virtual void close();
+ virtual void close() override;
private:
zipFile mZip;