OLD | NEW |
| (Empty) |
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 <algorithm> | |
11 | |
12 #include "core/include/fxcrt/fx_basic.h" | |
13 #include "core/include/fxcrt/fx_safe_types.h" | |
14 | |
15 class IFXCRT_FileAccess { | |
16 public: | |
17 virtual ~IFXCRT_FileAccess() {} | |
18 virtual FX_BOOL Open(const CFX_ByteStringC& fileName, FX_DWORD dwMode) = 0; | |
19 virtual FX_BOOL Open(const CFX_WideStringC& fileName, FX_DWORD dwMode) = 0; | |
20 virtual void Close() = 0; | |
21 virtual void Release() = 0; | |
22 virtual FX_FILESIZE GetSize() const = 0; | |
23 virtual FX_FILESIZE GetPosition() const = 0; | |
24 virtual FX_FILESIZE SetPosition(FX_FILESIZE pos) = 0; | |
25 virtual size_t Read(void* pBuffer, size_t szBuffer) = 0; | |
26 virtual size_t Write(const void* pBuffer, size_t szBuffer) = 0; | |
27 virtual size_t ReadPos(void* pBuffer, size_t szBuffer, FX_FILESIZE pos) = 0; | |
28 virtual size_t WritePos(const void* pBuffer, | |
29 size_t szBuffer, | |
30 FX_FILESIZE pos) = 0; | |
31 virtual FX_BOOL Flush() = 0; | |
32 virtual FX_BOOL Truncate(FX_FILESIZE szFile) = 0; | |
33 }; | |
34 IFXCRT_FileAccess* FXCRT_FileAccess_Create(); | |
35 | |
36 #ifdef PDF_ENABLE_XFA | |
37 class CFX_CRTFileAccess : public IFX_FileAccess { | |
38 public: | |
39 CFX_CRTFileAccess() : m_RefCount(0) {} | |
40 | |
41 // IFX_FileAccess | |
42 void Release() override { | |
43 if (--m_RefCount == 0) | |
44 delete this; | |
45 } | |
46 | |
47 IFX_FileAccess* Retain() override { | |
48 m_RefCount++; | |
49 return (IFX_FileAccess*)this; | |
50 } | |
51 | |
52 void GetPath(CFX_WideString& wsPath) override { wsPath = m_path; } | |
53 | |
54 IFX_FileStream* CreateFileStream(FX_DWORD dwModes) override { | |
55 return FX_CreateFileStream(m_path, dwModes); | |
56 } | |
57 | |
58 FX_BOOL Init(const CFX_WideStringC& wsPath) { | |
59 m_path = wsPath; | |
60 m_RefCount = 1; | |
61 return TRUE; | |
62 } | |
63 | |
64 protected: | |
65 CFX_WideString m_path; | |
66 FX_DWORD m_RefCount; | |
67 }; | |
68 #endif // PDF_ENABLE_XFA | |
69 | |
70 class CFX_CRTFileStream final : public IFX_FileStream { | |
71 public: | |
72 explicit CFX_CRTFileStream(IFXCRT_FileAccess* pFA); | |
73 ~CFX_CRTFileStream() override; | |
74 | |
75 // IFX_FileStream: | |
76 IFX_FileStream* Retain() override; | |
77 void Release() override; | |
78 FX_FILESIZE GetSize() override; | |
79 FX_BOOL IsEOF() override; | |
80 FX_FILESIZE GetPosition() override; | |
81 FX_BOOL ReadBlock(void* buffer, FX_FILESIZE offset, size_t size) override; | |
82 size_t ReadBlock(void* buffer, size_t size) override; | |
83 FX_BOOL WriteBlock(const void* buffer, | |
84 FX_FILESIZE offset, | |
85 size_t size) override; | |
86 FX_BOOL Flush() override; | |
87 | |
88 protected: | |
89 IFXCRT_FileAccess* m_pFile; | |
90 FX_DWORD m_dwCount; | |
91 }; | |
92 | |
93 #define FX_MEMSTREAM_BlockSize (64 * 1024) | |
94 #define FX_MEMSTREAM_Consecutive 0x01 | |
95 #define FX_MEMSTREAM_TakeOver 0x02 | |
96 class CFX_MemoryStream final : public IFX_MemoryStream { | |
97 public: | |
98 explicit CFX_MemoryStream(FX_BOOL bConsecutive) | |
99 : m_dwCount(1), | |
100 m_nTotalSize(0), | |
101 m_nCurSize(0), | |
102 m_nCurPos(0), | |
103 m_nGrowSize(FX_MEMSTREAM_BlockSize) { | |
104 m_dwFlags = | |
105 FX_MEMSTREAM_TakeOver | (bConsecutive ? FX_MEMSTREAM_Consecutive : 0); | |
106 } | |
107 CFX_MemoryStream(uint8_t* pBuffer, size_t nSize, FX_BOOL bTakeOver) | |
108 : m_dwCount(1), | |
109 m_nTotalSize(nSize), | |
110 m_nCurSize(nSize), | |
111 m_nCurPos(0), | |
112 m_nGrowSize(FX_MEMSTREAM_BlockSize) { | |
113 m_Blocks.Add(pBuffer); | |
114 m_dwFlags = | |
115 FX_MEMSTREAM_Consecutive | (bTakeOver ? FX_MEMSTREAM_TakeOver : 0); | |
116 } | |
117 ~CFX_MemoryStream() override { | |
118 if (m_dwFlags & FX_MEMSTREAM_TakeOver) { | |
119 for (int32_t i = 0; i < m_Blocks.GetSize(); i++) { | |
120 FX_Free(m_Blocks[i]); | |
121 } | |
122 } | |
123 m_Blocks.RemoveAll(); | |
124 } | |
125 | |
126 // IFX_MemoryStream: | |
127 IFX_FileStream* Retain() override { | |
128 m_dwCount++; | |
129 return this; | |
130 } | |
131 void Release() override { | |
132 FX_DWORD nCount = --m_dwCount; | |
133 if (nCount) { | |
134 return; | |
135 } | |
136 delete this; | |
137 } | |
138 FX_FILESIZE GetSize() override { return (FX_FILESIZE)m_nCurSize; } | |
139 FX_BOOL IsEOF() override { return m_nCurPos >= (size_t)GetSize(); } | |
140 FX_FILESIZE GetPosition() override { return (FX_FILESIZE)m_nCurPos; } | |
141 FX_BOOL ReadBlock(void* buffer, FX_FILESIZE offset, size_t size) override { | |
142 if (!buffer || !size) { | |
143 return FALSE; | |
144 } | |
145 | |
146 FX_SAFE_SIZE_T newPos = size; | |
147 newPos += offset; | |
148 if (!newPos.IsValid() || newPos.ValueOrDefault(0) == 0 || | |
149 newPos.ValueOrDie() > m_nCurSize) { | |
150 return FALSE; | |
151 } | |
152 | |
153 m_nCurPos = newPos.ValueOrDie(); | |
154 if (m_dwFlags & FX_MEMSTREAM_Consecutive) { | |
155 FXSYS_memcpy(buffer, m_Blocks[0] + (size_t)offset, size); | |
156 return TRUE; | |
157 } | |
158 size_t nStartBlock = (size_t)offset / m_nGrowSize; | |
159 offset -= (FX_FILESIZE)(nStartBlock * m_nGrowSize); | |
160 while (size) { | |
161 size_t nRead = m_nGrowSize - (size_t)offset; | |
162 if (nRead > size) { | |
163 nRead = size; | |
164 } | |
165 FXSYS_memcpy(buffer, m_Blocks[(int)nStartBlock] + (size_t)offset, nRead); | |
166 buffer = ((uint8_t*)buffer) + nRead; | |
167 size -= nRead; | |
168 nStartBlock++; | |
169 offset = 0; | |
170 } | |
171 return TRUE; | |
172 } | |
173 size_t ReadBlock(void* buffer, size_t size) override { | |
174 if (m_nCurPos >= m_nCurSize) { | |
175 return 0; | |
176 } | |
177 size_t nRead = std::min(size, m_nCurSize - m_nCurPos); | |
178 if (!ReadBlock(buffer, (int32_t)m_nCurPos, nRead)) { | |
179 return 0; | |
180 } | |
181 return nRead; | |
182 } | |
183 FX_BOOL WriteBlock(const void* buffer, | |
184 FX_FILESIZE offset, | |
185 size_t size) override { | |
186 if (!buffer || !size) { | |
187 return FALSE; | |
188 } | |
189 if (m_dwFlags & FX_MEMSTREAM_Consecutive) { | |
190 FX_SAFE_SIZE_T newPos = size; | |
191 newPos += offset; | |
192 if (!newPos.IsValid()) | |
193 return FALSE; | |
194 | |
195 m_nCurPos = newPos.ValueOrDie(); | |
196 if (m_nCurPos > m_nTotalSize) { | |
197 m_nTotalSize = | |
198 (m_nCurPos + m_nGrowSize - 1) / m_nGrowSize * m_nGrowSize; | |
199 if (m_Blocks.GetSize() < 1) { | |
200 uint8_t* block = FX_Alloc(uint8_t, m_nTotalSize); | |
201 m_Blocks.Add(block); | |
202 } else { | |
203 m_Blocks[0] = FX_Realloc(uint8_t, m_Blocks[0], m_nTotalSize); | |
204 } | |
205 if (!m_Blocks[0]) { | |
206 m_Blocks.RemoveAll(); | |
207 return FALSE; | |
208 } | |
209 } | |
210 FXSYS_memcpy(m_Blocks[0] + (size_t)offset, buffer, size); | |
211 if (m_nCurSize < m_nCurPos) { | |
212 m_nCurSize = m_nCurPos; | |
213 } | |
214 return TRUE; | |
215 } | |
216 | |
217 FX_SAFE_SIZE_T newPos = size; | |
218 newPos += offset; | |
219 if (!newPos.IsValid()) { | |
220 return FALSE; | |
221 } | |
222 | |
223 if (!ExpandBlocks(newPos.ValueOrDie())) { | |
224 return FALSE; | |
225 } | |
226 m_nCurPos = newPos.ValueOrDie(); | |
227 size_t nStartBlock = (size_t)offset / m_nGrowSize; | |
228 offset -= (FX_FILESIZE)(nStartBlock * m_nGrowSize); | |
229 while (size) { | |
230 size_t nWrite = m_nGrowSize - (size_t)offset; | |
231 if (nWrite > size) { | |
232 nWrite = size; | |
233 } | |
234 FXSYS_memcpy(m_Blocks[(int)nStartBlock] + (size_t)offset, buffer, nWrite); | |
235 buffer = ((uint8_t*)buffer) + nWrite; | |
236 size -= nWrite; | |
237 nStartBlock++; | |
238 offset = 0; | |
239 } | |
240 return TRUE; | |
241 } | |
242 FX_BOOL Flush() override { return TRUE; } | |
243 FX_BOOL IsConsecutive() const override { | |
244 return m_dwFlags & FX_MEMSTREAM_Consecutive; | |
245 } | |
246 void EstimateSize(size_t nInitSize, size_t nGrowSize) override { | |
247 if (m_dwFlags & FX_MEMSTREAM_Consecutive) { | |
248 if (m_Blocks.GetSize() < 1) { | |
249 uint8_t* pBlock = | |
250 FX_Alloc(uint8_t, std::max(nInitSize, static_cast<size_t>(4096))); | |
251 m_Blocks.Add(pBlock); | |
252 } | |
253 m_nGrowSize = std::max(nGrowSize, static_cast<size_t>(4096)); | |
254 } else if (m_Blocks.GetSize() < 1) { | |
255 m_nGrowSize = std::max(nGrowSize, static_cast<size_t>(4096)); | |
256 } | |
257 } | |
258 uint8_t* GetBuffer() const override { | |
259 return m_Blocks.GetSize() ? m_Blocks[0] : nullptr; | |
260 } | |
261 void AttachBuffer(uint8_t* pBuffer, | |
262 size_t nSize, | |
263 FX_BOOL bTakeOver = FALSE) override { | |
264 if (!(m_dwFlags & FX_MEMSTREAM_Consecutive)) { | |
265 return; | |
266 } | |
267 m_Blocks.RemoveAll(); | |
268 m_Blocks.Add(pBuffer); | |
269 m_nTotalSize = m_nCurSize = nSize; | |
270 m_nCurPos = 0; | |
271 m_dwFlags = | |
272 FX_MEMSTREAM_Consecutive | (bTakeOver ? FX_MEMSTREAM_TakeOver : 0); | |
273 } | |
274 void DetachBuffer() override { | |
275 if (!(m_dwFlags & FX_MEMSTREAM_Consecutive)) { | |
276 return; | |
277 } | |
278 m_Blocks.RemoveAll(); | |
279 m_nTotalSize = m_nCurSize = m_nCurPos = 0; | |
280 m_dwFlags = FX_MEMSTREAM_TakeOver; | |
281 } | |
282 | |
283 protected: | |
284 CFX_ArrayTemplate<uint8_t*> m_Blocks; | |
285 FX_DWORD m_dwCount; | |
286 size_t m_nTotalSize; | |
287 size_t m_nCurSize; | |
288 size_t m_nCurPos; | |
289 size_t m_nGrowSize; | |
290 FX_DWORD m_dwFlags; | |
291 FX_BOOL ExpandBlocks(size_t size) { | |
292 if (m_nCurSize < size) { | |
293 m_nCurSize = size; | |
294 } | |
295 if (size <= m_nTotalSize) { | |
296 return TRUE; | |
297 } | |
298 int32_t iCount = m_Blocks.GetSize(); | |
299 size = (size - m_nTotalSize + m_nGrowSize - 1) / m_nGrowSize; | |
300 m_Blocks.SetSize(m_Blocks.GetSize() + (int32_t)size); | |
301 while (size--) { | |
302 uint8_t* pBlock = FX_Alloc(uint8_t, m_nGrowSize); | |
303 m_Blocks.SetAt(iCount++, pBlock); | |
304 m_nTotalSize += m_nGrowSize; | |
305 } | |
306 return TRUE; | |
307 } | |
308 }; | |
309 | |
310 #ifdef __cplusplus | |
311 extern "C" { | |
312 #endif | |
313 #define MT_N 848 | |
314 #define MT_M 456 | |
315 #define MT_Matrix_A 0x9908b0df | |
316 #define MT_Upper_Mask 0x80000000 | |
317 #define MT_Lower_Mask 0x7fffffff | |
318 struct FX_MTRANDOMCONTEXT { | |
319 FX_MTRANDOMCONTEXT() { | |
320 mti = MT_N + 1; | |
321 bHaveSeed = FALSE; | |
322 } | |
323 FX_DWORD mti; | |
324 FX_BOOL bHaveSeed; | |
325 FX_DWORD mt[MT_N]; | |
326 }; | |
327 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ | |
328 FX_BOOL FX_GenerateCryptoRandom(FX_DWORD* pBuffer, int32_t iCount); | |
329 #endif | |
330 #ifdef __cplusplus | |
331 } | |
332 #endif | |
333 | |
334 #endif // CORE_SRC_FXCRT_EXTENSION_H_ | |
OLD | NEW |