summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLei Zhang <thestig@chromium.org>2018-08-15 18:42:32 +0000
committerChromium commit bot <commit-bot@chromium.org>2018-08-15 18:42:32 +0000
commit48ae3075a5c80e75923a60d4d0ba0b56d9b08c2a (patch)
tree464540a6b17b7e2cc3096d7f579729745f5b0664
parent55ccb526913debb3269a33792bbd61b05656ec46 (diff)
downloadpdfium-48ae3075a5c80e75923a60d4d0ba0b56d9b08c2a.tar.xz
Make CFX_MemoryStream always consecutive.chromium/3524
Non-consecutive mode has questionable correctness and is not an obvious performance win. Change-Id: Idaa66e5ee5c4604628a0f55b67d5a04ab47ea5ec Reviewed-on: https://pdfium-review.googlesource.com/40050 Reviewed-by: Tom Sepez <tsepez@chromium.org> Commit-Queue: Lei Zhang <thestig@chromium.org>
-rw-r--r--core/fxcrt/cfx_memorystream.cpp109
-rw-r--r--core/fxcrt/cfx_memorystream.h14
-rw-r--r--fpdfsdk/fpdf_save.cpp4
-rw-r--r--fxjs/xfa/cjx_node.cpp2
-rw-r--r--xfa/fxfa/parser/xfa_utils.cpp2
5 files changed, 37 insertions, 94 deletions
diff --git a/core/fxcrt/cfx_memorystream.cpp b/core/fxcrt/cfx_memorystream.cpp
index b0a0bd91d1..d64d2a0b43 100644
--- a/core/fxcrt/cfx_memorystream.cpp
+++ b/core/fxcrt/cfx_memorystream.cpp
@@ -10,24 +10,12 @@
#include "core/fxcrt/fx_safe_types.h"
-namespace {
-
-constexpr size_t kBlockSize = 64 * 1024;
-
-} // namespace
-
-CFX_MemoryStream::CFX_MemoryStream(bool bConsecutive)
- : m_nTotalSize(0), m_nCurSize(0), m_bConsecutive(bConsecutive) {}
+CFX_MemoryStream::CFX_MemoryStream() : m_nTotalSize(0), m_nCurSize(0) {}
CFX_MemoryStream::CFX_MemoryStream(uint8_t* pBuffer, size_t nSize)
- : m_nTotalSize(nSize), m_nCurSize(nSize), m_bConsecutive(true) {
- m_Blocks.push_back(pBuffer);
-}
+ : m_data(pBuffer), m_nTotalSize(nSize), m_nCurSize(nSize) {}
-CFX_MemoryStream::~CFX_MemoryStream() {
- for (uint8_t* pBlock : m_Blocks)
- FX_Free(pBlock);
-}
+CFX_MemoryStream::~CFX_MemoryStream() = default;
FX_FILESIZE CFX_MemoryStream::GetSize() {
return static_cast<FX_FILESIZE>(m_nCurSize);
@@ -48,7 +36,7 @@ bool CFX_MemoryStream::Flush() {
bool CFX_MemoryStream::ReadBlock(void* buffer,
FX_FILESIZE offset,
size_t size) {
- if (!buffer || !size || offset < 0)
+ if (!buffer || offset < 0 || !size)
return false;
FX_SAFE_SIZE_T newPos = size;
@@ -59,21 +47,7 @@ bool CFX_MemoryStream::ReadBlock(void* buffer,
}
m_nCurPos = newPos.ValueOrDie();
- if (m_bConsecutive) {
- memcpy(buffer, m_Blocks[0] + static_cast<size_t>(offset), size);
- return true;
- }
-
- size_t nStartBlock = static_cast<size_t>(offset) / kBlockSize;
- offset -= static_cast<FX_FILESIZE>(nStartBlock * kBlockSize);
- while (size) {
- size_t nRead = std::min(size, kBlockSize - static_cast<size_t>(offset));
- memcpy(buffer, m_Blocks[nStartBlock] + offset, nRead);
- buffer = static_cast<uint8_t*>(buffer) + nRead;
- size -= nRead;
- ++nStartBlock;
- offset = 0;
- }
+ memcpy(buffer, &GetBuffer()[offset], size);
return true;
}
@@ -91,62 +65,35 @@ size_t CFX_MemoryStream::ReadBlock(void* buffer, size_t size) {
bool CFX_MemoryStream::WriteBlock(const void* buffer,
FX_FILESIZE offset,
size_t size) {
- if (!buffer || !size)
+ if (!buffer || offset < 0 || !size)
return false;
- if (m_bConsecutive) {
- 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 + kBlockSize - 1) / kBlockSize * kBlockSize;
- 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);
- }
+ FX_SAFE_SIZE_T safe_new_pos = size;
+ safe_new_pos += offset;
+ if (!safe_new_pos.IsValid())
+ return false;
- memcpy(m_Blocks[0] + offset, buffer, size);
- m_nCurSize = std::max(m_nCurSize, m_nCurPos);
+ size_t new_pos = safe_new_pos.ValueOrDie();
+ if (new_pos > m_nTotalSize) {
+ static constexpr size_t kBlockSize = 64 * 1024;
+ FX_SAFE_SIZE_T new_size = new_pos;
+ new_size *= 2;
+ new_size += (kBlockSize - 1);
+ new_size /= kBlockSize;
+ new_size *= kBlockSize;
+ if (!new_size.IsValid())
+ return false;
- return true;
+ m_nTotalSize = new_size.ValueOrDie();
+ if (m_data)
+ m_data.reset(FX_Realloc(uint8_t, m_data.get(), m_nTotalSize));
+ else
+ m_data.reset(FX_Alloc(uint8_t, m_nTotalSize));
}
+ m_nCurPos = new_pos;
- FX_SAFE_SIZE_T newPos = size;
- newPos += offset;
- if (!newPos.IsValid())
- return false;
- if (!ExpandBlocks(newPos.ValueOrDie()))
- return false;
+ memcpy(&m_data.get()[offset], buffer, size);
+ m_nCurSize = std::max(m_nCurSize, m_nCurPos);
- m_nCurPos = newPos.ValueOrDie();
- size_t nStartBlock = static_cast<size_t>(offset) / kBlockSize;
- offset -= static_cast<FX_FILESIZE>(nStartBlock * kBlockSize);
- while (size) {
- size_t nWrite = std::min(size, kBlockSize - 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;
-}
-
-bool CFX_MemoryStream::ExpandBlocks(size_t size) {
- m_nCurSize = std::max(m_nCurSize, size);
- if (size <= m_nTotalSize)
- return true;
-
- size = (size - m_nTotalSize + kBlockSize - 1) / kBlockSize;
- size_t iCount = m_Blocks.size();
- m_Blocks.resize(iCount + size);
- while (size--) {
- m_Blocks[iCount++] = FX_Alloc(uint8_t, kBlockSize);
- m_nTotalSize += kBlockSize;
- }
return true;
}
diff --git a/core/fxcrt/cfx_memorystream.h b/core/fxcrt/cfx_memorystream.h
index 95f62b6a2c..47e491275c 100644
--- a/core/fxcrt/cfx_memorystream.h
+++ b/core/fxcrt/cfx_memorystream.h
@@ -7,8 +7,9 @@
#ifndef CORE_FXCRT_CFX_MEMORYSTREAM_H_
#define CORE_FXCRT_CFX_MEMORYSTREAM_H_
-#include <vector>
+#include <memory>
+#include "core/fxcrt/fx_memory.h"
#include "core/fxcrt/fx_stream.h"
#include "core/fxcrt/retain_ptr.h"
@@ -26,24 +27,19 @@ class CFX_MemoryStream : public IFX_SeekableStream {
bool WriteBlock(const void* buffer, FX_FILESIZE offset, size_t size) override;
bool Flush() override;
- uint8_t* GetBuffer() {
- return !m_Blocks.empty() ? m_Blocks.front() : nullptr;
- }
+ const uint8_t* GetBuffer() const { return m_data.get(); }
private:
- explicit CFX_MemoryStream(bool bConsecutive);
+ CFX_MemoryStream();
// Takes ownership of |pBuffer|.
CFX_MemoryStream(uint8_t* pBuffer, size_t nSize);
~CFX_MemoryStream() override;
- bool ExpandBlocks(size_t size);
-
- std::vector<uint8_t*> m_Blocks;
+ std::unique_ptr<uint8_t, FxFreeDeleter> m_data;
size_t m_nTotalSize;
size_t m_nCurSize;
size_t m_nCurPos = 0;
- const bool m_bConsecutive;
};
#endif // CORE_FXCRT_CFX_MEMORYSTREAM_H_
diff --git a/fpdfsdk/fpdf_save.cpp b/fpdfsdk/fpdf_save.cpp
index 52b87264e7..be1dbd14f8 100644
--- a/fpdfsdk/fpdf_save.cpp
+++ b/fpdfsdk/fpdf_save.cpp
@@ -120,7 +120,7 @@ bool SaveXFADocumentData(CPDFXFA_Context* pContext,
// L"datasets"
{
RetainPtr<IFX_SeekableStream> pDsfileWrite =
- pdfium::MakeRetain<CFX_MemoryStream>(false);
+ pdfium::MakeRetain<CFX_MemoryStream>();
CXFA_FFDoc* ffdoc = pXFADocView->GetDoc();
if (ffdoc->SavePackage(
ToNode(ffdoc->GetXFADoc()->GetXFAObject(XFA_HASHCODE_Datasets)),
@@ -146,7 +146,7 @@ bool SaveXFADocumentData(CPDFXFA_Context* pContext,
// L"form"
{
RetainPtr<IFX_SeekableStream> pfileWrite =
- pdfium::MakeRetain<CFX_MemoryStream>(false);
+ pdfium::MakeRetain<CFX_MemoryStream>();
CXFA_FFDoc* ffdoc = pXFADocView->GetDoc();
if (ffdoc->SavePackage(
diff --git a/fxjs/xfa/cjx_node.cpp b/fxjs/xfa/cjx_node.cpp
index efef5af87b..b1d8c2cb66 100644
--- a/fxjs/xfa/cjx_node.cpp
+++ b/fxjs/xfa/cjx_node.cpp
@@ -357,7 +357,7 @@ CJS_Return CJX_Node::saveXML(CFX_V8* runtime,
XFA_DataExporter_DealWithDataGroupNode(GetXFANode());
}
- auto pMemoryStream = pdfium::MakeRetain<CFX_MemoryStream>(true);
+ auto pMemoryStream = pdfium::MakeRetain<CFX_MemoryStream>();
pMemoryStream->WriteString(bsXMLHeader.AsStringView());
if (GetXFANode()->GetPacketType() == XFA_PacketType::Form) {
diff --git a/xfa/fxfa/parser/xfa_utils.cpp b/xfa/fxfa/parser/xfa_utils.cpp
index 5a8f1c8711..ba3d857522 100644
--- a/xfa/fxfa/parser/xfa_utils.cpp
+++ b/xfa/fxfa/parser/xfa_utils.cpp
@@ -215,7 +215,7 @@ void RegenerateFormFile_Changed(CXFA_Node* pNode,
if (!pRichTextXML)
break;
- auto pMemStream = pdfium::MakeRetain<CFX_MemoryStream>(true);
+ auto pMemStream = pdfium::MakeRetain<CFX_MemoryStream>();
pRichTextXML->Save(pMemStream);
wsChildren += WideString::FromUTF8(
ByteStringView(pMemStream->GetBuffer(), pMemStream->GetSize()));