Avoid string streams in PDF_EncodeString() and PDF_HexEncodeString().

Pass arguments by stringview while at it.

Change-Id: Ib89b1850cec881ce8de7d6d7d2ae01c217f6e3b8
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/88971
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
diff --git a/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp b/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp
index 8740268..d6ab0b0 100644
--- a/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp
+++ b/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp
@@ -589,6 +589,6 @@
     if (charcode != CPDF_Font::kInvalidCharCode)
       pFont->AppendChar(&text, charcode);
   }
-  *buf << PDF_HexEncodeString(text) << " Tj ET";
+  *buf << PDF_HexEncodeString(text.AsStringView()) << " Tj ET";
   *buf << " Q\n";
 }
diff --git a/core/fpdfapi/parser/cpdf_string.cpp b/core/fpdfapi/parser/cpdf_string.cpp
index 001865b..2501cd1 100644
--- a/core/fpdfapi/parser/cpdf_string.cpp
+++ b/core/fpdfapi/parser/cpdf_string.cpp
@@ -74,12 +74,13 @@
     encrypted_data = encryptor->Encrypt(data);
     data = encrypted_data;
   }
-  const ByteString raw(data.data(), data.size());
-  const ByteString content =
+  ByteStringView raw(data.data(), data.size());
+  ByteString content =
       m_bHex ? PDF_HexEncodeString(raw) : PDF_EncodeString(raw);
   return archive->WriteString(content.AsStringView());
 }
 
 ByteString CPDF_String::EncodeString() const {
-  return m_bHex ? PDF_HexEncodeString(m_String) : PDF_EncodeString(m_String);
+  return m_bHex ? PDF_HexEncodeString(m_String.AsStringView())
+                : PDF_EncodeString(m_String.AsStringView());
 }
diff --git a/core/fpdfapi/parser/fpdf_parser_decode.cpp b/core/fpdfapi/parser/fpdf_parser_decode.cpp
index b9b3c94..9a5a8eb 100644
--- a/core/fpdfapi/parser/fpdf_parser_decode.cpp
+++ b/core/fpdfapi/parser/fpdf_parser_decode.cpp
@@ -10,7 +10,6 @@
 #include <limits.h>
 
 #include <algorithm>
-#include <sstream>
 #include <utility>
 #include <vector>
 
@@ -560,40 +559,40 @@
   return result;
 }
 
-ByteString PDF_EncodeString(const ByteString& src) {
-  std::ostringstream result;
-  int srclen = src.GetLength();
-  result << '(';
-  for (int i = 0; i < srclen; ++i) {
+ByteString PDF_EncodeString(ByteStringView src) {
+  ByteString result;
+  result.Reserve(src.GetLength() + 2);
+  result += '(';
+  for (size_t i = 0; i < src.GetLength(); ++i) {
     uint8_t ch = src[i];
     if (ch == 0x0a) {
-      result << "\\n";
+      result += "\\n";
       continue;
     }
     if (ch == 0x0d) {
-      result << "\\r";
+      result += "\\r";
       continue;
     }
     if (ch == ')' || ch == '\\' || ch == '(')
-      result << '\\';
-    result << static_cast<char>(ch);
+      result += '\\';
+    result += static_cast<char>(ch);
   }
-  result << ')';
-  return ByteString(result);
+  result += ')';
+  return result;
 }
 
-ByteString PDF_HexEncodeString(const ByteString& src) {
-  std::ostringstream result;
-  int srclen = src.GetLength();
-  result << '<';
-  for (int i = 0; i < srclen; ++i) {
+ByteString PDF_HexEncodeString(ByteStringView src) {
+  ByteString result;
+  result.Reserve(2 * src.GetLength() + 2);
+  result += '<';
+  for (size_t i = 0; i < src.GetLength(); ++i) {
     char buf[2];
     FXSYS_IntToTwoHexChars(src[i], buf);
-    result << buf[0];
-    result << buf[1];
+    result += buf[0];
+    result += buf[1];
   }
-  result << '>';
-  return ByteString(result);
+  result += '>';
+  return result;
 }
 
 bool FlateEncode(pdfium::span<const uint8_t> src_span,
diff --git a/core/fpdfapi/parser/fpdf_parser_decode.h b/core/fpdfapi/parser/fpdf_parser_decode.h
index de3c3f3..537456b 100644
--- a/core/fpdfapi/parser/fpdf_parser_decode.h
+++ b/core/fpdfapi/parser/fpdf_parser_decode.h
@@ -30,8 +30,8 @@
 
 bool ValidateDecoderPipeline(const CPDF_Array* pDecoders);
 
-ByteString PDF_EncodeString(const ByteString& src);
-ByteString PDF_HexEncodeString(const ByteString& src);
+ByteString PDF_EncodeString(ByteStringView src);
+ByteString PDF_HexEncodeString(ByteStringView src);
 WideString PDF_DecodeText(pdfium::span<const uint8_t> span);
 ByteString PDF_EncodeText(const WideString& str);
 
diff --git a/core/fpdfdoc/cpdf_generateap.cpp b/core/fpdfdoc/cpdf_generateap.cpp
index cc800d2..276e3ef 100644
--- a/core/fpdfdoc/cpdf_generateap.cpp
+++ b/core/fpdfdoc/cpdf_generateap.cpp
@@ -75,10 +75,10 @@
   return sWord;
 }
 
-ByteString GetWordRenderString(const ByteString& strWords) {
-  if (strWords.GetLength() > 0)
-    return PDF_EncodeString(strWords) + " Tj\n";
-  return ByteString();
+ByteString GetWordRenderString(ByteStringView strWords) {
+  if (strWords.IsEmpty())
+    return ByteString();
+  return PDF_EncodeString(strWords) + " Tj\n";
 }
 
 ByteString GetFontSetString(IPVT_FontMap* pFontMap,
@@ -111,7 +111,7 @@
     if (bContinuous) {
       if (place.LineCmp(oldplace) != 0) {
         if (!sWords.IsEmpty()) {
-          sLineStream << GetWordRenderString(sWords);
+          sLineStream << GetWordRenderString(sWords.AsStringView());
           sEditStream << sLineStream.str();
           sLineStream.str("");
           sWords.clear();
@@ -136,7 +136,7 @@
       if (pIterator->GetWord(word)) {
         if (word.nFontIndex != nCurFontIndex) {
           if (!sWords.IsEmpty()) {
-            sLineStream << GetWordRenderString(sWords);
+            sLineStream << GetWordRenderString(sWords.AsStringView());
             sWords.clear();
           }
           sLineStream << GetFontSetString(pFontMap, word.nFontIndex,
@@ -162,12 +162,13 @@
           nCurFontIndex = word.nFontIndex;
         }
         sEditStream << GetWordRenderString(
-            GetPDFWordString(pFontMap, nCurFontIndex, word.Word, SubWord));
+            GetPDFWordString(pFontMap, nCurFontIndex, word.Word, SubWord)
+                .AsStringView());
       }
     }
   }
   if (!sWords.IsEmpty()) {
-    sLineStream << GetWordRenderString(sWords);
+    sLineStream << GetWordRenderString(sWords.AsStringView());
     sEditStream << sLineStream.str();
   }
   return ByteString(sEditStream);
diff --git a/fpdfsdk/cpdfsdk_appstream.cpp b/fpdfsdk/cpdfsdk_appstream.cpp
index 37dfbc0..2dd0b27 100644
--- a/fpdfsdk/cpdfsdk_appstream.cpp
+++ b/fpdfsdk/cpdfsdk_appstream.cpp
@@ -580,10 +580,10 @@
   return ByteString(sRet);
 }
 
-ByteString GetWordRenderString(const ByteString& strWords) {
-  if (strWords.GetLength() > 0)
-    return PDF_EncodeString(strWords) + " " + kShowTextOperator + "\n";
-  return ByteString();
+ByteString GetWordRenderString(ByteStringView strWords) {
+  if (strWords.IsEmpty())
+    return ByteString();
+  return PDF_EncodeString(strWords) + " " + kShowTextOperator + "\n";
 }
 
 ByteString GetEditAppStream(CPWL_EditImpl* pEdit,
@@ -605,7 +605,7 @@
     if (bContinuous) {
       if (place.LineCmp(oldplace) != 0) {
         if (!sWords.IsEmpty()) {
-          sEditStream << GetWordRenderString(sWords);
+          sEditStream << GetWordRenderString(sWords.AsStringView());
           sWords.clear();
         }
 
@@ -632,7 +632,7 @@
       if (pIterator->GetWord(word)) {
         if (word.nFontIndex != nCurFontIndex) {
           if (!sWords.IsEmpty()) {
-            sEditStream << GetWordRenderString(sWords);
+            sEditStream << GetWordRenderString(sWords.AsStringView());
             sWords.clear();
           }
           sEditStream << GetFontSetString(pEdit->GetFontMap(), word.nFontIndex,
@@ -660,13 +660,14 @@
           nCurFontIndex = word.nFontIndex;
         }
         sEditStream << GetWordRenderString(
-            pEdit->GetPDFWordString(nCurFontIndex, word.Word, SubWord));
+            pEdit->GetPDFWordString(nCurFontIndex, word.Word, SubWord)
+                .AsStringView());
       }
     }
   }
 
   if (!sWords.IsEmpty())
-    sEditStream << GetWordRenderString(sWords);
+    sEditStream << GetWordRenderString(sWords.AsStringView());
 
   std::ostringstream sAppStream;
   if (sEditStream.tellp() > 0) {
diff --git a/fpdfsdk/fpdf_attachment.cpp b/fpdfsdk/fpdf_attachment.cpp
index 4955b1d..d1fba0d 100644
--- a/fpdfsdk/fpdf_attachment.cpp
+++ b/fpdfsdk/fpdf_attachment.cpp
@@ -188,7 +188,8 @@
   if (bsKey == kChecksumKey && !value.IsEmpty()) {
     CPDF_String* stringValue = pParamsDict->GetObjectFor(bsKey)->AsString();
     if (stringValue->IsHex()) {
-      ByteString encoded = PDF_HexEncodeString(stringValue->GetString());
+      ByteString encoded =
+          PDF_HexEncodeString(stringValue->GetString().AsStringView());
       value = pdfium::MakeRetain<CPDF_String>(nullptr, encoded, false)
                   ->GetUnicodeText();
     }