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