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 |