summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/fxcrt/cfx_bytestring.cpp5
-rw-r--r--core/fxcrt/cfx_bytestring.h2
-rw-r--r--core/fxcrt/cfx_bytestring_unittest.cpp42
-rw-r--r--fpdfsdk/cpdfsdk_widget.cpp16
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";