1 /*
2  * Copyright (C) 2024 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef MEDIAPROVIDER_PDF_JNI_PDFCLIENT_FILE_H_
18 #define MEDIAPROVIDER_PDF_JNI_PDFCLIENT_FILE_H_
19 
20 #include <stddef.h>
21 
22 #include "cpp/fpdf_scopers.h"
23 #include "fpdf_dataavail.h"
24 #include "fpdf_save.h"
25 #include "fpdfview.h"
26 #include "linux_fileops.h"
27 
28 namespace pdfClient {
29 
30 // Returns the actual current size of the given file, by seeking to the end.
31 // Only works with seekable file descriptors.
32 size_t GetFileSize(int fd);
33 
34 // A wrapper on a file-descriptor for reading - implements all the interfaces
35 // needed to open a PDF as it downloads, using fpdf_dataavail.h
36 // The data that is available is automatically updated as more data is written
37 // to the file-descriptor (see CanReadBlock).
38 class FileReader : public FPDF_FILEACCESS, public FX_FILEAVAIL, public FX_DOWNLOADHINTS {
39   public:
40     // We implement this interface too, but not by subclassing it.
41     ScopedFPDFAvail fpdf_avail_;
42 
43     // Start reading a file that has already been completely written.
44     explicit FileReader(LinuxFileOps::FDCloser fd);
45     // Start reading a file which, when completely written, will be completeSize.
46     FileReader(LinuxFileOps::FDCloser fd, size_t completeSize);
47 
48     // Move constructor.
49     FileReader(FileReader&& fr);
50 
51     virtual ~FileReader();
52 
RequestedHeaderSize()53     virtual size_t RequestedHeaderSize() const { return 0; }
RequestedFooterSize()54     virtual size_t RequestedFooterSize() const { return 0; }
55 
Fd()56     int Fd() const { return fd_.get(); }
57     int ReleaseFd();
58 
59     // How big this file will be once it is completely written - only part of this
60     // complete size will be available for reading until it is completely written.
CompleteSize()61     size_t CompleteSize() const { return complete_size_; }
62 
63     virtual bool IsComplete() const;
64     virtual bool CanReadBlock(size_t offset, size_t size) const;
65     virtual size_t DoReadBlock(size_t offset, void* buffer, size_t size) const;
66     virtual void RequestBlock(size_t offset, size_t size);
67 
68   protected:
69     LinuxFileOps::FDCloser fd_;  // File-descriptor.
70 
71     // How big the file will be once completely written.
72     size_t complete_size_;
73 
74     void InitImplementation();
75 
76     // Needed to implement FX_FILEAVAIL:
77     static int StaticIsDataAvailImpl(struct _FX_FILEAVAIL* pThis, size_t offset, size_t size);
78 
79     // Needed to implement FPDF_FILEACCESS:
80     static int StaticGetBlockImpl(void* param, unsigned long offset,  // NOLINT
81                                   unsigned char* buffer,
82                                   unsigned long size);  // NOLINT
83 
84     // Needed to implement FX_DOWNLOADHINTS:
85     static void StaticAddSegmentImpl(FX_DOWNLOADHINTS* pThis, size_t pos, size_t size);
86 };
87 
88 // A wrapper on a filedescriptor for writing - used to save a copy of a PDF
89 // with password-protection security removed (see document.h).
90 class FileWriter : public FPDF_FILEWRITE {
91   public:
92     explicit FileWriter(LinuxFileOps::FDCloser fd);
93     ~FileWriter();
94 
Fd()95     int Fd() { return fd_.get(); }
96 
97     size_t DoWriteBlock(const void* data, size_t size);
98 
99   private:
100     LinuxFileOps::FDCloser fd_;  // File-descriptor.
101 
102     // Needed to implement FPDF_FILEWRITE
103     static int StaticWriteBlockImpl(FPDF_FILEWRITE* pThis, const void* data,
104                                     unsigned long size);  // NOLINT
105 };
106 
107 // Returns some DownloadHints that only log each data range that pdfClient requests.
108 // They do not cause that part of the file to be downloaded.
109 FX_DOWNLOADHINTS* LogOnlyDownloadHints();
110 
111 }  // namespace pdfClient
112 
113 #endif  // MEDIAPROVIDER_PDF_JNI_PDFCLIENT_FILE_H_