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: ~IFXCRT_FileAccess()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: CFX_CRTFileStream(IFXCRT_FileAccess * pFA,IFX_Allocator * pAllocator)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) {} ~CFX_CRTFileStream()32 ~CFX_CRTFileStream() 33 { 34 if (m_pFile) { 35 m_pFile->Release(m_pAllocator); 36 } 37 } Retain()38 virtual IFX_FileStream* Retain() 39 { 40 m_dwCount ++; 41 return this; 42 } Release()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 } GetSize()54 virtual FX_FILESIZE GetSize() 55 { 56 return m_bUseRange ? m_nSize : m_pFile->GetSize(); 57 } IsEOF()58 virtual FX_BOOL IsEOF() 59 { 60 return GetPosition() >= GetSize(); 61 } GetPosition()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 } SetRange(FX_FILESIZE offset,FX_FILESIZE size)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 } ClearRange()80 virtual void ClearRange() 81 { 82 m_bUseRange = FALSE; 83 } ReadBlock(void * buffer,FX_FILESIZE offset,size_t size)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 } ReadBlock(void * buffer,size_t size)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 } WriteBlock(const void * buffer,FX_FILESIZE offset,size_t size)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 } Flush()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: CFX_MemoryStream(FX_BOOL bConsecutive,IFX_Allocator * pAllocator)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 } CFX_MemoryStream(FX_LPBYTE pBuffer,size_t nSize,FX_BOOL bTakeOver,IFX_Allocator * pAllocator)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 } ~CFX_MemoryStream()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 } Retain()161 virtual IFX_FileStream* Retain() 162 { 163 m_dwCount ++; 164 return this; 165 } Release()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 } GetSize()179 virtual FX_FILESIZE GetSize() 180 { 181 return m_bUseRange ? (FX_FILESIZE) m_nSize : (FX_FILESIZE)m_nCurSize; 182 } IsEOF()183 virtual FX_BOOL IsEOF() 184 { 185 return m_nCurPos >= (size_t)GetSize(); 186 } GetPosition()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 } SetRange(FX_FILESIZE offset,FX_FILESIZE size)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 } ClearRange()205 virtual void ClearRange() 206 { 207 m_bUseRange = FALSE; 208 } ReadBlock(void * buffer,FX_FILESIZE offset,size_t size)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 } ReadBlock(void * buffer,size_t size)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 } WriteBlock(const void * buffer,FX_FILESIZE offset,size_t size)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 } Flush()306 virtual FX_BOOL Flush() 307 { 308 return TRUE; 309 } IsConsecutive()310 virtual FX_BOOL IsConsecutive() const 311 { 312 return m_dwFlags & FX_MEMSTREAM_Consecutive; 313 } EstimateSize(size_t nInitSize,size_t nGrowSize)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 } GetBuffer()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 } DetachBuffer()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; ExpandBlocks(size_t size)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 { _FX_MTRANDOMCONTEXT_FX_MTRANDOMCONTEXT397 _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