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 #include "xfa/src/fgas/crt/fgas_stream.h" | |
8 | |
9 #include <algorithm> | |
10 | |
11 #include "xfa/src/fgas/crt/fgas_system.h" | |
12 #include "xfa/src/fgas/crt/fgas_codepage.h" | |
13 | |
14 namespace { | |
15 | |
16 class CFX_StreamImp { | |
17 public: | |
18 virtual void Release() { delete this; } | |
19 virtual FX_DWORD GetAccessModes() const { return m_dwAccess; } | |
20 virtual int32_t GetLength() const = 0; | |
21 virtual int32_t Seek(FX_STREAMSEEK eSeek, int32_t iOffset) = 0; | |
22 virtual int32_t GetPosition() = 0; | |
23 virtual FX_BOOL IsEOF() const = 0; | |
24 virtual int32_t ReadData(uint8_t* pBuffer, int32_t iBufferSize) = 0; | |
25 virtual int32_t ReadString(FX_WCHAR* pStr, | |
26 int32_t iMaxLength, | |
27 FX_BOOL& bEOS) = 0; | |
28 virtual int32_t WriteData(const uint8_t* pBuffer, int32_t iBufferSize) = 0; | |
29 virtual int32_t WriteString(const FX_WCHAR* pStr, int32_t iLength) = 0; | |
30 virtual void Flush() = 0; | |
31 virtual FX_BOOL SetLength(int32_t iLength) = 0; | |
32 | |
33 protected: | |
34 CFX_StreamImp(); | |
35 virtual ~CFX_StreamImp() {} | |
36 FX_DWORD m_dwAccess; | |
37 }; | |
38 | |
39 class CFX_FileStreamImp : public CFX_StreamImp { | |
40 public: | |
41 CFX_FileStreamImp(); | |
42 virtual ~CFX_FileStreamImp(); | |
43 FX_BOOL LoadFile(const FX_WCHAR* pszSrcFileName, FX_DWORD dwAccess); | |
44 virtual int32_t GetLength() const; | |
45 virtual int32_t Seek(FX_STREAMSEEK eSeek, int32_t iOffset); | |
46 virtual int32_t GetPosition(); | |
47 virtual FX_BOOL IsEOF() const; | |
48 virtual int32_t ReadData(uint8_t* pBuffer, int32_t iBufferSize); | |
49 virtual int32_t ReadString(FX_WCHAR* pStr, int32_t iMaxLength, FX_BOOL& bEOS); | |
50 virtual int32_t WriteData(const uint8_t* pBuffer, int32_t iBufferSize); | |
51 virtual int32_t WriteString(const FX_WCHAR* pStr, int32_t iLength); | |
52 virtual void Flush(); | |
53 virtual FX_BOOL SetLength(int32_t iLength); | |
54 | |
55 protected: | |
56 FXSYS_FILE* m_hFile; | |
57 int32_t m_iLength; | |
58 }; | |
59 | |
60 class CFX_BufferStreamImp : public CFX_StreamImp { | |
61 public: | |
62 CFX_BufferStreamImp(); | |
63 virtual ~CFX_BufferStreamImp() {} | |
64 FX_BOOL LoadBuffer(uint8_t* pData, int32_t iTotalSize, FX_DWORD dwAccess); | |
65 virtual int32_t GetLength() const; | |
66 virtual int32_t Seek(FX_STREAMSEEK eSeek, int32_t iOffset); | |
67 virtual int32_t GetPosition(); | |
68 virtual FX_BOOL IsEOF() const; | |
69 virtual int32_t ReadData(uint8_t* pBuffer, int32_t iBufferSize); | |
70 virtual int32_t ReadString(FX_WCHAR* pStr, int32_t iMaxLength, FX_BOOL& bEOS); | |
71 virtual int32_t WriteData(const uint8_t* pBuffer, int32_t iBufferSize); | |
72 virtual int32_t WriteString(const FX_WCHAR* pStr, int32_t iLength); | |
73 virtual void Flush() {} | |
74 virtual FX_BOOL SetLength(int32_t iLength) { return FALSE; } | |
75 | |
76 protected: | |
77 uint8_t* m_pData; | |
78 int32_t m_iTotalSize; | |
79 int32_t m_iPosition; | |
80 int32_t m_iLength; | |
81 }; | |
82 | |
83 class CFX_FileReadStreamImp : public CFX_StreamImp { | |
84 public: | |
85 CFX_FileReadStreamImp(); | |
86 virtual ~CFX_FileReadStreamImp() {} | |
87 FX_BOOL LoadFileRead(IFX_FileRead* pFileRead, FX_DWORD dwAccess); | |
88 virtual int32_t GetLength() const; | |
89 virtual int32_t Seek(FX_STREAMSEEK eSeek, int32_t iOffset); | |
90 virtual int32_t GetPosition() { return m_iPosition; } | |
91 virtual FX_BOOL IsEOF() const; | |
92 | |
93 virtual int32_t ReadData(uint8_t* pBuffer, int32_t iBufferSize); | |
94 virtual int32_t ReadString(FX_WCHAR* pStr, int32_t iMaxLength, FX_BOOL& bEOS); | |
95 virtual int32_t WriteData(const uint8_t* pBuffer, int32_t iBufferSize) { | |
96 return 0; | |
97 } | |
98 virtual int32_t WriteString(const FX_WCHAR* pStr, int32_t iLength) { | |
99 return 0; | |
100 } | |
101 virtual void Flush() {} | |
102 virtual FX_BOOL SetLength(int32_t iLength) { return FALSE; } | |
103 | |
104 protected: | |
105 IFX_FileRead* m_pFileRead; | |
106 int32_t m_iPosition; | |
107 int32_t m_iLength; | |
108 }; | |
109 | |
110 class CFX_BufferReadStreamImp : public CFX_StreamImp { | |
111 public: | |
112 CFX_BufferReadStreamImp(); | |
113 ~CFX_BufferReadStreamImp(); | |
114 FX_BOOL LoadBufferRead(IFX_BufferRead* pBufferRead, | |
115 int32_t iFileSize, | |
116 FX_DWORD dwAccess, | |
117 FX_BOOL bReleaseBufferRead); | |
118 | |
119 virtual int32_t GetLength() const; | |
120 virtual int32_t Seek(FX_STREAMSEEK eSeek, int32_t iOffset); | |
121 virtual int32_t GetPosition() { return m_iPosition; } | |
122 virtual FX_BOOL IsEOF() const; | |
123 | |
124 virtual int32_t ReadData(uint8_t* pBuffer, int32_t iBufferSize); | |
125 virtual int32_t ReadString(FX_WCHAR* pStr, int32_t iMaxLength, FX_BOOL& bEOS); | |
126 virtual int32_t WriteData(const uint8_t* pBuffer, int32_t iBufferSize) { | |
127 return 0; | |
128 } | |
129 virtual int32_t WriteString(const FX_WCHAR* pStr, int32_t iLength) { | |
130 return 0; | |
131 } | |
132 virtual void Flush() {} | |
133 virtual FX_BOOL SetLength(int32_t iLength) { return FALSE; } | |
134 | |
135 private: | |
136 IFX_BufferRead* m_pBufferRead; | |
137 FX_BOOL m_bReleaseBufferRead; | |
138 int32_t m_iPosition; | |
139 int32_t m_iBufferSize; | |
140 }; | |
141 | |
142 class CFX_FileWriteStreamImp : public CFX_StreamImp { | |
143 public: | |
144 CFX_FileWriteStreamImp(); | |
145 virtual ~CFX_FileWriteStreamImp() {} | |
146 FX_BOOL LoadFileWrite(IFX_FileWrite* pFileWrite, FX_DWORD dwAccess); | |
147 virtual int32_t GetLength() const; | |
148 virtual int32_t Seek(FX_STREAMSEEK eSeek, int32_t iOffset); | |
149 virtual int32_t GetPosition() { return m_iPosition; } | |
150 virtual FX_BOOL IsEOF() const; | |
151 virtual int32_t ReadData(uint8_t* pBuffer, int32_t iBufferSize) { return 0; } | |
152 virtual int32_t ReadString(FX_WCHAR* pStr, | |
153 int32_t iMaxLength, | |
154 FX_BOOL& bEOS) { | |
155 return 0; | |
156 } | |
157 virtual int32_t WriteData(const uint8_t* pBuffer, int32_t iBufferSize); | |
158 virtual int32_t WriteString(const FX_WCHAR* pStr, int32_t iLength); | |
159 virtual void Flush(); | |
160 virtual FX_BOOL SetLength(int32_t iLength) { return FALSE; } | |
161 | |
162 protected: | |
163 IFX_FileWrite* m_pFileWrite; | |
164 int32_t m_iPosition; | |
165 }; | |
166 | |
167 enum FX_STREAMTYPE { | |
168 FX_SREAMTYPE_Unknown = 0, | |
169 FX_STREAMTYPE_File, | |
170 FX_STREAMTYPE_Buffer, | |
171 FX_STREAMTYPE_Stream, | |
172 FX_STREAMTYPE_BufferRead, | |
173 }; | |
174 | |
175 class CFX_Stream : public IFX_Stream { | |
176 public: | |
177 CFX_Stream(); | |
178 ~CFX_Stream(); | |
179 FX_BOOL LoadFile(const FX_WCHAR* pszSrcFileName, FX_DWORD dwAccess); | |
180 FX_BOOL LoadBuffer(uint8_t* pData, int32_t iTotalSize, FX_DWORD dwAccess); | |
181 FX_BOOL LoadFileRead(IFX_FileRead* pFileRead, FX_DWORD dwAccess); | |
182 FX_BOOL LoadFileWrite(IFX_FileWrite* pFileWrite, FX_DWORD dwAccess); | |
183 FX_BOOL LoadBufferRead(IFX_BufferRead* pBufferRead, | |
184 int32_t iFileSize, | |
185 FX_DWORD dwAccess, | |
186 FX_BOOL bReleaseBufferRead); | |
187 virtual void Release(); | |
188 virtual IFX_Stream* Retain(); | |
189 virtual FX_DWORD GetAccessModes() const { return m_dwAccess; } | |
190 virtual int32_t GetLength() const; | |
191 virtual int32_t Seek(FX_STREAMSEEK eSeek, int32_t iOffset); | |
192 virtual int32_t GetPosition(); | |
193 virtual FX_BOOL IsEOF() const; | |
194 virtual int32_t ReadData(uint8_t* pBuffer, int32_t iBufferSize); | |
195 virtual int32_t ReadString(FX_WCHAR* pStr, | |
196 int32_t iMaxLength, | |
197 FX_BOOL& bEOS, | |
198 int32_t const* pByteSize = NULL); | |
199 virtual int32_t WriteData(const uint8_t* pBuffer, int32_t iBufferSize); | |
200 virtual int32_t WriteString(const FX_WCHAR* pStr, int32_t iLength); | |
201 virtual void Flush(); | |
202 virtual FX_BOOL SetLength(int32_t iLength); | |
203 virtual int32_t GetBOM(uint8_t bom[4]) const; | |
204 virtual FX_WORD GetCodePage() const; | |
205 virtual FX_WORD SetCodePage(FX_WORD wCodePage); | |
206 virtual IFX_Stream* CreateSharedStream(FX_DWORD dwAccess, | |
207 int32_t iOffset, | |
208 int32_t iLength); | |
209 | |
210 protected: | |
211 FX_STREAMTYPE m_eStreamType; | |
212 CFX_StreamImp* m_pStreamImp; | |
213 FX_DWORD m_dwAccess; | |
214 int32_t m_iTotalSize; | |
215 int32_t m_iPosition; | |
216 int32_t m_iStart; | |
217 int32_t m_iLength; | |
218 int32_t m_iRefCount; | |
219 }; | |
220 | |
221 class CFX_TextStream : public IFX_Stream { | |
222 public: | |
223 CFX_TextStream(IFX_Stream* pStream, FX_BOOL bDelStream); | |
224 ~CFX_TextStream(); | |
225 virtual void Release(); | |
226 virtual IFX_Stream* Retain(); | |
227 | |
228 virtual FX_DWORD GetAccessModes() const; | |
229 virtual int32_t GetLength() const; | |
230 virtual int32_t Seek(FX_STREAMSEEK eSeek, int32_t iOffset); | |
231 virtual int32_t GetPosition(); | |
232 virtual FX_BOOL IsEOF() const; | |
233 | |
234 virtual int32_t ReadData(uint8_t* pBuffer, int32_t iBufferSize); | |
235 virtual int32_t ReadString(FX_WCHAR* pStr, | |
236 int32_t iMaxLength, | |
237 FX_BOOL& bEOS, | |
238 int32_t const* pByteSize = NULL); | |
239 virtual int32_t WriteData(const uint8_t* pBuffer, int32_t iBufferSize); | |
240 virtual int32_t WriteString(const FX_WCHAR* pStr, int32_t iLength); | |
241 virtual void Flush(); | |
242 virtual FX_BOOL SetLength(int32_t iLength); | |
243 | |
244 virtual int32_t GetBOM(uint8_t bom[4]) const; | |
245 virtual FX_WORD GetCodePage() const; | |
246 virtual FX_WORD SetCodePage(FX_WORD wCodePage); | |
247 | |
248 virtual IFX_Stream* CreateSharedStream(FX_DWORD dwAccess, | |
249 int32_t iOffset, | |
250 int32_t iLength); | |
251 | |
252 protected: | |
253 FX_WORD m_wCodePage; | |
254 int32_t m_wBOMLength; | |
255 FX_DWORD m_dwBOM; | |
256 uint8_t* m_pBuf; | |
257 int32_t m_iBufSize; | |
258 FX_BOOL m_bDelStream; | |
259 IFX_Stream* m_pStreamImp; | |
260 int32_t m_iRefCount; | |
261 void InitStream(); | |
262 }; | |
263 | |
264 class CFGAS_FileRead : public IFX_FileRead { | |
265 public: | |
266 CFGAS_FileRead(IFX_Stream* pStream, FX_BOOL bReleaseStream); | |
267 virtual ~CFGAS_FileRead(); | |
268 virtual void Release() { delete this; } | |
269 virtual FX_FILESIZE GetSize(); | |
270 virtual FX_BOOL ReadBlock(void* buffer, FX_FILESIZE offset, size_t size); | |
271 | |
272 protected: | |
273 FX_BOOL m_bReleaseStream; | |
274 IFX_Stream* m_pStream; | |
275 }; | |
276 | |
277 class CFX_BufferAccImp : public IFX_FileRead { | |
278 public: | |
279 CFX_BufferAccImp(IFX_BufferRead* pBufferRead, | |
280 FX_FILESIZE iFileSize, | |
281 FX_BOOL bReleaseStream); | |
282 virtual ~CFX_BufferAccImp(); | |
283 virtual void Release() { delete this; } | |
284 virtual FX_FILESIZE GetSize(); | |
285 virtual FX_BOOL ReadBlock(void* buffer, FX_FILESIZE offset, size_t size); | |
286 | |
287 protected: | |
288 IFX_BufferRead* m_pBufferRead; | |
289 FX_BOOL m_bReleaseStream; | |
290 FX_FILESIZE m_iBufSize; | |
291 }; | |
292 | |
293 class CFGAS_FileWrite : public IFX_FileWrite { | |
294 public: | |
295 CFGAS_FileWrite(IFX_Stream* pStream, FX_BOOL bReleaseStream); | |
296 virtual ~CFGAS_FileWrite(); | |
297 virtual void Release() { delete this; } | |
298 virtual FX_FILESIZE GetSize(); | |
299 virtual FX_BOOL Flush(); | |
300 virtual FX_BOOL WriteBlock(const void* pData, size_t size); | |
301 virtual FX_BOOL WriteBlock(const void* pData, | |
302 FX_FILESIZE offset, | |
303 size_t size); | |
304 | |
305 protected: | |
306 IFX_Stream* m_pStream; | |
307 FX_BOOL m_bReleaseStream; | |
308 }; | |
309 | |
310 } // namespace | |
311 | |
312 IFX_Stream* IFX_Stream::CreateStream(IFX_BufferRead* pBufferRead, | |
313 FX_DWORD dwAccess, | |
314 int32_t iFileSize, | |
315 FX_BOOL bReleaseBufferRead) { | |
316 CFX_Stream* pSR = new CFX_Stream; | |
317 if (!pSR->LoadBufferRead(pBufferRead, iFileSize, dwAccess, | |
318 bReleaseBufferRead)) { | |
319 pSR->Release(); | |
320 return NULL; | |
321 } | |
322 if (dwAccess & FX_STREAMACCESS_Text) { | |
323 return new CFX_TextStream(pSR, TRUE); | |
324 } | |
325 return pSR; | |
326 } | |
327 IFX_Stream* IFX_Stream::CreateStream(IFX_FileRead* pFileRead, | |
328 FX_DWORD dwAccess) { | |
329 CFX_Stream* pSR = new CFX_Stream; | |
330 if (!pSR->LoadFileRead(pFileRead, dwAccess)) { | |
331 pSR->Release(); | |
332 return NULL; | |
333 } | |
334 if (dwAccess & FX_STREAMACCESS_Text) { | |
335 return new CFX_TextStream(pSR, TRUE); | |
336 } | |
337 return pSR; | |
338 } | |
339 IFX_Stream* IFX_Stream::CreateStream(IFX_FileWrite* pFileWrite, | |
340 FX_DWORD dwAccess) { | |
341 CFX_Stream* pSR = new CFX_Stream; | |
342 if (!pSR->LoadFileWrite(pFileWrite, dwAccess)) { | |
343 pSR->Release(); | |
344 return NULL; | |
345 } | |
346 if (dwAccess & FX_STREAMACCESS_Text) { | |
347 return new CFX_TextStream(pSR, TRUE); | |
348 } | |
349 return pSR; | |
350 } | |
351 IFX_Stream* IFX_Stream::CreateStream(const FX_WCHAR* pszFileName, | |
352 FX_DWORD dwAccess) { | |
353 CFX_Stream* pSR = new CFX_Stream; | |
354 if (!pSR->LoadFile(pszFileName, dwAccess)) { | |
355 pSR->Release(); | |
356 return NULL; | |
357 } | |
358 if (dwAccess & FX_STREAMACCESS_Text) { | |
359 return new CFX_TextStream(pSR, TRUE); | |
360 } | |
361 return pSR; | |
362 } | |
363 IFX_Stream* IFX_Stream::CreateStream(uint8_t* pData, | |
364 int32_t length, | |
365 FX_DWORD dwAccess) { | |
366 CFX_Stream* pSR = new CFX_Stream; | |
367 if (!pSR->LoadBuffer(pData, length, dwAccess)) { | |
368 pSR->Release(); | |
369 return NULL; | |
370 } | |
371 if (dwAccess & FX_STREAMACCESS_Text) { | |
372 return new CFX_TextStream(pSR, TRUE); | |
373 } | |
374 return pSR; | |
375 } | |
376 | |
377 CFX_StreamImp::CFX_StreamImp() : m_dwAccess(0) {} | |
378 CFX_FileStreamImp::CFX_FileStreamImp() | |
379 : CFX_StreamImp(), m_hFile(NULL), m_iLength(0) {} | |
380 CFX_FileStreamImp::~CFX_FileStreamImp() { | |
381 if (m_hFile != NULL) { | |
382 FXSYS_fclose(m_hFile); | |
383 } | |
384 } | |
385 FX_BOOL CFX_FileStreamImp::LoadFile(const FX_WCHAR* pszSrcFileName, | |
386 FX_DWORD dwAccess) { | |
387 FXSYS_assert(m_hFile == NULL); | |
388 FXSYS_assert(pszSrcFileName != NULL && FXSYS_wcslen(pszSrcFileName) > 0); | |
389 #if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN32_MOBILE_ || \ | |
390 _FX_OS_ == _FX_WIN64_ | |
391 CFX_WideString wsMode; | |
392 if (dwAccess & FX_STREAMACCESS_Write) { | |
393 if (dwAccess & FX_STREAMACCESS_Append) { | |
394 wsMode = L"a+b"; | |
395 } else if (dwAccess & FX_STREAMACCESS_Truncate) { | |
396 wsMode = L"w+b"; | |
397 } else { | |
398 wsMode = L"r+b"; | |
399 } | |
400 } else { | |
401 wsMode = L"rb"; | |
402 } | |
403 m_hFile = FXSYS_wfopen(pszSrcFileName, wsMode); | |
404 | |
405 if (!m_hFile) { | |
406 if (dwAccess & FX_STREAMACCESS_Write) { | |
407 if (dwAccess & FX_STREAMACCESS_Create) | |
408 m_hFile = FXSYS_wfopen(pszSrcFileName, L"w+b"); | |
409 | |
410 if (!m_hFile) { | |
411 m_hFile = FXSYS_wfopen(pszSrcFileName, L"r+b"); | |
412 if (!m_hFile) | |
413 return FALSE; | |
414 | |
415 if (dwAccess & FX_STREAMACCESS_Truncate) | |
416 FX_fsetsize(m_hFile, 0); | |
417 } | |
418 } else { | |
419 return FALSE; | |
420 } | |
421 } | |
422 #else | |
423 CFX_ByteString wsMode; | |
424 if (dwAccess & FX_STREAMACCESS_Write) { | |
425 if (dwAccess & FX_STREAMACCESS_Append) { | |
426 wsMode = "a+b"; | |
427 } else if (dwAccess & FX_STREAMACCESS_Truncate) { | |
428 wsMode = "w+b"; | |
429 } else { | |
430 wsMode = "r+b"; | |
431 } | |
432 } else { | |
433 wsMode = "rb"; | |
434 } | |
435 CFX_ByteString szFileName = CFX_ByteString::FromUnicode(pszSrcFileName); | |
436 m_hFile = FXSYS_fopen(szFileName, wsMode); | |
437 if (m_hFile == NULL) { | |
438 if (dwAccess & FX_STREAMACCESS_Write) { | |
439 if (dwAccess & FX_STREAMACCESS_Create) { | |
440 m_hFile = FXSYS_fopen(szFileName, "w+b"); | |
441 } | |
442 if (m_hFile == NULL) { | |
443 m_hFile = FXSYS_fopen(szFileName, "r+b"); | |
444 if (m_hFile == NULL) { | |
445 return FALSE; | |
446 } | |
447 if (dwAccess & FX_STREAMACCESS_Truncate) { | |
448 FX_fsetsize(m_hFile, 0); | |
449 } | |
450 } | |
451 } else { | |
452 return FALSE; | |
453 } | |
454 } | |
455 #endif | |
456 m_dwAccess = dwAccess; | |
457 if ((dwAccess & (FX_STREAMACCESS_Write | FX_STREAMACCESS_Truncate)) == | |
458 (FX_STREAMACCESS_Write | FX_STREAMACCESS_Truncate)) { | |
459 m_iLength = 0; | |
460 } else { | |
461 m_iLength = FX_filelength(m_hFile); | |
462 } | |
463 return TRUE; | |
464 } | |
465 int32_t CFX_FileStreamImp::GetLength() const { | |
466 FXSYS_assert(m_hFile != NULL); | |
467 return m_iLength; | |
468 } | |
469 int32_t CFX_FileStreamImp::Seek(FX_STREAMSEEK eSeek, int32_t iOffset) { | |
470 FXSYS_assert(m_hFile != NULL); | |
471 FXSYS_fseek(m_hFile, iOffset, eSeek); | |
472 return FXSYS_ftell(m_hFile); | |
473 } | |
474 int32_t CFX_FileStreamImp::GetPosition() { | |
475 FXSYS_assert(m_hFile != NULL); | |
476 return FXSYS_ftell(m_hFile); | |
477 } | |
478 FX_BOOL CFX_FileStreamImp::IsEOF() const { | |
479 FXSYS_assert(m_hFile != NULL); | |
480 return FXSYS_ftell(m_hFile) >= m_iLength; | |
481 } | |
482 int32_t CFX_FileStreamImp::ReadData(uint8_t* pBuffer, int32_t iBufferSize) { | |
483 FXSYS_assert(m_hFile != NULL); | |
484 FXSYS_assert(pBuffer != NULL && iBufferSize > 0); | |
485 return FXSYS_fread(pBuffer, 1, iBufferSize, m_hFile); | |
486 } | |
487 int32_t CFX_FileStreamImp::ReadString(FX_WCHAR* pStr, | |
488 int32_t iMaxLength, | |
489 FX_BOOL& bEOS) { | |
490 FXSYS_assert(m_hFile != NULL); | |
491 FXSYS_assert(pStr != NULL && iMaxLength > 0); | |
492 if (m_iLength <= 0) { | |
493 return 0; | |
494 } | |
495 int32_t iPosition = FXSYS_ftell(m_hFile); | |
496 int32_t iLen = std::min((m_iLength - iPosition) / 2, iMaxLength); | |
497 if (iLen <= 0) { | |
498 return 0; | |
499 } | |
500 iLen = FXSYS_fread(pStr, 2, iLen, m_hFile); | |
501 int32_t iCount = 0; | |
502 while (*pStr != L'\0' && iCount < iLen) { | |
503 pStr++, iCount++; | |
504 } | |
505 iPosition += iCount * 2; | |
506 if (FXSYS_ftell(m_hFile) != iPosition) { | |
507 FXSYS_fseek(m_hFile, iPosition, 0); | |
508 } | |
509 bEOS = (iPosition >= m_iLength); | |
510 return iCount; | |
511 } | |
512 int32_t CFX_FileStreamImp::WriteData(const uint8_t* pBuffer, | |
513 int32_t iBufferSize) { | |
514 FXSYS_assert(m_hFile != NULL && (m_dwAccess & FX_STREAMACCESS_Write) != 0); | |
515 FXSYS_assert(pBuffer != NULL && iBufferSize > 0); | |
516 int32_t iRet = FXSYS_fwrite(pBuffer, 1, iBufferSize, m_hFile); | |
517 if (iRet != 0) { | |
518 int32_t iPos = FXSYS_ftell(m_hFile); | |
519 if (iPos > m_iLength) { | |
520 m_iLength = iPos; | |
521 } | |
522 } | |
523 return iRet; | |
524 } | |
525 int32_t CFX_FileStreamImp::WriteString(const FX_WCHAR* pStr, int32_t iLength) { | |
526 FXSYS_assert(m_hFile != NULL && (m_dwAccess & FX_STREAMACCESS_Write) != 0); | |
527 FXSYS_assert(pStr != NULL && iLength > 0); | |
528 int32_t iRet = FXSYS_fwrite(pStr, 2, iLength, m_hFile); | |
529 if (iRet != 0) { | |
530 int32_t iPos = FXSYS_ftell(m_hFile); | |
531 if (iPos > m_iLength) { | |
532 m_iLength = iPos; | |
533 } | |
534 } | |
535 return iRet; | |
536 } | |
537 void CFX_FileStreamImp::Flush() { | |
538 FXSYS_assert(m_hFile != NULL && (m_dwAccess & FX_STREAMACCESS_Write) != 0); | |
539 FXSYS_fflush(m_hFile); | |
540 } | |
541 FX_BOOL CFX_FileStreamImp::SetLength(int32_t iLength) { | |
542 FXSYS_assert(m_hFile != NULL && (m_dwAccess & FX_STREAMACCESS_Write) != 0); | |
543 FX_BOOL bRet = FX_fsetsize(m_hFile, iLength); | |
544 m_iLength = FX_filelength(m_hFile); | |
545 return bRet; | |
546 } | |
547 CFX_FileReadStreamImp::CFX_FileReadStreamImp() | |
548 : m_pFileRead(NULL), m_iPosition(0), m_iLength(0) {} | |
549 FX_BOOL CFX_FileReadStreamImp::LoadFileRead(IFX_FileRead* pFileRead, | |
550 FX_DWORD dwAccess) { | |
551 FXSYS_assert(m_pFileRead == NULL && pFileRead != NULL); | |
552 if (dwAccess & FX_STREAMACCESS_Write) { | |
553 return FALSE; | |
554 } | |
555 m_pFileRead = pFileRead; | |
556 m_iLength = m_pFileRead->GetSize(); | |
557 return TRUE; | |
558 } | |
559 int32_t CFX_FileReadStreamImp::GetLength() const { | |
560 return m_iLength; | |
561 } | |
562 int32_t CFX_FileReadStreamImp::Seek(FX_STREAMSEEK eSeek, int32_t iOffset) { | |
563 switch (eSeek) { | |
564 case FX_STREAMSEEK_Begin: | |
565 m_iPosition = iOffset; | |
566 break; | |
567 case FX_STREAMSEEK_Current: | |
568 m_iPosition += iOffset; | |
569 break; | |
570 case FX_STREAMSEEK_End: | |
571 m_iPosition = m_iLength + iOffset; | |
572 break; | |
573 } | |
574 if (m_iPosition < 0) { | |
575 m_iPosition = 0; | |
576 } else if (m_iPosition >= m_iLength) { | |
577 m_iPosition = m_iLength; | |
578 } | |
579 return m_iPosition; | |
580 } | |
581 FX_BOOL CFX_FileReadStreamImp::IsEOF() const { | |
582 return m_iPosition >= m_iLength; | |
583 } | |
584 int32_t CFX_FileReadStreamImp::ReadData(uint8_t* pBuffer, int32_t iBufferSize) { | |
585 FXSYS_assert(m_pFileRead != NULL); | |
586 FXSYS_assert(pBuffer != NULL && iBufferSize > 0); | |
587 if (iBufferSize > m_iLength - m_iPosition) { | |
588 iBufferSize = m_iLength - m_iPosition; | |
589 } | |
590 if (m_pFileRead->ReadBlock(pBuffer, m_iPosition, iBufferSize)) { | |
591 m_iPosition += iBufferSize; | |
592 return iBufferSize; | |
593 } | |
594 return 0; | |
595 } | |
596 int32_t CFX_FileReadStreamImp::ReadString(FX_WCHAR* pStr, | |
597 int32_t iMaxLength, | |
598 FX_BOOL& bEOS) { | |
599 FXSYS_assert(m_pFileRead != NULL); | |
600 FXSYS_assert(pStr != NULL && iMaxLength > 0); | |
601 iMaxLength = ReadData((uint8_t*)pStr, iMaxLength * 2) / 2; | |
602 if (iMaxLength <= 0) { | |
603 return 0; | |
604 } | |
605 int32_t i = 0; | |
606 while (i < iMaxLength && pStr[i] != L'\0') { | |
607 ++i; | |
608 } | |
609 bEOS = (m_iPosition >= m_iLength) || pStr[i] == L'\0'; | |
610 return i; | |
611 } | |
612 CFX_BufferReadStreamImp::CFX_BufferReadStreamImp() | |
613 : m_pBufferRead(NULL), | |
614 m_bReleaseBufferRead(FALSE), | |
615 m_iPosition(0), | |
616 m_iBufferSize(0) {} | |
617 CFX_BufferReadStreamImp::~CFX_BufferReadStreamImp() { | |
618 if (m_bReleaseBufferRead && m_pBufferRead != NULL) { | |
619 m_pBufferRead->Release(); | |
620 } | |
621 } | |
622 FX_BOOL CFX_BufferReadStreamImp::LoadBufferRead(IFX_BufferRead* pBufferRead, | |
623 int32_t iFileSize, | |
624 FX_DWORD dwAccess, | |
625 FX_BOOL bReleaseBufferRead) { | |
626 FXSYS_assert(m_pBufferRead == NULL && pBufferRead != NULL); | |
627 if (dwAccess & FX_STREAMACCESS_Write) { | |
628 return FALSE; | |
629 } | |
630 m_bReleaseBufferRead = bReleaseBufferRead; | |
631 m_pBufferRead = pBufferRead; | |
632 m_iBufferSize = iFileSize; | |
633 if (m_iBufferSize >= 0) { | |
634 return TRUE; | |
635 } | |
636 if (!m_pBufferRead->ReadNextBlock(TRUE)) { | |
637 return FALSE; | |
638 } | |
639 m_iBufferSize = m_pBufferRead->GetBlockSize(); | |
640 while (!m_pBufferRead->IsEOF()) { | |
641 m_pBufferRead->ReadNextBlock(FALSE); | |
642 m_iBufferSize += m_pBufferRead->GetBlockSize(); | |
643 } | |
644 return TRUE; | |
645 } | |
646 int32_t CFX_BufferReadStreamImp::GetLength() const { | |
647 return m_iBufferSize; | |
648 } | |
649 int32_t CFX_BufferReadStreamImp::Seek(FX_STREAMSEEK eSeek, int32_t iOffset) { | |
650 int32_t iLength = GetLength(); | |
651 switch (eSeek) { | |
652 case FX_STREAMSEEK_Begin: | |
653 m_iPosition = iOffset; | |
654 break; | |
655 case FX_STREAMSEEK_Current: | |
656 m_iPosition += iOffset; | |
657 break; | |
658 case FX_STREAMSEEK_End: | |
659 m_iPosition = iLength + iOffset; | |
660 break; | |
661 } | |
662 if (m_iPosition < 0) { | |
663 m_iPosition = 0; | |
664 } else if (m_iPosition >= iLength) { | |
665 m_iPosition = iLength; | |
666 } | |
667 return m_iPosition; | |
668 } | |
669 FX_BOOL CFX_BufferReadStreamImp::IsEOF() const { | |
670 return m_pBufferRead ? m_pBufferRead->IsEOF() : TRUE; | |
671 } | |
672 int32_t CFX_BufferReadStreamImp::ReadData(uint8_t* pBuffer, | |
673 int32_t iBufferSize) { | |
674 FXSYS_assert(m_pBufferRead != NULL); | |
675 FXSYS_assert(pBuffer != NULL && iBufferSize > 0); | |
676 int32_t iLength = GetLength(); | |
677 if (m_iPosition >= iLength) { | |
678 return 0; | |
679 } | |
680 if (iBufferSize > iLength - m_iPosition) { | |
681 iBufferSize = iLength - m_iPosition; | |
682 } | |
683 FX_DWORD dwBlockOffset = m_pBufferRead->GetBlockOffset(); | |
684 FX_DWORD dwBlockSize = m_pBufferRead->GetBlockSize(); | |
685 if (m_iPosition < (int32_t)dwBlockOffset) { | |
686 if (!m_pBufferRead->ReadNextBlock(TRUE)) { | |
687 return 0; | |
688 } | |
689 dwBlockOffset = m_pBufferRead->GetBlockOffset(); | |
690 dwBlockSize = m_pBufferRead->GetBlockSize(); | |
691 } | |
692 while (m_iPosition < (int32_t)dwBlockOffset || | |
693 m_iPosition >= (int32_t)(dwBlockOffset + dwBlockSize)) { | |
694 if (m_pBufferRead->IsEOF() || !m_pBufferRead->ReadNextBlock(FALSE)) { | |
695 break; | |
696 } | |
697 dwBlockOffset = m_pBufferRead->GetBlockOffset(); | |
698 dwBlockSize = m_pBufferRead->GetBlockSize(); | |
699 } | |
700 if (m_iPosition < (int32_t)dwBlockOffset || | |
701 m_iPosition >= (int32_t)(dwBlockOffset + dwBlockSize)) { | |
702 return 0; | |
703 } | |
704 const uint8_t* pBufferTmp = m_pBufferRead->GetBlockBuffer(); | |
705 FX_DWORD dwOffsetTmp = m_iPosition - dwBlockOffset; | |
706 FX_DWORD dwCopySize = | |
707 std::min(iBufferSize, (int32_t)(dwBlockSize - dwOffsetTmp)); | |
708 FXSYS_memcpy(pBuffer, pBufferTmp + dwOffsetTmp, dwCopySize); | |
709 dwOffsetTmp = dwCopySize; | |
710 iBufferSize -= dwCopySize; | |
711 while (iBufferSize > 0) { | |
712 if (!m_pBufferRead->ReadNextBlock(FALSE)) { | |
713 break; | |
714 } | |
715 dwBlockOffset = m_pBufferRead->GetBlockOffset(); | |
716 dwBlockSize = m_pBufferRead->GetBlockSize(); | |
717 pBufferTmp = m_pBufferRead->GetBlockBuffer(); | |
718 dwCopySize = std::min((FX_DWORD)iBufferSize, dwBlockSize); | |
719 FXSYS_memcpy(pBuffer + dwOffsetTmp, pBufferTmp, dwCopySize); | |
720 dwOffsetTmp += dwCopySize; | |
721 iBufferSize -= dwCopySize; | |
722 } | |
723 m_iPosition += dwOffsetTmp; | |
724 return dwOffsetTmp; | |
725 } | |
726 int32_t CFX_BufferReadStreamImp::ReadString(FX_WCHAR* pStr, | |
727 int32_t iMaxLength, | |
728 FX_BOOL& bEOS) { | |
729 FXSYS_assert(m_pBufferRead != NULL); | |
730 FXSYS_assert(pStr != NULL && iMaxLength > 0); | |
731 iMaxLength = ReadData((uint8_t*)pStr, iMaxLength * 2) / 2; | |
732 if (iMaxLength <= 0) { | |
733 return 0; | |
734 } | |
735 int32_t i = 0; | |
736 while (i < iMaxLength && pStr[i] != L'\0') { | |
737 ++i; | |
738 } | |
739 bEOS = (m_iPosition >= GetLength()) || pStr[i] == L'\0'; | |
740 return i; | |
741 } | |
742 CFX_FileWriteStreamImp::CFX_FileWriteStreamImp() | |
743 : m_pFileWrite(NULL), m_iPosition(0) {} | |
744 FX_BOOL CFX_FileWriteStreamImp::LoadFileWrite(IFX_FileWrite* pFileWrite, | |
745 FX_DWORD dwAccess) { | |
746 FXSYS_assert(m_pFileWrite == NULL && pFileWrite != NULL); | |
747 if (dwAccess & FX_STREAMACCESS_Read) { | |
748 return FALSE; | |
749 } | |
750 if (dwAccess & FX_STREAMACCESS_Append) { | |
751 m_iPosition = pFileWrite->GetSize(); | |
752 } | |
753 m_pFileWrite = pFileWrite; | |
754 return TRUE; | |
755 } | |
756 int32_t CFX_FileWriteStreamImp::GetLength() const { | |
757 if (!m_pFileWrite) { | |
758 return 0; | |
759 } | |
760 return (int32_t)m_pFileWrite->GetSize(); | |
761 } | |
762 int32_t CFX_FileWriteStreamImp::Seek(FX_STREAMSEEK eSeek, int32_t iOffset) { | |
763 int32_t iLength = GetLength(); | |
764 switch (eSeek) { | |
765 case FX_STREAMSEEK_Begin: | |
766 m_iPosition = iOffset; | |
767 break; | |
768 case FX_STREAMSEEK_Current: | |
769 m_iPosition += iOffset; | |
770 break; | |
771 case FX_STREAMSEEK_End: | |
772 m_iPosition = iLength + iOffset; | |
773 break; | |
774 } | |
775 if (m_iPosition < 0) { | |
776 m_iPosition = 0; | |
777 } else if (m_iPosition >= iLength) { | |
778 m_iPosition = iLength; | |
779 } | |
780 return m_iPosition; | |
781 } | |
782 FX_BOOL CFX_FileWriteStreamImp::IsEOF() const { | |
783 return m_iPosition >= GetLength(); | |
784 } | |
785 int32_t CFX_FileWriteStreamImp::WriteData(const uint8_t* pBuffer, | |
786 int32_t iBufferSize) { | |
787 if (!m_pFileWrite) { | |
788 return 0; | |
789 } | |
790 if (m_pFileWrite->WriteBlock(pBuffer, m_iPosition, iBufferSize)) { | |
791 m_iPosition += iBufferSize; | |
792 } | |
793 return iBufferSize; | |
794 } | |
795 int32_t CFX_FileWriteStreamImp::WriteString(const FX_WCHAR* pStr, | |
796 int32_t iLength) { | |
797 return WriteData((const uint8_t*)pStr, iLength * sizeof(FX_WCHAR)); | |
798 } | |
799 void CFX_FileWriteStreamImp::Flush() { | |
800 if (m_pFileWrite) { | |
801 m_pFileWrite->Flush(); | |
802 } | |
803 } | |
804 CFX_BufferStreamImp::CFX_BufferStreamImp() | |
805 : CFX_StreamImp(), | |
806 m_pData(NULL), | |
807 m_iTotalSize(0), | |
808 m_iPosition(0), | |
809 m_iLength(0) {} | |
810 FX_BOOL CFX_BufferStreamImp::LoadBuffer(uint8_t* pData, | |
811 int32_t iTotalSize, | |
812 FX_DWORD dwAccess) { | |
813 FXSYS_assert(m_pData == NULL); | |
814 FXSYS_assert(pData != NULL && iTotalSize > 0); | |
815 m_dwAccess = dwAccess; | |
816 m_pData = pData; | |
817 m_iTotalSize = iTotalSize; | |
818 m_iPosition = 0; | |
819 m_iLength = (dwAccess & FX_STREAMACCESS_Write) != 0 ? 0 : iTotalSize; | |
820 return TRUE; | |
821 } | |
822 int32_t CFX_BufferStreamImp::GetLength() const { | |
823 FXSYS_assert(m_pData != NULL); | |
824 return m_iLength; | |
825 } | |
826 int32_t CFX_BufferStreamImp::Seek(FX_STREAMSEEK eSeek, int32_t iOffset) { | |
827 FXSYS_assert(m_pData != NULL); | |
828 if (eSeek == FX_STREAMSEEK_Begin) { | |
829 m_iPosition = iOffset; | |
830 } else if (eSeek == FX_STREAMSEEK_Current) { | |
831 m_iPosition += iOffset; | |
832 } else if (eSeek == FX_STREAMSEEK_End) { | |
833 m_iPosition = m_iLength + iOffset; | |
834 } | |
835 if (m_iPosition > m_iLength) { | |
836 m_iPosition = m_iLength; | |
837 } | |
838 if (m_iPosition < 0) { | |
839 m_iPosition = 0; | |
840 } | |
841 return m_iPosition; | |
842 } | |
843 int32_t CFX_BufferStreamImp::GetPosition() { | |
844 FXSYS_assert(m_pData != NULL); | |
845 return m_iPosition; | |
846 } | |
847 FX_BOOL CFX_BufferStreamImp::IsEOF() const { | |
848 FXSYS_assert(m_pData != NULL); | |
849 return m_iPosition >= m_iLength; | |
850 } | |
851 int32_t CFX_BufferStreamImp::ReadData(uint8_t* pBuffer, int32_t iBufferSize) { | |
852 FXSYS_assert(m_pData != NULL); | |
853 FXSYS_assert(pBuffer != NULL && iBufferSize > 0); | |
854 int32_t iLen = std::min(m_iLength - m_iPosition, iBufferSize); | |
855 if (iLen <= 0) { | |
856 return 0; | |
857 } | |
858 FXSYS_memcpy(pBuffer, m_pData + m_iPosition, iLen); | |
859 m_iPosition += iLen; | |
860 return iLen; | |
861 } | |
862 int32_t CFX_BufferStreamImp::ReadString(FX_WCHAR* pStr, | |
863 int32_t iMaxLength, | |
864 FX_BOOL& bEOS) { | |
865 FXSYS_assert(m_pData != NULL); | |
866 FXSYS_assert(pStr != NULL && iMaxLength > 0); | |
867 int32_t iLen = std::min((m_iLength - m_iPosition) / 2, iMaxLength); | |
868 if (iLen <= 0) { | |
869 return 0; | |
870 } | |
871 const FX_WCHAR* pSrc = (const FX_WCHAR*)(FX_CHAR*)(m_pData + m_iPosition); | |
872 int32_t iCount = 0; | |
873 while (*pSrc != L'\0' && iCount < iLen) { | |
874 *pStr++ = *pSrc++, iCount++; | |
875 } | |
876 m_iPosition += iCount * 2; | |
877 bEOS = (*pSrc == L'\0') || (m_iPosition >= m_iLength); | |
878 return iCount; | |
879 } | |
880 int32_t CFX_BufferStreamImp::WriteData(const uint8_t* pBuffer, | |
881 int32_t iBufferSize) { | |
882 FXSYS_assert(m_pData != NULL && (m_dwAccess & FX_STREAMACCESS_Write) != 0); | |
883 FXSYS_assert(pBuffer != NULL && iBufferSize > 0); | |
884 int32_t iLen = std::min(m_iTotalSize - m_iPosition, iBufferSize); | |
885 if (iLen <= 0) { | |
886 return 0; | |
887 } | |
888 FXSYS_memcpy(m_pData + m_iPosition, pBuffer, iLen); | |
889 m_iPosition += iLen; | |
890 if (m_iPosition > m_iLength) { | |
891 m_iLength = m_iPosition; | |
892 } | |
893 return iLen; | |
894 } | |
895 int32_t CFX_BufferStreamImp::WriteString(const FX_WCHAR* pStr, | |
896 int32_t iLength) { | |
897 FXSYS_assert(m_pData != NULL && (m_dwAccess & FX_STREAMACCESS_Write) != 0); | |
898 FXSYS_assert(pStr != NULL && iLength > 0); | |
899 int32_t iLen = std::min((m_iTotalSize - m_iPosition) / 2, iLength); | |
900 if (iLen <= 0) { | |
901 return 0; | |
902 } | |
903 FXSYS_memcpy(m_pData + m_iPosition, pStr, iLen * 2); | |
904 m_iPosition += iLen * 2; | |
905 if (m_iPosition > m_iLength) { | |
906 m_iLength = m_iPosition; | |
907 } | |
908 return iLen; | |
909 } | |
910 IFX_Stream* IFX_Stream::CreateTextStream(IFX_Stream* pBaseStream, | |
911 FX_BOOL bDeleteOnRelease) { | |
912 FXSYS_assert(pBaseStream != NULL); | |
913 return new CFX_TextStream(pBaseStream, bDeleteOnRelease); | |
914 } | |
915 CFX_TextStream::CFX_TextStream(IFX_Stream* pStream, FX_BOOL bDelStream) | |
916 : m_wCodePage(FX_CODEPAGE_DefANSI), | |
917 m_wBOMLength(0), | |
918 m_dwBOM(0), | |
919 m_pBuf(NULL), | |
920 m_iBufSize(0), | |
921 m_bDelStream(bDelStream), | |
922 m_pStreamImp(pStream), | |
923 m_iRefCount(1) { | |
924 FXSYS_assert(m_pStreamImp != NULL); | |
925 m_pStreamImp->Retain(); | |
926 InitStream(); | |
927 } | |
928 CFX_TextStream::~CFX_TextStream() { | |
929 m_pStreamImp->Release(); | |
930 if (m_bDelStream) { | |
931 m_pStreamImp->Release(); | |
932 } | |
933 if (m_pBuf != NULL) { | |
934 FX_Free(m_pBuf); | |
935 } | |
936 } | |
937 void CFX_TextStream::InitStream() { | |
938 int32_t iPosition = m_pStreamImp->GetPosition(); | |
939 m_pStreamImp->Seek(FX_STREAMSEEK_Begin, 0); | |
940 m_pStreamImp->ReadData((uint8_t*)&m_dwBOM, 3); | |
941 #if _FX_ENDIAN_ == _FX_LITTLE_ENDIAN_ | |
942 m_dwBOM &= 0x00FFFFFF; | |
943 if (m_dwBOM == 0x00BFBBEF) { | |
944 m_wBOMLength = 3; | |
945 m_wCodePage = FX_CODEPAGE_UTF8; | |
946 } else { | |
947 m_dwBOM &= 0x0000FFFF; | |
948 if (m_dwBOM == 0x0000FFFE) { | |
949 m_wBOMLength = 2; | |
950 m_wCodePage = FX_CODEPAGE_UTF16BE; | |
951 } else if (m_dwBOM == 0x0000FEFF) { | |
952 m_wBOMLength = 2; | |
953 m_wCodePage = FX_CODEPAGE_UTF16LE; | |
954 } else { | |
955 m_wBOMLength = 0; | |
956 m_dwBOM = 0; | |
957 m_wCodePage = FXSYS_GetACP(); | |
958 } | |
959 } | |
960 #else | |
961 m_dwBOM &= 0xFFFFFF00; | |
962 if (m_dwBOM == 0xEFBBBF00) { | |
963 m_wBOMLength = 3; | |
964 m_wCodePage = FX_CODEPAGE_UTF8; | |
965 } else { | |
966 m_dwBOM &= 0xFFFF0000; | |
967 if (m_dwBOM == 0xFEFF0000) { | |
968 m_wBOMLength = 2; | |
969 m_wCodePage = FX_CODEPAGE_UTF16BE; | |
970 } else if (m_dwBOM == 0xFFFE0000) { | |
971 m_wBOMLength = 2; | |
972 m_wCodePage = FX_CODEPAGE_UTF16LE; | |
973 } else { | |
974 m_wBOMLength = 0; | |
975 m_dwBOM = 0; | |
976 m_wCodePage = FXSYS_GetACP(); | |
977 } | |
978 } | |
979 #endif | |
980 m_pStreamImp->Seek(FX_STREAMSEEK_Begin, std::max(m_wBOMLength, iPosition)); | |
981 } | |
982 void CFX_TextStream::Release() { | |
983 if (--m_iRefCount < 1) { | |
984 delete this; | |
985 } | |
986 } | |
987 IFX_Stream* CFX_TextStream::Retain() { | |
988 m_iRefCount++; | |
989 return this; | |
990 } | |
991 FX_DWORD CFX_TextStream::GetAccessModes() const { | |
992 return m_pStreamImp->GetAccessModes() | FX_STREAMACCESS_Text; | |
993 } | |
994 int32_t CFX_TextStream::GetLength() const { | |
995 return m_pStreamImp->GetLength(); | |
996 } | |
997 int32_t CFX_TextStream::Seek(FX_STREAMSEEK eSeek, int32_t iOffset) { | |
998 return m_pStreamImp->Seek(eSeek, iOffset); | |
999 } | |
1000 int32_t CFX_TextStream::GetPosition() { | |
1001 return m_pStreamImp->GetPosition(); | |
1002 } | |
1003 FX_BOOL CFX_TextStream::IsEOF() const { | |
1004 return m_pStreamImp->IsEOF(); | |
1005 } | |
1006 int32_t CFX_TextStream::ReadData(uint8_t* pBuffer, int32_t iBufferSize) { | |
1007 return m_pStreamImp->ReadData(pBuffer, iBufferSize); | |
1008 } | |
1009 int32_t CFX_TextStream::WriteData(const uint8_t* pBuffer, int32_t iBufferSize) { | |
1010 return m_pStreamImp->WriteData(pBuffer, iBufferSize); | |
1011 } | |
1012 void CFX_TextStream::Flush() { | |
1013 m_pStreamImp->Flush(); | |
1014 } | |
1015 FX_BOOL CFX_TextStream::SetLength(int32_t iLength) { | |
1016 return m_pStreamImp->SetLength(iLength); | |
1017 } | |
1018 FX_WORD CFX_TextStream::GetCodePage() const { | |
1019 return m_wCodePage; | |
1020 } | |
1021 IFX_Stream* CFX_TextStream::CreateSharedStream(FX_DWORD dwAccess, | |
1022 int32_t iOffset, | |
1023 int32_t iLength) { | |
1024 IFX_Stream* pSR = | |
1025 m_pStreamImp->CreateSharedStream(dwAccess, iOffset, iLength); | |
1026 if (pSR == NULL) { | |
1027 return NULL; | |
1028 } | |
1029 if (dwAccess & FX_STREAMACCESS_Text) { | |
1030 return new CFX_TextStream(pSR, TRUE); | |
1031 } | |
1032 return pSR; | |
1033 } | |
1034 int32_t CFX_TextStream::GetBOM(uint8_t bom[4]) const { | |
1035 if (m_wBOMLength < 1) { | |
1036 return 0; | |
1037 } | |
1038 *(FX_DWORD*)bom = m_dwBOM; | |
1039 return m_wBOMLength; | |
1040 } | |
1041 FX_WORD CFX_TextStream::SetCodePage(FX_WORD wCodePage) { | |
1042 if (m_wBOMLength > 0) { | |
1043 return m_wCodePage; | |
1044 } | |
1045 FX_WORD v = m_wCodePage; | |
1046 m_wCodePage = wCodePage; | |
1047 return v; | |
1048 } | |
1049 int32_t CFX_TextStream::ReadString(FX_WCHAR* pStr, | |
1050 int32_t iMaxLength, | |
1051 FX_BOOL& bEOS, | |
1052 int32_t const* pByteSize) { | |
1053 FXSYS_assert(pStr != NULL && iMaxLength > 0); | |
1054 if (m_pStreamImp == NULL) { | |
1055 return -1; | |
1056 } | |
1057 int32_t iLen; | |
1058 if (m_wCodePage == FX_CODEPAGE_UTF16LE || | |
1059 m_wCodePage == FX_CODEPAGE_UTF16BE) { | |
1060 int32_t iBytes = pByteSize == NULL ? iMaxLength * 2 : *pByteSize; | |
1061 iLen = m_pStreamImp->ReadData((uint8_t*)pStr, iBytes); | |
1062 iMaxLength = iLen / 2; | |
1063 if (sizeof(FX_WCHAR) > 2) { | |
1064 FX_UTF16ToWChar(pStr, iMaxLength); | |
1065 } | |
1066 #if _FX_ENDIAN_ == _FX_BIG_ENDIAN_ | |
1067 if (m_wCodePage == FX_CODEPAGE_UTF16LE) { | |
1068 FX_SwapByteOrder(pStr, iMaxLength); | |
1069 } | |
1070 #else | |
1071 if (m_wCodePage == FX_CODEPAGE_UTF16BE) { | |
1072 FX_SwapByteOrder(pStr, iMaxLength); | |
1073 } | |
1074 #endif | |
1075 } else { | |
1076 int32_t pos = m_pStreamImp->GetPosition(); | |
1077 int32_t iBytes = pByteSize == NULL ? iMaxLength : *pByteSize; | |
1078 iBytes = std::min(iBytes, m_pStreamImp->GetLength() - pos); | |
1079 if (iBytes > 0) { | |
1080 if (m_pBuf == NULL) { | |
1081 m_pBuf = FX_Alloc(uint8_t, iBytes); | |
1082 m_iBufSize = iBytes; | |
1083 } else if (iBytes > m_iBufSize) { | |
1084 m_pBuf = FX_Realloc(uint8_t, m_pBuf, iBytes); | |
1085 m_iBufSize = iBytes; | |
1086 } | |
1087 iLen = m_pStreamImp->ReadData(m_pBuf, iBytes); | |
1088 int32_t iSrc = iLen; | |
1089 int32_t iDecode = FX_DecodeString(m_wCodePage, (const FX_CHAR*)m_pBuf, | |
1090 &iSrc, pStr, &iMaxLength, TRUE); | |
1091 m_pStreamImp->Seek(FX_STREAMSEEK_Current, iSrc - iLen); | |
1092 if (iDecode < 1) { | |
1093 return -1; | |
1094 } | |
1095 } else { | |
1096 iMaxLength = 0; | |
1097 } | |
1098 } | |
1099 bEOS = m_pStreamImp->IsEOF(); | |
1100 return iMaxLength; | |
1101 } | |
1102 int32_t CFX_TextStream::WriteString(const FX_WCHAR* pStr, int32_t iLength) { | |
1103 FXSYS_assert(pStr != NULL && iLength > 0); | |
1104 if ((m_pStreamImp->GetAccessModes() & FX_STREAMACCESS_Write) == 0) { | |
1105 return -1; | |
1106 } | |
1107 if (m_wCodePage == FX_CODEPAGE_UTF8) { | |
1108 int32_t len = iLength; | |
1109 CFX_UTF8Encoder encoder; | |
1110 while (len-- > 0) { | |
1111 encoder.Input(*pStr++); | |
1112 } | |
1113 CFX_ByteStringC bsResult = encoder.GetResult(); | |
1114 m_pStreamImp->WriteData((const uint8_t*)bsResult.GetCStr(), | |
1115 bsResult.GetLength()); | |
1116 } | |
1117 return iLength; | |
1118 } | |
1119 CFX_Stream::CFX_Stream() | |
1120 : m_eStreamType(FX_SREAMTYPE_Unknown), | |
1121 m_pStreamImp(NULL), | |
1122 m_dwAccess(0), | |
1123 m_iTotalSize(0), | |
1124 m_iPosition(0), | |
1125 m_iStart(0), | |
1126 m_iLength(0), | |
1127 m_iRefCount(1) {} | |
1128 CFX_Stream::~CFX_Stream() { | |
1129 if (m_eStreamType != FX_STREAMTYPE_Stream && m_pStreamImp != NULL) { | |
1130 m_pStreamImp->Release(); | |
1131 } | |
1132 } | |
1133 FX_BOOL CFX_Stream::LoadFile(const FX_WCHAR* pszSrcFileName, | |
1134 FX_DWORD dwAccess) { | |
1135 if (m_eStreamType != FX_SREAMTYPE_Unknown || m_pStreamImp != NULL) { | |
1136 return FALSE; | |
1137 } | |
1138 if (pszSrcFileName == NULL || FXSYS_wcslen(pszSrcFileName) < 1) { | |
1139 return FALSE; | |
1140 } | |
1141 m_pStreamImp = new CFX_FileStreamImp(); | |
1142 FX_BOOL bRet = | |
1143 ((CFX_FileStreamImp*)m_pStreamImp)->LoadFile(pszSrcFileName, dwAccess); | |
1144 if (!bRet) { | |
1145 m_pStreamImp->Release(); | |
1146 m_pStreamImp = NULL; | |
1147 } else { | |
1148 m_eStreamType = FX_STREAMTYPE_File; | |
1149 m_dwAccess = dwAccess; | |
1150 m_iLength = m_pStreamImp->GetLength(); | |
1151 } | |
1152 return bRet; | |
1153 } | |
1154 FX_BOOL CFX_Stream::LoadFileRead(IFX_FileRead* pFileRead, FX_DWORD dwAccess) { | |
1155 if (m_eStreamType != FX_SREAMTYPE_Unknown || m_pStreamImp != NULL) { | |
1156 return FALSE; | |
1157 } | |
1158 if (pFileRead == NULL) { | |
1159 return FALSE; | |
1160 } | |
1161 m_pStreamImp = new CFX_FileReadStreamImp(); | |
1162 FX_BOOL bRet = | |
1163 ((CFX_FileReadStreamImp*)m_pStreamImp)->LoadFileRead(pFileRead, dwAccess); | |
1164 if (!bRet) { | |
1165 m_pStreamImp->Release(); | |
1166 m_pStreamImp = NULL; | |
1167 } else { | |
1168 m_eStreamType = FX_STREAMTYPE_File; | |
1169 m_dwAccess = dwAccess; | |
1170 m_iLength = m_pStreamImp->GetLength(); | |
1171 } | |
1172 return bRet; | |
1173 } | |
1174 FX_BOOL CFX_Stream::LoadFileWrite(IFX_FileWrite* pFileWrite, | |
1175 FX_DWORD dwAccess) { | |
1176 if (m_eStreamType != FX_SREAMTYPE_Unknown || m_pStreamImp != NULL) { | |
1177 return FALSE; | |
1178 } | |
1179 if (pFileWrite == NULL) { | |
1180 return FALSE; | |
1181 } | |
1182 m_pStreamImp = new CFX_FileWriteStreamImp(); | |
1183 FX_BOOL bRet = ((CFX_FileWriteStreamImp*)m_pStreamImp) | |
1184 ->LoadFileWrite(pFileWrite, dwAccess); | |
1185 if (!bRet) { | |
1186 m_pStreamImp->Release(); | |
1187 m_pStreamImp = NULL; | |
1188 } else { | |
1189 m_eStreamType = FX_STREAMTYPE_File; | |
1190 m_dwAccess = dwAccess; | |
1191 m_iLength = m_pStreamImp->GetLength(); | |
1192 } | |
1193 return bRet; | |
1194 } | |
1195 FX_BOOL CFX_Stream::LoadBuffer(uint8_t* pData, | |
1196 int32_t iTotalSize, | |
1197 FX_DWORD dwAccess) { | |
1198 if (m_eStreamType != FX_SREAMTYPE_Unknown || m_pStreamImp != NULL) { | |
1199 return FALSE; | |
1200 } | |
1201 if (pData == NULL || iTotalSize < 1) { | |
1202 return FALSE; | |
1203 } | |
1204 m_pStreamImp = new CFX_BufferStreamImp(); | |
1205 FX_BOOL bRet = ((CFX_BufferStreamImp*)m_pStreamImp) | |
1206 ->LoadBuffer(pData, iTotalSize, dwAccess); | |
1207 if (!bRet) { | |
1208 m_pStreamImp->Release(); | |
1209 m_pStreamImp = NULL; | |
1210 } else { | |
1211 m_eStreamType = FX_STREAMTYPE_Buffer; | |
1212 m_dwAccess = dwAccess; | |
1213 m_iLength = m_pStreamImp->GetLength(); | |
1214 } | |
1215 return bRet; | |
1216 } | |
1217 FX_BOOL CFX_Stream::LoadBufferRead(IFX_BufferRead* pBufferRead, | |
1218 int32_t iFileSize, | |
1219 FX_DWORD dwAccess, | |
1220 FX_BOOL bReleaseBufferRead) { | |
1221 if (m_eStreamType != FX_SREAMTYPE_Unknown || m_pStreamImp != NULL) { | |
1222 return FALSE; | |
1223 } | |
1224 if (!pBufferRead) { | |
1225 return FALSE; | |
1226 } | |
1227 m_pStreamImp = new CFX_BufferReadStreamImp; | |
1228 FX_BOOL bRet = ((CFX_BufferReadStreamImp*)m_pStreamImp) | |
1229 ->LoadBufferRead(pBufferRead, iFileSize, dwAccess, | |
1230 bReleaseBufferRead); | |
1231 if (!bRet) { | |
1232 m_pStreamImp->Release(); | |
1233 m_pStreamImp = NULL; | |
1234 } else { | |
1235 m_eStreamType = FX_STREAMTYPE_BufferRead; | |
1236 m_dwAccess = dwAccess; | |
1237 m_iLength = m_pStreamImp->GetLength(); | |
1238 } | |
1239 return bRet; | |
1240 } | |
1241 void CFX_Stream::Release() { | |
1242 if (--m_iRefCount < 1) { | |
1243 delete this; | |
1244 } | |
1245 } | |
1246 IFX_Stream* CFX_Stream::Retain() { | |
1247 m_iRefCount++; | |
1248 return this; | |
1249 } | |
1250 int32_t CFX_Stream::GetLength() const { | |
1251 if (m_pStreamImp == NULL) { | |
1252 return -1; | |
1253 } | |
1254 if (m_eStreamType == FX_STREAMTYPE_File || | |
1255 m_eStreamType == FX_STREAMTYPE_Buffer) { | |
1256 return m_pStreamImp->GetLength(); | |
1257 } | |
1258 return m_iLength; | |
1259 } | |
1260 int32_t CFX_Stream::Seek(FX_STREAMSEEK eSeek, int32_t iOffset) { | |
1261 if (m_pStreamImp == NULL) { | |
1262 return -1; | |
1263 } | |
1264 if (m_eStreamType == FX_STREAMTYPE_File || | |
1265 m_eStreamType == FX_STREAMTYPE_Buffer) { | |
1266 return m_iPosition = m_pStreamImp->Seek(eSeek, iOffset); | |
1267 } | |
1268 int32_t iEnd = m_iStart + m_iLength; | |
1269 int32_t iPosition = m_iStart + iOffset; | |
1270 if (eSeek == FX_STREAMSEEK_Begin) { | |
1271 m_iPosition = iPosition; | |
1272 } else if (eSeek == FX_STREAMSEEK_Current) { | |
1273 m_iPosition += iOffset; | |
1274 } else if (eSeek == FX_STREAMSEEK_End) { | |
1275 m_iPosition = iEnd + iOffset; | |
1276 } | |
1277 if (m_iPosition > iEnd) { | |
1278 m_iPosition = iEnd; | |
1279 } | |
1280 if (m_iPosition < m_iStart) { | |
1281 m_iPosition = m_iStart; | |
1282 } | |
1283 return m_iPosition - m_iStart; | |
1284 } | |
1285 int32_t CFX_Stream::GetPosition() { | |
1286 if (m_pStreamImp == NULL) { | |
1287 return -1; | |
1288 } | |
1289 if (m_eStreamType == FX_STREAMTYPE_File || | |
1290 m_eStreamType == FX_STREAMTYPE_Buffer) { | |
1291 return m_iPosition = m_pStreamImp->GetPosition(); | |
1292 } | |
1293 return m_iPosition - m_iStart; | |
1294 } | |
1295 FX_BOOL CFX_Stream::IsEOF() const { | |
1296 if (m_pStreamImp == NULL) { | |
1297 return TRUE; | |
1298 } | |
1299 if (m_eStreamType == FX_STREAMTYPE_File || | |
1300 m_eStreamType == FX_STREAMTYPE_Buffer) { | |
1301 return m_pStreamImp->IsEOF(); | |
1302 } | |
1303 return m_iPosition >= m_iStart + m_iLength; | |
1304 } | |
1305 int32_t CFX_Stream::ReadData(uint8_t* pBuffer, int32_t iBufferSize) { | |
1306 FXSYS_assert(pBuffer != NULL && iBufferSize > 0); | |
1307 if (m_pStreamImp == NULL) { | |
1308 return -1; | |
1309 } | |
1310 int32_t iLen = std::min(m_iStart + m_iLength - m_iPosition, iBufferSize); | |
1311 if (iLen <= 0) { | |
1312 return 0; | |
1313 } | |
1314 if (m_pStreamImp->GetPosition() != m_iPosition) { | |
1315 m_pStreamImp->Seek(FX_STREAMSEEK_Begin, m_iPosition); | |
1316 } | |
1317 iLen = m_pStreamImp->ReadData(pBuffer, iLen); | |
1318 m_iPosition = m_pStreamImp->GetPosition(); | |
1319 return iLen; | |
1320 } | |
1321 int32_t CFX_Stream::ReadString(FX_WCHAR* pStr, | |
1322 int32_t iMaxLength, | |
1323 FX_BOOL& bEOS, | |
1324 int32_t const* pByteSize) { | |
1325 FXSYS_assert(pStr != NULL && iMaxLength > 0); | |
1326 if (m_pStreamImp == NULL) { | |
1327 return -1; | |
1328 } | |
1329 int32_t iEnd = m_iStart + m_iLength; | |
1330 int32_t iLen = iEnd - m_iPosition; | |
1331 if (pByteSize != NULL) { | |
1332 iLen = std::min(iLen, *pByteSize); | |
1333 } | |
1334 iLen = std::min(iEnd / 2, iMaxLength); | |
1335 if (iLen <= 0) { | |
1336 return 0; | |
1337 } | |
1338 if (m_pStreamImp->GetPosition() != m_iPosition) { | |
1339 m_pStreamImp->Seek(FX_STREAMSEEK_Begin, m_iPosition); | |
1340 } | |
1341 iLen = m_pStreamImp->ReadString(pStr, iLen, bEOS); | |
1342 m_iPosition = m_pStreamImp->GetPosition(); | |
1343 if (iLen > 0 && m_iPosition >= iEnd) { | |
1344 bEOS = TRUE; | |
1345 } | |
1346 return iLen; | |
1347 } | |
1348 int32_t CFX_Stream::WriteData(const uint8_t* pBuffer, int32_t iBufferSize) { | |
1349 FXSYS_assert(pBuffer != NULL && iBufferSize > 0); | |
1350 if (m_pStreamImp == NULL) { | |
1351 return -1; | |
1352 } | |
1353 if ((m_dwAccess & FX_STREAMACCESS_Write) == 0) { | |
1354 return -1; | |
1355 } | |
1356 int32_t iLen = iBufferSize; | |
1357 if (m_eStreamType == FX_STREAMTYPE_Stream) { | |
1358 iLen = std::min(m_iStart + m_iTotalSize - m_iPosition, iBufferSize); | |
1359 if (iLen <= 0) { | |
1360 return 0; | |
1361 } | |
1362 } | |
1363 int32_t iEnd = m_iStart + m_iLength; | |
1364 if (m_pStreamImp->GetPosition() != m_iPosition) { | |
1365 m_pStreamImp->Seek(FX_STREAMSEEK_Begin, m_iPosition); | |
1366 } | |
1367 iLen = m_pStreamImp->WriteData(pBuffer, iLen); | |
1368 m_iPosition = m_pStreamImp->GetPosition(); | |
1369 if (m_iPosition > iEnd) { | |
1370 m_iLength = m_iPosition - m_iStart; | |
1371 } | |
1372 return iLen; | |
1373 } | |
1374 int32_t CFX_Stream::WriteString(const FX_WCHAR* pStr, int32_t iLength) { | |
1375 FXSYS_assert(pStr != NULL && iLength > 0); | |
1376 if (m_pStreamImp == NULL) { | |
1377 return -1; | |
1378 } | |
1379 if ((m_dwAccess & FX_STREAMACCESS_Write) == 0) { | |
1380 return -1; | |
1381 } | |
1382 int32_t iLen = iLength; | |
1383 if (m_eStreamType == FX_STREAMTYPE_Stream) { | |
1384 iLen = std::min((m_iStart + m_iTotalSize - m_iPosition) / 2, iLength); | |
1385 if (iLen <= 0) { | |
1386 return 0; | |
1387 } | |
1388 } | |
1389 int32_t iEnd = m_iStart + m_iLength; | |
1390 if (m_pStreamImp->GetPosition() != m_iPosition) { | |
1391 m_pStreamImp->Seek(FX_STREAMSEEK_Begin, m_iPosition); | |
1392 } | |
1393 iLen = m_pStreamImp->WriteString(pStr, iLen); | |
1394 m_iPosition = m_pStreamImp->GetPosition(); | |
1395 if (m_iPosition > iEnd) { | |
1396 m_iLength = m_iPosition - m_iStart; | |
1397 } | |
1398 return iLen; | |
1399 } | |
1400 void CFX_Stream::Flush() { | |
1401 if (m_pStreamImp == NULL) { | |
1402 return; | |
1403 } | |
1404 if ((m_dwAccess & FX_STREAMACCESS_Write) == 0) { | |
1405 return; | |
1406 } | |
1407 m_pStreamImp->Flush(); | |
1408 } | |
1409 FX_BOOL CFX_Stream::SetLength(int32_t iLength) { | |
1410 if (m_pStreamImp == NULL) { | |
1411 return FALSE; | |
1412 } | |
1413 if ((m_dwAccess & FX_STREAMACCESS_Write) == 0) { | |
1414 return FALSE; | |
1415 } | |
1416 return m_pStreamImp->SetLength(iLength); | |
1417 } | |
1418 int32_t CFX_Stream::GetBOM(uint8_t bom[4]) const { | |
1419 if (m_pStreamImp == NULL) { | |
1420 return -1; | |
1421 } | |
1422 return 0; | |
1423 } | |
1424 FX_WORD CFX_Stream::GetCodePage() const { | |
1425 #if _FX_ENDIAN_ == _FX_LITTLE_ENDIAN_ | |
1426 return FX_CODEPAGE_UTF16LE; | |
1427 #else | |
1428 return FX_CODEPAGE_UTF16BE; | |
1429 #endif | |
1430 } | |
1431 FX_WORD CFX_Stream::SetCodePage(FX_WORD wCodePage) { | |
1432 #if _FX_ENDIAN_ == _FX_LITTLE_ENDIAN_ | |
1433 return FX_CODEPAGE_UTF16LE; | |
1434 #else | |
1435 return FX_CODEPAGE_UTF16BE; | |
1436 #endif | |
1437 } | |
1438 IFX_Stream* CFX_Stream::CreateSharedStream(FX_DWORD dwAccess, | |
1439 int32_t iOffset, | |
1440 int32_t iLength) { | |
1441 FXSYS_assert(iLength > 0); | |
1442 if (m_pStreamImp == NULL) { | |
1443 return NULL; | |
1444 } | |
1445 if ((m_dwAccess & FX_STREAMACCESS_Text) != 0 && | |
1446 (dwAccess & FX_STREAMACCESS_Text) == 0) { | |
1447 return NULL; | |
1448 } | |
1449 if ((m_dwAccess & FX_STREAMACCESS_Write) == 0 && | |
1450 (dwAccess & FX_STREAMACCESS_Write) != 0) { | |
1451 return NULL; | |
1452 } | |
1453 int32_t iStart = m_iStart + iOffset; | |
1454 int32_t iTotal = m_iStart + m_iLength; | |
1455 if (iStart < m_iStart || iStart >= iTotal) { | |
1456 return NULL; | |
1457 } | |
1458 int32_t iEnd = iStart + iLength; | |
1459 if (iEnd < iStart || iEnd > iTotal) { | |
1460 return NULL; | |
1461 } | |
1462 CFX_Stream* pShared = new CFX_Stream; | |
1463 pShared->m_eStreamType = FX_STREAMTYPE_Stream; | |
1464 pShared->m_pStreamImp = m_pStreamImp; | |
1465 pShared->m_dwAccess = dwAccess; | |
1466 pShared->m_iTotalSize = iLength; | |
1467 pShared->m_iPosition = iStart; | |
1468 pShared->m_iStart = iStart; | |
1469 pShared->m_iLength = (dwAccess & FX_STREAMACCESS_Write) != 0 ? 0 : iLength; | |
1470 if (dwAccess & FX_STREAMACCESS_Text) { | |
1471 return IFX_Stream::CreateTextStream(pShared, TRUE); | |
1472 } | |
1473 return pShared; | |
1474 } | |
1475 IFX_FileRead* FX_CreateFileRead(IFX_Stream* pBaseStream, | |
1476 FX_BOOL bReleaseStream) { | |
1477 FXSYS_assert(pBaseStream != NULL); | |
1478 return new CFGAS_FileRead(pBaseStream, bReleaseStream); | |
1479 } | |
1480 CFGAS_FileRead::CFGAS_FileRead(IFX_Stream* pStream, FX_BOOL bReleaseStream) | |
1481 : m_bReleaseStream(bReleaseStream), m_pStream(pStream) { | |
1482 FXSYS_assert(m_pStream != NULL); | |
1483 } | |
1484 CFGAS_FileRead::~CFGAS_FileRead() { | |
1485 if (m_bReleaseStream) { | |
1486 m_pStream->Release(); | |
1487 } | |
1488 } | |
1489 FX_FILESIZE CFGAS_FileRead::GetSize() { | |
1490 return (FX_FILESIZE)m_pStream->GetLength(); | |
1491 } | |
1492 FX_BOOL CFGAS_FileRead::ReadBlock(void* buffer, | |
1493 FX_FILESIZE offset, | |
1494 size_t size) { | |
1495 m_pStream->Seek(FX_STREAMSEEK_Begin, (int32_t)offset); | |
1496 int32_t iLen = m_pStream->ReadData((uint8_t*)buffer, (int32_t)size); | |
1497 return iLen == (int32_t)size; | |
1498 } | |
1499 | |
1500 IFX_FileRead* FX_CreateFileRead(IFX_BufferRead* pBufferRead, | |
1501 FX_FILESIZE iFileSize, | |
1502 FX_BOOL bReleaseStream) { | |
1503 if (!pBufferRead) { | |
1504 return NULL; | |
1505 } | |
1506 return new CFX_BufferAccImp(pBufferRead, iFileSize, bReleaseStream); | |
1507 } | |
1508 CFX_BufferAccImp::CFX_BufferAccImp(IFX_BufferRead* pBufferRead, | |
1509 FX_FILESIZE iFileSize, | |
1510 FX_BOOL bReleaseStream) | |
1511 : m_pBufferRead(pBufferRead), | |
1512 m_bReleaseStream(bReleaseStream), | |
1513 m_iBufSize(iFileSize) { | |
1514 FXSYS_assert(m_pBufferRead); | |
1515 } | |
1516 CFX_BufferAccImp::~CFX_BufferAccImp() { | |
1517 if (m_bReleaseStream && m_pBufferRead) { | |
1518 m_pBufferRead->Release(); | |
1519 } | |
1520 } | |
1521 FX_FILESIZE CFX_BufferAccImp::GetSize() { | |
1522 if (!m_pBufferRead) { | |
1523 return 0; | |
1524 } | |
1525 if (m_iBufSize >= 0) { | |
1526 return m_iBufSize; | |
1527 } | |
1528 if (!m_pBufferRead->ReadNextBlock(TRUE)) { | |
1529 return 0; | |
1530 } | |
1531 m_iBufSize = (FX_FILESIZE)m_pBufferRead->GetBlockSize(); | |
1532 while (!m_pBufferRead->IsEOF()) { | |
1533 m_pBufferRead->ReadNextBlock(FALSE); | |
1534 m_iBufSize += (FX_FILESIZE)m_pBufferRead->GetBlockSize(); | |
1535 } | |
1536 return m_iBufSize; | |
1537 } | |
1538 FX_BOOL CFX_BufferAccImp::ReadBlock(void* buffer, | |
1539 FX_FILESIZE offset, | |
1540 size_t size) { | |
1541 if (!m_pBufferRead) { | |
1542 return FALSE; | |
1543 } | |
1544 if (!buffer || !size) { | |
1545 return TRUE; | |
1546 } | |
1547 FX_FILESIZE dwBufSize = GetSize(); | |
1548 if (offset >= dwBufSize) { | |
1549 return FALSE; | |
1550 } | |
1551 size_t dwBlockSize = m_pBufferRead->GetBlockSize(); | |
1552 FX_FILESIZE dwBlockOffset = m_pBufferRead->GetBlockOffset(); | |
1553 if (offset < dwBlockOffset) { | |
1554 if (!m_pBufferRead->ReadNextBlock(TRUE)) { | |
1555 return FALSE; | |
1556 } | |
1557 dwBlockSize = m_pBufferRead->GetBlockSize(); | |
1558 dwBlockOffset = m_pBufferRead->GetBlockOffset(); | |
1559 } | |
1560 while (offset < dwBlockOffset || | |
1561 offset >= (FX_FILESIZE)(dwBlockOffset + dwBlockSize)) { | |
1562 if (m_pBufferRead->IsEOF() || !m_pBufferRead->ReadNextBlock(FALSE)) { | |
1563 break; | |
1564 } | |
1565 dwBlockSize = m_pBufferRead->GetBlockSize(); | |
1566 dwBlockOffset = m_pBufferRead->GetBlockOffset(); | |
1567 } | |
1568 if (offset < dwBlockOffset || | |
1569 offset >= (FX_FILESIZE)(dwBlockOffset + dwBlockSize)) { | |
1570 return FALSE; | |
1571 } | |
1572 const uint8_t* pBuffer = m_pBufferRead->GetBlockBuffer(); | |
1573 const FX_FILESIZE dwOffset = offset - dwBlockOffset; | |
1574 size_t dwCopySize = | |
1575 std::min(size, static_cast<size_t>(dwBlockSize - dwOffset)); | |
1576 FXSYS_memcpy(buffer, pBuffer + dwOffset, dwCopySize); | |
1577 offset = dwCopySize; | |
1578 size -= dwCopySize; | |
1579 while (size) { | |
1580 if (!m_pBufferRead->ReadNextBlock(FALSE)) { | |
1581 break; | |
1582 } | |
1583 dwBlockOffset = m_pBufferRead->GetBlockOffset(); | |
1584 dwBlockSize = m_pBufferRead->GetBlockSize(); | |
1585 pBuffer = m_pBufferRead->GetBlockBuffer(); | |
1586 dwCopySize = std::min(size, dwBlockSize); | |
1587 FXSYS_memcpy(((uint8_t*)buffer) + offset, pBuffer, dwCopySize); | |
1588 offset += dwCopySize; | |
1589 size -= dwCopySize; | |
1590 } | |
1591 return TRUE; | |
1592 } | |
1593 | |
1594 IFX_FileWrite* FX_CreateFileWrite(IFX_Stream* pBaseStream, | |
1595 FX_BOOL bReleaseStream) { | |
1596 FXSYS_assert(pBaseStream != NULL); | |
1597 return new CFGAS_FileWrite(pBaseStream, bReleaseStream); | |
1598 } | |
1599 | |
1600 CFGAS_FileWrite::CFGAS_FileWrite(IFX_Stream* pStream, FX_BOOL bReleaseStream) | |
1601 : m_pStream(pStream), m_bReleaseStream(bReleaseStream) { | |
1602 FXSYS_assert(m_pStream != NULL); | |
1603 } | |
1604 CFGAS_FileWrite::~CFGAS_FileWrite() { | |
1605 if (m_bReleaseStream) { | |
1606 m_pStream->Release(); | |
1607 } | |
1608 } | |
1609 FX_FILESIZE CFGAS_FileWrite::GetSize() { | |
1610 return m_pStream->GetLength(); | |
1611 } | |
1612 FX_BOOL CFGAS_FileWrite::Flush() { | |
1613 m_pStream->Flush(); | |
1614 return TRUE; | |
1615 } | |
1616 FX_BOOL CFGAS_FileWrite::WriteBlock(const void* pData, size_t size) { | |
1617 return m_pStream->WriteData((const uint8_t*)pData, (int32_t)size) == | |
1618 (int32_t)size; | |
1619 } | |
1620 FX_BOOL CFGAS_FileWrite::WriteBlock(const void* pData, | |
1621 FX_FILESIZE offset, | |
1622 size_t size) { | |
1623 m_pStream->Seek(FX_STREAMSEEK_Begin, offset); | |
1624 int32_t iLen = m_pStream->WriteData((uint8_t*)pData, (int32_t)size); | |
1625 return iLen == (int32_t)size; | |
1626 } | |
OLD | NEW |