Remove ostringstream usage from CPDF_StreamParser.
Accumulates without conversion, so avoid copy at end (note that First()
is a copy-free when returning the entire string).
Change-Id: I575d5661a1f5f88f0fab4845362d085397919575
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/89110
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
diff --git a/core/fpdfapi/page/cpdf_streamparser.cpp b/core/fpdfapi/page/cpdf_streamparser.cpp
index 212e169..14a474d 100644
--- a/core/fpdfapi/page/cpdf_streamparser.cpp
+++ b/core/fpdfapi/page/cpdf_streamparser.cpp
@@ -10,7 +10,6 @@
#include <algorithm>
#include <memory>
-#include <sstream>
#include <utility>
#include "constants/stream_dict_common.h"
@@ -461,32 +460,27 @@
if (!PositionIsInBounds())
return ByteString();
- uint8_t ch = m_pBuf[m_Pos++];
- std::ostringstream buf;
+ ByteString buf;
int parlevel = 0;
int status = 0;
int iEscCode = 0;
+ uint8_t ch = m_pBuf[m_Pos++];
while (1) {
switch (status) {
case 0:
if (ch == ')') {
if (parlevel == 0) {
- if (buf.tellp() <= 0)
- return ByteString();
-
- return ByteString(
- buf.str().c_str(),
- std::min(static_cast<size_t>(buf.tellp()), kMaxStringLength));
+ return buf.First(std::min(buf.GetLength(), kMaxStringLength));
}
parlevel--;
- buf << ')';
+ buf += ')';
} else if (ch == '(') {
parlevel++;
- buf << '(';
+ buf += '(';
} else if (ch == '\\') {
status = 1;
} else {
- buf << static_cast<char>(ch);
+ buf += static_cast<char>(ch);
}
break;
case 1:
@@ -502,17 +496,17 @@
if (ch == '\n') {
// Do nothing.
} else if (ch == 'n') {
- buf << '\n';
+ buf += '\n';
} else if (ch == 'r') {
- buf << '\r';
+ buf += '\r';
} else if (ch == 't') {
- buf << '\t';
+ buf += '\t';
} else if (ch == 'b') {
- buf << '\b';
+ buf += '\b';
} else if (ch == 'f') {
- buf << '\f';
+ buf += '\f';
} else {
- buf << static_cast<char>(ch);
+ buf += static_cast<char>(ch);
}
status = 0;
break;
@@ -522,7 +516,7 @@
iEscCode * 8 + FXSYS_DecimalCharToInt(static_cast<char>(ch));
status = 3;
} else {
- buf << static_cast<char>(iEscCode);
+ buf += static_cast<char>(iEscCode);
status = 0;
continue;
}
@@ -531,10 +525,10 @@
if (FXSYS_IsOctalDigit(ch)) {
iEscCode =
iEscCode * 8 + FXSYS_DecimalCharToInt(static_cast<char>(ch));
- buf << static_cast<char>(iEscCode);
+ buf += static_cast<char>(iEscCode);
status = 0;
} else {
- buf << static_cast<char>(iEscCode);
+ buf += static_cast<char>(iEscCode);
status = 0;
continue;
}
@@ -546,26 +540,17 @@
break;
}
if (!PositionIsInBounds())
- break;
+ return buf.First(std::min(buf.GetLength(), kMaxStringLength));
ch = m_pBuf[m_Pos++];
}
- if (PositionIsInBounds())
- ++m_Pos;
-
- if (buf.tellp() <= 0)
- return ByteString();
-
- return ByteString(
- buf.str().c_str(),
- std::min(static_cast<size_t>(buf.tellp()), kMaxStringLength));
}
ByteString CPDF_StreamParser::ReadHexString() {
if (!PositionIsInBounds())
return ByteString();
- std::ostringstream buf;
+ ByteString buf;
bool bFirst = true;
int code = 0;
while (PositionIsInBounds()) {
@@ -581,19 +566,14 @@
code = val * 16;
} else {
code += val;
- buf << static_cast<uint8_t>(code);
+ buf += static_cast<uint8_t>(code);
}
bFirst = !bFirst;
}
if (!bFirst)
- buf << static_cast<char>(code);
+ buf += static_cast<char>(code);
- if (buf.tellp() <= 0)
- return ByteString();
-
- return ByteString(
- buf.str().c_str(),
- std::min(static_cast<size_t>(buf.tellp()), kMaxStringLength));
+ return buf.First(std::min<size_t>(buf.GetLength(), kMaxStringLength));
}
bool CPDF_StreamParser::PositionIsInBounds() const {