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