diff options
-rw-r--r-- | core/fxcrt/cfx_widestring.cpp | 9 | ||||
-rw-r--r-- | core/fxcrt/cfx_widestring.h | 4 | ||||
-rw-r--r-- | core/fxcrt/cfx_widestring_unittest.cpp | 108 |
3 files changed, 121 insertions, 0 deletions
diff --git a/core/fxcrt/cfx_widestring.cpp b/core/fxcrt/cfx_widestring.cpp index ef6aaad931..46192de4ab 100644 --- a/core/fxcrt/cfx_widestring.cpp +++ b/core/fxcrt/cfx_widestring.cpp @@ -1049,3 +1049,12 @@ int CFX_WideString::GetInteger() const { float CFX_WideString::GetFloat() const { return m_pData ? FX_wtof(m_pData->m_String, m_pData->m_nDataLength) : 0.0f; } + +std::wostream& operator<<(std::wostream& os, const CFX_WideString& str) { + return os.write(str.c_str(), str.GetLength()); +} + +std::ostream& operator<<(std::ostream& os, const CFX_WideString& str) { + os << str.UTF8Encode(); + return os; +} diff --git a/core/fxcrt/cfx_widestring.h b/core/fxcrt/cfx_widestring.h index 977114816d..3d69b0be55 100644 --- a/core/fxcrt/cfx_widestring.h +++ b/core/fxcrt/cfx_widestring.h @@ -228,6 +228,10 @@ inline bool operator!=(const CFX_WideStringC& lhs, const CFX_WideString& rhs) { uint32_t FX_HashCode_GetW(const CFX_WideStringC& str, bool bIgnoreCase); +std::wostream& operator<<(std::wostream& os, const CFX_WideString& str); + +std::ostream& operator<<(std::ostream& os, const CFX_WideString& str); + namespace std { template <> diff --git a/core/fxcrt/cfx_widestring_unittest.cpp b/core/fxcrt/cfx_widestring_unittest.cpp index 165b43add6..2578cb6429 100644 --- a/core/fxcrt/cfx_widestring_unittest.cpp +++ b/core/fxcrt/cfx_widestring_unittest.cpp @@ -1102,3 +1102,111 @@ TEST(fxcrt, WideStringAnyAllNoneOf) { EXPECT_TRUE(pdfium::ContainsValue(str, L'b')); EXPECT_FALSE(pdfium::ContainsValue(str, L'z')); } + +TEST(fxcrt, OStreamWideStringOverload) { + std::ostringstream stream; + + // Basic case, empty string + CFX_WideString str; + stream << str; + EXPECT_EQ("", stream.str()); + + // Basic case, wide character + str = L"\u20AC"; + stream << str; + EXPECT_EQ("\u20AC", stream.str()); + + // Basic case, non-empty string + str = L"def"; + stream.str(""); + stream << "abc" << str << "ghi"; + EXPECT_EQ("abcdefghi", stream.str()); + + // Changing the CFX_WideString does not change the stream it was written to. + str = L"123"; + EXPECT_EQ("abcdefghi", stream.str()); + + // Writing it again to the stream will use the latest value. + stream.str(""); + stream << "abc" << str << "ghi"; + EXPECT_EQ("abc123ghi", stream.str()); + + wchar_t stringWithNulls[]{'x', 'y', '\0', 'z'}; + + // Writing a CFX_WideString with nulls and no specified length treats it as + // a C-style null-terminated string. + str = CFX_WideString(stringWithNulls); + EXPECT_EQ(2, str.GetLength()); + stream.str(""); + stream << str; + EXPECT_EQ(2u, stream.tellp()); + + // Writing a CFX_WideString with nulls but specifying its length treats it as + // a C++-style string. + str = CFX_WideString(stringWithNulls, 4); + EXPECT_EQ(4, str.GetLength()); + stream.str(""); + stream << str; + EXPECT_EQ(4u, stream.tellp()); + + // << operators can be chained. + CFX_WideString str1(L"abc"); + CFX_WideString str2(L"def"); + stream.str(""); + stream << str1 << str2; + EXPECT_EQ("abcdef", stream.str()); +} + +TEST(fxcrt, WideOStreamWideStringOverload) { + std::wostringstream stream; + + // Basic case, empty string + CFX_WideString str; + stream << str; + EXPECT_EQ(L"", stream.str()); + + // Basic case, wide character + str = L"\u20AC"; + stream << str; + EXPECT_EQ(L"\u20AC", stream.str()); + + // Basic case, non-empty string + str = L"def"; + stream.str(L""); + stream << L"abc" << str << L"ghi"; + EXPECT_EQ(L"abcdefghi", stream.str()); + + // Changing the CFX_WideString does not change the stream it was written to. + str = L"123"; + EXPECT_EQ(L"abcdefghi", stream.str()); + + // Writing it again to the stream will use the latest value. + stream.str(L""); + stream << L"abc" << str << L"ghi"; + EXPECT_EQ(L"abc123ghi", stream.str()); + + wchar_t stringWithNulls[]{'x', 'y', '\0', 'z'}; + + // Writing a CFX_WideString with nulls and no specified length treats it as + // a C-style null-terminated string. + str = CFX_WideString(stringWithNulls); + EXPECT_EQ(2, str.GetLength()); + stream.str(L""); + stream << str; + EXPECT_EQ(2u, stream.tellp()); + + // Writing a CFX_WideString with nulls but specifying its length treats it as + // a C++-style string. + str = CFX_WideString(stringWithNulls, 4); + EXPECT_EQ(4, str.GetLength()); + stream.str(L""); + stream << str; + EXPECT_EQ(4u, stream.tellp()); + + // << operators can be chained. + CFX_WideString str1(L"abc"); + CFX_WideString str2(L"def"); + stream.str(L""); + stream << str1 << str2; + EXPECT_EQ(L"abcdef", stream.str()); +} |