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