diff options
Diffstat (limited to 'core')
-rw-r--r-- | core/fpdfapi/parser/cfdf_document.cpp | 4 | ||||
-rw-r--r-- | core/fpdfapi/parser/cpdf_data_avail.cpp | 17 | ||||
-rw-r--r-- | core/fpdfapi/parser/cpdf_parser.cpp | 10 | ||||
-rw-r--r-- | core/fpdfapi/parser/cpdf_syntax_parser_unittest.cpp | 29 | ||||
-rw-r--r-- | core/fxcrt/cfx_memorystream.cpp | 199 | ||||
-rw-r--r-- | core/fxcrt/cfx_memorystream.h | 56 | ||||
-rw-r--r-- | core/fxcrt/cfx_seekablestreamproxy.cpp | 5 | ||||
-rw-r--r-- | core/fxcrt/fx_stream.cpp | 232 | ||||
-rw-r--r-- | core/fxcrt/fx_stream.h | 16 | ||||
-rw-r--r-- | core/fxcrt/xml/cfx_saxreader_unittest.cpp | 10 |
10 files changed, 298 insertions, 280 deletions
diff --git a/core/fpdfapi/parser/cfdf_document.cpp b/core/fpdfapi/parser/cfdf_document.cpp index 03cc655a0a..85e2f6ef04 100644 --- a/core/fpdfapi/parser/cfdf_document.cpp +++ b/core/fpdfapi/parser/cfdf_document.cpp @@ -13,6 +13,7 @@ #include "core/fpdfapi/parser/cpdf_dictionary.h" #include "core/fpdfapi/parser/cpdf_syntax_parser.h" #include "core/fpdfapi/parser/fpdf_parser_utility.h" +#include "core/fxcrt/cfx_memorystream.h" #include "third_party/base/ptr_util.h" CFDF_Document::CFDF_Document() @@ -39,7 +40,8 @@ std::unique_ptr<CFDF_Document> CFDF_Document::ParseFile( std::unique_ptr<CFDF_Document> CFDF_Document::ParseMemory(uint8_t* pData, uint32_t size) { - return CFDF_Document::ParseFile(IFX_MemoryStream::Create(pData, size)); + return CFDF_Document::ParseFile( + pdfium::MakeRetain<CFX_MemoryStream>(pData, size, false)); } void CFDF_Document::ParseStream( diff --git a/core/fpdfapi/parser/cpdf_data_avail.cpp b/core/fpdfapi/parser/cpdf_data_avail.cpp index f99cb467e5..41a3f0dae2 100644 --- a/core/fpdfapi/parser/cpdf_data_avail.cpp +++ b/core/fpdfapi/parser/cpdf_data_avail.cpp @@ -21,6 +21,7 @@ #include "core/fpdfapi/parser/cpdf_reference.h" #include "core/fpdfapi/parser/cpdf_stream.h" #include "core/fpdfapi/parser/fpdf_parser_utility.h" +#include "core/fxcrt/cfx_memorystream.h" #include "core/fxcrt/fx_extension.h" #include "core/fxcrt/fx_safe_types.h" #include "third_party/base/numerics/safe_conversions.h" @@ -716,8 +717,8 @@ bool CPDF_DataAvail::IsLinearizedFile(uint8_t* pData, uint32_t dwLen) { if (m_pLinearized) return true; - CFX_RetainPtr<IFX_MemoryStream> file = - IFX_MemoryStream::Create(pData, (size_t)dwLen, false); + auto file = pdfium::MakeRetain<CFX_MemoryStream>( + pData, static_cast<size_t>(dwLen), false); int32_t offset = GetHeaderOffset(file); if (offset == -1) { m_docStatus = PDF_DATAAVAIL_ERROR; @@ -756,8 +757,8 @@ bool CPDF_DataAvail::CheckEnd(DownloadHints* pHints) { uint8_t buffer[1024]; m_pFileRead->ReadBlock(buffer, req_pos, dwSize); - CFX_RetainPtr<IFX_MemoryStream> file = - IFX_MemoryStream::Create(buffer, (size_t)dwSize, false); + auto file = pdfium::MakeRetain<CFX_MemoryStream>( + buffer, static_cast<size_t>(dwSize), false); m_syntaxParser.InitParser(file, 0); m_syntaxParser.RestorePos(dwSize - 1); @@ -804,8 +805,8 @@ int32_t CPDF_DataAvail::CheckCrossRefStream(DownloadHints* pHints, m_pFileRead->ReadBlock(pBuf, m_dwCurrentXRefSteam, iSize); - CFX_RetainPtr<IFX_MemoryStream> file = - IFX_MemoryStream::Create(pBuf, (size_t)iSize, false); + auto file = pdfium::MakeRetain<CFX_MemoryStream>( + pBuf, static_cast<size_t>(iSize), false); m_parser.m_pSyntax->InitParser(file, 0); bool bNumber; @@ -1049,8 +1050,8 @@ bool CPDF_DataAvail::CheckTrailer(DownloadHints* pHints) { if (!m_pFileRead->ReadBlock(pBuf, m_dwTrailerOffset, iSize)) return false; - CFX_RetainPtr<IFX_MemoryStream> file = - IFX_MemoryStream::Create(pBuf, (size_t)iSize, false); + auto file = pdfium::MakeRetain<CFX_MemoryStream>( + pBuf, static_cast<size_t>(iSize), false); m_syntaxParser.InitParser(file, 0); std::unique_ptr<CPDF_Object> pTrailer( diff --git a/core/fpdfapi/parser/cpdf_parser.cpp b/core/fpdfapi/parser/cpdf_parser.cpp index c18a183a33..86428ab9d7 100644 --- a/core/fpdfapi/parser/cpdf_parser.cpp +++ b/core/fpdfapi/parser/cpdf_parser.cpp @@ -22,6 +22,7 @@ #include "core/fpdfapi/parser/cpdf_stream_acc.h" #include "core/fpdfapi/parser/cpdf_syntax_parser.h" #include "core/fpdfapi/parser/fpdf_parser_utility.h" +#include "core/fxcrt/cfx_memorystream.h" #include "core/fxcrt/fx_extension.h" #include "core/fxcrt/fx_safe_types.h" #include "third_party/base/ptr_util.h" @@ -1114,8 +1115,9 @@ std::unique_ptr<CPDF_Object> CPDF_Parser::ParseIndirectObject( if (!pObjStream) return nullptr; - CFX_RetainPtr<IFX_MemoryStream> file = IFX_MemoryStream::Create( - (uint8_t*)pObjStream->GetData(), (size_t)pObjStream->GetSize(), false); + auto file = pdfium::MakeRetain<CFX_MemoryStream>( + const_cast<uint8_t*>(pObjStream->GetData()), + static_cast<size_t>(pObjStream->GetSize()), false); CPDF_SyntaxParser syntax; syntax.InitParser(file, 0); const int32_t offset = GetStreamFirst(pObjStream); @@ -1194,8 +1196,8 @@ void CPDF_Parser::GetIndirectBinary(uint32_t objnum, int32_t offset = GetStreamFirst(pObjStream); const uint8_t* pData = pObjStream->GetData(); uint32_t totalsize = pObjStream->GetSize(); - CFX_RetainPtr<IFX_MemoryStream> file = - IFX_MemoryStream::Create((uint8_t*)pData, (size_t)totalsize, false); + auto file = pdfium::MakeRetain<CFX_MemoryStream>( + const_cast<uint8_t*>(pData), static_cast<size_t>(totalsize), false); CPDF_SyntaxParser syntax; syntax.InitParser(file, 0); diff --git a/core/fpdfapi/parser/cpdf_syntax_parser_unittest.cpp b/core/fpdfapi/parser/cpdf_syntax_parser_unittest.cpp index 5c7aa6054b..249276f29a 100644 --- a/core/fpdfapi/parser/cpdf_syntax_parser_unittest.cpp +++ b/core/fpdfapi/parser/cpdf_syntax_parser_unittest.cpp @@ -8,6 +8,7 @@ #include "core/fpdfapi/parser/cpdf_object.h" #include "core/fpdfapi/parser/cpdf_parser.h" #include "core/fpdfapi/parser/cpdf_syntax_parser.h" +#include "core/fxcrt/cfx_memorystream.h" #include "core/fxcrt/fx_extension.h" #include "core/fxcrt/fx_stream.h" #include "testing/gtest/include/gtest/gtest.h" @@ -18,7 +19,7 @@ TEST(cpdf_syntax_parser, ReadHexString) { // Empty string. uint8_t data[] = ""; CPDF_SyntaxParser parser; - parser.InitParser(IFX_MemoryStream::Create(data, 0, false), 0); + parser.InitParser(pdfium::MakeRetain<CFX_MemoryStream>(data, 0, false), 0); EXPECT_EQ("", parser.ReadHexString()); EXPECT_EQ(0, parser.SavePos()); } @@ -27,7 +28,7 @@ TEST(cpdf_syntax_parser, ReadHexString) { // Blank string. uint8_t data[] = " "; CPDF_SyntaxParser parser; - parser.InitParser(IFX_MemoryStream::Create(data, 2, false), 0); + parser.InitParser(pdfium::MakeRetain<CFX_MemoryStream>(data, 2, false), 0); EXPECT_EQ("", parser.ReadHexString()); EXPECT_EQ(2, parser.SavePos()); } @@ -36,7 +37,7 @@ TEST(cpdf_syntax_parser, ReadHexString) { // Skips unknown characters. uint8_t data[] = "z12b"; CPDF_SyntaxParser parser; - parser.InitParser(IFX_MemoryStream::Create(data, 4, false), 0); + parser.InitParser(pdfium::MakeRetain<CFX_MemoryStream>(data, 4, false), 0); EXPECT_EQ("\x12\xb0", parser.ReadHexString()); EXPECT_EQ(4, parser.SavePos()); } @@ -45,7 +46,7 @@ TEST(cpdf_syntax_parser, ReadHexString) { // Skips unknown characters. uint8_t data[] = "*<&*#$^&@1"; CPDF_SyntaxParser parser; - parser.InitParser(IFX_MemoryStream::Create(data, 10, false), 0); + parser.InitParser(pdfium::MakeRetain<CFX_MemoryStream>(data, 10, false), 0); EXPECT_EQ("\x10", parser.ReadHexString()); EXPECT_EQ(10, parser.SavePos()); } @@ -54,7 +55,7 @@ TEST(cpdf_syntax_parser, ReadHexString) { // Skips unknown characters. uint8_t data[] = "\x80zab"; CPDF_SyntaxParser parser; - parser.InitParser(IFX_MemoryStream::Create(data, 4, false), 0); + parser.InitParser(pdfium::MakeRetain<CFX_MemoryStream>(data, 4, false), 0); EXPECT_EQ("\xab", parser.ReadHexString()); EXPECT_EQ(4, parser.SavePos()); } @@ -63,7 +64,7 @@ TEST(cpdf_syntax_parser, ReadHexString) { // Skips unknown characters. uint8_t data[] = "\xffzab"; CPDF_SyntaxParser parser; - parser.InitParser(IFX_MemoryStream::Create(data, 4, false), 0); + parser.InitParser(pdfium::MakeRetain<CFX_MemoryStream>(data, 4, false), 0); EXPECT_EQ("\xab", parser.ReadHexString()); EXPECT_EQ(4, parser.SavePos()); } @@ -72,7 +73,7 @@ TEST(cpdf_syntax_parser, ReadHexString) { // Regular conversion. uint8_t data[] = "1A2b>abcd"; CPDF_SyntaxParser parser; - parser.InitParser(IFX_MemoryStream::Create(data, 9, false), 0); + parser.InitParser(pdfium::MakeRetain<CFX_MemoryStream>(data, 9, false), 0); EXPECT_EQ("\x1a\x2b", parser.ReadHexString()); EXPECT_EQ(5, parser.SavePos()); } @@ -81,7 +82,7 @@ TEST(cpdf_syntax_parser, ReadHexString) { // Position out of bounds. uint8_t data[] = "12ab>"; CPDF_SyntaxParser parser; - parser.InitParser(IFX_MemoryStream::Create(data, 5, false), 0); + parser.InitParser(pdfium::MakeRetain<CFX_MemoryStream>(data, 5, false), 0); parser.RestorePos(5); EXPECT_EQ("", parser.ReadHexString()); @@ -103,7 +104,7 @@ TEST(cpdf_syntax_parser, ReadHexString) { // Missing ending >. uint8_t data[] = "1A2b"; CPDF_SyntaxParser parser; - parser.InitParser(IFX_MemoryStream::Create(data, 4, false), 0); + parser.InitParser(pdfium::MakeRetain<CFX_MemoryStream>(data, 4, false), 0); EXPECT_EQ("\x1a\x2b", parser.ReadHexString()); EXPECT_EQ(4, parser.SavePos()); } @@ -112,7 +113,7 @@ TEST(cpdf_syntax_parser, ReadHexString) { // Missing ending >. uint8_t data[] = "12abz"; CPDF_SyntaxParser parser; - parser.InitParser(IFX_MemoryStream::Create(data, 5, false), 0); + parser.InitParser(pdfium::MakeRetain<CFX_MemoryStream>(data, 5, false), 0); EXPECT_EQ("\x12\xab", parser.ReadHexString()); EXPECT_EQ(5, parser.SavePos()); } @@ -121,7 +122,7 @@ TEST(cpdf_syntax_parser, ReadHexString) { // Uneven number of bytes. uint8_t data[] = "1A2>asdf"; CPDF_SyntaxParser parser; - parser.InitParser(IFX_MemoryStream::Create(data, 8, false), 0); + parser.InitParser(pdfium::MakeRetain<CFX_MemoryStream>(data, 8, false), 0); EXPECT_EQ("\x1a\x20", parser.ReadHexString()); EXPECT_EQ(4, parser.SavePos()); } @@ -130,7 +131,7 @@ TEST(cpdf_syntax_parser, ReadHexString) { // Uneven number of bytes. uint8_t data[] = "1A2zasdf"; CPDF_SyntaxParser parser; - parser.InitParser(IFX_MemoryStream::Create(data, 8, false), 0); + parser.InitParser(pdfium::MakeRetain<CFX_MemoryStream>(data, 8, false), 0); EXPECT_EQ("\x1a\x2a\xdf", parser.ReadHexString()); EXPECT_EQ(8, parser.SavePos()); } @@ -139,7 +140,7 @@ TEST(cpdf_syntax_parser, ReadHexString) { // Just ending character. uint8_t data[] = ">"; CPDF_SyntaxParser parser; - parser.InitParser(IFX_MemoryStream::Create(data, 1, false), 0); + parser.InitParser(pdfium::MakeRetain<CFX_MemoryStream>(data, 1, false), 0); EXPECT_EQ("", parser.ReadHexString()); EXPECT_EQ(1, parser.SavePos()); } @@ -149,7 +150,7 @@ TEST(cpdf_syntax_parser, GetInvalidReference) { CPDF_SyntaxParser parser; // Data with a reference with number CPDF_Object::kInvalidObjNum uint8_t data[] = "4294967295 0 R"; - parser.InitParser(IFX_MemoryStream::Create(data, 14, false), 0); + parser.InitParser(pdfium::MakeRetain<CFX_MemoryStream>(data, 14, false), 0); std::unique_ptr<CPDF_Object> ref = parser.GetObject(nullptr, CPDF_Object::kInvalidObjNum, 0, false); EXPECT_FALSE(ref); diff --git a/core/fxcrt/cfx_memorystream.cpp b/core/fxcrt/cfx_memorystream.cpp new file mode 100644 index 0000000000..345b381226 --- /dev/null +++ b/core/fxcrt/cfx_memorystream.cpp @@ -0,0 +1,199 @@ +// Copyright 2017 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#include "core/fxcrt/cfx_memorystream.h" + +#include <algorithm> + +#include "core/fxcrt/fx_safe_types.h" + +namespace { + +const int32_t kBlockSize = 64 * 1024; + +} // namespace + +CFX_MemoryStream::CFX_MemoryStream(bool bConsecutive) + : m_nTotalSize(0), + m_nCurSize(0), + m_nCurPos(0), + m_nGrowSize(kBlockSize), + m_dwFlags(Type::kTakeOver | (bConsecutive ? Type::kConsecutive : 0)) {} + +CFX_MemoryStream::CFX_MemoryStream(uint8_t* pBuffer, + size_t nSize, + bool bTakeOver) + : m_nTotalSize(nSize), + m_nCurSize(nSize), + m_nCurPos(0), + m_nGrowSize(kBlockSize), + m_dwFlags(Type::kConsecutive | (bTakeOver ? Type::kTakeOver : 0)) { + m_Blocks.push_back(pBuffer); +} + +CFX_MemoryStream::~CFX_MemoryStream() { + if (m_dwFlags & Type::kTakeOver) { + for (uint8_t* pBlock : m_Blocks) + FX_Free(pBlock); + } +} + +FX_FILESIZE CFX_MemoryStream::GetSize() { + return static_cast<FX_FILESIZE>(m_nCurSize); +} + +bool CFX_MemoryStream::IsEOF() { + return m_nCurPos >= static_cast<size_t>(GetSize()); +} + +FX_FILESIZE CFX_MemoryStream::GetPosition() { + return static_cast<FX_FILESIZE>(m_nCurPos); +} + +bool CFX_MemoryStream::Flush() { + return true; +} + +bool CFX_MemoryStream::ReadBlock(void* buffer, + FX_FILESIZE offset, + size_t size) { + if (!buffer || !size || offset < 0) + return false; + + FX_SAFE_SIZE_T newPos = size; + newPos += offset; + if (!newPos.IsValid() || newPos.ValueOrDefault(0) == 0 || + newPos.ValueOrDie() > m_nCurSize) { + return false; + } + + m_nCurPos = newPos.ValueOrDie(); + if (m_dwFlags & Type::kConsecutive) { + memcpy(buffer, m_Blocks[0] + static_cast<size_t>(offset), size); + return true; + } + + size_t nStartBlock = static_cast<size_t>(offset) / m_nGrowSize; + offset -= static_cast<FX_FILESIZE>(nStartBlock * m_nGrowSize); + while (size) { + size_t nRead = std::min(size, m_nGrowSize - static_cast<size_t>(offset)); + memcpy(buffer, m_Blocks[nStartBlock] + offset, nRead); + buffer = static_cast<uint8_t*>(buffer) + nRead; + size -= nRead; + ++nStartBlock; + offset = 0; + } + return true; +} + +size_t CFX_MemoryStream::ReadBlock(void* buffer, size_t size) { + if (m_nCurPos >= m_nCurSize) + return 0; + + size_t nRead = std::min(size, m_nCurSize - m_nCurPos); + if (!ReadBlock(buffer, static_cast<int32_t>(m_nCurPos), nRead)) + return 0; + + return nRead; +} + +bool CFX_MemoryStream::WriteBlock(const void* buffer, + FX_FILESIZE offset, + size_t size) { + if (!buffer || !size) + return false; + + if (m_dwFlags & Type::kConsecutive) { + FX_SAFE_SIZE_T newPos = size; + newPos += offset; + if (!newPos.IsValid()) + return false; + + m_nCurPos = newPos.ValueOrDie(); + if (m_nCurPos > m_nTotalSize) { + m_nTotalSize = (m_nCurPos + m_nGrowSize - 1) / m_nGrowSize * m_nGrowSize; + if (m_Blocks.empty()) + m_Blocks.push_back(FX_Alloc(uint8_t, m_nTotalSize)); + else + m_Blocks[0] = FX_Realloc(uint8_t, m_Blocks[0], m_nTotalSize); + } + + memcpy(m_Blocks[0] + offset, buffer, size); + m_nCurSize = std::max(m_nCurSize, m_nCurPos); + + return true; + } + + FX_SAFE_SIZE_T newPos = size; + newPos += offset; + if (!newPos.IsValid()) + return false; + if (!ExpandBlocks(newPos.ValueOrDie())) + return false; + + m_nCurPos = newPos.ValueOrDie(); + size_t nStartBlock = static_cast<size_t>(offset) / m_nGrowSize; + offset -= static_cast<FX_FILESIZE>(nStartBlock * m_nGrowSize); + while (size) { + size_t nWrite = std::min(size, m_nGrowSize - static_cast<size_t>(offset)); + memcpy(m_Blocks[nStartBlock] + offset, buffer, nWrite); + buffer = static_cast<const uint8_t*>(buffer) + nWrite; + size -= nWrite; + ++nStartBlock; + offset = 0; + } + return true; +} + +void CFX_MemoryStream::EstimateSize(size_t nInitSize, size_t nGrowSize) { + if (m_dwFlags & Type::kConsecutive) { + if (m_Blocks.empty()) { + m_Blocks.push_back( + FX_Alloc(uint8_t, std::max(nInitSize, static_cast<size_t>(4096)))); + } + m_nGrowSize = std::max(nGrowSize, static_cast<size_t>(4096)); + } else if (m_Blocks.empty()) { + m_nGrowSize = std::max(nGrowSize, static_cast<size_t>(4096)); + } +} + +void CFX_MemoryStream::AttachBuffer(uint8_t* pBuffer, size_t nSize) { + if (!(m_dwFlags & Type::kConsecutive)) + return; + + m_Blocks.clear(); + m_Blocks.push_back(pBuffer); + m_nTotalSize = nSize; + m_nCurSize = nSize; + m_nCurPos = 0; + m_dwFlags = Type::kConsecutive; +} + +void CFX_MemoryStream::DetachBuffer() { + if (!(m_dwFlags & Type::kConsecutive)) + return; + + m_Blocks.clear(); + m_nTotalSize = 0; + m_nCurSize = 0; + m_nCurPos = 0; + m_dwFlags = Type::kTakeOver; +} + +bool CFX_MemoryStream::ExpandBlocks(size_t size) { + m_nCurSize = std::max(m_nCurSize, size); + if (size <= m_nTotalSize) + return true; + + size = (size - m_nTotalSize + m_nGrowSize - 1) / m_nGrowSize; + size_t iCount = m_Blocks.size(); + m_Blocks.resize(iCount + size); + while (size--) { + m_Blocks[iCount++] = FX_Alloc(uint8_t, m_nGrowSize); + m_nTotalSize += m_nGrowSize; + } + return true; +} diff --git a/core/fxcrt/cfx_memorystream.h b/core/fxcrt/cfx_memorystream.h new file mode 100644 index 0000000000..2112280237 --- /dev/null +++ b/core/fxcrt/cfx_memorystream.h @@ -0,0 +1,56 @@ +// Copyright 2017 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef CORE_FXCRT_CFX_MEMORYSTREAM_H_ +#define CORE_FXCRT_CFX_MEMORYSTREAM_H_ + +#include <vector> + +#include "core/fxcrt/cfx_retain_ptr.h" +#include "core/fxcrt/fx_stream.h" + +class CFX_MemoryStream : public IFX_SeekableStream { + public: + enum Type { kConsecutive = 1 << 0, kTakeOver = 1 << 1 }; + + template <typename T, typename... Args> + friend CFX_RetainPtr<T> pdfium::MakeRetain(Args&&... args); + + // IFX_SeekableStream + FX_FILESIZE GetSize() override; + FX_FILESIZE GetPosition() override; + bool IsEOF() override; + bool ReadBlock(void* buffer, FX_FILESIZE offset, size_t size) override; + size_t ReadBlock(void* buffer, size_t size) override; + bool WriteBlock(const void* buffer, FX_FILESIZE offset, size_t size) override; + bool Flush() override; + + bool IsConsecutive() const { return !!(m_dwFlags & Type::kConsecutive); } + + uint8_t* GetBuffer() const { + return !m_Blocks.empty() ? m_Blocks.front() : nullptr; + } + + void EstimateSize(size_t nInitSize, size_t nGrowSize); + void AttachBuffer(uint8_t* pBuffer, size_t nSize); + void DetachBuffer(); + + private: + explicit CFX_MemoryStream(bool bConsecutive); + CFX_MemoryStream(uint8_t* pBuffer, size_t nSize, bool bTakeOver); + ~CFX_MemoryStream() override; + + bool ExpandBlocks(size_t size); + + std::vector<uint8_t*> m_Blocks; + size_t m_nTotalSize; + size_t m_nCurSize; + size_t m_nCurPos; + size_t m_nGrowSize; + uint32_t m_dwFlags; +}; + +#endif // CORE_FXCRT_CFX_MEMORYSTREAM_H_ diff --git a/core/fxcrt/cfx_seekablestreamproxy.cpp b/core/fxcrt/cfx_seekablestreamproxy.cpp index 8be2e0898f..622f56b3ec 100644 --- a/core/fxcrt/cfx_seekablestreamproxy.cpp +++ b/core/fxcrt/cfx_seekablestreamproxy.cpp @@ -17,6 +17,7 @@ #include <utility> #include <vector> +#include "core/fxcrt/cfx_memorystream.h" #include "core/fxcrt/fx_codepage.h" #include "core/fxcrt/fx_extension.h" #include "third_party/base/ptr_util.h" @@ -189,7 +190,9 @@ CFX_SeekableStreamProxy::CFX_SeekableStreamProxy( } CFX_SeekableStreamProxy::CFX_SeekableStreamProxy(uint8_t* data, FX_STRSIZE size) - : CFX_SeekableStreamProxy(IFX_MemoryStream::Create(data, size), false) {} + : CFX_SeekableStreamProxy( + pdfium::MakeRetain<CFX_MemoryStream>(data, size, false), + false) {} CFX_SeekableStreamProxy::~CFX_SeekableStreamProxy() {} diff --git a/core/fxcrt/fx_stream.cpp b/core/fxcrt/fx_stream.cpp index a0086f269e..2c451c67b8 100644 --- a/core/fxcrt/fx_stream.cpp +++ b/core/fxcrt/fx_stream.cpp @@ -14,10 +14,6 @@ #include "core/fxcrt/fx_safe_types.h" #include "core/fxcrt/ifxcrt_fileaccess.h" -#define FX_MEMSTREAM_BlockSize (64 * 1024) -#define FX_MEMSTREAM_Consecutive 0x01 -#define FX_MEMSTREAM_TakeOver 0x02 - namespace { class CFX_CRTFileStream final : public IFX_SeekableStream { @@ -50,222 +46,6 @@ class CFX_CRTFileStream final : public IFX_SeekableStream { std::unique_ptr<IFXCRT_FileAccess> m_pFile; }; -class CFX_MemoryStream final : public IFX_MemoryStream { - public: - template <typename T, typename... Args> - friend CFX_RetainPtr<T> pdfium::MakeRetain(Args&&... args); - - // IFX_MemoryStream - FX_FILESIZE GetSize() override { - return static_cast<FX_FILESIZE>(m_nCurSize); - } - bool IsEOF() override { return m_nCurPos >= static_cast<size_t>(GetSize()); } - FX_FILESIZE GetPosition() override { - return static_cast<FX_FILESIZE>(m_nCurPos); - } - bool ReadBlock(void* buffer, FX_FILESIZE offset, size_t size) override; - size_t ReadBlock(void* buffer, size_t size) override; - bool WriteBlock(const void* buffer, FX_FILESIZE offset, size_t size) override; - bool Flush() override { return true; } - bool IsConsecutive() const override { - return !!(m_dwFlags & FX_MEMSTREAM_Consecutive); - } - void EstimateSize(size_t nInitSize, size_t nGrowSize) override; - uint8_t* GetBuffer() const override { - return !m_Blocks.empty() ? m_Blocks.front() : nullptr; - } - void AttachBuffer(uint8_t* pBuffer, - size_t nSize, - bool bTakeOver = false) override; - void DetachBuffer() override; - - private: - explicit CFX_MemoryStream(bool bConsecutive); - CFX_MemoryStream(uint8_t* pBuffer, size_t nSize, bool bTakeOver); - ~CFX_MemoryStream() override; - - bool ExpandBlocks(size_t size); - - std::vector<uint8_t*> m_Blocks; - size_t m_nTotalSize; - size_t m_nCurSize; - size_t m_nCurPos; - size_t m_nGrowSize; - uint32_t m_dwFlags; -}; - -CFX_MemoryStream::CFX_MemoryStream(bool bConsecutive) - : m_nTotalSize(0), - m_nCurSize(0), - m_nCurPos(0), - m_nGrowSize(FX_MEMSTREAM_BlockSize) { - m_dwFlags = - FX_MEMSTREAM_TakeOver | (bConsecutive ? FX_MEMSTREAM_Consecutive : 0); -} - -CFX_MemoryStream::CFX_MemoryStream(uint8_t* pBuffer, - size_t nSize, - bool bTakeOver) - : m_nTotalSize(nSize), - m_nCurSize(nSize), - m_nCurPos(0), - m_nGrowSize(FX_MEMSTREAM_BlockSize) { - m_Blocks.push_back(pBuffer); - m_dwFlags = - FX_MEMSTREAM_Consecutive | (bTakeOver ? FX_MEMSTREAM_TakeOver : 0); -} - -CFX_MemoryStream::~CFX_MemoryStream() { - if (m_dwFlags & FX_MEMSTREAM_TakeOver) { - for (uint8_t* pBlock : m_Blocks) - FX_Free(pBlock); - } -} - -bool CFX_MemoryStream::ReadBlock(void* buffer, - FX_FILESIZE offset, - size_t size) { - if (!buffer || !size || offset < 0) - return false; - - FX_SAFE_SIZE_T newPos = size; - newPos += offset; - if (!newPos.IsValid() || newPos.ValueOrDefault(0) == 0 || - newPos.ValueOrDie() > m_nCurSize) { - return false; - } - - m_nCurPos = newPos.ValueOrDie(); - if (m_dwFlags & FX_MEMSTREAM_Consecutive) { - memcpy(buffer, m_Blocks[0] + static_cast<size_t>(offset), size); - return true; - } - - size_t nStartBlock = static_cast<size_t>(offset) / m_nGrowSize; - offset -= static_cast<FX_FILESIZE>(nStartBlock * m_nGrowSize); - while (size) { - size_t nRead = std::min(size, m_nGrowSize - static_cast<size_t>(offset)); - memcpy(buffer, m_Blocks[nStartBlock] + offset, nRead); - buffer = static_cast<uint8_t*>(buffer) + nRead; - size -= nRead; - ++nStartBlock; - offset = 0; - } - return true; -} - -size_t CFX_MemoryStream::ReadBlock(void* buffer, size_t size) { - if (m_nCurPos >= m_nCurSize) - return 0; - - size_t nRead = std::min(size, m_nCurSize - m_nCurPos); - if (!ReadBlock(buffer, static_cast<int32_t>(m_nCurPos), nRead)) - return 0; - - return nRead; -} - -bool CFX_MemoryStream::WriteBlock(const void* buffer, - FX_FILESIZE offset, - size_t size) { - if (!buffer || !size) - return false; - - if (m_dwFlags & FX_MEMSTREAM_Consecutive) { - FX_SAFE_SIZE_T newPos = size; - newPos += offset; - if (!newPos.IsValid()) - return false; - - m_nCurPos = newPos.ValueOrDie(); - if (m_nCurPos > m_nTotalSize) { - m_nTotalSize = (m_nCurPos + m_nGrowSize - 1) / m_nGrowSize * m_nGrowSize; - if (m_Blocks.empty()) - m_Blocks.push_back(FX_Alloc(uint8_t, m_nTotalSize)); - else - m_Blocks[0] = FX_Realloc(uint8_t, m_Blocks[0], m_nTotalSize); - } - - memcpy(m_Blocks[0] + offset, buffer, size); - m_nCurSize = std::max(m_nCurSize, m_nCurPos); - - return true; - } - - FX_SAFE_SIZE_T newPos = size; - newPos += offset; - if (!newPos.IsValid()) - return false; - if (!ExpandBlocks(newPos.ValueOrDie())) - return false; - - m_nCurPos = newPos.ValueOrDie(); - size_t nStartBlock = static_cast<size_t>(offset) / m_nGrowSize; - offset -= static_cast<FX_FILESIZE>(nStartBlock * m_nGrowSize); - while (size) { - size_t nWrite = std::min(size, m_nGrowSize - static_cast<size_t>(offset)); - memcpy(m_Blocks[nStartBlock] + offset, buffer, nWrite); - buffer = static_cast<const uint8_t*>(buffer) + nWrite; - size -= nWrite; - ++nStartBlock; - offset = 0; - } - return true; -} - -void CFX_MemoryStream::EstimateSize(size_t nInitSize, size_t nGrowSize) { - if (m_dwFlags & FX_MEMSTREAM_Consecutive) { - if (m_Blocks.empty()) { - m_Blocks.push_back( - FX_Alloc(uint8_t, std::max(nInitSize, static_cast<size_t>(4096)))); - } - m_nGrowSize = std::max(nGrowSize, static_cast<size_t>(4096)); - } else if (m_Blocks.empty()) { - m_nGrowSize = std::max(nGrowSize, static_cast<size_t>(4096)); - } -} - -void CFX_MemoryStream::AttachBuffer(uint8_t* pBuffer, - size_t nSize, - bool bTakeOver) { - if (!(m_dwFlags & FX_MEMSTREAM_Consecutive)) - return; - - m_Blocks.clear(); - m_Blocks.push_back(pBuffer); - m_nTotalSize = nSize; - m_nCurSize = nSize; - m_nCurPos = 0; - m_dwFlags = - FX_MEMSTREAM_Consecutive | (bTakeOver ? FX_MEMSTREAM_TakeOver : 0); -} - -void CFX_MemoryStream::DetachBuffer() { - if (!(m_dwFlags & FX_MEMSTREAM_Consecutive)) - return; - - m_Blocks.clear(); - m_nTotalSize = 0; - m_nCurSize = 0; - m_nCurPos = 0; - m_dwFlags = FX_MEMSTREAM_TakeOver; -} - -bool CFX_MemoryStream::ExpandBlocks(size_t size) { - m_nCurSize = std::max(m_nCurSize, size); - if (size <= m_nTotalSize) - return true; - - size = (size - m_nTotalSize + m_nGrowSize - 1) / m_nGrowSize; - size_t iCount = m_Blocks.size(); - m_Blocks.resize(iCount + size); - while (size--) { - m_Blocks[iCount++] = FX_Alloc(uint8_t, m_nGrowSize); - m_nTotalSize += m_nGrowSize; - } - return true; -} - } // namespace // static @@ -294,18 +74,6 @@ IFX_SeekableReadStream::CreateFromFilename(const char* filename) { return IFX_SeekableStream::CreateFromFilename(filename, FX_FILEMODE_ReadOnly); } -// static -CFX_RetainPtr<IFX_MemoryStream> IFX_MemoryStream::Create(uint8_t* pBuffer, - size_t dwSize, - bool bTakeOver) { - return pdfium::MakeRetain<CFX_MemoryStream>(pBuffer, dwSize, bTakeOver); -} - -// static -CFX_RetainPtr<IFX_MemoryStream> IFX_MemoryStream::Create(bool bConsecutive) { - return pdfium::MakeRetain<CFX_MemoryStream>(bConsecutive); -} - bool IFX_SeekableWriteStream::WriteBlock(const void* pData, size_t size) { return WriteBlock(pData, GetSize(), size); } diff --git a/core/fxcrt/fx_stream.h b/core/fxcrt/fx_stream.h index 1aa9feae58..5eb83e5681 100644 --- a/core/fxcrt/fx_stream.h +++ b/core/fxcrt/fx_stream.h @@ -111,22 +111,6 @@ class IFX_SeekableStream : public IFX_SeekableReadStream, bool Flush() override = 0; }; -class IFX_MemoryStream : public IFX_SeekableStream { - public: - static CFX_RetainPtr<IFX_MemoryStream> Create(uint8_t* pBuffer, - size_t nSize, - bool bTakeOver = false); - static CFX_RetainPtr<IFX_MemoryStream> Create(bool bConsecutive = false); - - virtual bool IsConsecutive() const = 0; - virtual void EstimateSize(size_t nInitSize, size_t nGrowSize) = 0; - virtual uint8_t* GetBuffer() const = 0; - virtual void AttachBuffer(uint8_t* pBuffer, - size_t nSize, - bool bTakeOver = false) = 0; - virtual void DetachBuffer() = 0; -}; - #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ class CFindFileData { public: diff --git a/core/fxcrt/xml/cfx_saxreader_unittest.cpp b/core/fxcrt/xml/cfx_saxreader_unittest.cpp index 7865d0b77c..0bb5e1a066 100644 --- a/core/fxcrt/xml/cfx_saxreader_unittest.cpp +++ b/core/fxcrt/xml/cfx_saxreader_unittest.cpp @@ -3,6 +3,7 @@ // found in the LICENSE file. #include "core/fxcrt/xml/cfx_saxreader.h" +#include "core/fxcrt/cfx_memorystream.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "testing/test_support.h" @@ -50,10 +51,11 @@ class CFX_SAXReaderTest : public pdfium::FPDF_Test { } bool StartParse(char* str) { - return reader_.StartParse(IFX_MemoryStream::Create( - reinterpret_cast<uint8_t*>(str), strlen(str)), - 0, static_cast<uint32_t>(-1), - CFX_SaxParseMode_NotSkipSpace) >= 0; + return reader_.StartParse( + pdfium::MakeRetain<CFX_MemoryStream>( + reinterpret_cast<uint8_t*>(str), strlen(str), false), + 0, static_cast<uint32_t>(-1), + CFX_SaxParseMode_NotSkipSpace) >= 0; } int32_t ContinueParse() { |