diff --git a/CMakeLists.txt b/CMakeLists.txt index 14d2ed10..10bbe870 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -70,7 +70,7 @@ endif() ######################################################################################################################## ### dependencies and options -ecbuild_find_package( NAME eckit VERSION 1.4 REQUIRED ) +ecbuild_find_package( NAME eckit VERSION 1.29 REQUIRED ) ecbuild_add_option( FEATURE FORTRAN DESCRIPTION "whether or not to build the Fortran interface" diff --git a/src/odc/Indexer.cc b/src/odc/Indexer.cc index 271842e0..3fce56bc 100644 --- a/src/odc/Indexer.cc +++ b/src/odc/Indexer.cc @@ -7,10 +7,13 @@ * granted to it by virtue of its status as an intergovernmental organisation nor * does it submit to any jurisdiction. */ - #include "odc/Indexer.h" -#include "eckit/eckit.h" +#include +#include +#include + +#include "eckit/io/DataHandle.h" #include "eckit/io/Length.h" #include "eckit/io/Offset.h" #include "eckit/io/PartFileHandle.h" diff --git a/src/odc/ODBAPISettings.cc b/src/odc/ODBAPISettings.cc index 5c711078..a1947517 100644 --- a/src/odc/ODBAPISettings.cc +++ b/src/odc/ODBAPISettings.cc @@ -17,12 +17,14 @@ #include "eckit/io/FileHandle.h" #include "eckit/log/Log.h" #include "eckit/thread/ThreadSingleton.h" +#include "eckit/utils/Literals.h" #include "eckit/utils/StringTools.h" #include "odc/LibOdc.h" #include "odc/ODBAPISettings.h" using namespace eckit; +using namespace eckit::literals; using namespace std; template class eckit::ThreadSingleton; @@ -47,7 +49,7 @@ void odc::ODBAPISettings::setHome(const char* argv0) { ::free(absoluteArgv0); } else if (argv0[0] == '.' && argv0[1] == '/') { - size_t bufferLen = 1024 * 8; + constexpr size_t bufferLen = 8_KiB; char buffer[bufferLen]; full = string(::getcwd(buffer, bufferLen)) + string(argv0 + 1); } @@ -58,7 +60,7 @@ void odc::ODBAPISettings::setHome(const char* argv0) { if (PathName(ps[i] + "/" + argv0).exists()) { full = ps[i] + "/" + argv0; if (ps[i][0] != '/') { - size_t bufferLen = 1024 * 8; + constexpr size_t bufferLen = 8_KiB; char buffer[bufferLen]; full = string(::getcwd(buffer, bufferLen)) + full; } diff --git a/src/odc/RowsCounter.h b/src/odc/RowsCounter.h index 8591a6f5..f33076e5 100644 --- a/src/odc/RowsCounter.h +++ b/src/odc/RowsCounter.h @@ -10,9 +10,7 @@ #pragma once -namespace eckit { -class PathName; -} +#include namespace odc { diff --git a/src/odc/WriterBufferingIterator.cc b/src/odc/WriterBufferingIterator.cc index 4c1b04fd..eb0e8e4e 100644 --- a/src/odc/WriterBufferingIterator.cc +++ b/src/odc/WriterBufferingIterator.cc @@ -189,7 +189,7 @@ double* WriterBufferingIterator::data() { } double& WriterBufferingIterator::data(size_t i) { ASSERT(initialisedColumns_); - ASSERT(i >= 0 && i < columns().size()); + ASSERT(i < columns().size()); return nextRow_[columnOffsets_[i]]; } diff --git a/src/odc/WriterDispatchingIterator.cc b/src/odc/WriterDispatchingIterator.cc index bc1b4e7e..db163f4e 100644 --- a/src/odc/WriterDispatchingIterator.cc +++ b/src/odc/WriterDispatchingIterator.cc @@ -19,29 +19,10 @@ using namespace odc::core; - -namespace { -// n.b. Duplicated from eckit::sql::expression::function::FunctionEQ::trimStringInDouble. -// TODO: Put somewhere better. -void trimStringInDouble(char*& p, size_t& len) { - len = 0; - for (; len < sizeof(double) && isprint(p[len]); ++len) - ; - for (; len > 0 && isspace(p[len - 1]); --len) - ; - size_t plen = len; - for (char* pp = p; isspace(*p) && p < pp + plen;) { - ++p; - --len; - } -} -} // namespace - namespace odc { //---------------------------------------------------------------------------------------------------------------------- - template WriterDispatchingIterator::WriterDispatchingIterator(OWNER& owner, int maxOpenFiles, bool append) : @@ -103,6 +84,23 @@ int WriterDispatchingIterator::setBitfieldColumn(size_t i template std::string WriterDispatchingIterator::generateFileName(const double* values, unsigned long count) { + // n.b. Duplicated from eckit::sql::expression::function::FunctionEQ::trimStringInDouble. + // Provided as static lambda because this .cc file is included in the header and even when the + // function is declared in an annonymos workspace the declaration is marked as unneeded and emits + // a warning. + // TODO: Put somewhere better. + static const auto trimStringInDouble = [](char*& p, size_t& len) { + len = 0; + for (; len < sizeof(double) && isprint(p[len]); ++len) + ; + for (; len > 0 && isspace(p[len - 1]); --len) + ; + size_t plen = len; + for (char* pp = p; isspace(*p) && p < pp + plen;) { + ++p; + --len; + } + }; std::string fileName(outputFileTemplate_); int diff(0); for (TemplateParameters::iterator it(templateParameters_.begin()); it != templateParameters_.end(); ++it) { diff --git a/src/odc/api/ColumnInfo.h b/src/odc/api/ColumnInfo.h index 12b21c1f..5ee185a7 100644 --- a/src/odc/api/ColumnInfo.h +++ b/src/odc/api/ColumnInfo.h @@ -39,13 +39,13 @@ struct ColumnInfo { }; /** Column name */ - std::string name; + std::string name{}; /** Column data type */ - ColumnType type; + ColumnType type{}; /** Size of a single decoded value in bytes */ - size_t decodedSize; + size_t decodedSize{}; /** List of bit and bit groups associated with a bitfield column */ - std::vector bitfield; + std::vector bitfield{}; }; //---------------------------------------------------------------------------------------------------------------------- diff --git a/src/odc/api/odc.cc b/src/odc/api/odc.cc index 4d42a119..624c61ad 100644 --- a/src/odc/api/odc.cc +++ b/src/odc/api/odc.cc @@ -327,7 +327,7 @@ int odc_close(const odc_reader_t* reader) { int odc_new_frame(odc_frame_t** frame, odc_reader_t* reader) { return wrapApiFunction([frame, reader] { ASSERT(reader); - (*frame) = new odc_frame_t{*reader, false}; + (*frame) = new odc_frame_t{*reader, false, {}, {}}; }); } @@ -835,7 +835,7 @@ int odc_encoder_set_data_array(odc_encoder_t* encoder, const void* data, long wi int odc_encoder_add_column(odc_encoder_t* encoder, const char* name, int type) { return wrapApiFunction([encoder, name, type] { ASSERT(encoder); - encoder->columnInfo.emplace_back(ColumnInfo{std::string(name), ColumnType(type)}); + encoder->columnInfo.emplace_back(ColumnInfo{std::string(name), ColumnType(type), {}, {}}); encoder->columnData.emplace_back(odc_encoder_t::EncodeColumn{0, 0}); }); } diff --git a/src/odc/codec/CodecOptimizer.h b/src/odc/codec/CodecOptimizer.h index 0e593982..24b841cc 100644 --- a/src/odc/codec/CodecOptimizer.h +++ b/src/odc/codec/CodecOptimizer.h @@ -98,6 +98,7 @@ int CodecOptimizer::setOptimalCodecs(core::MetaData& columns) { case api::STRING: { n = col.coder().numStrings(); ASSERT(n < 65536); + if (n == 1 && col.coder().dataSizeDoubles() == 1) codec = "constant_string"; else if (n == 1 && std::getenv("ODC_ENABLE_WRITING_LONG_STRING_CODEC") != NULL) @@ -106,7 +107,6 @@ int CodecOptimizer::setOptimalCodecs(core::MetaData& columns) { codec = "int8_string"; else if (n < 65536) codec = "int16_string"; - std::unique_ptr newCodec = core::CodecFactory::instance().build(codec, col.type()); if (codec == "constant_string") { diff --git a/src/odc/core/Table.cc b/src/odc/core/Table.cc index 90027c0d..4f85a1b9 100644 --- a/src/odc/core/Table.cc +++ b/src/odc/core/Table.cc @@ -397,7 +397,9 @@ Span Table::decodeSpan(const std::vector& columns) { // Do the decoding std::vector lastDecoded(ncols, 0); - double decodeBuffer[maxDoublesDecode]; + + std::vector decodeBufferVec(maxDoublesDecode); + auto decodeBuffer = decodeBufferVec.data(); for (size_t rowCount = 0; rowCount < nrows; ++rowCount) { diff --git a/src/odc/csv/TextReaderIterator.cc b/src/odc/csv/TextReaderIterator.cc index d949a361..2141c283 100644 --- a/src/odc/csv/TextReaderIterator.cc +++ b/src/odc/csv/TextReaderIterator.cc @@ -197,8 +197,10 @@ bool TextReaderIterator::next() { std::vector values(S::split(delimiter_, line)); size_t nCols = values.size(); - if (nCols == 0) - return !(noMore_ = true); + if (nCols == 0) { + noMore_ = true; + return false; + } ASSERT(nCols == columns().size()); for (size_t i = 0; i < nCols; ++i) { diff --git a/src/odc/tools/ODAHeaderTool.cc b/src/odc/tools/ODAHeaderTool.cc index c239f982..b743cf4c 100644 --- a/src/odc/tools/ODAHeaderTool.cc +++ b/src/odc/tools/ODAHeaderTool.cc @@ -55,10 +55,6 @@ class OffsetsPrinter : public MDPrinter { Length length(tbl.nextPosition() - tbl.startPosition()); o << offset << " " << length << " " << tbl.rowCount() << " " << tbl.columnCount() << std::endl; } - -private: - - unsigned long headerCount_; }; class DDLPrinter : public MDPrinter { diff --git a/src/odc/tools/SplitTool.cc b/src/odc/tools/SplitTool.cc index 38b760d9..9c9692a7 100644 --- a/src/odc/tools/SplitTool.cc +++ b/src/odc/tools/SplitTool.cc @@ -31,7 +31,7 @@ using namespace std; namespace odc { namespace tool { -SplitTool::SplitTool(int argc, char* argv[]) : Tool(argc, argv), sort_(false), maxOpenFiles_(200) { +SplitTool::SplitTool(int argc, char* argv[]) : Tool(argc, argv), maxOpenFiles_(200), sort_(false) { registerOptionWithArgument("-maxopenfiles"); } diff --git a/src/odc/tools/TestInt16_MissingCodec.cc b/src/odc/tools/TestInt16_MissingCodec.cc index 1610da53..5242ac53 100644 --- a/src/odc/tools/TestInt16_MissingCodec.cc +++ b/src/odc/tools/TestInt16_MissingCodec.cc @@ -66,8 +66,8 @@ class MockReaderIterator3 { data_ = columns_[0]->coder().missingValue(); break; default: - return !(noMore_ = true); - break; + noMore_ = true; + return false; } return true; } diff --git a/src/odc/tools/TestIntegerValues.cc b/src/odc/tools/TestIntegerValues.cc index b1c2fb60..f8b53a12 100644 --- a/src/odc/tools/TestIntegerValues.cc +++ b/src/odc/tools/TestIntegerValues.cc @@ -53,9 +53,7 @@ static void test() { } std::cout << std::endl; - int nrows = 0; for (; it != odb.end(); ++it) { - ++nrows; for (size_t i = 0; i < it->columns().size(); ++i) { // float nr = ((*it)[i]); /// <- WRONG! double nr = ((*it)[i]); diff --git a/tests/api/odc_encode_custom.cc b/tests/api/odc_encode_custom.cc index c979cc97..4a8ce3c8 100644 --- a/tests/api/odc_encode_custom.cc +++ b/tests/api/odc_encode_custom.cc @@ -69,24 +69,24 @@ void create_scratch_data(size_t nrows, char data0[][8], int64_t data1[], char da long integer_pool[] = {1234, 4321, Settings::integerMissingValue()}; int integer_pool_size = sizeof(integer_pool) / sizeof(integer_pool[0]); - long missing_integers[nrows]; - cycle_longs(missing_integers, nrows, integer_pool, integer_pool_size); + std::vector missing_integers(nrows); + cycle_longs(missing_integers.data(), nrows, integer_pool, integer_pool_size); // Prepare the list of double values, including the missing value double double_pool[] = {12.34, 43.21, Settings::doubleMissingValue()}; int double_pool_size = sizeof(double_pool) / sizeof(double_pool[0]); - double missing_doubles[nrows]; - cycle_doubles(missing_doubles, nrows, double_pool, double_pool_size); + std::vector missing_doubles(nrows); + cycle_doubles(missing_doubles.data(), nrows, double_pool, double_pool_size); // Prepare the list of bitfield values long bitfield_pool[] = {Ob00000001, Ob00001011, Ob01101011}; int bitfield_pool_size = sizeof(bitfield_pool) / sizeof(bitfield_pool[0]); - long bitfield_values[nrows]; - cycle_longs(bitfield_values, nrows, bitfield_pool, bitfield_pool_size); + std::vector bitfield_values(nrows); + cycle_longs(bitfield_values.data(), nrows, bitfield_pool, bitfield_pool_size); // Fill in the passed data arrays with scratch values for (size_t i = 0; i < nrows; i++) { diff --git a/tests/api/read.cc b/tests/api/read.cc index 54fd03c7..e164445c 100644 --- a/tests/api/read.cc +++ b/tests/api/read.cc @@ -1139,7 +1139,7 @@ CASE("Where Span interface is used to read values without decoding") { } // Check string values - for (const std::string val : expver_vals) { + for (const auto& val : expver_vals) { EXPECT(val == "xxxx"); } diff --git a/tests/c_api/encode.cc b/tests/c_api/encode.cc index 48a7904c..13a603ce 100644 --- a/tests/c_api/encode.cc +++ b/tests/c_api/encode.cc @@ -319,7 +319,6 @@ CASE("Encode data with custom stride") { const int ncols = 5; // Construct some source data - long icol[2 * nrows] = {1111, 2222, 3333, 4444, 5555, 6666, 7777, 8888, 9999, 0}; long bcol[2 * nrows] = {1101, 2202, 3303, 4404, 5505, 6606, 7707, 8808, 9909, 0}; char scol[2 * nrows][3 * sizeof(double)] = {0}; @@ -421,7 +420,6 @@ CASE("Encode with more rows that fit inside a table") { const int ncols = 5; // Construct some source data - long icol[nrows] = {1111, 2222, 3333, 4444, 5555, 6666, 7777, 8888, 9999, 0}; long bcol[nrows] = {1101, 2202, 3303, 4404, 5505, 6606, 7707, 8808, 9909, 0}; char scol[nrows][3 * sizeof(double)] = {0};