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