Move parsing logic from FPDF_DataAvail into CPDF_DataAvail.

Change-Id: Iacae9723e88eeae52154276b2478e4fd8c309c2d
Reviewed-on: https://pdfium-review.googlesource.com/15512
Commit-Queue: Art Snake <art-snake@yandex-team.ru>
Reviewed-by: dsinclair <dsinclair@chromium.org>
diff --git a/core/fpdfapi/parser/cpdf_data_avail.cpp b/core/fpdfapi/parser/cpdf_data_avail.cpp
index 4259d73..e72d7cd 100644
--- a/core/fpdfapi/parser/cpdf_data_avail.cpp
+++ b/core/fpdfapi/parser/cpdf_data_avail.cpp
@@ -106,10 +106,6 @@
   m_pHintTables.reset();
 }
 
-void CPDF_DataAvail::SetDocument(CPDF_Document* pDoc) {
-  m_pDocument = pDoc;
-}
-
 CPDF_DataAvail::DocAvailStatus CPDF_DataAvail::IsDocAvail(
     DownloadHints* pHints) {
   if (!m_dwFileLen)
@@ -1044,6 +1040,33 @@
   return obj_avail.CheckAvail() == DocAvailStatus::DataAvailable;
 }
 
+std::pair<CPDF_Parser::Error, std::unique_ptr<CPDF_Document>>
+CPDF_DataAvail::ParseDocument(const char* password) {
+  if (m_pDocument) {
+    // We already returned parsed document.
+    return std::make_pair(CPDF_Parser::HANDLER_ERROR, nullptr);
+  }
+  auto parser = pdfium::MakeUnique<CPDF_Parser>();
+  parser->SetPassword(password);
+  auto document = pdfium::MakeUnique<CPDF_Document>(std::move(parser));
+
+  CPDF_ReadValidator::Session read_session(GetValidator().Get());
+  CPDF_Parser::Error error = document->GetParser()->StartLinearizedParse(
+      GetFileRead(), document.get());
+
+  // Additional check, that all ok.
+  if (GetValidator()->has_read_problems()) {
+    NOTREACHED();
+    return std::make_pair(CPDF_Parser::HANDLER_ERROR, nullptr);
+  }
+
+  if (error != CPDF_Parser::SUCCESS)
+    return std::make_pair(error, nullptr);
+
+  m_pDocument = document.get();
+  return std::make_pair(CPDF_Parser::SUCCESS, std::move(document));
+}
+
 CPDF_DataAvail::PageNode::PageNode() : m_type(PDF_PAGENODE_UNKNOWN) {}
 
 CPDF_DataAvail::PageNode::~PageNode() {}
diff --git a/core/fpdfapi/parser/cpdf_data_avail.h b/core/fpdfapi/parser/cpdf_data_avail.h
index 8916088..001bf22 100644
--- a/core/fpdfapi/parser/cpdf_data_avail.h
+++ b/core/fpdfapi/parser/cpdf_data_avail.h
@@ -10,6 +10,7 @@
 #include <map>
 #include <memory>
 #include <set>
+#include <utility>
 #include <vector>
 
 #include "core/fpdfapi/parser/cpdf_parser.h"
@@ -96,7 +97,6 @@
   ~CPDF_DataAvail();
 
   DocAvailStatus IsDocAvail(DownloadHints* pHints);
-  void SetDocument(CPDF_Document* pDoc);
   DocAvailStatus IsPageAvail(uint32_t dwPage, DownloadHints* pHints);
   DocFormStatus IsFormAvail(DownloadHints* pHints);
   DocLinearizationStatus IsLinearizedPDF();
@@ -105,6 +105,9 @@
   CPDF_Dictionary* GetPage(int index);
   RetainPtr<CPDF_ReadValidator> GetValidator() const;
 
+  std::pair<CPDF_Parser::Error, std::unique_ptr<CPDF_Document>> ParseDocument(
+      const char* password);
+
   const CPDF_HintTables* GetHintTables() const { return m_pHintTables.get(); }
 
  protected:
diff --git a/fpdfsdk/fpdf_dataavail.cpp b/fpdfsdk/fpdf_dataavail.cpp
index 0a74c9c..b1a134d 100644
--- a/fpdfsdk/fpdf_dataavail.cpp
+++ b/fpdfsdk/fpdf_dataavail.cpp
@@ -147,20 +147,15 @@
   auto* pDataAvail = FPDFAvailContextFromFPDFAvail(avail);
   if (!pDataAvail)
     return nullptr;
-
-  auto pParser = pdfium::MakeUnique<CPDF_Parser>();
-  pParser->SetPassword(password);
-
-  auto pDocument = pdfium::MakeUnique<CPDF_Document>(std::move(pParser));
-  CPDF_Parser::Error error = pDocument->GetParser()->StartLinearizedParse(
-      pDataAvail->m_pDataAvail->GetFileRead(), pDocument.get());
+  CPDF_Parser::Error error;
+  std::unique_ptr<CPDF_Document> document;
+  std::tie(error, document) = pDataAvail->m_pDataAvail->ParseDocument(password);
   if (error != CPDF_Parser::SUCCESS) {
     ProcessParseError(error);
     return nullptr;
   }
-  pDataAvail->m_pDataAvail->SetDocument(pDocument.get());
-  CheckUnSupportError(pDocument.get(), FPDF_ERR_SUCCESS);
-  return FPDFDocumentFromCPDFDocument(pDocument.release());
+  CheckUnSupportError(document.get(), FPDF_ERR_SUCCESS);
+  return FPDFDocumentFromCPDFDocument(document.release());
 }
 
 FPDF_EXPORT int FPDF_CALLCONV FPDFAvail_GetFirstPageNum(FPDF_DOCUMENT doc) {