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