From 44dd818b4df46ca9a6b6aae96b20b606253196eb Mon Sep 17 00:00:00 2001 From: Henrique Nakashima Date: Tue, 27 Jun 2017 10:15:48 -0400 Subject: Adding overload for ostream << CFX_ByteString Bug: pdfium:731 Change-Id: I285332c8f9d988327e8633cb0746af2b76c401e5 Reviewed-on: https://pdfium-review.googlesource.com/6911 Reviewed-by: dsinclair Commit-Queue: dsinclair --- core/fxcrt/cfx_bytestring.cpp | 5 ++++ core/fxcrt/cfx_bytestring.h | 2 ++ core/fxcrt/cfx_bytestring_unittest.cpp | 42 ++++++++++++++++++++++++++++++++++ fpdfsdk/cpdfsdk_widget.cpp | 16 ++++--------- 4 files changed, 53 insertions(+), 12 deletions(-) diff --git a/core/fxcrt/cfx_bytestring.cpp b/core/fxcrt/cfx_bytestring.cpp index b83c59ffeb..967bcce0eb 100644 --- a/core/fxcrt/cfx_bytestring.cpp +++ b/core/fxcrt/cfx_bytestring.cpp @@ -867,8 +867,13 @@ FX_STRSIZE FX_ftoa(float d, char* buf) { } return buf_size; } + CFX_ByteString CFX_ByteString::FormatFloat(float d, int precision) { char buf[32]; FX_STRSIZE len = FX_ftoa(d, buf); return CFX_ByteString(buf, len); } + +std::ostream& operator<<(std::ostream& os, const CFX_ByteString& str) { + return os.write(str.c_str(), str.GetLength()); +} diff --git a/core/fxcrt/cfx_bytestring.h b/core/fxcrt/cfx_bytestring.h index 23e02491c5..7459f27745 100644 --- a/core/fxcrt/cfx_bytestring.h +++ b/core/fxcrt/cfx_bytestring.h @@ -233,6 +233,8 @@ 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); + namespace std { template <> diff --git a/core/fxcrt/cfx_bytestring_unittest.cpp b/core/fxcrt/cfx_bytestring_unittest.cpp index 609f89201b..86fa3830c2 100644 --- a/core/fxcrt/cfx_bytestring_unittest.cpp +++ b/core/fxcrt/cfx_bytestring_unittest.cpp @@ -1259,3 +1259,45 @@ TEST(fxcrt, EqualNoCase) { EXPECT_FALSE(str.EqualNoCase("a")); EXPECT_FALSE(str.EqualNoCase("")); } + +TEST(fxcrt, OStreamByteStringOverload) { + // Basic case + std::ostringstream stream; + CFX_ByteString str("def"); + stream << "abc" << str << "ghi"; + EXPECT_EQ("abcdefghi", stream.str()); + + // Changing the CFX_ByteString does not change the stream it was written to. + str = "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()); + + char stringWithNulls[]{'x', 'y', '\0', 'z'}; + + // Writing a CFX_ByteString with nulls and no specified length treats it as + // a C-style null-terminated string. + str = CFX_ByteString(stringWithNulls); + EXPECT_EQ(2, str.GetLength()); + stream.str(""); + stream << str; + EXPECT_EQ(2u, stream.tellp()); + + // Writing a CFX_ByteString with nulls but specifying its length treats it as + // a C++-style string. + str = CFX_ByteString(stringWithNulls, 4); + EXPECT_EQ(4, str.GetLength()); + stream.str(""); + stream << str; + EXPECT_EQ(4u, stream.tellp()); + + // << operators can be chained. + CFX_ByteString str1("abc"); + CFX_ByteString str2("def"); + stream.str(""); + stream << str1 << str2; + EXPECT_EQ("abcdef", stream.str()); +} diff --git a/fpdfsdk/cpdfsdk_widget.cpp b/fpdfsdk/cpdfsdk_widget.cpp index e7e6c0131f..6670b29002 100644 --- a/fpdfsdk/cpdfsdk_widget.cpp +++ b/fpdfsdk/cpdfsdk_widget.cpp @@ -1400,12 +1400,11 @@ void CPDFSDK_Widget::ResetAppearance_ComboBox(const CFX_WideString* sValue) { CPWL_Color crText = GetTextPWLColor(); sBody << "BT\n" - << CPWL_Utils::GetColorAppStream(crText).c_str() << sEdit.c_str() - << "ET\n" + << CPWL_Utils::GetColorAppStream(crText) << sEdit << "ET\n" << "Q\nEMC\n"; } - sBody << CPWL_Utils::GetDropButtonAppStream(rcButton).c_str(); + sBody << CPWL_Utils::GetDropButtonAppStream(rcButton); CFX_ByteString sAP = GetBackgroundAppStream() + GetBorderAppStream() + CFX_ByteString(sBody); @@ -1462,7 +1461,6 @@ void CPDFSDK_Widget::ResetAppearance_ListBox() { CPWL_Color(COLORTYPE_RGB, 0, 51.0f / 255.0f, 113.0f / 255.0f), true) - .c_str() << rcItem.left << " " << rcItem.bottom << " " << rcItem.Width() << " " << rcItem.Height() << " re f\n" << "Q\n"; @@ -1470,16 +1468,13 @@ void CPDFSDK_Widget::ResetAppearance_ListBox() { sList << "BT\n" << CPWL_Utils::GetColorAppStream(CPWL_Color(COLORTYPE_GRAY, 1), true) - .c_str() << CPWL_Utils::GetEditAppStream(pEdit.get(), CFX_PointF(0.0f, fy)) - .c_str() << "ET\n"; } else { CPWL_Color crText = GetTextPWLColor(); sList << "BT\n" - << CPWL_Utils::GetColorAppStream(crText, true).c_str() + << CPWL_Utils::GetColorAppStream(crText, true) << CPWL_Utils::GetEditAppStream(pEdit.get(), CFX_PointF(0.0f, fy)) - .c_str() << "ET\n"; } @@ -1581,8 +1576,7 @@ void CPDFSDK_Widget::ResetAppearance_TextField(const CFX_WideString* sValue) { } CPWL_Color crText = GetTextPWLColor(); sBody << "BT\n" - << CPWL_Utils::GetColorAppStream(crText).c_str() << sEdit.c_str() - << "ET\n" + << CPWL_Utils::GetColorAppStream(crText) << sEdit << "ET\n" << "Q\nEMC\n"; } @@ -1595,7 +1589,6 @@ void CPDFSDK_Widget::ResetAppearance_TextField(const CFX_WideString* sValue) { sLines << "q\n" << GetBorderWidth() << " w\n" << CPWL_Utils::GetColorAppStream(GetBorderPWLColor(), false) - .c_str() << " 2 J 0 j\n"; for (int32_t i = 1; i < nMaxLen; ++i) { @@ -1620,7 +1613,6 @@ void CPDFSDK_Widget::ResetAppearance_TextField(const CFX_WideString* sValue) { sLines << "q\n" << GetBorderWidth() << " w\n" << CPWL_Utils::GetColorAppStream(GetBorderPWLColor(), false) - .c_str() << "[" << dsBorder.nDash << " " << dsBorder.nGap << "] " << dsBorder.nPhase << " d\n"; -- cgit v1.2.3