Home | History | Annotate | Download | only in fxcrt
      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
    414