| OLD | NEW |
| 1 // Copyright 2014 PDFium Authors. All rights reserved. | 1 // Copyright 2014 PDFium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
| 6 | 6 |
| 7 #include "xfa/fgas/crt/fgas_stream.h" | 7 #include "xfa/fgas/crt/fgas_stream.h" |
| 8 | 8 |
| 9 #if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN32_MOBILE_ || \ |
| 10 _FX_OS_ == _FX_WIN64_ |
| 11 #include <io.h> |
| 12 #endif |
| 13 |
| 9 #include <algorithm> | 14 #include <algorithm> |
| 10 #include <memory> | 15 #include <memory> |
| 11 | 16 |
| 12 #include "xfa/fgas/crt/fgas_codepage.h" | 17 #include "xfa/fgas/crt/fgas_codepage.h" |
| 13 #include "xfa/fgas/crt/fgas_system.h" | 18 #include "xfa/fgas/crt/fgas_system.h" |
| 14 | 19 |
| 15 namespace { | 20 namespace { |
| 16 | 21 |
| 17 class IFX_StreamImp { | 22 class IFX_StreamImp { |
| 18 public: | 23 public: |
| (...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 292 virtual ~CFGAS_FileRead(); | 297 virtual ~CFGAS_FileRead(); |
| 293 virtual void Release() { delete this; } | 298 virtual void Release() { delete this; } |
| 294 virtual FX_FILESIZE GetSize(); | 299 virtual FX_FILESIZE GetSize(); |
| 295 virtual FX_BOOL ReadBlock(void* buffer, FX_FILESIZE offset, size_t size); | 300 virtual FX_BOOL ReadBlock(void* buffer, FX_FILESIZE offset, size_t size); |
| 296 | 301 |
| 297 protected: | 302 protected: |
| 298 FX_BOOL m_bReleaseStream; | 303 FX_BOOL m_bReleaseStream; |
| 299 IFX_Stream* m_pStream; | 304 IFX_Stream* m_pStream; |
| 300 }; | 305 }; |
| 301 | 306 |
| 302 class CFX_BufferAccImp : public IFX_FileRead { | 307 int32_t FileLength(FXSYS_FILE* file) { |
| 303 public: | 308 ASSERT(file != NULL); |
| 304 CFX_BufferAccImp(IFX_BufferRead* pBufferRead, | 309 #if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN64_ |
| 305 FX_FILESIZE iFileSize, | 310 return _filelength(_fileno(file)); |
| 306 FX_BOOL bReleaseStream); | 311 #else |
| 307 virtual ~CFX_BufferAccImp(); | 312 int32_t iPos = FXSYS_ftell(file); |
| 308 virtual void Release() { delete this; } | 313 FXSYS_fseek(file, 0, FXSYS_SEEK_END); |
| 309 virtual FX_FILESIZE GetSize(); | 314 int32_t iLen = FXSYS_ftell(file); |
| 310 virtual FX_BOOL ReadBlock(void* buffer, FX_FILESIZE offset, size_t size); | 315 FXSYS_fseek(file, iPos, FXSYS_SEEK_SET); |
| 316 return iLen; |
| 317 #endif |
| 318 } |
| 311 | 319 |
| 312 protected: | 320 FX_BOOL FileSetSize(FXSYS_FILE* file, int32_t size) { |
| 313 IFX_BufferRead* m_pBufferRead; | 321 ASSERT(file != NULL); |
| 314 FX_BOOL m_bReleaseStream; | 322 #if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN64_ |
| 315 FX_FILESIZE m_iBufSize; | 323 return _chsize(_fileno(file), size) == 0; |
| 316 }; | 324 #elif _FX_OS_ == _FX_WIN32_MOBILE_ |
| 317 | 325 HANDLE hFile = _fileno(file); |
| 318 class CFGAS_FileWrite : public IFX_FileWrite { | 326 uint32_t dwPos = ::SetFilePointer(hFile, 0, 0, FILE_CURRENT); |
| 319 public: | 327 ::SetFilePointer(hFile, size, 0, FILE_BEGIN); |
| 320 CFGAS_FileWrite(IFX_Stream* pStream, FX_BOOL bReleaseStream); | 328 FX_BOOL bRet = ::SetEndOfFile(hFile); |
| 321 virtual ~CFGAS_FileWrite(); | 329 ::SetFilePointer(hFile, (int32_t)dwPos, 0, FILE_BEGIN); |
| 322 virtual void Release() { delete this; } | 330 return bRet; |
| 323 virtual FX_FILESIZE GetSize(); | 331 #else |
| 324 virtual FX_BOOL Flush(); | 332 return FALSE; |
| 325 virtual FX_BOOL WriteBlock(const void* pData, size_t size); | 333 #endif |
| 326 virtual FX_BOOL WriteBlock(const void* pData, | 334 } |
| 327 FX_FILESIZE offset, | |
| 328 size_t size); | |
| 329 | |
| 330 protected: | |
| 331 IFX_Stream* m_pStream; | |
| 332 FX_BOOL m_bReleaseStream; | |
| 333 }; | |
| 334 | 335 |
| 335 } // namespace | 336 } // namespace |
| 336 | 337 |
| 337 IFX_Stream* IFX_Stream::CreateStream(IFX_BufferRead* pBufferRead, | 338 IFX_Stream* IFX_Stream::CreateStream(IFX_BufferRead* pBufferRead, |
| 338 uint32_t dwAccess, | 339 uint32_t dwAccess, |
| 339 int32_t iFileSize, | 340 int32_t iFileSize, |
| 340 FX_BOOL bReleaseBufferRead) { | 341 FX_BOOL bReleaseBufferRead) { |
| 341 CFX_Stream* pSR = new CFX_Stream; | 342 CFX_Stream* pSR = new CFX_Stream; |
| 342 if (!pSR->LoadBufferRead(pBufferRead, iFileSize, dwAccess, | 343 if (!pSR->LoadBufferRead(pBufferRead, iFileSize, dwAccess, |
| 343 bReleaseBufferRead)) { | 344 bReleaseBufferRead)) { |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 432 if (dwAccess & FX_STREAMACCESS_Write) { | 433 if (dwAccess & FX_STREAMACCESS_Write) { |
| 433 if (dwAccess & FX_STREAMACCESS_Create) | 434 if (dwAccess & FX_STREAMACCESS_Create) |
| 434 m_hFile = FXSYS_wfopen(pszSrcFileName, L"w+b"); | 435 m_hFile = FXSYS_wfopen(pszSrcFileName, L"w+b"); |
| 435 | 436 |
| 436 if (!m_hFile) { | 437 if (!m_hFile) { |
| 437 m_hFile = FXSYS_wfopen(pszSrcFileName, L"r+b"); | 438 m_hFile = FXSYS_wfopen(pszSrcFileName, L"r+b"); |
| 438 if (!m_hFile) | 439 if (!m_hFile) |
| 439 return FALSE; | 440 return FALSE; |
| 440 | 441 |
| 441 if (dwAccess & FX_STREAMACCESS_Truncate) | 442 if (dwAccess & FX_STREAMACCESS_Truncate) |
| 442 FX_fsetsize(m_hFile, 0); | 443 FileSetSize(m_hFile, 0); |
| 443 } | 444 } |
| 444 } else { | 445 } else { |
| 445 return FALSE; | 446 return FALSE; |
| 446 } | 447 } |
| 447 } | 448 } |
| 448 #else | 449 #else |
| 449 const FX_CHAR* wsMode = "rb"; | 450 const FX_CHAR* wsMode = "rb"; |
| 450 if (dwAccess & FX_STREAMACCESS_Write) { | 451 if (dwAccess & FX_STREAMACCESS_Write) { |
| 451 if (dwAccess & FX_STREAMACCESS_Append) { | 452 if (dwAccess & FX_STREAMACCESS_Append) { |
| 452 wsMode = "a+b"; | 453 wsMode = "a+b"; |
| 453 } else if (dwAccess & FX_STREAMACCESS_Truncate) { | 454 } else if (dwAccess & FX_STREAMACCESS_Truncate) { |
| 454 wsMode = "w+b"; | 455 wsMode = "w+b"; |
| 455 } else { | 456 } else { |
| 456 wsMode = "r+b"; | 457 wsMode = "r+b"; |
| 457 } | 458 } |
| 458 } | 459 } |
| 459 CFX_ByteString szFileName = CFX_ByteString::FromUnicode(pszSrcFileName); | 460 CFX_ByteString szFileName = CFX_ByteString::FromUnicode(pszSrcFileName); |
| 460 m_hFile = FXSYS_fopen(szFileName.c_str(), wsMode); | 461 m_hFile = FXSYS_fopen(szFileName.c_str(), wsMode); |
| 461 if (m_hFile == NULL) { | 462 if (m_hFile == NULL) { |
| 462 if (dwAccess & FX_STREAMACCESS_Write) { | 463 if (dwAccess & FX_STREAMACCESS_Write) { |
| 463 if (dwAccess & FX_STREAMACCESS_Create) { | 464 if (dwAccess & FX_STREAMACCESS_Create) { |
| 464 m_hFile = FXSYS_fopen(szFileName.c_str(), "w+b"); | 465 m_hFile = FXSYS_fopen(szFileName.c_str(), "w+b"); |
| 465 } | 466 } |
| 466 if (m_hFile == NULL) { | 467 if (m_hFile == NULL) { |
| 467 m_hFile = FXSYS_fopen(szFileName.c_str(), "r+b"); | 468 m_hFile = FXSYS_fopen(szFileName.c_str(), "r+b"); |
| 468 if (m_hFile == NULL) { | 469 if (m_hFile == NULL) { |
| 469 return FALSE; | 470 return FALSE; |
| 470 } | 471 } |
| 471 if (dwAccess & FX_STREAMACCESS_Truncate) { | 472 if (dwAccess & FX_STREAMACCESS_Truncate) { |
| 472 FX_fsetsize(m_hFile, 0); | 473 FileSetSize(m_hFile, 0); |
| 473 } | 474 } |
| 474 } | 475 } |
| 475 } else { | 476 } else { |
| 476 return FALSE; | 477 return FALSE; |
| 477 } | 478 } |
| 478 } | 479 } |
| 479 #endif | 480 #endif |
| 480 SetAccessModes(dwAccess); | 481 SetAccessModes(dwAccess); |
| 481 if ((dwAccess & (FX_STREAMACCESS_Write | FX_STREAMACCESS_Truncate)) == | 482 if ((dwAccess & (FX_STREAMACCESS_Write | FX_STREAMACCESS_Truncate)) == |
| 482 (FX_STREAMACCESS_Write | FX_STREAMACCESS_Truncate)) { | 483 (FX_STREAMACCESS_Write | FX_STREAMACCESS_Truncate)) { |
| 483 m_iLength = 0; | 484 m_iLength = 0; |
| 484 } else { | 485 } else { |
| 485 m_iLength = FX_filelength(m_hFile); | 486 m_iLength = FileLength(m_hFile); |
| 486 } | 487 } |
| 487 return TRUE; | 488 return TRUE; |
| 488 } | 489 } |
| 489 int32_t CFX_FileStreamImp::GetLength() const { | 490 int32_t CFX_FileStreamImp::GetLength() const { |
| 490 ASSERT(m_hFile != NULL); | 491 ASSERT(m_hFile != NULL); |
| 491 return m_iLength; | 492 return m_iLength; |
| 492 } | 493 } |
| 493 int32_t CFX_FileStreamImp::Seek(FX_STREAMSEEK eSeek, int32_t iOffset) { | 494 int32_t CFX_FileStreamImp::Seek(FX_STREAMSEEK eSeek, int32_t iOffset) { |
| 494 ASSERT(m_hFile != NULL); | 495 ASSERT(m_hFile != NULL); |
| 495 FXSYS_fseek(m_hFile, iOffset, eSeek); | 496 FXSYS_fseek(m_hFile, iOffset, eSeek); |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 557 } | 558 } |
| 558 } | 559 } |
| 559 return iRet; | 560 return iRet; |
| 560 } | 561 } |
| 561 void CFX_FileStreamImp::Flush() { | 562 void CFX_FileStreamImp::Flush() { |
| 562 ASSERT(m_hFile && (GetAccessModes() & FX_STREAMACCESS_Write) != 0); | 563 ASSERT(m_hFile && (GetAccessModes() & FX_STREAMACCESS_Write) != 0); |
| 563 FXSYS_fflush(m_hFile); | 564 FXSYS_fflush(m_hFile); |
| 564 } | 565 } |
| 565 FX_BOOL CFX_FileStreamImp::SetLength(int32_t iLength) { | 566 FX_BOOL CFX_FileStreamImp::SetLength(int32_t iLength) { |
| 566 ASSERT(m_hFile && (GetAccessModes() & FX_STREAMACCESS_Write) != 0); | 567 ASSERT(m_hFile && (GetAccessModes() & FX_STREAMACCESS_Write) != 0); |
| 567 FX_BOOL bRet = FX_fsetsize(m_hFile, iLength); | 568 FX_BOOL bRet = FileSetSize(m_hFile, iLength); |
| 568 m_iLength = FX_filelength(m_hFile); | 569 m_iLength = FileLength(m_hFile); |
| 569 return bRet; | 570 return bRet; |
| 570 } | 571 } |
| 571 CFX_FileReadStreamImp::CFX_FileReadStreamImp() | 572 CFX_FileReadStreamImp::CFX_FileReadStreamImp() |
| 572 : m_pFileRead(NULL), m_iPosition(0), m_iLength(0) {} | 573 : m_pFileRead(NULL), m_iPosition(0), m_iLength(0) {} |
| 573 FX_BOOL CFX_FileReadStreamImp::LoadFileRead(IFX_FileRead* pFileRead, | 574 FX_BOOL CFX_FileReadStreamImp::LoadFileRead(IFX_FileRead* pFileRead, |
| 574 uint32_t dwAccess) { | 575 uint32_t dwAccess) { |
| 575 ASSERT(m_pFileRead == NULL && pFileRead != NULL); | 576 ASSERT(m_pFileRead == NULL && pFileRead != NULL); |
| 576 if (dwAccess & FX_STREAMACCESS_Write) { | 577 if (dwAccess & FX_STREAMACCESS_Write) { |
| 577 return FALSE; | 578 return FALSE; |
| 578 } | 579 } |
| (...skipping 923 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1502 FX_FILESIZE CFGAS_FileRead::GetSize() { | 1503 FX_FILESIZE CFGAS_FileRead::GetSize() { |
| 1503 return (FX_FILESIZE)m_pStream->GetLength(); | 1504 return (FX_FILESIZE)m_pStream->GetLength(); |
| 1504 } | 1505 } |
| 1505 FX_BOOL CFGAS_FileRead::ReadBlock(void* buffer, | 1506 FX_BOOL CFGAS_FileRead::ReadBlock(void* buffer, |
| 1506 FX_FILESIZE offset, | 1507 FX_FILESIZE offset, |
| 1507 size_t size) { | 1508 size_t size) { |
| 1508 m_pStream->Seek(FX_STREAMSEEK_Begin, (int32_t)offset); | 1509 m_pStream->Seek(FX_STREAMSEEK_Begin, (int32_t)offset); |
| 1509 int32_t iLen = m_pStream->ReadData((uint8_t*)buffer, (int32_t)size); | 1510 int32_t iLen = m_pStream->ReadData((uint8_t*)buffer, (int32_t)size); |
| 1510 return iLen == (int32_t)size; | 1511 return iLen == (int32_t)size; |
| 1511 } | 1512 } |
| 1512 | |
| 1513 IFX_FileRead* FX_CreateFileRead(IFX_BufferRead* pBufferRead, | |
| 1514 FX_FILESIZE iFileSize, | |
| 1515 FX_BOOL bReleaseStream) { | |
| 1516 if (!pBufferRead) { | |
| 1517 return NULL; | |
| 1518 } | |
| 1519 return new CFX_BufferAccImp(pBufferRead, iFileSize, bReleaseStream); | |
| 1520 } | |
| 1521 CFX_BufferAccImp::CFX_BufferAccImp(IFX_BufferRead* pBufferRead, | |
| 1522 FX_FILESIZE iFileSize, | |
| 1523 FX_BOOL bReleaseStream) | |
| 1524 : m_pBufferRead(pBufferRead), | |
| 1525 m_bReleaseStream(bReleaseStream), | |
| 1526 m_iBufSize(iFileSize) { | |
| 1527 ASSERT(m_pBufferRead); | |
| 1528 } | |
| 1529 CFX_BufferAccImp::~CFX_BufferAccImp() { | |
| 1530 if (m_bReleaseStream && m_pBufferRead) { | |
| 1531 m_pBufferRead->Release(); | |
| 1532 } | |
| 1533 } | |
| 1534 FX_FILESIZE CFX_BufferAccImp::GetSize() { | |
| 1535 if (!m_pBufferRead) { | |
| 1536 return 0; | |
| 1537 } | |
| 1538 if (m_iBufSize >= 0) { | |
| 1539 return m_iBufSize; | |
| 1540 } | |
| 1541 if (!m_pBufferRead->ReadNextBlock(TRUE)) { | |
| 1542 return 0; | |
| 1543 } | |
| 1544 m_iBufSize = (FX_FILESIZE)m_pBufferRead->GetBlockSize(); | |
| 1545 while (!m_pBufferRead->IsEOF()) { | |
| 1546 m_pBufferRead->ReadNextBlock(FALSE); | |
| 1547 m_iBufSize += (FX_FILESIZE)m_pBufferRead->GetBlockSize(); | |
| 1548 } | |
| 1549 return m_iBufSize; | |
| 1550 } | |
| 1551 FX_BOOL CFX_BufferAccImp::ReadBlock(void* buffer, | |
| 1552 FX_FILESIZE offset, | |
| 1553 size_t size) { | |
| 1554 if (!m_pBufferRead) { | |
| 1555 return FALSE; | |
| 1556 } | |
| 1557 if (!buffer || !size) { | |
| 1558 return TRUE; | |
| 1559 } | |
| 1560 FX_FILESIZE dwBufSize = GetSize(); | |
| 1561 if (offset >= dwBufSize) { | |
| 1562 return FALSE; | |
| 1563 } | |
| 1564 size_t dwBlockSize = m_pBufferRead->GetBlockSize(); | |
| 1565 FX_FILESIZE dwBlockOffset = m_pBufferRead->GetBlockOffset(); | |
| 1566 if (offset < dwBlockOffset) { | |
| 1567 if (!m_pBufferRead->ReadNextBlock(TRUE)) { | |
| 1568 return FALSE; | |
| 1569 } | |
| 1570 dwBlockSize = m_pBufferRead->GetBlockSize(); | |
| 1571 dwBlockOffset = m_pBufferRead->GetBlockOffset(); | |
| 1572 } | |
| 1573 while (offset < dwBlockOffset || | |
| 1574 offset >= (FX_FILESIZE)(dwBlockOffset + dwBlockSize)) { | |
| 1575 if (m_pBufferRead->IsEOF() || !m_pBufferRead->ReadNextBlock(FALSE)) { | |
| 1576 break; | |
| 1577 } | |
| 1578 dwBlockSize = m_pBufferRead->GetBlockSize(); | |
| 1579 dwBlockOffset = m_pBufferRead->GetBlockOffset(); | |
| 1580 } | |
| 1581 if (offset < dwBlockOffset || | |
| 1582 offset >= (FX_FILESIZE)(dwBlockOffset + dwBlockSize)) { | |
| 1583 return FALSE; | |
| 1584 } | |
| 1585 const uint8_t* pBuffer = m_pBufferRead->GetBlockBuffer(); | |
| 1586 const FX_FILESIZE dwOffset = offset - dwBlockOffset; | |
| 1587 size_t dwCopySize = | |
| 1588 std::min(size, static_cast<size_t>(dwBlockSize - dwOffset)); | |
| 1589 FXSYS_memcpy(buffer, pBuffer + dwOffset, dwCopySize); | |
| 1590 offset = dwCopySize; | |
| 1591 size -= dwCopySize; | |
| 1592 while (size) { | |
| 1593 if (!m_pBufferRead->ReadNextBlock(FALSE)) { | |
| 1594 break; | |
| 1595 } | |
| 1596 dwBlockOffset = m_pBufferRead->GetBlockOffset(); | |
| 1597 dwBlockSize = m_pBufferRead->GetBlockSize(); | |
| 1598 pBuffer = m_pBufferRead->GetBlockBuffer(); | |
| 1599 dwCopySize = std::min(size, dwBlockSize); | |
| 1600 FXSYS_memcpy(((uint8_t*)buffer) + offset, pBuffer, dwCopySize); | |
| 1601 offset += dwCopySize; | |
| 1602 size -= dwCopySize; | |
| 1603 } | |
| 1604 return TRUE; | |
| 1605 } | |
| 1606 | |
| 1607 IFX_FileWrite* FX_CreateFileWrite(IFX_Stream* pBaseStream, | |
| 1608 FX_BOOL bReleaseStream) { | |
| 1609 ASSERT(pBaseStream != NULL); | |
| 1610 return new CFGAS_FileWrite(pBaseStream, bReleaseStream); | |
| 1611 } | |
| 1612 | |
| 1613 CFGAS_FileWrite::CFGAS_FileWrite(IFX_Stream* pStream, FX_BOOL bReleaseStream) | |
| 1614 : m_pStream(pStream), m_bReleaseStream(bReleaseStream) { | |
| 1615 ASSERT(m_pStream != NULL); | |
| 1616 } | |
| 1617 CFGAS_FileWrite::~CFGAS_FileWrite() { | |
| 1618 if (m_bReleaseStream) { | |
| 1619 m_pStream->Release(); | |
| 1620 } | |
| 1621 } | |
| 1622 FX_FILESIZE CFGAS_FileWrite::GetSize() { | |
| 1623 return m_pStream->GetLength(); | |
| 1624 } | |
| 1625 FX_BOOL CFGAS_FileWrite::Flush() { | |
| 1626 m_pStream->Flush(); | |
| 1627 return TRUE; | |
| 1628 } | |
| 1629 FX_BOOL CFGAS_FileWrite::WriteBlock(const void* pData, size_t size) { | |
| 1630 return m_pStream->WriteData((const uint8_t*)pData, (int32_t)size) == | |
| 1631 (int32_t)size; | |
| 1632 } | |
| 1633 FX_BOOL CFGAS_FileWrite::WriteBlock(const void* pData, | |
| 1634 FX_FILESIZE offset, | |
| 1635 size_t size) { | |
| 1636 m_pStream->Seek(FX_STREAMSEEK_Begin, offset); | |
| 1637 int32_t iLen = m_pStream->WriteData((uint8_t*)pData, (int32_t)size); | |
| 1638 return iLen == (int32_t)size; | |
| 1639 } | |
| OLD | NEW |