diff --git a/externals/coda-oss/UnitTest/UnitTest.vcxproj b/externals/coda-oss/UnitTest/UnitTest.vcxproj
index 020ee7b39..d79dab6f9 100644
--- a/externals/coda-oss/UnitTest/UnitTest.vcxproj
+++ b/externals/coda-oss/UnitTest/UnitTest.vcxproj
@@ -23,7 +23,6 @@
DynamicLibrary
true
v143
- false
Unicode
@@ -31,7 +30,6 @@
false
v143
true
- false
Unicode
@@ -97,6 +95,7 @@
true
/Zc:__cplusplus %(AdditionalOptions)
AdvancedVectorExtensions2
+ Speed
Windows
diff --git a/externals/coda-oss/modules/c++/logging/source/Setup.cpp b/externals/coda-oss/modules/c++/logging/source/Setup.cpp
index 3c1c36363..345c6b516 100644
--- a/externals/coda-oss/modules/c++/logging/source/Setup.cpp
+++ b/externals/coda-oss/modules/c++/logging/source/Setup.cpp
@@ -53,8 +53,7 @@ logging::setupLogger(const path& program_,
// setup logging formatter
std::unique_ptr formatter;
const auto logFile = logFile_.string();
- auto file = logFile;
- str::lower(file);
+ const auto file = str::lower(logFile);
if (str::endsWith(file, ".xml"))
{
formatter.reset(
diff --git a/externals/coda-oss/modules/c++/plugin/include/plugin/ErrorHandler.h b/externals/coda-oss/modules/c++/plugin/include/plugin/ErrorHandler.h
index 234e6c5a1..248b61f46 100644
--- a/externals/coda-oss/modules/c++/plugin/include/plugin/ErrorHandler.h
+++ b/externals/coda-oss/modules/c++/plugin/include/plugin/ErrorHandler.h
@@ -49,7 +49,7 @@ class CODA_OSS_API ErrorHandler
virtual void onPluginError(except::Context& c) = 0;
};
-class CODA_OSS_API DefaultErrorHandler final : public ErrorHandler
+class CODA_OSS_API DefaultErrorHandler : public ErrorHandler
{
public:
DefaultErrorHandler(logging::LoggerPtr logger = logging::LoggerPtr());
diff --git a/externals/coda-oss/modules/c++/str/include/str/Manip.h b/externals/coda-oss/modules/c++/str/include/str/Manip.h
index 0b48673a5..c9c96eb60 100644
--- a/externals/coda-oss/modules/c++/str/include/str/Manip.h
+++ b/externals/coda-oss/modules/c++/str/include/str/Manip.h
@@ -1,4 +1,4 @@
-/* =========================================================================
+/* =========================================================================
* This file is part of str-c++
* =========================================================================
*
@@ -34,6 +34,7 @@
#include "coda_oss/CPlusPlus.h"
#include "coda_oss/string.h"
#include "str/Convert.h"
+#include "str/W1252string.h"
namespace str
{
@@ -177,10 +178,71 @@ CODA_OSS_API std::vector split(const std::string& s,
const std::string& splitter = " ",
size_t maxSplit = std::string::npos);
+/***********************************************************************************/
//! Uses std::transform to convert all chars to lower case
//! Uses std::transform to convert all chars to upper case
-CODA_OSS_API void lower(std::string& s);
-CODA_OSS_API void upper(std::string& s);
+//CODA_OSS_API void lower(std::string& s);
+//CODA_OSS_API void upper(std::string& s);
+//
+// Using std::transform() with ::toupper() is considerably slower than a lookup-table
+CODA_OSS_API void ascii_lower(std::string& s);
+inline void lower(std::string& s)
+{
+ ascii_lower(s);
+}
+inline std::string lower(const std::string& s)
+{
+ std::string retval = s;
+ lower(retval);
+ return retval;
+}
+
+CODA_OSS_API void ascii_upper(std::string& s);
+inline void upper(std::string& s)
+{
+ ascii_upper(s);
+}
+inline std::string upper(const std::string& s)
+{
+ std::string retval = s;
+ upper(retval);
+ return retval;
+}
+
+// At this point, you might want to `lower()` and `upper()` for UTF-8 and/or
+// Windows-1252. That can be done, but ... our needs are mostly English (99.9%)
+// with a very occassional smattering of French (Canada). We've gotten by this
+// long without being able to upper/lower 'ä' and 'Ä' and there's no current
+// requirement to do so.
+//
+// Furthermore, while Windows-1252 is easy as it's a single-byte encoding and
+// covers many european languages, the standard is UTF-8.
+// Upper/lower-casing in Unicode is quite a bit more complicated as there can be
+// numerous rules for various languages. For example, in German, the "old
+// rules" where that 'ß' was uppercased to "SS"; however, there is now a 'ẞ'.
+// And then there are semantics: in German, no word can begin with 'ß' (or 'ẞ')
+// making "ßanything" rather non-sensical.
+//
+// So for now (until there is a real use case), just "define these problems
+// away" by not implementing `w1252_lower()`, `utf8_upper()`, etc.
+/*
+CODA_OSS_API void w1252_lower(std::string& s);
+CODA_OSS_API void w1252_upper(std::string& s);
+CODA_OSS_API void lower(str::W1252string& s);
+CODA_OSS_API void upper(str::W1252string& s);
+
+CODA_OSS_API void utf8_lower(std::string& s);
+CODA_OSS_API void utf8_upper(std::string& s);
+CODA_OSS_API void lower(coda_oss::u8string& s);
+CODA_OSS_API void upper(coda_oss::u8string& s);
+*/
+
+// I've already got these hooked up, keep the code around ... long ugly
+// names to discourage use.
+CODA_OSS_API str::Windows1252_T to_w1252_upper(str::Windows1252_T);
+CODA_OSS_API str::Windows1252_T to_w1252_lower(str::Windows1252_T);
+
+/***********************************************************************************/
/*!
* Replaces any characters that are invalid in XML (&, <, >, ', ") with their
diff --git a/externals/coda-oss/modules/c++/str/source/Encoding.cpp b/externals/coda-oss/modules/c++/str/source/Encoding.cpp
index eacc016d8..80603dae9 100644
--- a/externals/coda-oss/modules/c++/str/source/Encoding.cpp
+++ b/externals/coda-oss/modules/c++/str/source/Encoding.cpp
@@ -33,6 +33,7 @@
#include
#include
#include
+#include
#include "gsl/gsl.h"
#include "config/compiler_extensions.h"
@@ -65,59 +66,58 @@ CODA_OSS_disable_warning_pop
// Need to look up characters from \x80 (EURO SIGN) to \x9F (LATIN CAPITAL LETTER Y WITH DIAERESIS)
// in a map: http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1252.TXT
-inline coda_oss::u8string utf8_(uint32_t i)
+inline coda_oss::u8string utf8_(char32_t i)
{
const auto ch = gsl::narrow(i);
return str::to_u8string(std::u32string{ch});
}
-static const auto& Windows1252_x80_x9F_to_u8string()
-{
- static const std::map retval {
- {0x80, utf8_(0x20AC) } // EURO SIGN
- // , {0x81, replacement_character } // UNDEFINED
- , {0x82, utf8_(0x201A) } // SINGLE LOW-9 QUOTATION MARK
- , {0x83, utf8_(0x0192) } // LATIN SMALL LETTER F WITH HOOK
- , {0x84, utf8_(0x201E) } // DOUBLE LOW-9 QUOTATION MARK
- , {0x85, utf8_(0x2026) } // HORIZONTAL ELLIPSIS
- , {0x86, utf8_(0x2020) } // DAGGER
- , {0x87, utf8_(0x2021) } // DOUBLE DAGGER
- , {0x88, utf8_(0x02C6) } // MODIFIER LETTER CIRCUMFLEX ACCENT
- , {0x89, utf8_(0x2030) } // PER MILLE SIGN
- , {0x8A, utf8_(0x0160) } // LATIN CAPITAL LETTER S WITH CARON
- , {0x8B, utf8_(0x2039) } // SINGLE LEFT-POINTING ANGLE QUOTATION MARK
- , {0x8C, utf8_(0x0152) } // LATIN CAPITAL LIGATURE OE
- //, {0x8D, replacement_character } // UNDEFINED
- , {0x8E, utf8_(0x017D) } // LATIN CAPITAL LETTER Z WITH CARON
- //, {0x8F, replacement_character } // UNDEFINED
- //, {0x90, replacement_character } // UNDEFINED
- , {0x91, utf8_(0x2018) } // LEFT SINGLE QUOTATION MARK
- , {0x92, utf8_(0x2019) } // RIGHT SINGLE QUOTATION MARK
- , {0x93, utf8_(0x201C) } // LEFT DOUBLE QUOTATION MARK
- , {0x94, utf8_(0x201D) } // RIGHT DOUBLE QUOTATION MARK
- , {0x95, utf8_(0x2022) } // BULLET
- , {0x96, utf8_(0x2013) } // EN DASH
- , {0x97, utf8_(0x2014) } // EM DASH
- , {0x98, utf8_(0x02DC) } // SMALL TILDE
- , {0x99, utf8_(0x2122) } // TRADE MARK SIGN
- , {0x9A, utf8_(0x0161) } // LATIN SMALL LETTER S WITH CARON
- , {0x9B, utf8_(0x203A) } // SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
- , {0x9C, utf8_(0x0153) } // LATIN SMALL LIGATURE OE
- //, {0x9D, replacement_character } // UNDEFINED
- , {0x9E, utf8_(0x017E) } // LATIN SMALL LETTER Z WITH CARON
- , {0x9F, utf8_(0x0178) } // LATIN CAPITAL LETTER Y WITH DIAERESIS
+static const auto& Windows1252_x80_x9F_to_u8string_()
+{
+ static const std::map retval{
+ {U'\x80', utf8_(U'\x20AC')} // EURO SIGN
+ // , {U'\x81, replacement_character } // UNDEFINED
+ , {U'\x82', utf8_(U'\x201A') } // SINGLE LOW-9 QUOTATION MARK
+ , {U'\x83', utf8_(U'\x0192') } // LATIN SMALL LETTER F WITH HOOK
+ , {U'\x84', utf8_(U'\x201E') } // DOUBLE LOW-9 QUOTATION MARK
+ , {U'\x85', utf8_(U'\x2026') } // HORIZONTAL ELLIPSIS
+ , {U'\x86', utf8_(U'\x2020') } // DAGGER
+ , {U'\x87', utf8_(U'\x2021') } // DOUBLE DAGGER
+ , {U'\x88', utf8_(U'\x02C6') } // MODIFIER LETTER CIRCUMFLEX ACCENT
+ , {U'\x89', utf8_(U'\x2030') } // PER MILLE SIGN
+ , {U'\x8A', utf8_(U'\x0160') } // LATIN CAPITAL LETTER S WITH CARON
+ , {U'\x8B', utf8_(U'\x2039') } // SINGLE LEFT-POINTING ANGLE QUOTATION MARK
+ , {U'\x8C', utf8_(U'\x0152') } // LATIN CAPITAL LIGATURE OE
+ //, {U'\x8D, replacement_character } // UNDEFINED
+ , {U'\x8E', utf8_(U'\x017D') } // LATIN CAPITAL LETTER Z WITH CARON
+ //, {U'\x8F, replacement_character } // UNDEFINED
+ //, {U'\x90, replacement_character } // UNDEFINED
+ , {U'\x91', utf8_(U'\x2018') } // LEFT SINGLE QUOTATION MARK
+ , {U'\x92', utf8_(U'\x2019') } // RIGHT SINGLE QUOTATION MARK
+ , {U'\x93', utf8_(U'\x201C') } // LEFT DOUBLE QUOTATION MARK
+ , {U'\x94', utf8_(U'\x201D') } // RIGHT DOUBLE QUOTATION MARK
+ , {U'\x95', utf8_(U'\x2022') } // BULLET
+ , {U'\x96', utf8_(U'\x2013') } // EN DASH
+ , {U'\x97', utf8_(U'\x2014') } // EM DASH
+ , {U'\x98', utf8_(U'\x02DC') } // SMALL TILDE
+ , {U'\x99', utf8_(U'\x2122') } // TRADE MARK SIGN
+ , {U'\x9A', utf8_(U'\x0161') } // LATIN SMALL LETTER S WITH CARON
+ , {U'\x9B', utf8_(U'\x203A') } // SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
+ , {U'\x9C', utf8_(U'\x0153') } // LATIN SMALL LIGATURE OE
+ //, {U'\x9D, replacement_character } // UNDEFINED
+ , {U'\x9E', utf8_(U'\x017E') } // LATIN SMALL LETTER Z WITH CARON
+ , {U'\x9F', utf8_(U'\x0178') } // LATIN CAPITAL LETTER Y WITH DIAERESIS
};
return retval;
}
-
static auto Windows1252_to_u8string()
{
- auto retval = Windows1252_x80_x9F_to_u8string();
+ auto retval = Windows1252_x80_x9F_to_u8string_();
// Add the ISO8859-1 values to the map too. 1) We're already looking
// in the map anyway for Windows-1252 characters. 2) Need map
// entires for conversion from UTF-8 to Windows-1252.
- for (std::u32string::value_type ch = 0xA0; ch <= 0xff; ch++)
+ for (char32_t ch = U'\xA0'; ch <= U'\xff'; ch++)
{
// ISO8859-1 can be converted to UTF-8 with bit-twiddling
@@ -186,7 +186,14 @@ static void fromWindows1252_(str::W1252string::value_type ch, std::basic_string<
// If the input text contains a character that isn't defined in Windows-1252; return a
// "replacement character." Yes, this will **corrupt** the input data as information is lost:
// https://en.wikipedia.org/wiki/Specials_(Unicode_block)#Replacement_character
- static const coda_oss::u8string replacement_character = utf8_(0xfffd);
+ //
+ // Or ... https://en.wikipedia.org/wiki/Windows-1252
+ // > According to the information on Microsoft's and the Unicode
+ // > Consortium's websites, positions 81, 8D, 8F, 90, and 9D are
+ // > unused; however, the Windows API `MultiByteToWideChar` maps these
+ // > to the corresponding C1 control codes. The "best fit" mapping
+ // > documents this behavior, too.
+ static const coda_oss::u8string replacement_character = utf8_(U'\xfffd');
append(result, replacement_character);
}
else
@@ -229,7 +236,7 @@ inline void w1252to32(str::W1252string::const_pointer p, size_t sz, std::u32stri
}
template
-std::map kv_to_vk(const std::map& kv)
+auto kv_to_vk(const std::map& kv)
{
std::map retval;
for (const auto& p : kv)
diff --git a/externals/coda-oss/modules/c++/str/source/Manip.cpp b/externals/coda-oss/modules/c++/str/source/Manip.cpp
index f8dbce7db..1d6bae1c2 100644
--- a/externals/coda-oss/modules/c++/str/source/Manip.cpp
+++ b/externals/coda-oss/modules/c++/str/source/Manip.cpp
@@ -32,6 +32,7 @@
#include
#include
#include
+#include
#include "gsl/gsl.h"
@@ -40,7 +41,7 @@
namespace
{
-char transformCheck(int c, int (*transform)(int))
+inline char transformCheck(int c, int (*transform)(int))
{
// Ensure the character can be represented
// as an unsigned char or is 'EOF', as the
@@ -56,12 +57,12 @@ char transformCheck(int c, int (*transform)(int))
}
}
-char tolowerCheck(char c)
+inline char tolowerCheck(char c)
{
return transformCheck(c, tolower);
}
-char toupperCheck(char c)
+inline char toupperCheck(char c)
{
return transformCheck(c, toupper);
}
@@ -239,9 +240,8 @@ bool isAlphanumeric(const std::string& s)
bool isAsciiPrintable(const std::string& s)
{
- for (const auto& ch : s)
+ for (const auto& c : s)
{
- char c = ch;
if (c < 32 || c > 126)
return false;
}
@@ -290,24 +290,136 @@ std::vector split(const std::string& s,
return vec;
}
-template
-inline void transform(std::basic_string& s, Fn f)
+
+// Calling ::toupper() can be slow as the CRT might check for locales.
+// Since we only have 256 values, a lookup table is very fast and doesn't
+// use much memory.
+static const auto& make_lookup(std::array& result,
+ char (*to)(char))
+{
+ // For each of 256 values, record the corresponding tolower/toupper value;
+ // this makes converting very fast as no checking or arithmetic must be done.
+ for (size_t i = 0; i <= 0xff; i++)
+ {
+ const auto ch = to(static_cast(i));
+ result[i] = static_cast(ch);
+ }
+ return result;
+}
+
+template
+static void do_lookup(std::basic_string& s, const std::array& lookup)
{
- (void) std::transform(s.begin(), s.end(), s.begin(), f);
+ for (auto& ch : s)
+ {
+ const auto i = static_cast(ch);
+ ch = static_cast(lookup[i]);
+ }
}
-void lower(std::string& s)
+
+void ascii_upper(std::string& s)
{
- transform(s, tolowerCheck);
+ static std::array lookup_;
+ static const auto& lookup = make_lookup(lookup_, toupperCheck);
+ do_lookup(s, lookup);
+}
+
+void ascii_lower(std::string& s)
+{
+ static std::array lookup_;
+ static const auto& lookup = make_lookup(lookup_, tolowerCheck);
+ do_lookup(s, lookup);
+}
+
+inline char to_w1252_upper_(char ch)
+{
+ if ((ch >= 'a') && (ch <= 'z'))
+ {
+ return ch ^ 0x20; // ('a' - 'A');
+ }
+
+ // See chart at: https://en.wikipedia.org/wiki/Windows-1252
+ constexpr uint8_t s_with_caron = 0x9a /* š */;
+ constexpr uint8_t oe = 0x9c /* œ */;
+ constexpr uint8_t z_with_caron = 0x9e /* ž */;
+ constexpr uint8_t a_with_grave = 0xe0 /* à */;
+ constexpr uint8_t o_with_diaeresis = 0xf6 /* ö */;
+ constexpr uint8_t o_with_slash = 0xf8 /* ø */;
+ constexpr uint8_t small_thorn = 0xfe /* þ */;
+ constexpr uint8_t y_with_diaeresis = 0xff /* ÿ */;
+
+ const auto u8 = static_cast(ch);
+ if ((u8 == s_with_caron) || (u8 == oe) || (u8 == z_with_caron))
+ {
+ return ch ^ 0x10;
+ }
+ if ((u8 >= a_with_grave) && (u8 <= o_with_diaeresis))
+ {
+ return ch ^ 0x20;
+ }
+ if ((u8 >= o_with_slash) && (u8 <= small_thorn))
+ {
+ return ch ^ 0x20;
+ }
+ if (u8 == y_with_diaeresis)
+ {
+ constexpr uint8_t Y_with_diaeresis = 0x9f /* Ÿ */;
+ return Y_with_diaeresis;
+ }
+
+ return ch;
+}
+str::Windows1252_T to_w1252_upper(str::Windows1252_T ch)
+{
+ const auto retval = to_w1252_upper_(static_cast(ch));
+ return static_cast(retval);
+}
+
+inline char to_w1252_lower_(char ch)
+{
+ if ((ch >= 'A') && (ch <= 'Z'))
+ {
+ return ch | 0x20;
+ }
+
+ constexpr uint8_t S_with_caron = 0x8a /* Š */;
+ constexpr uint8_t OE = 0x8c /*Œ */;
+ constexpr uint8_t Z_with_caron = 0x8e /* Ž */;
+ constexpr uint8_t Y_with_diaeresis = 0x9f /* Ÿ */;
+ constexpr uint8_t A_with_grave = 0xc0 /* À */;
+ constexpr uint8_t O_with_diaeresis = 0xd6 /* Ö */;
+ constexpr uint8_t O_with_slash = 0xd8 /* Ø */;
+ constexpr uint8_t capital_thorn = 0xde /* Þ */;
+
+ const auto u8 = static_cast(ch);
+ if ((u8 == S_with_caron) || (u8 == OE) || (u8 == Z_with_caron))
+ {
+ return ch | 0x10;
+ }
+ if (u8 == Y_with_diaeresis)
+ {
+ constexpr uint8_t y_with_diaeresis = 0xff /* ÿ */;
+ return y_with_diaeresis;
+ }
+ if ((u8 >= A_with_grave) && (u8 <= O_with_diaeresis))
+ {
+ return ch | 0x20;
+ }
+ if ((u8 >= O_with_slash) && (u8 <= capital_thorn))
+ {
+ return ch | 0x20;
+ }
+ return ch;
}
-void upper(std::string& s)
+str::Windows1252_T to_w1252_lower(str::Windows1252_T ch)
{
- transform(s, toupperCheck);
+ const auto retval = to_w1252_lower_(static_cast(ch));
+ return static_cast(retval);
}
void escapeForXML(std::string& str)
{
- // & needs to be first or else it'll mess up the other characters that we
- // replace
+ // & needs to be first or else it'll mess up the other characters that we replace
replaceAll(str, "&", "&");
replaceAll(str, "<", "<");
replaceAll(str, ">", ">");
diff --git a/externals/coda-oss/modules/c++/str/unittests/test_base_convert.cpp b/externals/coda-oss/modules/c++/str/unittests/test_base_convert.cpp
index 3b951015a..c2ecf4f36 100644
--- a/externals/coda-oss/modules/c++/str/unittests/test_base_convert.cpp
+++ b/externals/coda-oss/modules/c++/str/unittests/test_base_convert.cpp
@@ -216,21 +216,18 @@ TEST_CASE(test_string_to_u8string_iso8859_1)
}
}
-template
-static void test_change_case_(const std::string& testName, const TString& lower, const TString& upper)
+template
+static void test_change_case_(const std::string& testName,
+ const std::basic_string& lower, const std::basic_string& upper)
{
- auto s = upper;
- str::lower(s);
+ auto s = str::lower(upper);
TEST_ASSERT(s == lower);
- s = lower;
- str::upper(s);
+ s = str::upper(lower);
TEST_ASSERT(s == upper);
- s = upper;
- str::upper(s);
+ s = str::upper(upper);
TEST_ASSERT(s == upper);
- s = lower;
- str::lower(s);
+ s = str::lower(lower);
TEST_ASSERT(s == lower);
}
TEST_CASE(test_change_case)
@@ -243,14 +240,16 @@ TEST_CASE(test_change_case)
//const std::wstring abc_w = L"abc";
//test_change_case_(testName, abc_w, ABC_w);
- //// Yes, this can really come up, "non classifié" is French (Canadian) for "unclassified".
- //const std::string DEF_1252{'D', '\xc9', 'F'}; // "DÉF" Windows-1252
- //const auto DEF8 = from_windows1252(DEF_1252);
+ // Yes, this can really come up, "non classifié" is French (Canadian) for "unclassified".
+ const std::string DEF_1252_{'D', '\xc9', 'F'}; // "DÉF" Windows-1252
+ const auto DEF_1252 = str::str(DEF_1252_);
+ const auto DEF8 = str::to_u8string(DEF_1252);
- //const std::string def_1252{'d', '\xe9', 'f'}; // "déf" Windows-1252
- //const auto def8 = from_windows1252(def_1252);
+ const std::string def_1252_{'d', '\xe9', 'f'}; // "déf" Windows-1252
+ const auto def_1252 = str::str(def_1252_);
+ const auto def8 = str::to_u8string(def_1252);
- ////test_change_case_(testName, def, DEF);
+ //test_change_case_(testName, def8, DEF8);
//test_change_case_(testName, def_1252, DEF_1252);
}
diff --git a/externals/coda-oss/modules/c++/str/unittests/test_str.cpp b/externals/coda-oss/modules/c++/str/unittests/test_str.cpp
index 2d00862d8..eb4821608 100644
--- a/externals/coda-oss/modules/c++/str/unittests/test_str.cpp
+++ b/externals/coda-oss/modules/c++/str/unittests/test_str.cpp
@@ -57,16 +57,78 @@ TEST_CASE(testData)
TEST_CASE(testUpper)
{
- std::string s = "test-something1";
+ const std::string s_ = "test-something1";
+ std::string s = s_;
+ TEST_ASSERT(str::eq(s, "TEST-SOMETHING1"));
str::upper( s);
TEST_ASSERT_EQ(s, "TEST-SOMETHING1");
+
+ //#if _WIN32
+ //s = "<×àa`öo\"øo/þb÷>";
+ //str::w1252_upper(s);
+ //TEST_ASSERT_EQ(s, "<×ÀA`ÖO\"ØO/ÞB÷>");
+ //#endif
+}
+
+TEST_CASE(test_toupper)
+{
+ for (uint16_t i = 0x20; i <= 0xff; i++) // uint16_t to avoid wrap-around
+ {
+ const auto w1252 = static_cast(i);
+ const auto w1252_upper = str::to_w1252_upper(w1252);
+
+ const auto w1252_lower = w1252 == w1252_upper ? w1252 : str::to_w1252_lower(w1252_upper); // round-trip
+ TEST_ASSERT_EQ(static_cast(w1252), static_cast(w1252_lower));
+
+ if (i <= 0x7f) // ASCII
+ {
+ const auto ch = static_cast(i);
+ const auto upper = toupper(ch);
+ TEST_ASSERT_EQ(static_cast(upper), static_cast(w1252_upper));
+
+ const auto lower = ch == upper ? ch : tolower(upper); // round-trip
+ TEST_ASSERT_EQ(ch, lower);
+ TEST_ASSERT_EQ(static_cast(lower), static_cast(w1252_lower));
+ }
+ }
}
TEST_CASE(testLower)
{
- std::string s = "TEST1";
- str::lower( s);
+ const std::string s_ = "TEST1";
+ std::string s = s_;
+ TEST_ASSERT(str::eq(s, "test1"));
+ str::lower(s);
TEST_ASSERT_EQ(s, "test1");
+
+ //#if _WIN32
+ //s = "[×ÀÖØÞ÷]";
+ //str::w1252_lower(s);
+ //TEST_ASSERT_EQ(s, "[×àöøþ÷]");
+ //#endif
+}
+
+TEST_CASE(test_tolower)
+{
+ for (uint16_t i = 0x20; i <= 0xff; i++) // uint16_t to avoid wrap-around
+ {
+ const auto w1252 = static_cast(i);
+ const auto w1252_lower = str::to_w1252_lower(w1252);
+
+ const auto w1252_upper = w1252 == w1252_lower ? w1252 : str::to_w1252_upper(w1252_lower); // round-trip
+ TEST_ASSERT_EQ(static_cast(w1252), static_cast(w1252_upper));
+
+ if (i <= 0x7f) // ASCII
+ {
+ const auto ch = static_cast(i);
+ const auto lower = tolower(ch);
+ TEST_ASSERT_EQ(static_cast(lower), static_cast(w1252_lower));
+
+ const auto upper = ch == lower ? ch : toupper(lower); // round-trip
+ TEST_ASSERT_EQ(ch, upper);
+ TEST_ASSERT_EQ(static_cast(upper), static_cast(w1252_upper));
+ }
+ }
}
TEST_CASE(test_eq_ne)
@@ -309,7 +371,9 @@ TEST_MAIN(
TEST_CHECK(testTrim);
TEST_CHECK(testData);
TEST_CHECK(testUpper);
+ TEST_CHECK(test_toupper);
TEST_CHECK(testLower);
+ TEST_CHECK(test_tolower);
TEST_CHECK(test_eq_ne);
TEST_CHECK(testReplace);
TEST_CHECK(testReplaceAllInfinite);
diff --git a/externals/coda-oss/modules/c++/sys/include/sys/Path.h b/externals/coda-oss/modules/c++/sys/include/sys/Path.h
index d7d950202..74d78af5c 100644
--- a/externals/coda-oss/modules/c++/sys/include/sys/Path.h
+++ b/externals/coda-oss/modules/c++/sys/include/sys/Path.h
@@ -27,13 +27,15 @@
#include
#include
#include
+#include
#include "config/Exports.h"
-
#include
+#include "coda_oss/span.h"
#include "sys/OS.h"
#include "sys/filesystem.h"
+#include "sys/Span.h"
/*!
@@ -295,6 +297,16 @@ class CODA_OSS_API Path
std::ostream& operator<<(std::ostream& os, const sys::Path& path);
std::istream& operator>>(std::istream& os, sys::Path& path);
+
+// Convert between collections of paths as strings and sys::filesystem::path
+CODA_OSS_API std::vector convertPaths(coda_oss::span);
+CODA_OSS_API std::vector convertPaths(coda_oss::span);
+template
+inline auto convertPaths(const std::vector& paths)
+{
+ return convertPaths(make_span(paths));
+}
+
}
#endif // CODA_OSS_sys_Path_h_INCLUDED_
diff --git a/externals/coda-oss/modules/c++/sys/source/AbstractOS.cpp b/externals/coda-oss/modules/c++/sys/source/AbstractOS.cpp
index dd22c3786..436e12bb6 100644
--- a/externals/coda-oss/modules/c++/sys/source/AbstractOS.cpp
+++ b/externals/coda-oss/modules/c++/sys/source/AbstractOS.cpp
@@ -86,29 +86,14 @@ AbstractOS::search(const std::vector& searchPaths,
return elementsFound;
}
-inline auto convert(const std::vector& paths)
-{
- std::vector retval;
- std::transform(paths.begin(), paths.end(), std::back_inserter(retval),
- [](const fs::path& p) { return p.string(); });
- return retval;
-}
-inline auto convert(const std::vector& paths)
-{
- std::vector retval;
- std::transform(paths.begin(), paths.end(), std::back_inserter(retval),
- [](const auto& p) { return p; });
- return retval;
-}
-
std::vector AbstractOS::search(
const std::vector& searchPaths,
const std::string& fragment,
const std::string& extension,
bool recursive) const
{
- const auto results = search(convert(searchPaths), fragment, extension, recursive);
- return convert(results);
+ const auto results = search(convertPaths(searchPaths), fragment, extension, recursive);
+ return convertPaths(results);
}
void AbstractOS::remove(const std::string& path) const
diff --git a/externals/coda-oss/modules/c++/sys/source/DateTime.cpp b/externals/coda-oss/modules/c++/sys/source/DateTime.cpp
index b6669002d..0679aed62 100644
--- a/externals/coda-oss/modules/c++/sys/source/DateTime.cpp
+++ b/externals/coda-oss/modules/c++/sys/source/DateTime.cpp
@@ -169,15 +169,13 @@ char* strptime(const char *buf, const char *fmt, struct tm& tm, double& millis)
// Full name.
len = DAY[i].size();
std::string day(bp, len);
- str::lower(day);
- if (day == DAY[i])
+ if (str::eq(day, DAY[i]))
break;
// Abbreviated name.
len = AB_DAY[i].size();
day = std::string(bp, len);
- str::lower(day);
- if (day == AB_DAY[i])
+ if (str::eq(day, AB_DAY[i]))
break;
}
@@ -202,15 +200,13 @@ char* strptime(const char *buf, const char *fmt, struct tm& tm, double& millis)
// Full name.
len = MONTH[i].size();
std::string month(bp, len);
- str::lower(month);
- if (month == MONTH[i])
+ if (str::eq(month, MONTH[i]))
break;
// Abbreviated name.
len = AB_MONTH[i].size();
month = std::string(bp, len);
- str::lower(month);
- if (month == AB_MONTH[i])
+ if (str::eq(month, AB_MONTH[i]))
break;
}
@@ -467,9 +463,7 @@ std::string sys::DateTime::dayOfWeekToStringAbbr(int dayOfWeek)
int sys::DateTime::monthToValue(const std::string& month)
{
- std::string m = month;
- str::lower(m);
-
+ const auto m = str::lower(month);
if (str::startsWith(m, "jan"))
return 1;
else if (str::startsWith(m, "feb"))
@@ -501,9 +495,7 @@ int sys::DateTime::monthToValue(const std::string& month)
int sys::DateTime::dayOfWeekToValue(const std::string& dayOfWeek)
{
- std::string d = dayOfWeek;
- str::lower(d);
-
+ const auto d = str::lower(dayOfWeek);
if (str::startsWith(d, "sun"))
return 1;
else if (str::startsWith(d, "mon"))
diff --git a/externals/coda-oss/modules/c++/sys/source/FileFinder.cpp b/externals/coda-oss/modules/c++/sys/source/FileFinder.cpp
index b33cc47c4..7edf1a512 100644
--- a/externals/coda-oss/modules/c++/sys/source/FileFinder.cpp
+++ b/externals/coda-oss/modules/c++/sys/source/FileFinder.cpp
@@ -56,12 +56,8 @@ bool sys::FragmentPredicate::operator()(const std::string& entry) const
{
if (mIgnoreCase)
{
- std::string base = entry;
- str::lower(base);
-
- std::string match = mFragment;
- str::lower(match);
-
+ const auto base = str::lower(entry);
+ const auto match = str::lower(mFragment);
return str::contains(base, match);
}
else
@@ -80,13 +76,10 @@ bool sys::ExtensionPredicate::operator()(const std::string& filename) const
if (!sys::FileOnlyPredicate::operator()(filename))
return false;
- std::string ext = sys::Path::splitExt(filename).second;
+ const std::string ext = sys::Path::splitExt(filename).second;
if (mIgnoreCase)
{
- std::string matchExt = mExt;
- str::lower(matchExt);
- str::lower(ext);
- return ext == matchExt;
+ return str::eq(ext, mExt);
}
else
return ext == mExt;
diff --git a/externals/coda-oss/modules/c++/sys/source/Path.cpp b/externals/coda-oss/modules/c++/sys/source/Path.cpp
index 4c91e6d18..99233b236 100644
--- a/externals/coda-oss/modules/c++/sys/source/Path.cpp
+++ b/externals/coda-oss/modules/c++/sys/source/Path.cpp
@@ -22,6 +22,7 @@
#include "sys/Path.h"
#include
+#include
#include
namespace fs = coda_oss::filesystem;
@@ -849,4 +850,20 @@ std::string Path::expandEnvironmentVariables(const std::string& path, fs::file_t
return expandEnvironmentVariables_(path, unused_checkIfExists, &type);
}
+template
+inline auto convertPaths_(coda_oss::span paths, TFunc fun)
+{
+ std::vector retval;
+ std::transform(paths.begin(), paths.end(), std::back_inserter(retval), fun);
+ return retval;
+}
+std::vector convertPaths(coda_oss::span paths)
+{
+ return convertPaths_(paths, [](const auto& p) { return p.string(); });
}
+std::vector convertPaths(coda_oss::span paths)
+{
+ return convertPaths_(paths, [](const auto& p) { return p; });
+}
+
+}
\ No newline at end of file
diff --git a/externals/coda-oss/modules/c++/xml.lite/include/xml/lite/UtilitiesXerces.h b/externals/coda-oss/modules/c++/xml.lite/include/xml/lite/UtilitiesXerces.h
index ef2039123..159bbb6ea 100644
--- a/externals/coda-oss/modules/c++/xml.lite/include/xml/lite/UtilitiesXerces.h
+++ b/externals/coda-oss/modules/c++/xml.lite/include/xml/lite/UtilitiesXerces.h
@@ -29,6 +29,7 @@
#include
#include
#include
+#include
#include "config/compiler_extensions.h"
#include "config/Exports.h"
@@ -409,17 +410,20 @@ struct XercesErrorHandler final : public XercesErrorHandlerInterface_T
*/
struct CODA_OSS_API XercesContext final
{
- //! Constructor
XercesContext();
-
- //! Destructor
~XercesContext();
+ XercesContext(const XercesContext&) = delete;
+ XercesContext& operator=(const XercesContext&) = delete;
+ XercesContext(XercesContext&&) = delete;
+ XercesContext& operator=(XercesContext&&) = delete;
+
void destroy();
private:
- static std::mutex mMutex;
- bool mIsDestroyed;
+ struct Impl;
+ static std::shared_ptr getInstance();
+ std::shared_ptr mpImpl;
};
}
}
diff --git a/externals/coda-oss/modules/c++/xml.lite/include/xml/lite/ValidatorXerces.h b/externals/coda-oss/modules/c++/xml.lite/include/xml/lite/ValidatorXerces.h
index 8d5d79ba0..56e9689ae 100644
--- a/externals/coda-oss/modules/c++/xml.lite/include/xml/lite/ValidatorXerces.h
+++ b/externals/coda-oss/modules/c++/xml.lite/include/xml/lite/ValidatorXerces.h
@@ -89,12 +89,8 @@ struct ValidationErrorHandler final : public xercesc::DOMErrorHandler
*
* This class is the Xercesc schema validator
*/
-class CODA_OSS_API ValidatorXerces : public ValidatorInterface
+struct CODA_OSS_API ValidatorXerces : public ValidatorInterface
{
- XercesContext mCtxt; //! this must be the first member listed
-
-public:
-
/*!
* Constructor
* \param schemaPaths Vector of both paths and singular schemas
@@ -104,10 +100,10 @@ class CODA_OSS_API ValidatorXerces : public ValidatorInterface
* input
*/
ValidatorXerces(const std::vector& schemaPaths,
- logging::Logger* log,
+ logging::Logger* log = nullptr,
bool recursive = true);
- ValidatorXerces(const std::vector&, // fs::path -> mLegacyStringConversion = false
- logging::Logger* log,
+ ValidatorXerces(const std::vector&,
+ logging::Logger* log = nullptr,
bool recursive = true);
ValidatorXerces(const ValidatorXerces&) = delete;
@@ -133,6 +129,8 @@ class CODA_OSS_API ValidatorXerces : public ValidatorInterface
static std::vector loadSchemas(const std::vector& schemaPaths, bool recursive=true);
private:
+ XercesContext mCtxt;
+
bool validate_(const coda_oss::u8string& xml,
const std::string& xmlID,
std::vector& errors) const;
diff --git a/externals/coda-oss/modules/c++/xml.lite/include/xml/lite/XMLReaderXerces.h b/externals/coda-oss/modules/c++/xml.lite/include/xml/lite/XMLReaderXerces.h
index a808be8d8..d40aea202 100644
--- a/externals/coda-oss/modules/c++/xml.lite/include/xml/lite/XMLReaderXerces.h
+++ b/externals/coda-oss/modules/c++/xml.lite/include/xml/lite/XMLReaderXerces.h
@@ -61,7 +61,7 @@ namespace lite
*/
class CODA_OSS_API XMLReaderXerces final : public XMLReaderInterface
{
- XercesContext mCtxt; //! this must be the first member listed
+ XercesContext mCtxt;
std::unique_ptr mNative;
std::unique_ptr mDriverContentHandler;
std::unique_ptr mErrorHandler;
diff --git a/externals/coda-oss/modules/c++/xml.lite/source/UtilitiesXerces.cpp b/externals/coda-oss/modules/c++/xml.lite/source/UtilitiesXerces.cpp
index ffb0f7fd7..943eb5e5f 100644
--- a/externals/coda-oss/modules/c++/xml.lite/source/UtilitiesXerces.cpp
+++ b/externals/coda-oss/modules/c++/xml.lite/source/UtilitiesXerces.cpp
@@ -28,8 +28,6 @@ namespace xml
{
namespace lite
{
-std::mutex XercesContext::mMutex;
-
XercesLocalString::XercesLocalString(XMLCh* xmlStr) :
mLocal(xmlStr)
{
@@ -186,8 +184,16 @@ fatalError(const SAXParseException &exception)
throw except::Error(Ctxt(xex.getMessage()));
}
-XercesContext::XercesContext() :
- mIsDestroyed(false)
+/*!
+ * \class XercesContext::Impl
+ * \brief This class safely creates and destroys Xerces
+ */
+struct XercesContext::Impl final
+{
+ static std::mutex mMutex;
+ bool mIsDestroyed = false;
+
+Impl()
{
//! XMLPlatformUtils::Initialize is not thread safe!
try
@@ -203,7 +209,7 @@ XercesContext::XercesContext() :
}
}
-XercesContext::~XercesContext()
+~Impl()
{
try
{
@@ -214,7 +220,7 @@ XercesContext::~XercesContext()
}
}
-void XercesContext::destroy()
+void destroy()
{
// wrapping it here saves the mutex lock
if (!mIsDestroyed)
@@ -235,7 +241,28 @@ void XercesContext::destroy()
}
}
}
+};
+std::mutex XercesContext::Impl::mMutex;
+
+std::shared_ptr XercesContext::getInstance()
+{
+ // The one and only instance; call XMLPlatformUtils::Initialize() and XMLPlatformUtils::Terminate() just once.
+ static auto impl = std::make_shared();
+ return impl; // increment reference count
+}
+XercesContext::XercesContext() : mpImpl(getInstance()) // increment reference count
+{
+}
+XercesContext::~XercesContext()
+{
+ destroy();
}
+void XercesContext::destroy()
+{
+ mpImpl.reset();
}
+} // lite
+} // xml
+
#endif
diff --git a/externals/coda-oss/modules/c++/xml.lite/source/ValidatorXerces.cpp b/externals/coda-oss/modules/c++/xml.lite/source/ValidatorXerces.cpp
index 3950d1242..dba996bd9 100644
--- a/externals/coda-oss/modules/c++/xml.lite/source/ValidatorXerces.cpp
+++ b/externals/coda-oss/modules/c++/xml.lite/source/ValidatorXerces.cpp
@@ -37,6 +37,7 @@ CODA_OSS_disable_warning(-Wshadow)
CODA_OSS_disable_warning_pop
#include
+#include
#include
#include
@@ -89,26 +90,11 @@ bool ValidationErrorHandler::handleError(
return true;
}
-inline std::vector convert(const std::vector& schemaPaths)
-{
- std::vector retval;
- std::transform(schemaPaths.begin(), schemaPaths.end(), std::back_inserter(retval),
- [](const fs::path& p) { return p.string(); });
- return retval;
-}
-inline auto convert(const std::vector& paths)
-{
- std::vector retval;
- std::transform(paths.begin(), paths.end(), std::back_inserter(retval),
- [](const auto& p) { return p; });
- return retval;
-}
-
ValidatorXerces::ValidatorXerces(
const std::vector& schemaPaths,
logging::Logger* log,
bool recursive) :
- ValidatorXerces(convert(schemaPaths), log, recursive)
+ ValidatorXerces(sys::convertPaths(schemaPaths), log, recursive)
{
}
ValidatorXerces::ValidatorXerces(
@@ -169,7 +155,7 @@ ValidatorXerces::ValidatorXerces(
// load our schemas --
// search each directory for schemas
- const auto schemas = loadSchemas(convert(schemaPaths), recursive);
+ const auto schemas = loadSchemas(sys::convertPaths(schemaPaths), recursive);
// add the schema to the validator
// add the schema to the validator
@@ -179,9 +165,12 @@ ValidatorXerces::ValidatorXerces(
xercesc::Grammar::SchemaGrammarType,
true))
{
- std::ostringstream oss;
- oss << "Error: Failure to load schema " << schema;
- log->warn(Ctxt(oss));
+ if (log != nullptr)
+ {
+ std::ostringstream oss;
+ oss << "Error: Failure to load schema " << schema;
+ log->warn(Ctxt(oss));
+ }
}
}
diff --git a/externals/coda-oss/modules/c++/xml.lite/unittests/test_xmlparser.cpp b/externals/coda-oss/modules/c++/xml.lite/unittests/test_xmlparser.cpp
index e35911651..b39f411fb 100644
--- a/externals/coda-oss/modules/c++/xml.lite/unittests/test_xmlparser.cpp
+++ b/externals/coda-oss/modules/c++/xml.lite/unittests/test_xmlparser.cpp
@@ -463,8 +463,8 @@ static void testValidateXmlFile_(const std::string& testName, const std::string&
static const auto xsd = find_unittest_file("doc.xsd");
const auto path = find_unittest_file(xmlFile);
- const std::vector schemaPaths{xsd.parent_path()}; // fs::path -> new string-conversion code
- const xml::lite::Validator validator(schemaPaths, nullptr /*log*/);
+ const std::vector schemaPaths{xsd.parent_path()};
+ const xml::lite::Validator validator(schemaPaths);
io::FileInputStream fis(path);
std::vector errors;
diff --git a/six/modules/c++/cphd/source/CPHDReader.cpp b/six/modules/c++/cphd/source/CPHDReader.cpp
index 40258717e..8cb31fbb9 100644
--- a/six/modules/c++/cphd/source/CPHDReader.cpp
+++ b/six/modules/c++/cphd/source/CPHDReader.cpp
@@ -31,6 +31,7 @@
#include
#include
#include
+#include
#include
#include
@@ -60,10 +61,7 @@ static cphd::Metadata fromXML(io::SeekableInputStream& inStream,
logger = std::make_shared();
}
- std::vector schemaPaths;
- std::transform(schemaPaths_.begin(), schemaPaths_.end(), std::back_inserter(schemaPaths),
- [](const std::string& s) { return s; });
-
+ const auto schemaPaths = sys::convertPaths(schemaPaths_);
return cphd::CPHDXMLControl(logger.get()).fromXML(xmlParser.getDocument(), schemaPaths);
}
cphd::CPHDReader::CPHDReader(std::shared_ptr inStream,
diff --git a/six/modules/c++/cphd/source/CPHDWriter.cpp b/six/modules/c++/cphd/source/CPHDWriter.cpp
index 89f719332..60d0d5f7f 100644
--- a/six/modules/c++/cphd/source/CPHDWriter.cpp
+++ b/six/modules/c++/cphd/source/CPHDWriter.cpp
@@ -26,6 +26,7 @@
#include
#include
+#include
#include
#include
@@ -62,13 +63,6 @@ CPHDWriter::CPHDWriter(const Metadata& metadata,
{
}
-static auto transform(const std::vector& schemaPaths)
-{
- std::vector retval;
- std::transform(schemaPaths.begin(), schemaPaths.end(), std::back_inserter(retval),
- [](const std::string& s) { return s; });
- return retval;
-}
CPHDWriter::CPHDWriter(const Metadata& metadata,
std::shared_ptr outStream,
const std::vector& schemaPaths,
@@ -78,7 +72,7 @@ CPHDWriter::CPHDWriter(const Metadata& metadata,
mElementSize(metadata.data.getNumBytesPerSample()),
mScratchSpaceSize(scratchSpaceSize),
mNumThreads(numThreads),
- mSchemaPaths(transform(schemaPaths)),
+ mSchemaPaths(sys::convertPaths(schemaPaths)),
mpSchemaPaths(&mSchemaPaths),
mSharedStream(outStream),
mStream(*mSharedStream),
diff --git a/six/modules/c++/cphd/source/CPHDXMLControl.cpp b/six/modules/c++/cphd/source/CPHDXMLControl.cpp
index f7902398d..791549005 100644
--- a/six/modules/c++/cphd/source/CPHDXMLControl.cpp
+++ b/six/modules/c++/cphd/source/CPHDXMLControl.cpp
@@ -33,6 +33,7 @@
#include
#include
#include
+#include
#include
#include
@@ -62,8 +63,7 @@ std::u8string CPHDXMLControl::toXMLString(
std::vector schemaPaths;
if (pSchemaPaths != nullptr)
{
- std::transform(pSchemaPaths->begin(), pSchemaPaths->end(), std::back_inserter(schemaPaths),
- [](const std::filesystem::path& p) { return p.string(); });
+ schemaPaths = sys::convertPaths(*pSchemaPaths);
}
std::unique_ptr doc(toXML(metadata, schemaPaths));
@@ -78,10 +78,7 @@ std::u8string CPHDXMLControl::toXMLString(
const std::vector& schemaPaths_,
bool prettyPrint)
{
- std::vector schemaPaths;
- std::transform(schemaPaths_.begin(), schemaPaths_.end(), std::back_inserter(schemaPaths),
- [](const std::string& s) { return s; });
-
+ const auto schemaPaths = sys::convertPaths(schemaPaths_);
return toXMLString(metadata, &schemaPaths, prettyPrint);
}
std::string CPHDXMLControl::toXMLString_(
@@ -130,10 +127,7 @@ std::unique_ptr CPHDXMLControl::toXMLImpl(const Metadata& m
std::unique_ptr CPHDXMLControl::fromXML(const std::string& xmlString,
const std::vector& schemaPaths_)
{
- std::vector schemaPaths;
- std::transform(schemaPaths_.begin(), schemaPaths_.end(), std::back_inserter(schemaPaths),
- [](const std::string& s) { return s; });
-
+ const auto schemaPaths = sys::convertPaths(schemaPaths_);
return fromXML(str::u8FromNative(xmlString), schemaPaths);
}
std::unique_ptr CPHDXMLControl::fromXML(const std::u8string& xmlString,
@@ -158,9 +152,7 @@ std::unique_ptr CPHDXMLControl::fromXML(const xml::lite::Document* doc
}
Metadata CPHDXMLControl::fromXML(const xml::lite::Document& doc, const std::vector& schemaPaths)
{
- std::vector schemaPaths_;
- std::transform(schemaPaths.begin(), schemaPaths.end(), std::back_inserter(schemaPaths_),
- [](const std::filesystem::path& p) { return p.string(); });
+ const auto schemaPaths_ = sys::convertPaths(schemaPaths);
auto result = fromXML(&doc, schemaPaths_);
auto retval = std::move(*(result.release()));
diff --git a/six/modules/c++/six.sicd/source/CropUtils.cpp b/six/modules/c++/six.sicd/source/CropUtils.cpp
index 64b25cd5c..347cca5e0 100644
--- a/six/modules/c++/six.sicd/source/CropUtils.cpp
+++ b/six/modules/c++/six.sicd/source/CropUtils.cpp
@@ -31,6 +31,8 @@
#include
#include
#include
+#include
+
#include
#include
#include
@@ -126,8 +128,7 @@ void cropSICD(six::NITFReadControl& reader,
// Write the AOI SICD out
six::NITFWriteControl writer(std::move(aoiData));
const std::span image(buffer.get(), origDims.area());
- std::vector schemaPaths;
- std::transform(schemaPaths_.begin(), schemaPaths_.end(), std::back_inserter(schemaPaths), [](const std::string& s) { return s; });
+ const auto schemaPaths = sys::convertPaths(schemaPaths_);
writer.save_image(image, outPathname, schemaPaths);
}
diff --git a/six/modules/c++/six.sicd/source/Utilities.cpp b/six/modules/c++/six.sicd/source/Utilities.cpp
index c56b8eed3..039c528c2 100644
--- a/six/modules/c++/six.sicd/source/Utilities.cpp
+++ b/six/modules/c++/six.sicd/source/Utilities.cpp
@@ -48,6 +48,7 @@
#include
#include
#include
+#include
#include
#include
@@ -632,8 +633,7 @@ void Utilities::readSicd(const fs::path& sicdPathname,
std::unique_ptr& complexData,
std::vector& widebandData)
{
- std::vector schemaPaths_;
- std::transform(schemaPaths.begin(), schemaPaths.end(), std::back_inserter(schemaPaths_), [](const fs::path& p) { return p.string(); });
+ const auto schemaPaths_ = sys::convertPaths(schemaPaths);
readSicd(sicdPathname.string(), schemaPaths_, complexData, widebandData);
}
ComplexImageResult Utilities::readSicd(const fs::path& sicdPathname, const std::vector& schemaPaths)
@@ -1026,11 +1026,7 @@ std::unique_ptr Utilities::parseDataFromString(
logging::Logger& log)
{
const auto xmlStr = str::u8FromNative(xmlStr_);
-
- std::vector schemaPaths;
- std::transform(schemaPaths_.begin(), schemaPaths_.end(), std::back_inserter(schemaPaths),
- [](const std::string& s) { return s; });
-
+ const auto schemaPaths = sys::convertPaths(schemaPaths_);
return parseDataFromString(xmlStr, &schemaPaths, &log);
}
std::unique_ptr Utilities::parseDataFromString(const std::u8string& xmlStr,
@@ -1045,10 +1041,7 @@ std::u8string Utilities::toXMLString(const ComplexData& data,
const std::vector& schemaPaths_,
logging::Logger* logger)
{
- std::vector schemaPaths;
- std::transform(schemaPaths_.begin(), schemaPaths_.end(), std::back_inserter(schemaPaths),
- [](const std::string& s) { return s; });
-
+ const auto schemaPaths = sys::convertPaths(schemaPaths_);
return toXMLString(data, &schemaPaths, logger);
}
std::string Utilities::toXMLString_(const ComplexData& data,
@@ -1641,8 +1634,7 @@ static void writeAsNITF(const fs::path& pathname, const std::vector
writer.setLogger(logging::setupLogger("out"));
const std::span image(image_, getExtent(data).area());
- std::vector schemaPaths;
- std::transform(schemaPaths_.begin(), schemaPaths_.end(), std::back_inserter(schemaPaths), [](const std::string& s) { return s; });
+ const auto schemaPaths = sys::convertPaths(schemaPaths_);
writer.save_image(image, pathname, schemaPaths);
}
void six::sicd::writeAsNITF(const fs::path& pathname, const std::vector& schemaPaths, const ComplexData& data, std::span image)
@@ -1655,8 +1647,7 @@ void six::sicd::writeAsNITF(const fs::path& pathname, const std::vector& schemaPaths, const ComplexData& data, std::span image)
{
- std::vector schemaPaths_;
- std::transform(schemaPaths.begin(), schemaPaths.end(), std::back_inserter(schemaPaths_), [](const fs::path& p) { return p.string(); });
+ const auto schemaPaths_ = sys::convertPaths(schemaPaths);
writeAsNITF(pathname, schemaPaths_, data, image);
}
void six::sicd::writeAsNITF(const fs::path& pathname, const std::vector& schemaPaths, const ComplexImage& image)
diff --git a/six/modules/c++/six.sicd/unittests/test_valid_six.cpp b/six/modules/c++/six.sicd/unittests/test_valid_six.cpp
index 456569108..03f5b0d4b 100644
--- a/six/modules/c++/six.sicd/unittests/test_valid_six.cpp
+++ b/six/modules/c++/six.sicd/unittests/test_valid_six.cpp
@@ -184,9 +184,7 @@ TEST_CASE(sicd_French_xml)
// const auto schemaPaths = ::six::testing::getSchemaPaths();
//
// // Use legacy APIs ... to test other XML processing path
-// std::vector schemaPaths_;
-// std::transform(schemaPaths.begin(), schemaPaths.end(), std::back_inserter(schemaPaths_),
-// [](const std::filesystem::path& p) { return p.string(); });
+// const auto schemaPaths_ = sys::convertPaths(schemaPaths);
//
// six::sicd::NITFReadComplexXMLControl reader;
// reader.setLogger();
diff --git a/six/modules/c++/six.sidd/source/Utilities.cpp b/six/modules/c++/six.sidd/source/Utilities.cpp
index 8a2455db2..3cd07c034 100644
--- a/six/modules/c++/six.sidd/source/Utilities.cpp
+++ b/six/modules/c++/six.sidd/source/Utilities.cpp
@@ -26,6 +26,7 @@
#include
#include
+#include
#include "six/Utilities.h"
#include "six/sidd/DerivedXMLControl.h"
@@ -564,10 +565,7 @@ std::unique_ptr Utilities::parseDataFromString(const std::string& x
const std::vector& schemaPaths_, logging::Logger& log)
{
const auto xmlStr = str::u8FromNative(xmlStr_);
-
- std::vector schemaPaths;
- std::transform(schemaPaths_.begin(), schemaPaths_.end(), std::back_inserter(schemaPaths),
- [](const std::string& s) { return s; });
+ const auto schemaPaths = sys::convertPaths(schemaPaths_);
auto result = parseDataFromString(xmlStr, &schemaPaths, &log);
return std::unique_ptr(result.release());
@@ -583,10 +581,7 @@ std::unique_ptr Utilities::parseDataFromString(const std::u8string&
std::u8string Utilities::toXMLString(const DerivedData& data,
const std::vector& schemaPaths_, logging::Logger* logger)
{
- std::vector schemaPaths;
- std::transform(schemaPaths_.begin(), schemaPaths_.end(), std::back_inserter(schemaPaths),
- [](const std::string& s) { return s; });
-
+ const auto schemaPaths = sys::convertPaths(schemaPaths_);
return toXMLString(data, &schemaPaths, logger);
}
std::string Utilities::toXMLString_(const DerivedData& data,
diff --git a/six/modules/c++/six/include/six/NITFWriteControl.h b/six/modules/c++/six/include/six/NITFWriteControl.h
index c72806999..642bbed97 100644
--- a/six/modules/c++/six/include/six/NITFWriteControl.h
+++ b/six/modules/c++/six/include/six/NITFWriteControl.h
@@ -35,6 +35,7 @@
#include
#include
+#include
#include "six/Types.h"
#include "six/Container.h"
@@ -573,9 +574,7 @@ template
inline void save(NITFWriteControl& writeControl,
std::span imageData, const std::string& outputFile, const std::vector& schemaPaths_)
{
- std::vector schemaPaths;
- std::transform(schemaPaths_.begin(), schemaPaths_.end(), std::back_inserter(schemaPaths),
- [](const std::string& s) { return s; });
+ const auto schemaPaths = sys::convertPaths(schemaPaths_);
save(writeControl, imageData, outputFile, schemaPaths);
}
diff --git a/six/modules/c++/six/include/six/ReadControl.h b/six/modules/c++/six/include/six/ReadControl.h
index a522c6502..570cd3fad 100644
--- a/six/modules/c++/six/include/six/ReadControl.h
+++ b/six/modules/c++/six/include/six/ReadControl.h
@@ -27,6 +27,10 @@
#include
#include
+#include
+#include
+#include
+
#include "six/Types.h"
#include "six/Region.h"
#include "six/Container.h"
@@ -34,8 +38,6 @@
#include "six/XMLControlFactory.h"
#include "six/Logger.h"
#include "six/Exports.h"
-#include
-#include
namespace six
{
@@ -95,7 +97,7 @@ struct SIX_SIX_API ReadControl
std::vector schemaPaths_;
if (pSchemaPaths != nullptr)
{
- std::transform(pSchemaPaths->begin(), pSchemaPaths->end(), std::back_inserter(schemaPaths_), [](const std::filesystem::path& p) { return p.string(); });
+ schemaPaths_ = sys::convertPaths(*pSchemaPaths);
}
load(fromFile.string(), schemaPaths_);
}
diff --git a/six/modules/c++/six/source/NITFWriteControl.cpp b/six/modules/c++/six/source/NITFWriteControl.cpp
index add7312eb..f92806cb9 100644
--- a/six/modules/c++/six/source/NITFWriteControl.cpp
+++ b/six/modules/c++/six/source/NITFWriteControl.cpp
@@ -35,6 +35,7 @@
#include
#include
#include
+#include
#include
#include
@@ -510,36 +511,29 @@ void NITFWriteControl::do_save_(const T& imageData, bool doByteSwap, bool enable
}
}
-static std::vector convert_paths( const std::vector& schemaPaths)
-{
- std::vector retval;
- std::transform(schemaPaths.begin(), schemaPaths.end(), std::back_inserter(retval),
- [](const std::filesystem::path& p) { return p.string(); });
- return retval;
-}
void NITFWriteControl::save_image(std::span imageData,
nitf::IOInterface& outputFile,
const std::vector& schemaPaths)
{
- do_save(imageData, outputFile, convert_paths(schemaPaths));
+ do_save(imageData, outputFile, sys::convertPaths(schemaPaths));
}
void NITFWriteControl::save_image(std::span imageData,
nitf::IOInterface& outputFile,
const std::vector& schemaPaths)
{
- do_save(imageData, outputFile, convert_paths(schemaPaths));
+ do_save(imageData, outputFile, sys::convertPaths(schemaPaths));
}
void NITFWriteControl::save_image(std::span imageData,
nitf::IOInterface& outputFile,
const std::vector& schemaPaths)
{
- do_save(imageData, outputFile, convert_paths(schemaPaths));
+ do_save(imageData, outputFile, sys::convertPaths(schemaPaths));
}
void NITFWriteControl::save_image(std::span imageData,
nitf::IOInterface& outputFile,
const std::vector& schemaPaths)
{
- do_save(imageData, outputFile, convert_paths(schemaPaths));
+ do_save(imageData, outputFile, sys::convertPaths(schemaPaths));
}
void NITFWriteControl::save(const BufferList& list, const std::string& outputFile, const std::vector& schemaPaths)
diff --git a/six/modules/c++/six/source/Utilities.cpp b/six/modules/c++/six/source/Utilities.cpp
index 857b01f5a..52d688375 100644
--- a/six/modules/c++/six/source/Utilities.cpp
+++ b/six/modules/c++/six/source/Utilities.cpp
@@ -29,6 +29,8 @@
#include