Make CFX_SeekableStreamProxy a subclass of IFX_SeekableReadStream

This CL changes CFX_SeekableStreamProxy to be an IFX_SeekableReadStream
subclass.

This is a reland of https://pdfium-review.googlesource.com/c/pdfium/+/30879
after fix bad merge.

Change-Id: Iad58abe7e065541867f202059a944e9be4da5713
Reviewed-on: https://pdfium-review.googlesource.com/31195
Reviewed-by: Henrique Nakashima <hnakashima@chromium.org>
Commit-Queue: dsinclair <dsinclair@chromium.org>
diff --git a/core/fxcrt/cfx_seekablestreamproxy.cpp b/core/fxcrt/cfx_seekablestreamproxy.cpp
index d8fe4f4..eb5874b 100644
--- a/core/fxcrt/cfx_seekablestreamproxy.cpp
+++ b/core/fxcrt/cfx_seekablestreamproxy.cpp
@@ -134,7 +134,7 @@
 #define BOM_UTF16_LE 0x0000FEFF
 
 CFX_SeekableStreamProxy::CFX_SeekableStreamProxy(
-    const RetainPtr<IFX_SeekableStream>& stream)
+    const RetainPtr<IFX_SeekableReadStream>& stream)
     : m_wCodePage(FX_CODEPAGE_DefANSI),
       m_wBOMLength(0),
       m_iPosition(0),
@@ -169,6 +169,18 @@
 
 CFX_SeekableStreamProxy::~CFX_SeekableStreamProxy() = default;
 
+FX_FILESIZE CFX_SeekableStreamProxy::GetSize() {
+  return m_pStream->GetSize();
+}
+
+FX_FILESIZE CFX_SeekableStreamProxy::GetPosition() {
+  return m_iPosition;
+}
+
+bool CFX_SeekableStreamProxy::IsEOF() {
+  return m_iPosition >= GetSize();
+}
+
 void CFX_SeekableStreamProxy::Seek(From eSeek, FX_FILESIZE iOffset) {
   switch (eSeek) {
     case From::Begin:
@@ -182,7 +194,7 @@
     } break;
   }
   m_iPosition =
-      pdfium::clamp(m_iPosition, static_cast<FX_FILESIZE>(0), GetLength());
+      pdfium::clamp(m_iPosition, static_cast<FX_FILESIZE>(0), GetSize());
 }
 
 void CFX_SeekableStreamProxy::SetCodePage(uint16_t wCodePage) {
@@ -195,7 +207,7 @@
   ASSERT(pBuffer && iBufferSize > 0);
 
   iBufferSize =
-      std::min(iBufferSize, static_cast<size_t>(GetLength() - m_iPosition));
+      std::min(iBufferSize, static_cast<size_t>(GetSize() - m_iPosition));
   if (iBufferSize <= 0)
     return 0;
 
@@ -208,27 +220,24 @@
   return new_pos.IsValid() ? iBufferSize : 0;
 }
 
-size_t CFX_SeekableStreamProxy::ReadString(wchar_t* pStr,
-                                           size_t iMaxLength,
-                                           bool* bEOS) {
-  if (!pStr || iMaxLength == 0)
+size_t CFX_SeekableStreamProxy::ReadBlock(void* pStr, size_t size) {
+  if (!pStr || size == 0)
     return 0;
 
   if (m_wCodePage == FX_CODEPAGE_UTF16LE ||
       m_wCodePage == FX_CODEPAGE_UTF16BE) {
-    size_t iBytes = iMaxLength * 2;
+    size_t iBytes = size * 2;
     size_t iLen = ReadData(reinterpret_cast<uint8_t*>(pStr), iBytes);
-    iMaxLength = iLen / 2;
-    if (sizeof(wchar_t) > 2 && iMaxLength > 0)
-      UTF16ToWChar(pStr, iMaxLength);
+    size = iLen / 2;
+    if (sizeof(wchar_t) > 2 && size > 0)
+      UTF16ToWChar(pStr, size);
 
     if (m_wCodePage == FX_CODEPAGE_UTF16BE)
-      SwapByteOrder(pStr, iMaxLength);
+      SwapByteOrder(static_cast<wchar_t*>(pStr), size);
 
   } else {
     FX_FILESIZE pos = GetPosition();
-    size_t iBytes =
-        std::min(iMaxLength, static_cast<size_t>(GetLength() - pos));
+    size_t iBytes = std::min(size, static_cast<size_t>(GetSize() - pos));
 
     if (iBytes > 0) {
       std::vector<uint8_t> buf(iBytes);
@@ -238,14 +247,21 @@
         return 0;
 
       size_t iSrc = 0;
-      std::tie(iSrc, iMaxLength) = UTF8Decode(
-          reinterpret_cast<const char*>(buf.data()), iLen, pStr, iMaxLength);
+      std::tie(iSrc, size) =
+          UTF8Decode(reinterpret_cast<const char*>(buf.data()), iLen,
+                     static_cast<wchar_t*>(pStr), size);
       Seek(From::Current, iSrc - iLen);
     } else {
-      iMaxLength = 0;
+      size = 0;
     }
   }
 
-  *bEOS = IsEOF();
-  return iMaxLength;
+  return size;
+}
+
+bool CFX_SeekableStreamProxy::ReadBlock(void* pStr,
+                                        FX_FILESIZE offset,
+                                        size_t size) {
+  NOTREACHED();
+  return false;
 }
diff --git a/core/fxcrt/cfx_seekablestreamproxy.h b/core/fxcrt/cfx_seekablestreamproxy.h
index 5e0eecb..d389baf 100644
--- a/core/fxcrt/cfx_seekablestreamproxy.h
+++ b/core/fxcrt/cfx_seekablestreamproxy.h
@@ -13,7 +13,7 @@
 #include "core/fxcrt/fx_system.h"
 #include "core/fxcrt/retain_ptr.h"
 
-class CFX_SeekableStreamProxy : public Retainable {
+class CFX_SeekableStreamProxy : public IFX_SeekableReadStream {
  public:
   enum class From {
     Begin = 0,
@@ -23,27 +23,28 @@
   template <typename T, typename... Args>
   friend RetainPtr<T> pdfium::MakeRetain(Args&&... args);
 
-  FX_FILESIZE GetLength() const { return m_pStream->GetSize(); }
-  FX_FILESIZE GetPosition() { return m_iPosition; }
-  size_t GetBOMLength() const { return m_wBOMLength; }
-  bool IsEOF() const { return m_iPosition >= GetLength(); }
+  FX_FILESIZE GetSize() override;
+  FX_FILESIZE GetPosition() override;
+  bool IsEOF() override;
 
-  void Seek(From eSeek, FX_FILESIZE iOffset);
-  size_t ReadString(wchar_t* pStr, size_t iMaxLength, bool* bEOS);
+  size_t ReadBlock(void* pStr, size_t size) override;
+  bool ReadBlock(void* pStr, FX_FILESIZE offset, size_t size) override;
 
   uint16_t GetCodePage() const { return m_wCodePage; }
   void SetCodePage(uint16_t wCodePage);
 
  private:
-  explicit CFX_SeekableStreamProxy(const RetainPtr<IFX_SeekableStream>& stream);
+  explicit CFX_SeekableStreamProxy(
+      const RetainPtr<IFX_SeekableReadStream>& stream);
   ~CFX_SeekableStreamProxy() override;
 
+  void Seek(From eSeek, FX_FILESIZE iOffset);
   size_t ReadData(uint8_t* pBuffer, size_t iBufferSize);
 
   uint16_t m_wCodePage;
   size_t m_wBOMLength;
   FX_FILESIZE m_iPosition;
-  RetainPtr<IFX_SeekableStream> m_pStream;
+  RetainPtr<IFX_SeekableReadStream> m_pStream;
 };
 
 #endif  // CORE_FXCRT_CFX_SEEKABLESTREAMPROXY_H_
diff --git a/core/fxcrt/xml/cfx_xmlparser.cpp b/core/fxcrt/xml/cfx_xmlparser.cpp
index 7788a42..bf57829 100644
--- a/core/fxcrt/xml/cfx_xmlparser.cpp
+++ b/core/fxcrt/xml/cfx_xmlparser.cpp
@@ -11,6 +11,7 @@
 #include <iterator>
 #include <utility>
 
+#include "core/fxcrt/cfx_seekablestreamproxy.h"
 #include "core/fxcrt/fx_codepage.h"
 #include "core/fxcrt/fx_extension.h"
 #include "core/fxcrt/fx_safe_types.h"
@@ -57,13 +58,10 @@
 }
 
 CFX_XMLParser::CFX_XMLParser(CFX_XMLNode* pParent,
-                             const RetainPtr<IFX_SeekableStream>& pStream)
+                             const RetainPtr<IFX_SeekableReadStream>& pStream)
     : m_pParent(pParent),
       m_pChild(nullptr),
-      m_pStream(pdfium::MakeRetain<CFX_SeekableStreamProxy>(pStream)),
       m_iXMLPlaneSize(1024),
-      m_iCurrentPos(0),
-      m_bEOS(false),
       m_Start(0),
       m_End(0),
       m_CurNodeType(FX_XMLNODE_Unknown),
@@ -77,18 +75,19 @@
   ASSERT(m_pParent);
   ASSERT(pStream);
 
-  uint16_t wCodePage = m_pStream->GetCodePage();
+  auto proxy = pdfium::MakeRetain<CFX_SeekableStreamProxy>(pStream);
+  uint16_t wCodePage = proxy->GetCodePage();
   if (wCodePage != FX_CODEPAGE_UTF16LE && wCodePage != FX_CODEPAGE_UTF16BE &&
       wCodePage != FX_CODEPAGE_UTF8) {
-    m_pStream->SetCodePage(FX_CODEPAGE_UTF8);
+    proxy->SetCodePage(FX_CODEPAGE_UTF8);
   }
+  m_pStream = proxy;
 
   m_NodeStack.push(m_pParent);
 
   m_iXMLPlaneSize =
       std::min(m_iXMLPlaneSize,
-               pdfium::base::checked_cast<size_t>(m_pStream->GetLength()));
-  m_iCurrentPos = m_pStream->GetBOMLength();
+               pdfium::base::checked_cast<size_t>(m_pStream->GetSize()));
 
   FX_SAFE_SIZE_T alloc_size_safe = m_iXMLPlaneSize;
   alloc_size_safe += 1;  // For NUL.
@@ -217,28 +216,20 @@
     return m_syntaxParserResult;
   }
 
-  FX_FILESIZE iStreamLength = m_pStream->GetLength();
-  FX_FILESIZE iPos;
-
   FX_XmlSyntaxResult syntaxParserResult = FX_XmlSyntaxResult::None;
   while (true) {
     if (m_Start >= m_End) {
-      if (m_bEOS || m_iCurrentPos >= iStreamLength) {
+      if (m_pStream->IsEOF()) {
         m_syntaxParserResult = FX_XmlSyntaxResult::EndOfString;
         return m_syntaxParserResult;
       }
-      if (m_pStream->GetPosition() != m_iCurrentPos)
-        m_pStream->Seek(CFX_SeekableStreamProxy::From::Begin, m_iCurrentPos);
 
       size_t buffer_chars =
-          m_pStream->ReadString(m_Buffer.data(), m_iXMLPlaneSize, &m_bEOS);
-      iPos = m_pStream->GetPosition();
+          m_pStream->ReadBlock(m_Buffer.data(), m_iXMLPlaneSize);
       if (buffer_chars == 0) {
-        m_iCurrentPos = iStreamLength;
         m_syntaxParserResult = FX_XmlSyntaxResult::EndOfString;
         return m_syntaxParserResult;
       }
-      m_iCurrentPos = iPos;
       m_Start = 0;
       m_End = buffer_chars;
     }
@@ -665,13 +656,7 @@
 }
 
 bool CFX_XMLParser::GetStatus() const {
-  if (!m_pStream)
-    return false;
-
-  int32_t iStreamLength = m_pStream->GetLength();
-  if (iStreamLength < 1)
-    return true;
-  return m_syntaxParserResult != FX_XmlSyntaxResult::Error;
+  return m_pStream && m_syntaxParserResult != FX_XmlSyntaxResult::Error;
 }
 
 void CFX_XMLParser::ParseTextChar(wchar_t character) {
diff --git a/core/fxcrt/xml/cfx_xmlparser.h b/core/fxcrt/xml/cfx_xmlparser.h
index f369453..6405b61 100644
--- a/core/fxcrt/xml/cfx_xmlparser.h
+++ b/core/fxcrt/xml/cfx_xmlparser.h
@@ -12,14 +12,13 @@
 #include <vector>
 
 #include "core/fxcrt/cfx_blockbuffer.h"
-#include "core/fxcrt/cfx_seekablestreamproxy.h"
 #include "core/fxcrt/fx_string.h"
 #include "core/fxcrt/retain_ptr.h"
 #include "core/fxcrt/xml/cfx_xmlnode.h"
 
 class CFX_XMLElement;
 class CFX_XMLNode;
-class IFX_SeekableStream;
+class IFX_SeekableReadStream;
 
 enum class FX_XmlSyntaxResult {
   None,
@@ -44,7 +43,7 @@
   static bool IsXMLNameChar(wchar_t ch, bool bFirstChar);
 
   CFX_XMLParser(CFX_XMLNode* pParent,
-                const RetainPtr<IFX_SeekableStream>& pStream);
+                const RetainPtr<IFX_SeekableReadStream>& pStream);
   virtual ~CFX_XMLParser();
 
   bool Parse();
@@ -100,11 +99,9 @@
   std::stack<CFX_XMLNode*> m_NodeStack;
   WideString m_ws1;
 
-  RetainPtr<CFX_SeekableStreamProxy> m_pStream;
+  RetainPtr<IFX_SeekableReadStream> m_pStream;
   size_t m_iXMLPlaneSize;
-  FX_FILESIZE m_iCurrentPos;
   std::vector<wchar_t> m_Buffer;
-  bool m_bEOS;
   FX_FILESIZE m_Start;  // Start position in m_Buffer
   FX_FILESIZE m_End;    // End position in m_Buffer
   FX_XMLNODETYPE m_CurNodeType;