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 |