pdfium_document.cc 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. // Copyright 2018 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "pdf/pdfium/pdfium_document.h"
  5. #include <utility>
  6. #include "base/check.h"
  7. #include "base/memory/raw_ptr.h"
  8. #include "pdf/loader/document_loader.h"
  9. namespace chrome_pdf {
  10. namespace {
  11. class FileAvail : public FX_FILEAVAIL {
  12. public:
  13. explicit FileAvail(DocumentLoader* doc_loader) : doc_loader_(doc_loader) {
  14. DCHECK(doc_loader);
  15. version = 1;
  16. IsDataAvail = &FileAvail::IsDataAvailImpl;
  17. }
  18. private:
  19. // PDFium interface to check is block of data is available.
  20. static FPDF_BOOL IsDataAvailImpl(FX_FILEAVAIL* param,
  21. size_t offset,
  22. size_t size) {
  23. auto* file_avail = static_cast<FileAvail*>(param);
  24. return file_avail->doc_loader_->IsDataAvailable(offset, size);
  25. }
  26. raw_ptr<DocumentLoader> doc_loader_;
  27. };
  28. class DownloadHints : public FX_DOWNLOADHINTS {
  29. public:
  30. explicit DownloadHints(DocumentLoader* doc_loader) : doc_loader_(doc_loader) {
  31. DCHECK(doc_loader);
  32. version = 1;
  33. AddSegment = &DownloadHints::AddSegmentImpl;
  34. }
  35. private:
  36. // PDFium interface to request download of the block of data.
  37. static void AddSegmentImpl(FX_DOWNLOADHINTS* param,
  38. size_t offset,
  39. size_t size) {
  40. auto* download_hints = static_cast<DownloadHints*>(param);
  41. return download_hints->doc_loader_->RequestData(offset, size);
  42. }
  43. raw_ptr<DocumentLoader> doc_loader_;
  44. };
  45. class FileAccess : public FPDF_FILEACCESS {
  46. public:
  47. explicit FileAccess(DocumentLoader* doc_loader) : doc_loader_(doc_loader) {
  48. DCHECK(doc_loader);
  49. m_FileLen = 0;
  50. m_GetBlock = &FileAccess::GetBlockImpl;
  51. m_Param = this;
  52. }
  53. private:
  54. // PDFium interface to get block of data.
  55. static int GetBlockImpl(void* param,
  56. unsigned long position,
  57. unsigned char* buffer,
  58. unsigned long size) {
  59. auto* file_access = static_cast<FileAccess*>(param);
  60. return file_access->doc_loader_->GetBlock(position, size, buffer);
  61. }
  62. raw_ptr<DocumentLoader> doc_loader_;
  63. };
  64. } // namespace
  65. PDFiumDocument::PDFiumDocument(DocumentLoader* doc_loader)
  66. : doc_loader_(doc_loader),
  67. file_access_(std::make_unique<FileAccess>(doc_loader)),
  68. file_availability_(std::make_unique<FileAvail>(doc_loader)),
  69. download_hints_(std::make_unique<DownloadHints>(doc_loader)) {}
  70. PDFiumDocument::~PDFiumDocument() = default;
  71. void PDFiumDocument::CreateFPDFAvailability() {
  72. fpdf_availability_.reset(
  73. FPDFAvail_Create(file_availability_.get(), file_access_.get()));
  74. }
  75. void PDFiumDocument::ResetFPDFAvailability() {
  76. fpdf_availability_.reset();
  77. }
  78. void PDFiumDocument::LoadDocument(const std::string& password) {
  79. const char* password_cstr = password.empty() ? nullptr : password.c_str();
  80. if (doc_loader_->IsDocumentComplete() &&
  81. !FPDFAvail_IsLinearized(fpdf_availability_.get())) {
  82. doc_handle_.reset(
  83. FPDF_LoadCustomDocument(file_access_.get(), password_cstr));
  84. } else {
  85. doc_handle_.reset(
  86. FPDFAvail_GetDocument(fpdf_availability_.get(), password_cstr));
  87. }
  88. }
  89. void PDFiumDocument::SetFormStatus() {
  90. form_status_ =
  91. FPDFAvail_IsFormAvail(fpdf_availability_.get(), download_hints_.get());
  92. }
  93. void PDFiumDocument::InitializeForm(FPDF_FORMFILLINFO* form_info) {
  94. form_handle_.reset(FPDFDOC_InitFormFillEnvironment(doc(), form_info));
  95. }
  96. } // namespace chrome_pdf