Remove the unused IFX_StreamRead::SetRange() mechanism.
[pdfium.git] / core / src / fxcrt / extension.h
1 // Copyright 2014 PDFium 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
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6
7 #ifndef CORE_SRC_FXCRT_EXTENSION_H_
8 #define CORE_SRC_FXCRT_EXTENSION_H_
9
10 #include "../../include/fxcrt/fx_basic.h"
11 #include "../../include/fxcrt/fx_safe_types.h"
12
13 class IFXCRT_FileAccess {
14  public:
15   virtual ~IFXCRT_FileAccess() {}
16   virtual FX_BOOL Open(const CFX_ByteStringC& fileName, FX_DWORD dwMode) = 0;
17   virtual FX_BOOL Open(const CFX_WideStringC& fileName, FX_DWORD dwMode) = 0;
18   virtual void Close() = 0;
19   virtual void Release() = 0;
20   virtual FX_FILESIZE GetSize() const = 0;
21   virtual FX_FILESIZE GetPosition() const = 0;
22   virtual FX_FILESIZE SetPosition(FX_FILESIZE pos) = 0;
23   virtual size_t Read(void* pBuffer, size_t szBuffer) = 0;
24   virtual size_t Write(const void* pBuffer, size_t szBuffer) = 0;
25   virtual size_t ReadPos(void* pBuffer, size_t szBuffer, FX_FILESIZE pos) = 0;
26   virtual size_t WritePos(const void* pBuffer,
27                           size_t szBuffer,
28                           FX_FILESIZE pos) = 0;
29   virtual FX_BOOL Flush() = 0;
30   virtual FX_BOOL Truncate(FX_FILESIZE szFile) = 0;
31 };
32 IFXCRT_FileAccess* FXCRT_FileAccess_Create();
33 class CFX_CRTFileStream final : public IFX_FileStream {
34  public:
35   CFX_CRTFileStream(IFXCRT_FileAccess* pFA)
36       : m_pFile(pFA),
37         m_dwCount(1) {
38   }
39   ~CFX_CRTFileStream() {
40     if (m_pFile) {
41       m_pFile->Release();
42     }
43   }
44   virtual IFX_FileStream* Retain() override {
45     m_dwCount++;
46     return this;
47   }
48   virtual void Release() override {
49     FX_DWORD nCount = --m_dwCount;
50     if (!nCount) {
51       delete this;
52     }
53   }
54   virtual FX_FILESIZE GetSize() override {
55     return m_pFile->GetSize();
56   }
57   virtual FX_BOOL IsEOF() override { return GetPosition() >= GetSize(); }
58   virtual FX_FILESIZE GetPosition() override {
59     return m_pFile->GetPosition();
60   }
61   virtual FX_BOOL ReadBlock(void* buffer,
62                             FX_FILESIZE offset,
63                             size_t size) override {
64     return (FX_BOOL)m_pFile->ReadPos(buffer, size, offset);
65   }
66   virtual size_t ReadBlock(void* buffer, size_t size) override {
67     return m_pFile->Read(buffer, size);
68   }
69   virtual FX_BOOL WriteBlock(const void* buffer,
70                              FX_FILESIZE offset,
71                              size_t size) override {
72     return (FX_BOOL)m_pFile->WritePos(buffer, size, offset);
73   }
74   virtual FX_BOOL Flush() override { return m_pFile->Flush(); }
75
76  protected:
77   IFXCRT_FileAccess* m_pFile;
78   FX_DWORD m_dwCount;
79 };
80 #define FX_MEMSTREAM_BlockSize (64 * 1024)
81 #define FX_MEMSTREAM_Consecutive 0x01
82 #define FX_MEMSTREAM_TakeOver 0x02
83 class CFX_MemoryStream final : public IFX_MemoryStream {
84  public:
85   CFX_MemoryStream(FX_BOOL bConsecutive)
86       : m_dwCount(1),
87         m_nTotalSize(0),
88         m_nCurSize(0),
89         m_nCurPos(0),
90         m_nGrowSize(FX_MEMSTREAM_BlockSize) {
91     m_dwFlags =
92         FX_MEMSTREAM_TakeOver | (bConsecutive ? FX_MEMSTREAM_Consecutive : 0);
93   }
94   CFX_MemoryStream(uint8_t* pBuffer, size_t nSize, FX_BOOL bTakeOver)
95       : m_dwCount(1),
96         m_nTotalSize(nSize),
97         m_nCurSize(nSize),
98         m_nCurPos(0),
99         m_nGrowSize(FX_MEMSTREAM_BlockSize) {
100     m_Blocks.Add(pBuffer);
101     m_dwFlags =
102         FX_MEMSTREAM_Consecutive | (bTakeOver ? FX_MEMSTREAM_TakeOver : 0);
103   }
104   ~CFX_MemoryStream() {
105     if (m_dwFlags & FX_MEMSTREAM_TakeOver) {
106       for (int32_t i = 0; i < m_Blocks.GetSize(); i++) {
107         FX_Free((uint8_t*)m_Blocks[i]);
108       }
109     }
110     m_Blocks.RemoveAll();
111   }
112   virtual IFX_FileStream* Retain() override {
113     m_dwCount++;
114     return this;
115   }
116   virtual void Release() override {
117     FX_DWORD nCount = --m_dwCount;
118     if (nCount) {
119       return;
120     }
121     delete this;
122   }
123   virtual FX_FILESIZE GetSize() override {
124     return (FX_FILESIZE)m_nCurSize;
125   }
126   virtual FX_BOOL IsEOF() override { return m_nCurPos >= (size_t)GetSize(); }
127   virtual FX_FILESIZE GetPosition() override {
128     return (FX_FILESIZE)m_nCurPos;
129   }
130   virtual FX_BOOL ReadBlock(void* buffer,
131                             FX_FILESIZE offset,
132                             size_t size) override {
133     if (!buffer || !size) {
134       return FALSE;
135     }
136
137     FX_SAFE_SIZE_T newPos = size;
138     newPos += offset;
139     if (!newPos.IsValid() || newPos.ValueOrDefault(0) == 0 ||
140         newPos.ValueOrDie() > m_nCurSize) {
141       return FALSE;
142     }
143
144     m_nCurPos = newPos.ValueOrDie();
145     if (m_dwFlags & FX_MEMSTREAM_Consecutive) {
146       FXSYS_memcpy(buffer, (uint8_t*)m_Blocks[0] + (size_t)offset, size);
147       return TRUE;
148     }
149     size_t nStartBlock = (size_t)offset / m_nGrowSize;
150     offset -= (FX_FILESIZE)(nStartBlock * m_nGrowSize);
151     while (size) {
152       size_t nRead = m_nGrowSize - (size_t)offset;
153       if (nRead > size) {
154         nRead = size;
155       }
156       FXSYS_memcpy(
157           buffer, (uint8_t*)m_Blocks[(int)nStartBlock] + (size_t)offset, nRead);
158       buffer = ((uint8_t*)buffer) + nRead;
159       size -= nRead;
160       nStartBlock++;
161       offset = 0;
162     }
163     return TRUE;
164   }
165   virtual size_t ReadBlock(void* buffer, size_t size) override {
166     if (m_nCurPos >= m_nCurSize) {
167       return 0;
168     }
169     size_t nRead = FX_MIN(size, m_nCurSize - m_nCurPos);
170     if (!ReadBlock(buffer, (int32_t)m_nCurPos, nRead)) {
171       return 0;
172     }
173     return nRead;
174   }
175   virtual FX_BOOL WriteBlock(const void* buffer,
176                              FX_FILESIZE offset,
177                              size_t size) override {
178     if (!buffer || !size) {
179       return FALSE;
180     }
181     if (m_dwFlags & FX_MEMSTREAM_Consecutive) {
182       FX_SAFE_SIZE_T newPos = size;
183       newPos += offset;
184       if (!newPos.IsValid())
185         return FALSE;
186
187       m_nCurPos = newPos.ValueOrDie();
188       if (m_nCurPos > m_nTotalSize) {
189         m_nTotalSize =
190             (m_nCurPos + m_nGrowSize - 1) / m_nGrowSize * m_nGrowSize;
191         if (m_Blocks.GetSize() < 1) {
192           void* block = FX_Alloc(uint8_t, m_nTotalSize);
193           m_Blocks.Add(block);
194         } else {
195           m_Blocks[0] = FX_Realloc(uint8_t, m_Blocks[0], m_nTotalSize);
196         }
197         if (!m_Blocks[0]) {
198           m_Blocks.RemoveAll();
199           return FALSE;
200         }
201       }
202       FXSYS_memcpy((uint8_t*)m_Blocks[0] + (size_t)offset, buffer, size);
203       if (m_nCurSize < m_nCurPos) {
204         m_nCurSize = m_nCurPos;
205       }
206       return TRUE;
207     }
208
209     FX_SAFE_SIZE_T newPos = size;
210     newPos += offset;
211     if (!newPos.IsValid()) {
212       return FALSE;
213     }
214
215     if (!ExpandBlocks(newPos.ValueOrDie())) {
216       return FALSE;
217     }
218     m_nCurPos = newPos.ValueOrDie();
219     size_t nStartBlock = (size_t)offset / m_nGrowSize;
220     offset -= (FX_FILESIZE)(nStartBlock * m_nGrowSize);
221     while (size) {
222       size_t nWrite = m_nGrowSize - (size_t)offset;
223       if (nWrite > size) {
224         nWrite = size;
225       }
226       FXSYS_memcpy((uint8_t*)m_Blocks[(int)nStartBlock] + (size_t)offset,
227                    buffer, nWrite);
228       buffer = ((uint8_t*)buffer) + nWrite;
229       size -= nWrite;
230       nStartBlock++;
231       offset = 0;
232     }
233     return TRUE;
234   }
235   virtual FX_BOOL Flush() override { return TRUE; }
236   virtual FX_BOOL IsConsecutive() const override {
237     return m_dwFlags & FX_MEMSTREAM_Consecutive;
238   }
239   virtual void EstimateSize(size_t nInitSize, size_t nGrowSize) override {
240     if (m_dwFlags & FX_MEMSTREAM_Consecutive) {
241       if (m_Blocks.GetSize() < 1) {
242         uint8_t* pBlock = FX_Alloc(uint8_t, FX_MAX(nInitSize, 4096));
243         m_Blocks.Add(pBlock);
244       }
245       m_nGrowSize = FX_MAX(nGrowSize, 4096);
246     } else if (m_Blocks.GetSize() < 1) {
247       m_nGrowSize = FX_MAX(nGrowSize, 4096);
248     }
249   }
250   virtual uint8_t* GetBuffer() const override {
251     return m_Blocks.GetSize() ? (uint8_t*)m_Blocks[0] : NULL;
252   }
253   virtual void AttachBuffer(uint8_t* pBuffer,
254                             size_t nSize,
255                             FX_BOOL bTakeOver = FALSE) override {
256     if (!(m_dwFlags & FX_MEMSTREAM_Consecutive)) {
257       return;
258     }
259     m_Blocks.RemoveAll();
260     m_Blocks.Add(pBuffer);
261     m_nTotalSize = m_nCurSize = nSize;
262     m_nCurPos = 0;
263     m_dwFlags =
264         FX_MEMSTREAM_Consecutive | (bTakeOver ? FX_MEMSTREAM_TakeOver : 0);
265   }
266   virtual void DetachBuffer() override {
267     if (!(m_dwFlags & FX_MEMSTREAM_Consecutive)) {
268       return;
269     }
270     m_Blocks.RemoveAll();
271     m_nTotalSize = m_nCurSize = m_nCurPos = 0;
272     m_dwFlags = FX_MEMSTREAM_TakeOver;
273   }
274
275  protected:
276   CFX_PtrArray m_Blocks;
277   FX_DWORD m_dwCount;
278   size_t m_nTotalSize;
279   size_t m_nCurSize;
280   size_t m_nCurPos;
281   size_t m_nGrowSize;
282   FX_DWORD m_dwFlags;
283   FX_BOOL ExpandBlocks(size_t size) {
284     if (m_nCurSize < size) {
285       m_nCurSize = size;
286     }
287     if (size <= m_nTotalSize) {
288       return TRUE;
289     }
290     int32_t iCount = m_Blocks.GetSize();
291     size = (size - m_nTotalSize + m_nGrowSize - 1) / m_nGrowSize;
292     m_Blocks.SetSize(m_Blocks.GetSize() + (int32_t)size);
293     while (size--) {
294       uint8_t* pBlock = FX_Alloc(uint8_t, m_nGrowSize);
295       m_Blocks.SetAt(iCount++, pBlock);
296       m_nTotalSize += m_nGrowSize;
297     }
298     return TRUE;
299   }
300 };
301 #ifdef __cplusplus
302 extern "C" {
303 #endif
304 #define MT_N 848
305 #define MT_M 456
306 #define MT_Matrix_A 0x9908b0df
307 #define MT_Upper_Mask 0x80000000
308 #define MT_Lower_Mask 0x7fffffff
309 typedef struct _FX_MTRANDOMCONTEXT {
310   _FX_MTRANDOMCONTEXT() {
311     mti = MT_N + 1;
312     bHaveSeed = FALSE;
313   }
314   FX_DWORD mti;
315   FX_BOOL bHaveSeed;
316   FX_DWORD mt[MT_N];
317 } FX_MTRANDOMCONTEXT, *FX_LPMTRANDOMCONTEXT;
318 typedef FX_MTRANDOMCONTEXT const* FX_LPCMTRANDOMCONTEXT;
319 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
320 FX_BOOL FX_GenerateCryptoRandom(FX_DWORD* pBuffer, int32_t iCount);
321 #endif
322 #ifdef __cplusplus
323 }
324 #endif
325
326 #endif  // CORE_SRC_FXCRT_EXTENSION_H_