diff --git a/include/OpenSpaceToolkit/Core/Types/String.hpp b/include/OpenSpaceToolkit/Core/Types/String.hpp index 7c048f79..7a374601 100644 --- a/include/OpenSpaceToolkit/Core/Types/String.hpp +++ b/include/OpenSpaceToolkit/Core/Types/String.hpp @@ -116,6 +116,20 @@ class String : public std::string static String Replicate(const String& aString, Size aCount); + /// @brief Checks if the string contains any invalid UTF-8 characters + /// + /// @param [in] aString A string + /// @return True if valid UTF-8 string + + static bool IsValidUTF8(const String& aString); + + /// @brief Sanitizes the string by removing any invalid UTF-8 characters + /// + /// @param [in] aString A string + /// @return valid UTF-8 string + + static String SanitizeUTF8(const String& aString); + /// @brief Create formatted string /// /// @code diff --git a/share/util/Test.cxx b/share/util/Test.cxx index 9c62363f..7644f8cf 100644 --- a/share/util/Test.cxx +++ b/share/util/Test.cxx @@ -2,79 +2,78 @@ #include - class TestClass { + public: + TestClass(); - public: - - TestClass ( ) ; - - friend std::ostream& operator << ( std::ostream& anOutputStream, - const TestClass& aTestClass ) ; - - private: - - int integer_ ; - double double_ ; + friend std::ostream& operator<<(std::ostream& anOutputStream, const TestClass& aTestClass); -} ; + private: + int integer_; + double double_; +}; - - TestClass::TestClass ( ) - : integer_(123), - double_(456.789) +TestClass::TestClass() + : integer_(123), + double_(456.789) { - } -std::ostream& operator << ( std::ostream& anOutputStream, - const TestClass& aTestClass ) +std::ostream& operator<<(std::ostream& anOutputStream, const TestClass& aTestClass) { + anOutputStream << "Class ▸ " << aTestClass.integer_ << " " << aTestClass.double_; - anOutputStream << "Class ▸ " << aTestClass.integer_ << " " << aTestClass.double_ ; - - return anOutputStream ; - + return anOutputStream; } - -int main ( ) +int main() { - - LOG_SCOPE("Test") ; - - using ostk::core::types::Integer ; - using ostk::core::Logger ; - using ostk::core::logger::Severity ; - - Logger logger = Logger::Console(Severity::Info) ; - - logger << 1 ; - logger << 123.456 ; - logger << 'a' ; - logger << "Hello World!" ; - logger << "Hello" << " " << "World!" ; - logger << TestClass() ; - - LOG_TRACE(logger) << TestClass() << " !!!" ; - LOG_DEBUG(logger) << TestClass() << " !!!" ; - LOG_INFO(logger) << TestClass() << " !!!" ; - LOG_WARNING(logger) << TestClass() << " !!!" ; - LOG_ERROR(logger) << TestClass() << " !!!" ; - - GLOBAL_LOG_TRACE << "Hello " << " " << "World!" ; - GLOBAL_LOG_DEBUG << "Hello " << " " << "World!" ; - GLOBAL_LOG_INFO << "Hello " << " " << "World!" ; - GLOBAL_LOG_WARNING << "Hello " << " " << "World!" ; - GLOBAL_LOG_ERROR << "Hello " << " " << "World!" ; - GLOBAL_LOG_FATAL << "Hello " << " " << "World!" ; - - Integer a = 6 ; + LOG_SCOPE("Test"); + + using ostk::core::types::Integer; + using ostk::core::Logger; + using ostk::core::logger::Severity; + + Logger logger = Logger::Console(Severity::Info); + + logger << 1; + logger << 123.456; + logger << 'a'; + logger << "Hello World!"; + logger << "Hello" + << " " + << "World!"; + logger << TestClass(); + + LOG_TRACE(logger) << TestClass() << " !!!"; + LOG_DEBUG(logger) << TestClass() << " !!!"; + LOG_INFO(logger) << TestClass() << " !!!"; + LOG_WARNING(logger) << TestClass() << " !!!"; + LOG_ERROR(logger) << TestClass() << " !!!"; + + GLOBAL_LOG_TRACE << "Hello " + << " " + << "World!"; + GLOBAL_LOG_DEBUG << "Hello " + << " " + << "World!"; + GLOBAL_LOG_INFO << "Hello " + << " " + << "World!"; + GLOBAL_LOG_WARNING << "Hello " + << " " + << "World!"; + GLOBAL_LOG_ERROR << "Hello " + << " " + << "World!"; + GLOBAL_LOG_FATAL << "Hello " + << " " + << "World!"; + + Integer a = 6; if (a < 5) { - } - } diff --git a/src/OpenSpaceToolkit/Core/Error/RuntimeError.cpp b/src/OpenSpaceToolkit/Core/Error/RuntimeError.cpp index 80032c77..a1068ad9 100644 --- a/src/OpenSpaceToolkit/Core/Error/RuntimeError.cpp +++ b/src/OpenSpaceToolkit/Core/Error/RuntimeError.cpp @@ -1,5 +1,4 @@ /// Apache License 2.0 - #include namespace ostk @@ -12,19 +11,19 @@ namespace error RuntimeError::RuntimeError(const String& aMessage) : Exception(String::Empty()), message_(aMessage), - stackTrace_(boost::stacktrace::to_string(boost::stacktrace::stacktrace())), - what_(stackTrace_ + message_) + stackTrace_(String::SanitizeUTF8(boost::stacktrace::to_string(boost::stacktrace::stacktrace()))), + what_(aMessage + "\n" + stackTrace_) { } String RuntimeError::getMessage() const { - return message_.data(); + return message_; } String RuntimeError::getStackTrace() const { - return stackTrace_.data(); + return stackTrace_; } RuntimeError::~RuntimeError() {} diff --git a/src/OpenSpaceToolkit/Core/Types/String.cpp b/src/OpenSpaceToolkit/Core/Types/String.cpp index 59e4e825..c6112f0b 100644 --- a/src/OpenSpaceToolkit/Core/Types/String.cpp +++ b/src/OpenSpaceToolkit/Core/Types/String.cpp @@ -208,6 +208,84 @@ String String::Replicate(const String& aString, Size aCount) return stringStream.str(); } +bool String::IsValidUTF8(const String& string) +{ + const Size stringLength = string.getLength(); + + for (Size i = 0; i < stringLength; i++) + { + Integer c = (unsigned char)string[i]; + + Size n; + + if (0x00 <= c && c <= 0x7f) + { + n = 0; // 0bbbbbbb + } + else if ((c & 0xE0) == 0xC0) + { + n = 1; // 110bbbbb + } + else if (c == 0xed && i < (stringLength - 1) && ((unsigned char)string[i + 1] & 0xa0) == 0xa0) + { + return false; // U+d800 to U+dfff + } + else if ((c & 0xF0) == 0xE0) + { + n = 2; // 1110bbbb + } + else if ((c & 0xF8) == 0xF0) + { + n = 3; // 11110bbb + } + else + { + return false; + } + for (Size j = 0; j < n && i < stringLength; j++) + { + if ((++i == stringLength) || (((unsigned char)string[i] & 0xC0) != 0x80)) + { + return false; + } + } + } + + return true; +} + +String String::SanitizeUTF8(const String& string) +{ + String result; + + for (Size i = 0; i < string.getLength();) + { + Size len = 1; + bool valid = true; + + unsigned char c = static_cast(string[i]); + if (c >= 0xF0) + len = 4; + else if (c >= 0xE0) + len = 3; + else if (c >= 0xC0) + len = 2; + + if (i + len > string.size()) + break; + + const String sub = string.getSubstring(i, len); + if (!IsValidUTF8(sub)) + valid = false; + + if (valid) + result += sub; + + i += len; + } + return result; +} + } // namespace types } // namespace core } // namespace ostk diff --git a/test/OpenSpaceToolkit/Core/Containers/Dictionary.test.cpp b/test/OpenSpaceToolkit/Core/Containers/Dictionary.test.cpp index d1c4d807..2d243b6c 100644 --- a/test/OpenSpaceToolkit/Core/Containers/Dictionary.test.cpp +++ b/test/OpenSpaceToolkit/Core/Containers/Dictionary.test.cpp @@ -39,7 +39,8 @@ TEST(OpenSpaceToolkit_Core_Containers_Dictionary, InitializerListConstructor) {"Integer", Object::Integer(456)}, {"Real", Object::Real(456.789)}}, Object::Array({Object::Integer(123), Object::Integer(456), Object::Integer(789)})} - )}}; + )} + }; EXPECT_FALSE(dictionary.isEmpty()); @@ -101,7 +102,8 @@ TEST(OpenSpaceToolkit_Core_Containers_Dictionary, CopyConstructor) {"Boolean", Object::Boolean(true)}, {"Integer", Object::Integer(123)}, {"Real", Object::Real(123.456)}, - {"String", Object::String("Hello World!")}}; + {"String", Object::String("Hello World!")} + }; const Dictionary secondDictionary(firstDictionary); @@ -127,7 +129,8 @@ TEST(OpenSpaceToolkit_Core_Containers_Dictionary, AssignmentOperator) {"Boolean", Object::Boolean(true)}, {"Integer", Object::Integer(123)}, {"Real", Object::Real(123.456)}, - {"String", Object::String("Hello World!")}}; + {"String", Object::String("Hello World!")} + }; const Dictionary secondDictionary = firstDictionary; @@ -153,7 +156,8 @@ TEST(OpenSpaceToolkit_Core_Containers_Dictionary, EqualToOperator) {"Boolean", Object::Boolean(true)}, {"Integer", Object::Integer(123)}, {"Real", Object::Real(123.456)}, - {"String", Object::String("Hello World!")}}; + {"String", Object::String("Hello World!")} + }; EXPECT_TRUE(firstDictionary == firstDictionary); } @@ -164,14 +168,16 @@ TEST(OpenSpaceToolkit_Core_Containers_Dictionary, EqualToOperator) {"Boolean", Object::Boolean(true)}, {"Integer", Object::Integer(123)}, {"Real", Object::Real(123.456)}, - {"String", Object::String("Hello World!")}}; + {"String", Object::String("Hello World!")} + }; const Dictionary secondDictionary = { {"Undefined", Object::Undefined()}, {"Boolean", Object::Boolean(true)}, {"Integer", Object::Integer(123)}, {"Real", Object::Real(123.456)}, - {"String", Object::String("Hello World!")}}; + {"String", Object::String("Hello World!")} + }; EXPECT_TRUE(firstDictionary == secondDictionary); } @@ -182,14 +188,16 @@ TEST(OpenSpaceToolkit_Core_Containers_Dictionary, EqualToOperator) {"Boolean", Object::Boolean(true)}, {"Integer", Object::Integer(123)}, {"Real", Object::Real(123.456)}, - {"String", Object::String("Hello World!")}}; + {"String", Object::String("Hello World!")} + }; const Dictionary secondDictionary = { {"Undefined", Object::Undefined()}, {"Boolean", Object::Boolean(false)}, {"Integer", Object::Integer(123)}, {"Real", Object::Real(123.456)}, - {"String", Object::String("Hello World!")}}; + {"String", Object::String("Hello World!")} + }; EXPECT_FALSE(firstDictionary == secondDictionary); } @@ -206,7 +214,8 @@ TEST(OpenSpaceToolkit_Core_Containers_Dictionary, NotEqualToOperator) {"Boolean", Object::Boolean(true)}, {"Integer", Object::Integer(123)}, {"Real", Object::Real(123.456)}, - {"String", Object::String("Hello World!")}}; + {"String", Object::String("Hello World!")} + }; EXPECT_FALSE(firstDictionary != firstDictionary); } @@ -217,14 +226,16 @@ TEST(OpenSpaceToolkit_Core_Containers_Dictionary, NotEqualToOperator) {"Boolean", Object::Boolean(true)}, {"Integer", Object::Integer(123)}, {"Real", Object::Real(123.456)}, - {"String", Object::String("Hello World!")}}; + {"String", Object::String("Hello World!")} + }; const Dictionary secondDictionary = { {"Undefined", Object::Undefined()}, {"Boolean", Object::Boolean(true)}, {"Integer", Object::Integer(123)}, {"Real", Object::Real(123.456)}, - {"String", Object::String("Hello World!")}}; + {"String", Object::String("Hello World!")} + }; EXPECT_FALSE(firstDictionary != secondDictionary); } @@ -235,14 +246,16 @@ TEST(OpenSpaceToolkit_Core_Containers_Dictionary, NotEqualToOperator) {"Boolean", Object::Boolean(true)}, {"Integer", Object::Integer(123)}, {"Real", Object::Real(123.456)}, - {"String", Object::String("Hello World!")}}; + {"String", Object::String("Hello World!")} + }; const Dictionary secondDictionary = { {"Undefined", Object::Undefined()}, {"Boolean", Object::Boolean(false)}, {"Integer", Object::Integer(123)}, {"Real", Object::Real(123.456)}, - {"String", Object::String("Hello World!")}}; + {"String", Object::String("Hello World!")} + }; EXPECT_TRUE(firstDictionary != secondDictionary); } @@ -264,9 +277,9 @@ TEST(OpenSpaceToolkit_Core_Containers_Dictionary, KeySubscriptOperator) {"Integer", Object::Integer(456)}, {"Real", Object::Real(456.789)}, {"Dictionary", - {{"Boolean", Object::Boolean(true)}, - {"Integer", Object::Integer(789)}, - {"Real", Object::Real(789.123)}}}}}}; + {{"Boolean", Object::Boolean(true)}, {"Integer", Object::Integer(789)}, {"Real", Object::Real(789.123)}}} + }} + }; EXPECT_EQ(true, dictionary["Boolean"].getBoolean()); EXPECT_EQ(123, dictionary["Integer"].getInteger()); @@ -293,7 +306,8 @@ TEST(OpenSpaceToolkit_Core_Containers_Dictionary, Iterators) {"Boolean", Object::Boolean(true)}, {"Integer", Object::Integer(123)}, {"Real", Object::Real(123.456)}, - {"String", Object::String("Hello World!")}}; + {"String", Object::String("Hello World!")} + }; uint idx = 0; @@ -342,7 +356,8 @@ TEST(OpenSpaceToolkit_Core_Containers_Dictionary, Iterators) {"Boolean", Object::Boolean(true)}, {"Integer", Object::Integer(123)}, {"Real", Object::Real(123.456)}, - {"String", Object::String("Hello World!")}}; + {"String", Object::String("Hello World!")} + }; { uint idx = 0; @@ -500,7 +515,8 @@ TEST(OpenSpaceToolkit_Core_Containers_Dictionary, GetSize) {"Integer", Object::Integer(456)}, {"Real", Object::Real(456.789)}}, Object::Array({Object::Integer(123), Object::Integer(456), Object::Integer(789)})} - )}}; + )} + }; EXPECT_EQ(Size(7), dictionary.getSize()); } diff --git a/test/OpenSpaceToolkit/Core/Containers/Object.test.cpp b/test/OpenSpaceToolkit/Core/Containers/Object.test.cpp index 685a1d2c..46f392ac 100644 --- a/test/OpenSpaceToolkit/Core/Containers/Object.test.cpp +++ b/test/OpenSpaceToolkit/Core/Containers/Object.test.cpp @@ -21,7 +21,8 @@ TEST(OpenSpaceToolkit_Core_Containers_Object, InitializerListConstructor) {"Boolean", Object::Boolean(true)}, {"Integer", Object::Integer(123)}, {"Real", Object::Real(123.456)}, - {"String", Object::String("Hello World!")}}; + {"String", Object::String("Hello World!")} + }; EXPECT_TRUE(object.isDefined()); EXPECT_TRUE(object.isDictionary()); diff --git a/test/OpenSpaceToolkit/Core/Containers/Table.test.cpp b/test/OpenSpaceToolkit/Core/Containers/Table.test.cpp index eb43a720..341f97d6 100644 --- a/test/OpenSpaceToolkit/Core/Containers/Table.test.cpp +++ b/test/OpenSpaceToolkit/Core/Containers/Table.test.cpp @@ -17,7 +17,8 @@ TEST(OpenSpaceToolkit_Core_Containers_Table, Constructor) const Array rows = { {Object::Integer(123), Object::Real(123.456)}, {Object::String("Hello"), Object::Undefined()}, - {Object::String("World!")}}; + {Object::String("World!")} + }; EXPECT_NO_THROW(Table table(header, rows);); } @@ -33,7 +34,8 @@ TEST(OpenSpaceToolkit_Core_Containers_Table, Constructor) const Array rows = { {Object::Integer(123), Object::Real(123.456)}, {Object::String("Hello"), Object::Undefined()}, - {Object::String("World!")}}; + {Object::String("World!")} + }; EXPECT_ANY_THROW(Table table(header, rows);); } @@ -52,7 +54,8 @@ TEST(OpenSpaceToolkit_Core_Containers_Table, CopyConstructor) const Array rows = { {Object::Integer(123), Object::Real(123.456)}, {Object::String("Hello"), Object::Undefined()}, - {Object::String("World!")}}; + {Object::String("World!")} + }; const Table table = {header, rows}; @@ -76,7 +79,8 @@ TEST(OpenSpaceToolkit_Core_Containers_Table, CopyAssignmentOperator) const Array rows = { {Object::Integer(123), Object::Real(123.456)}, {Object::String("Hello"), Object::Undefined()}, - {Object::String("World!")}}; + {Object::String("World!")} + }; const Table table = {header, rows}; @@ -100,7 +104,8 @@ TEST(OpenSpaceToolkit_Core_Containers_Table, EqualToOperator) const Array rows = { {Object::Integer(123), Object::Real(123.456)}, {Object::String("Hello"), Object::Undefined()}, - {Object::String("World!")}}; + {Object::String("World!")} + }; const Table table = {header, rows}; @@ -112,7 +117,8 @@ TEST(OpenSpaceToolkit_Core_Containers_Table, EqualToOperator) const Array rows = { {Object::Integer(123), Object::Real(123.456)}, {Object::String("Hello"), Object::Undefined()}, - {Object::String("World!")}}; + {Object::String("World!")} + }; const Table table_A = {header, rows}; const Table table_B = {header, rows}; @@ -125,13 +131,15 @@ TEST(OpenSpaceToolkit_Core_Containers_Table, EqualToOperator) const Array rows_A = { {Object::Integer(123), Object::Real(123.456)}, {Object::String("Hello"), Object::Undefined()}, - {Object::String("World!")}}; + {Object::String("World!")} + }; const Table table_A = {header_A, rows_A}; const Array header_B = {"Column A", "Column B"}; const Array rows_B = { - {Object::Integer(123), Object::Real(123.456)}, {Object::String("Hello"), Object::Undefined()}}; + {Object::Integer(123), Object::Real(123.456)}, {Object::String("Hello"), Object::Undefined()} + }; const Table table_B = {header_B, rows_B}; @@ -143,7 +151,8 @@ TEST(OpenSpaceToolkit_Core_Containers_Table, EqualToOperator) const Array rows_A = { {Object::Integer(123), Object::Real(123.456)}, {Object::String("Hello"), Object::Undefined()}, - {Object::String("World!")}}; + {Object::String("World!")} + }; const Table table_A = {header_A, rows_A}; @@ -151,7 +160,8 @@ TEST(OpenSpaceToolkit_Core_Containers_Table, EqualToOperator) const Array rows_B = { {Object::Integer(123), Object::Real(123.456)}, {Object::String("Hello"), Object::Undefined()}, - {Object::String("World!")}}; + {Object::String("World!")} + }; const Table table_B = {header_B, rows_B}; @@ -172,7 +182,8 @@ TEST(OpenSpaceToolkit_Core_Containers_Table, NotEqualToOperator) const Array rows = { {Object::Integer(123), Object::Real(123.456)}, {Object::String("Hello"), Object::Undefined()}, - {Object::String("World!")}}; + {Object::String("World!")} + }; const Table table = {header, rows}; @@ -184,7 +195,8 @@ TEST(OpenSpaceToolkit_Core_Containers_Table, NotEqualToOperator) const Array rows = { {Object::Integer(123), Object::Real(123.456)}, {Object::String("Hello"), Object::Undefined()}, - {Object::String("World!")}}; + {Object::String("World!")} + }; const Table table_A = {header, rows}; const Table table_B = {header, rows}; @@ -197,13 +209,15 @@ TEST(OpenSpaceToolkit_Core_Containers_Table, NotEqualToOperator) const Array rows_A = { {Object::Integer(123), Object::Real(123.456)}, {Object::String("Hello"), Object::Undefined()}, - {Object::String("World!")}}; + {Object::String("World!")} + }; const Table table_A = {header_A, rows_A}; const Array header_B = {"Column A", "Column B"}; const Array rows_B = { - {Object::Integer(123), Object::Real(123.456)}, {Object::String("Hello"), Object::Undefined()}}; + {Object::Integer(123), Object::Real(123.456)}, {Object::String("Hello"), Object::Undefined()} + }; const Table table_B = {header_B, rows_B}; @@ -215,7 +229,8 @@ TEST(OpenSpaceToolkit_Core_Containers_Table, NotEqualToOperator) const Array rows_A = { {Object::Integer(123), Object::Real(123.456)}, {Object::String("Hello"), Object::Undefined()}, - {Object::String("World!")}}; + {Object::String("World!")} + }; const Table table_A = {header_A, rows_A}; @@ -223,7 +238,8 @@ TEST(OpenSpaceToolkit_Core_Containers_Table, NotEqualToOperator) const Array rows_B = { {Object::Integer(123), Object::Real(123.456)}, {Object::String("Hello"), Object::Undefined()}, - {Object::String("World!")}}; + {Object::String("World!")} + }; const Table table_B = {header_B, rows_B}; @@ -244,7 +260,8 @@ TEST(OpenSpaceToolkit_Core_Containers_Table, SubscriptOperator) const Array rows = { {Object::Integer(123), Object::Real(123.456)}, {Object::String("Hello"), Object::Undefined()}, - {Object::String("World!")}}; + {Object::String("World!")} + }; const Table table = {header, rows}; @@ -297,7 +314,8 @@ TEST(OpenSpaceToolkit_Core_Containers_Table, FunctionCallOperator) const Array rows = { {Object::Integer(123), Object::Real(123.456)}, {Object::String("Hello"), Object::Undefined()}, - {Object::String("World!")}}; + {Object::String("World!")} + }; const Table table = {header, rows}; @@ -320,7 +338,8 @@ TEST(OpenSpaceToolkit_Core_Containers_Table, FunctionCallOperator) const Array rows = { {Object::Integer(123), Object::Real(123.456)}, {Object::String("Hello"), Object::Undefined()}, - {Object::String("World!")}}; + {Object::String("World!")} + }; const Table table = {header, rows}; @@ -352,7 +371,8 @@ TEST(OpenSpaceToolkit_Core_Containers_Table, StreamOperator) const Array rows = { {Object::Integer(123), Object::Real(123.456)}, {Object::String("Hello"), Object::Undefined()}, - {Object::String("World!")}}; + {Object::String("World!")} + }; const Table table = {header, rows}; @@ -378,7 +398,8 @@ TEST(OpenSpaceToolkit_Core_Containers_Table, Iterator) const Array rows = { {Object::Integer(123), Object::Real(123.456)}, {Object::String("Hello"), Object::Undefined()}, - {Object::String("World!")}}; + {Object::String("World!")} + }; const Table table = {header, rows}; @@ -425,7 +446,8 @@ TEST(OpenSpaceToolkit_Core_Containers_Table, IsEmpty) const Array rows = { {Object::Integer(123), Object::Real(123.456)}, {Object::String("Hello"), Object::Undefined()}, - {Object::String("World!")}}; + {Object::String("World!")} + }; const Table table = {header, rows}; @@ -458,7 +480,8 @@ TEST(OpenSpaceToolkit_Core_Containers_Table, HasColumnWithName) const Array rows = { {Object::Integer(123), Object::Real(123.456)}, {Object::String("Hello"), Object::Undefined()}, - {Object::String("World!")}}; + {Object::String("World!")} + }; const Table table = {header, rows}; @@ -501,7 +524,8 @@ TEST(OpenSpaceToolkit_Core_Containers_Table, GetRowCount) const Array rows = { {Object::Integer(123), Object::Real(123.456)}, {Object::String("Hello"), Object::Undefined()}, - {Object::String("World!")}}; + {Object::String("World!")} + }; const Table table = {header, rows}; @@ -526,7 +550,8 @@ TEST(OpenSpaceToolkit_Core_Containers_Table, GetColumnCount) const Array rows = { {Object::Integer(123), Object::Real(123.456)}, {Object::String("Hello"), Object::Undefined()}, - {Object::String("World!")}}; + {Object::String("World!")} + }; const Table table = {header, rows}; @@ -551,7 +576,8 @@ TEST(OpenSpaceToolkit_Core_Containers_Table, GetIndexOfColumnWithName) const Array rows = { {Object::Integer(123), Object::Real(123.456)}, {Object::String("Hello"), Object::Undefined()}, - {Object::String("World!")}}; + {Object::String("World!")} + }; const Table table = {header, rows}; @@ -618,7 +644,8 @@ TEST(OpenSpaceToolkit_Core_Containers_Table, Clear) const Array rows = { {Object::Integer(123), Object::Real(123.456)}, {Object::String("Hello"), Object::Undefined()}, - {Object::String("World!")}}; + {Object::String("World!")} + }; Table table = {header, rows}; @@ -664,7 +691,8 @@ TEST(OpenSpaceToolkit_Core_Containers_Table, Load) Object::String("!"), Object::String("Hello,"), Object::String("Wo\"\"rld")}, - {Object::Integer(1), Object::Undefined(), Object::Integer(3), Object::Undefined(), Object::Integer(5)}}; + {Object::Integer(1), Object::Undefined(), Object::Integer(3), Object::Undefined(), Object::Integer(5)} + }; const Table referenceTable = {header, rows}; @@ -683,7 +711,8 @@ TEST(OpenSpaceToolkit_Core_Containers_Table, Load) "Obstruction", "Current Condition", "Worst Condition", - "Total Duration (sec)"}; + "Total Duration (sec)" + }; const Array rows = { {Object::String("1 Jan 2018 00:00:00.000"), Object::String("1 Jan 2018 04:15:48.956"), @@ -691,7 +720,8 @@ TEST(OpenSpaceToolkit_Core_Containers_Table, Load) Object::String("Earth"), Object::String("Umbra"), Object::String("Umbra"), - Object::Real(15492.990)}}; + Object::Real(15492.990)} + }; const Table referenceTable = {header, rows}; diff --git a/test/OpenSpaceToolkit/Core/Types/String.test.cpp b/test/OpenSpaceToolkit/Core/Types/String.test.cpp index 5877beee..15a7e123 100644 --- a/test/OpenSpaceToolkit/Core/Types/String.test.cpp +++ b/test/OpenSpaceToolkit/Core/Types/String.test.cpp @@ -310,3 +310,14 @@ TEST(OpenSpaceToolkit_Core_Types_String, Format) ); } } + +TEST(OpenSpaceToolkit_Core_Types_String, SanitizeUTF8) +{ + using ostk::core::types::String; + + { + const String invalid = "okdata\xa0\xa1morevalid"; + const String valid = String::SanitizeUTF8(invalid); + EXPECT_EQ("okdatamorevalid", valid); + } +}