clang-format all pdfium code.
[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         m_bUseRange(FALSE),
39         m_nOffset(0),
40         m_nSize(0) {}
41   ~CFX_CRTFileStream() {
42     if (m_pFile) {
43       m_pFile->Release();
44     }
45   }
46   virtual IFX_FileStream* Retain() override {
47     m_dwCount++;
48     return this;
49   }
50   virtual void Release() override {
51     FX_DWORD nCount = --m_dwCount;
52     if (!nCount) {
53       delete this;
54     }
55   }
56   virtual FX_FILESIZE GetSize() override {
57     return m_bUseRange ? m_nSize : m_pFile->GetSize();
58   }
59   virtual FX_BOOL IsEOF() override { return GetPosition() >= GetSize(); }
60   virtual FX_FILESIZE GetPosition() override {
61     FX_FILESIZE pos = m_pFile->GetPosition();
62     if (m_bUseRange) {
63       pos -= m_nOffset;
64     }
65     return pos;
66   }
67   virtual FX_BOOL SetRange(FX_FILESIZE offset, FX_FILESIZE size) override {
68     if (offset < 0 || size < 0) {
69       return FALSE;
70     }
71
72     FX_SAFE_FILESIZE pos = size;
73     pos += offset;
74
75     if (!pos.IsValid() || pos.ValueOrDie() > m_pFile->GetSize()) {
76       return FALSE;
77     }
78
79     m_nOffset = offset, m_nSize = size;
80     m_bUseRange = TRUE;
81     m_pFile->SetPosition(m_nOffset);
82     return TRUE;
83   }
84   virtual void ClearRange() override { m_bUseRange = FALSE; }
85   virtual FX_BOOL ReadBlock(void* buffer,
86                             FX_FILESIZE offset,
87                             size_t size) override {
88     if (m_bUseRange && offset < 0) {
89       return FALSE;
90     }
91     FX_SAFE_FILESIZE pos = offset;
92
93     if (m_bUseRange) {
94       pos += m_nOffset;
95       if (!pos.IsValid() || pos.ValueOrDie() > (size_t)GetSize()) {
96         return FALSE;
97       }
98     }
99     return (FX_BOOL)m_pFile->ReadPos(buffer, size, pos.ValueOrDie());
100   }
101   virtual size_t ReadBlock(void* buffer, size_t size) override {
102     if (m_bUseRange) {
103       FX_FILESIZE availSize = m_nOffset + m_nSize - m_pFile->GetPosition();
104       if ((size_t)availSize < size) {
105         size -= size - (size_t)availSize;
106       }
107     }
108     return m_pFile->Read(buffer, size);
109   }
110   virtual FX_BOOL WriteBlock(const void* buffer,
111                              FX_FILESIZE offset,
112                              size_t size) override {
113     if (m_bUseRange) {
114       offset += m_nOffset;
115     }
116     return (FX_BOOL)m_pFile->WritePos(buffer, size, offset);
117   }
118   virtual FX_BOOL Flush() override { return m_pFile->Flush(); }
119   IFXCRT_FileAccess* m_pFile;
120   FX_DWORD m_dwCount;
121   FX_BOOL m_bUseRange;
122   FX_FILESIZE m_nOffset;
123   FX_FILESIZE m_nSize;
124 };
125 #define FX_MEMSTREAM_BlockSize (64 * 1024)
126 #define FX_MEMSTREAM_Consecutive 0x01
127 #define FX_MEMSTREAM_TakeOver 0x02
128 class CFX_MemoryStream final : public IFX_MemoryStream {
129  public:
130   CFX_MemoryStream(FX_BOOL bConsecutive)
131       : m_dwCount(1),
132         m_nTotalSize(0),
133         m_nCurSize(0),
134         m_nCurPos(0),
135         m_nGrowSize(FX_MEMSTREAM_BlockSize),
136         m_bUseRange(FALSE) {
137     m_dwFlags =
138         FX_MEMSTREAM_TakeOver | (bConsecutive ? FX_MEMSTREAM_Consecutive : 0);
139   }
140   CFX_MemoryStream(uint8_t* pBuffer, size_t nSize, FX_BOOL bTakeOver)
141       : m_dwCount(1),
142         m_nTotalSize(nSize),
143         m_nCurSize(nSize),
144         m_nCurPos(0),
145         m_nGrowSize(FX_MEMSTREAM_BlockSize),
146         m_bUseRange(FALSE) {
147     m_Blocks.Add(pBuffer);
148     m_dwFlags =
149         FX_MEMSTREAM_Consecutive | (bTakeOver ? FX_MEMSTREAM_TakeOver : 0);
150   }
151   ~CFX_MemoryStream() {
152     if (m_dwFlags & FX_MEMSTREAM_TakeOver) {
153       for (int32_t i = 0; i < m_Blocks.GetSize(); i++) {
154         FX_Free((uint8_t*)m_Blocks[i]);
155       }
156     }
157     m_Blocks.RemoveAll();
158   }
159   virtual IFX_FileStream* Retain() override {
160     m_dwCount++;
161     return this;
162   }
163   virtual void Release() override {
164     FX_DWORD nCount = --m_dwCount;
165     if (nCount) {
166       return;
167     }
168     delete this;
169   }
170   virtual FX_FILESIZE GetSize() override {
171     return m_bUseRange ? (FX_FILESIZE)m_nSize : (FX_FILESIZE)m_nCurSize;
172   }
173   virtual FX_BOOL IsEOF() override { return m_nCurPos >= (size_t)GetSize(); }
174   virtual FX_FILESIZE GetPosition() override {
175     FX_FILESIZE pos = (FX_FILESIZE)m_nCurPos;
176     if (m_bUseRange) {
177       pos -= (FX_FILESIZE)m_nOffset;
178     }
179     return pos;
180   }
181   virtual FX_BOOL SetRange(FX_FILESIZE offset, FX_FILESIZE size) override {
182     if (offset < 0 || size < 0) {
183       return FALSE;
184     }
185     FX_SAFE_FILESIZE range = size;
186     range += offset;
187     if (!range.IsValid() || range.ValueOrDie() > m_nCurSize) {
188       return FALSE;
189     }
190
191     m_nOffset = (size_t)offset, m_nSize = (size_t)size;
192     m_bUseRange = TRUE;
193     m_nCurPos = m_nOffset;
194     return TRUE;
195   }
196   virtual void ClearRange() override { m_bUseRange = FALSE; }
197   virtual FX_BOOL ReadBlock(void* buffer,
198                             FX_FILESIZE offset,
199                             size_t size) override {
200     if (!buffer || !size) {
201       return FALSE;
202     }
203
204     FX_SAFE_FILESIZE safeOffset = offset;
205     if (m_bUseRange) {
206       safeOffset += m_nOffset;
207     }
208
209     if (!safeOffset.IsValid()) {
210       return FALSE;
211     }
212
213     offset = safeOffset.ValueOrDie();
214
215     FX_SAFE_SIZE_T newPos = size;
216     newPos += offset;
217     if (!newPos.IsValid() || newPos.ValueOrDefault(0) == 0 ||
218         newPos.ValueOrDie() > m_nCurSize) {
219       return FALSE;
220     }
221
222     m_nCurPos = newPos.ValueOrDie();
223     if (m_dwFlags & FX_MEMSTREAM_Consecutive) {
224       FXSYS_memcpy(buffer, (uint8_t*)m_Blocks[0] + (size_t)offset, size);
225       return TRUE;
226     }
227     size_t nStartBlock = (size_t)offset / m_nGrowSize;
228     offset -= (FX_FILESIZE)(nStartBlock * m_nGrowSize);
229     while (size) {
230       size_t nRead = m_nGrowSize - (size_t)offset;
231       if (nRead > size) {
232         nRead = size;
233       }
234       FXSYS_memcpy(
235           buffer, (uint8_t*)m_Blocks[(int)nStartBlock] + (size_t)offset, nRead);
236       buffer = ((uint8_t*)buffer) + nRead;
237       size -= nRead;
238       nStartBlock++;
239       offset = 0;
240     }
241     return TRUE;
242   }
243   virtual size_t ReadBlock(void* buffer, size_t size) override {
244     if (m_nCurPos >= m_nCurSize) {
245       return 0;
246     }
247     if (m_bUseRange) {
248       size_t availSize = m_nOffset + m_nSize - m_nCurPos;
249       if (availSize < size) {
250         size -= size - (size_t)availSize;
251       }
252     }
253     size_t nRead = FX_MIN(size, m_nCurSize - m_nCurPos);
254     if (!ReadBlock(buffer, (int32_t)m_nCurPos, nRead)) {
255       return 0;
256     }
257     return nRead;
258   }
259   virtual FX_BOOL WriteBlock(const void* buffer,
260                              FX_FILESIZE offset,
261                              size_t size) override {
262     if (!buffer || !size) {
263       return FALSE;
264     }
265     if (m_bUseRange) {
266       offset += (FX_FILESIZE)m_nOffset;
267     }
268     if (m_dwFlags & FX_MEMSTREAM_Consecutive) {
269       FX_SAFE_SIZE_T newPos = size;
270       newPos += offset;
271       if (!newPos.IsValid())
272         return FALSE;
273
274       m_nCurPos = newPos.ValueOrDie();
275       if (m_nCurPos > m_nTotalSize) {
276         m_nTotalSize =
277             (m_nCurPos + m_nGrowSize - 1) / m_nGrowSize * m_nGrowSize;
278         if (m_Blocks.GetSize() < 1) {
279           void* block = FX_Alloc(uint8_t, m_nTotalSize);
280           m_Blocks.Add(block);
281         } else {
282           m_Blocks[0] = FX_Realloc(uint8_t, m_Blocks[0], m_nTotalSize);
283         }
284         if (!m_Blocks[0]) {
285           m_Blocks.RemoveAll();
286           return FALSE;
287         }
288       }
289       FXSYS_memcpy((uint8_t*)m_Blocks[0] + (size_t)offset, buffer, size);
290       if (m_nCurSize < m_nCurPos) {
291         m_nCurSize = m_nCurPos;
292       }
293       return TRUE;
294     }
295
296     FX_SAFE_SIZE_T newPos = size;
297     newPos += offset;
298     if (!newPos.IsValid()) {
299       return FALSE;
300     }
301
302     if (!ExpandBlocks(newPos.ValueOrDie())) {
303       return FALSE;
304     }
305     m_nCurPos = newPos.ValueOrDie();
306     size_t nStartBlock = (size_t)offset / m_nGrowSize;
307     offset -= (FX_FILESIZE)(nStartBlock * m_nGrowSize);
308     while (size) {
309       size_t nWrite = m_nGrowSize - (size_t)offset;
310       if (nWrite > size) {
311         nWrite = size;
312       }
313       FXSYS_memcpy((uint8_t*)m_Blocks[(int)nStartBlock] + (size_t)offset,
314                    buffer, nWrite);
315       buffer = ((uint8_t*)buffer) + nWrite;
316       size -= nWrite;
317       nStartBlock++;
318       offset = 0;
319     }
320     return TRUE;
321   }
322   virtual FX_BOOL Flush() override { return TRUE; }
323   virtual FX_BOOL IsConsecutive() const override {
324     return m_dwFlags & FX_MEMSTREAM_Consecutive;
325   }
326   virtual void EstimateSize(size_t nInitSize, size_t nGrowSize) override {
327     if (m_dwFlags & FX_MEMSTREAM_Consecutive) {
328       if (m_Blocks.GetSize() < 1) {
329         uint8_t* pBlock = FX_Alloc(uint8_t, FX_MAX(nInitSize, 4096));
330         m_Blocks.Add(pBlock);
331       }
332       m_nGrowSize = FX_MAX(nGrowSize, 4096);
333     } else if (m_Blocks.GetSize() < 1) {
334       m_nGrowSize = FX_MAX(nGrowSize, 4096);
335     }
336   }
337   virtual uint8_t* GetBuffer() const override {
338     return m_Blocks.GetSize() ? (uint8_t*)m_Blocks[0] : NULL;
339   }
340   virtual void AttachBuffer(uint8_t* pBuffer,
341                             size_t nSize,
342                             FX_BOOL bTakeOver = FALSE) override {
343     if (!(m_dwFlags & FX_MEMSTREAM_Consecutive)) {
344       return;
345     }
346     m_Blocks.RemoveAll();
347     m_Blocks.Add(pBuffer);
348     m_nTotalSize = m_nCurSize = nSize;
349     m_nCurPos = 0;
350     m_dwFlags =
351         FX_MEMSTREAM_Consecutive | (bTakeOver ? FX_MEMSTREAM_TakeOver : 0);
352     ClearRange();
353   }
354   virtual void DetachBuffer() override {
355     if (!(m_dwFlags & FX_MEMSTREAM_Consecutive)) {
356       return;
357     }
358     m_Blocks.RemoveAll();
359     m_nTotalSize = m_nCurSize = m_nCurPos = 0;
360     m_dwFlags = FX_MEMSTREAM_TakeOver;
361     ClearRange();
362   }
363
364  protected:
365   CFX_PtrArray m_Blocks;
366   FX_DWORD m_dwCount;
367   size_t m_nTotalSize;
368   size_t m_nCurSize;
369   size_t m_nCurPos;
370   size_t m_nGrowSize;
371   FX_DWORD m_dwFlags;
372   FX_BOOL m_bUseRange;
373   size_t m_nOffset;
374   size_t m_nSize;
375   FX_BOOL ExpandBlocks(size_t size) {
376     if (m_nCurSize < size) {
377       m_nCurSize = size;
378     }
379     if (size <= m_nTotalSize) {
380       return TRUE;
381     }
382     int32_t iCount = m_Blocks.GetSize();
383     size = (size - m_nTotalSize + m_nGrowSize - 1) / m_nGrowSize;
384     m_Blocks.SetSize(m_Blocks.GetSize() + (int32_t)size);
385     while (size--) {
386       uint8_t* pBlock = FX_Alloc(uint8_t, m_nGrowSize);
387       m_Blocks.SetAt(iCount++, pBlock);
388       m_nTotalSize += m_nGrowSize;
389     }
390     return TRUE;
391   }
392 };
393 #ifdef __cplusplus
394 extern "C" {
395 #endif
396 #define MT_N 848
397 #define MT_M 456
398 #define MT_Matrix_A 0x9908b0df
399 #define MT_Upper_Mask 0x80000000
400 #define MT_Lower_Mask 0x7fffffff
401 typedef struct _FX_MTRANDOMCONTEXT {
402   _FX_MTRANDOMCONTEXT() {
403     mti = MT_N + 1;
404     bHaveSeed = FALSE;
405   }
406   FX_DWORD mti;
407   FX_BOOL bHaveSeed;
408   FX_DWORD mt[MT_N];
409 } FX_MTRANDOMCONTEXT, *FX_LPMTRANDOMCONTEXT;
410 typedef FX_MTRANDOMCONTEXT const* FX_LPCMTRANDOMCONTEXT;
411 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
412 FX_BOOL FX_GenerateCryptoRandom(FX_DWORD* pBuffer, int32_t iCount);
413 #endif
414 #ifdef __cplusplus
415 }
416 #endif
417
418 #endif  // CORE_SRC_FXCRT_EXTENSION_H_