From 297f161a02d79cef88f55906722534bee2da730b Mon Sep 17 00:00:00 2001 From: Ryan Harrison Date: Wed, 28 Jun 2017 15:57:51 -0400 Subject: Add << overload for CFX_StringCTemplate classes BUG=pdfium:790 Change-Id: I4a3623dc0daac6ff8407c09cd00e9f2e4e5dd2d7 Reviewed-on: https://pdfium-review.googlesource.com/7051 Commit-Queue: Ryan Harrison Reviewed-by: Tom Sepez --- core/fxcrt/cfx_bytestring.cpp | 4 + core/fxcrt/cfx_bytestring.h | 1 + core/fxcrt/cfx_bytestring_unittest.cpp | 71 +++++++++++++++ core/fxcrt/cfx_widestring.cpp | 9 ++ core/fxcrt/cfx_widestring.h | 3 +- core/fxcrt/cfx_widestring_unittest.cpp | 156 +++++++++++++++++++++++++++++++++ 6 files changed, 243 insertions(+), 1 deletion(-) diff --git a/core/fxcrt/cfx_bytestring.cpp b/core/fxcrt/cfx_bytestring.cpp index 967bcce0eb..9d67ed30a1 100644 --- a/core/fxcrt/cfx_bytestring.cpp +++ b/core/fxcrt/cfx_bytestring.cpp @@ -877,3 +877,7 @@ CFX_ByteString CFX_ByteString::FormatFloat(float d, int precision) { std::ostream& operator<<(std::ostream& os, const CFX_ByteString& str) { return os.write(str.c_str(), str.GetLength()); } + +std::ostream& operator<<(std::ostream& os, const CFX_ByteStringC& str) { + return os.write(str.c_str(), str.GetLength()); +} diff --git a/core/fxcrt/cfx_bytestring.h b/core/fxcrt/cfx_bytestring.h index 7459f27745..abf8ac80c8 100644 --- a/core/fxcrt/cfx_bytestring.h +++ b/core/fxcrt/cfx_bytestring.h @@ -234,6 +234,7 @@ inline CFX_ByteString operator+(const CFX_ByteStringC& str1, uint32_t FX_HashCode_GetA(const CFX_ByteStringC& str, bool bIgnoreCase); std::ostream& operator<<(std::ostream& os, const CFX_ByteString& str); +std::ostream& operator<<(std::ostream& os, const CFX_ByteStringC& str); namespace std { diff --git a/core/fxcrt/cfx_bytestring_unittest.cpp b/core/fxcrt/cfx_bytestring_unittest.cpp index b0265038d5..f5d9413b7d 100644 --- a/core/fxcrt/cfx_bytestring_unittest.cpp +++ b/core/fxcrt/cfx_bytestring_unittest.cpp @@ -1308,3 +1308,74 @@ TEST(fxcrt, OStreamByteStringOverload) { stream << str1 << str2; EXPECT_EQ("abcdef", stream.str()); } + +TEST(fxcrt, OStreamByteStringCOverload) { + // Basic case, empty string + { + std::ostringstream stream; + CFX_ByteStringC str; + stream << str; + EXPECT_EQ("", stream.str()); + } + + // Basic case, non-empty string + { + std::ostringstream stream; + CFX_ByteStringC str("def"); + stream << "abc" << str << "ghi"; + EXPECT_EQ("abcdefghi", stream.str()); + } + + // Changing the CFX_ByteStringC does not change the stream it was written to. + { + std::ostringstream stream; + CFX_ByteStringC str("abc"); + stream << str; + str = "123"; + EXPECT_EQ("abc", stream.str()); + } + + // Writing it again to the stream will use the latest value. + { + std::ostringstream stream; + CFX_ByteStringC str("abc"); + stream << str; + stream.str(""); + str = "123"; + stream << str; + EXPECT_EQ("123", stream.str()); + } + + // Writing a CFX_ByteStringC with nulls and no specified length treats it as + // a C-style null-terminated string. + { + std::ostringstream stream; + char stringWithNulls[]{'x', 'y', '\0', 'z'}; + CFX_ByteStringC str(stringWithNulls); + EXPECT_EQ(2, str.GetLength()); + stream << str; + EXPECT_EQ(2u, stream.tellp()); + str = ""; + } + + // Writing a CFX_ByteStringC with nulls but specifying its length treats it as + // a C++-style string. + { + std::ostringstream stream; + char stringWithNulls[]{'x', 'y', '\0', 'z'}; + CFX_ByteStringC str(stringWithNulls, 4); + EXPECT_EQ(4, str.GetLength()); + stream << str; + EXPECT_EQ(4u, stream.tellp()); + str = ""; + } + + // << operators can be chained. + { + std::ostringstream stream; + CFX_ByteStringC str1("abc"); + CFX_ByteStringC str2("def"); + stream << str1 << str2; + EXPECT_EQ("abcdef", stream.str()); + } +} diff --git a/core/fxcrt/cfx_widestring.cpp b/core/fxcrt/cfx_widestring.cpp index 46192de4ab..70a0cb63be 100644 --- a/core/fxcrt/cfx_widestring.cpp +++ b/core/fxcrt/cfx_widestring.cpp @@ -1058,3 +1058,12 @@ std::ostream& operator<<(std::ostream& os, const CFX_WideString& str) { os << str.UTF8Encode(); return os; } + +std::wostream& operator<<(std::wostream& os, const CFX_WideStringC& str) { + return os.write(str.c_str(), str.GetLength()); +} + +std::ostream& operator<<(std::ostream& os, const CFX_WideStringC& str) { + os << FX_UTF8Encode(str); + return os; +} diff --git a/core/fxcrt/cfx_widestring.h b/core/fxcrt/cfx_widestring.h index 3d69b0be55..0e477bfc8b 100644 --- a/core/fxcrt/cfx_widestring.h +++ b/core/fxcrt/cfx_widestring.h @@ -229,8 +229,9 @@ 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); +std::wostream& operator<<(std::wostream& os, const CFX_WideStringC& str); +std::ostream& operator<<(std::ostream& os, const CFX_WideStringC& str); namespace std { diff --git a/core/fxcrt/cfx_widestring_unittest.cpp b/core/fxcrt/cfx_widestring_unittest.cpp index 2578cb6429..4cd71d9997 100644 --- a/core/fxcrt/cfx_widestring_unittest.cpp +++ b/core/fxcrt/cfx_widestring_unittest.cpp @@ -1210,3 +1210,159 @@ TEST(fxcrt, WideOStreamWideStringOverload) { stream << str1 << str2; EXPECT_EQ(L"abcdef", stream.str()); } + +TEST(fxcrt, OStreamWideStringCOverload) { + // Basic case, empty string + { + std::ostringstream stream; + CFX_WideStringC str; + stream << str; + EXPECT_EQ("", stream.str()); + } + + // Basic case, non-empty string + { + std::ostringstream stream; + CFX_WideStringC str(L"def"); + stream << "abc" << str << "ghi"; + EXPECT_EQ("abcdefghi", stream.str()); + } + + // Basic case, wide character + { + std::ostringstream stream; + CFX_WideStringC str(L"\u20AC"); + stream << str; + EXPECT_EQ("\u20AC", stream.str()); + } + + // Changing the CFX_WideStringC does not change the stream it was written to. + { + std::ostringstream stream; + CFX_WideStringC str(L"abc"); + stream << str; + str = L"123"; + EXPECT_EQ("abc", stream.str()); + } + + // Writing it again to the stream will use the latest value. + { + std::ostringstream stream; + CFX_WideStringC str(L"abc"); + stream << str; + stream.str(""); + str = L"123"; + stream << str; + EXPECT_EQ("123", stream.str()); + } + + // Writing a CFX_WideStringC with nulls and no specified length treats it as + // a C-style null-terminated string. + { + wchar_t stringWithNulls[]{'x', 'y', '\0', 'z'}; + std::ostringstream stream; + CFX_WideStringC str(stringWithNulls); + EXPECT_EQ(2, str.GetLength()); + stream << str; + EXPECT_EQ(2u, stream.tellp()); + str = L""; + } + + // Writing a CFX_WideStringC with nulls but specifying its length treats it as + // a C++-style string. + { + wchar_t stringWithNulls[]{'x', 'y', '\0', 'z'}; + std::ostringstream stream; + CFX_WideStringC str(stringWithNulls, 4); + EXPECT_EQ(4, str.GetLength()); + stream << str; + EXPECT_EQ(4u, stream.tellp()); + str = L""; + } + + // << operators can be chained. + { + std::ostringstream stream; + CFX_WideStringC str1(L"abc"); + CFX_WideStringC str2(L"def"); + stream << str1 << str2; + EXPECT_EQ("abcdef", stream.str()); + } +} + +TEST(fxcrt, WideOStreamWideStringCOverload) { + // Basic case, empty string + { + std::wostringstream stream; + CFX_WideStringC str; + stream << str; + EXPECT_EQ(L"", stream.str()); + } + + // Basic case, non-empty string + { + std::wostringstream stream; + CFX_WideStringC str(L"def"); + stream << "abc" << str << "ghi"; + EXPECT_EQ(L"abcdefghi", stream.str()); + } + + // Basic case, wide character + { + std::wostringstream stream; + CFX_WideStringC str(L"\u20AC"); + stream << str; + EXPECT_EQ(L"\u20AC", stream.str()); + } + + // Changing the CFX_WideStringC does not change the stream it was written to. + { + std::wostringstream stream; + CFX_WideStringC str(L"abc"); + stream << str; + str = L"123"; + EXPECT_EQ(L"abc", stream.str()); + } + + // Writing it again to the stream will use the latest value. + { + std::wostringstream stream; + CFX_WideStringC str(L"abc"); + stream << str; + stream.str(L""); + str = L"123"; + stream << str; + EXPECT_EQ(L"123", stream.str()); + } + + // Writing a CFX_WideStringC with nulls and no specified length treats it as + // a C-style null-terminated string. + { + wchar_t stringWithNulls[]{'x', 'y', '\0', 'z'}; + std::wostringstream stream; + CFX_WideStringC str(stringWithNulls); + EXPECT_EQ(2, str.GetLength()); + stream << str; + EXPECT_EQ(2u, stream.tellp()); + } + + // Writing a CFX_WideStringC with nulls but specifying its length treats it as + // a C++-style string. + { + wchar_t stringWithNulls[]{'x', 'y', '\0', 'z'}; + std::wostringstream stream; + CFX_WideStringC str(stringWithNulls, 4); + EXPECT_EQ(4, str.GetLength()); + stream << str; + EXPECT_EQ(4u, stream.tellp()); + } + + // << operators can be chained. + { + std::wostringstream stream; + CFX_WideStringC str1(L"abc"); + CFX_WideStringC str2(L"def"); + stream << str1 << str2; + EXPECT_EQ(L"abcdef", stream.str()); + } +} -- cgit v1.2.3