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