| 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 |