summaryrefslogtreecommitdiff
path: root/core/fxcrt
diff options
context:
space:
mode:
Diffstat (limited to 'core/fxcrt')
-rw-r--r--core/fxcrt/cfx_blockbuffer.cpp140
-rw-r--r--core/fxcrt/cfx_blockbuffer.h54
2 files changed, 194 insertions, 0 deletions
diff --git a/core/fxcrt/cfx_blockbuffer.cpp b/core/fxcrt/cfx_blockbuffer.cpp
new file mode 100644
index 0000000000..354f415282
--- /dev/null
+++ b/core/fxcrt/cfx_blockbuffer.cpp
@@ -0,0 +1,140 @@
+// 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_blockbuffer.h"
+
+#include <algorithm>
+
+#include "third_party/base/stl_util.h"
+
+CFX_BlockBuffer::CFX_BlockBuffer(int32_t iAllocStep)
+ : m_iDataLength(0),
+ m_iBufferSize(0),
+ m_iAllocStep(iAllocStep),
+ m_iStartPosition(0) {}
+
+CFX_BlockBuffer::~CFX_BlockBuffer() {
+ ClearBuffer();
+}
+
+wchar_t* CFX_BlockBuffer::GetAvailableBlock(int32_t& iIndexInBlock) {
+ iIndexInBlock = 0;
+ if (m_BlockArray.empty())
+ return nullptr;
+
+ int32_t iRealIndex = m_iStartPosition + m_iDataLength;
+ if (iRealIndex == m_iBufferSize) {
+ m_BlockArray.emplace_back(FX_Alloc(wchar_t, m_iAllocStep));
+ m_iBufferSize += m_iAllocStep;
+ return m_BlockArray.back().get();
+ }
+ iIndexInBlock = iRealIndex % m_iAllocStep;
+ return m_BlockArray[iRealIndex / m_iAllocStep].get();
+}
+
+bool CFX_BlockBuffer::InitBuffer(int32_t iBufferSize) {
+ ClearBuffer();
+ int32_t iNumOfBlock = (iBufferSize - 1) / m_iAllocStep + 1;
+ for (int32_t i = 0; i < iNumOfBlock; i++)
+ m_BlockArray.emplace_back(FX_Alloc(wchar_t, m_iAllocStep));
+
+ m_iBufferSize = iNumOfBlock * m_iAllocStep;
+ return true;
+}
+
+void CFX_BlockBuffer::SetTextChar(int32_t iIndex, wchar_t ch) {
+ if (iIndex < 0) {
+ return;
+ }
+ int32_t iRealIndex = m_iStartPosition + iIndex;
+ int32_t iBlockIndex = iRealIndex / m_iAllocStep;
+ int32_t iInnerIndex = iRealIndex % m_iAllocStep;
+ int32_t iBlockSize = pdfium::CollectionSize<int32_t>(m_BlockArray);
+ if (iBlockIndex >= iBlockSize) {
+ int32_t iNewBlocks = iBlockIndex - iBlockSize + 1;
+ do {
+ m_BlockArray.emplace_back(FX_Alloc(wchar_t, m_iAllocStep));
+ m_iBufferSize += m_iAllocStep;
+ } while (--iNewBlocks);
+ }
+ wchar_t* pTextData = m_BlockArray[iBlockIndex].get();
+ pTextData[iInnerIndex] = ch;
+ m_iDataLength = std::max(m_iDataLength, iIndex + 1);
+}
+
+int32_t CFX_BlockBuffer::DeleteTextChars(int32_t iCount, bool bDirection) {
+ if (iCount <= 0)
+ return m_iDataLength;
+
+ if (iCount >= m_iDataLength) {
+ Reset(false);
+ return 0;
+ }
+ if (bDirection) {
+ m_iStartPosition += iCount;
+ m_iDataLength -= iCount;
+ } else {
+ m_iDataLength -= iCount;
+ }
+ return m_iDataLength;
+}
+
+void CFX_BlockBuffer::GetTextData(CFX_WideString& wsTextData,
+ int32_t iStart,
+ int32_t iLength) const {
+ wsTextData.clear();
+ int32_t iMaybeDataLength = m_iBufferSize - 1 - m_iStartPosition;
+ if (iStart < 0 || iStart > iMaybeDataLength) {
+ return;
+ }
+ if (iLength == -1 || iLength > iMaybeDataLength) {
+ iLength = iMaybeDataLength;
+ }
+ if (iLength <= 0) {
+ return;
+ }
+ wchar_t* pBuf = wsTextData.GetBuffer(iLength);
+ if (!pBuf) {
+ return;
+ }
+ int32_t iStartBlockIndex = 0;
+ int32_t iStartInnerIndex = 0;
+ TextDataIndex2BufIndex(iStart, iStartBlockIndex, iStartInnerIndex);
+ int32_t iEndBlockIndex = 0;
+ int32_t iEndInnerIndex = 0;
+ TextDataIndex2BufIndex(iStart + iLength, iEndBlockIndex, iEndInnerIndex);
+ int32_t iPointer = 0;
+ for (int32_t i = iStartBlockIndex; i <= iEndBlockIndex; i++) {
+ int32_t iBufferPointer = 0;
+ int32_t iCopyLength = m_iAllocStep;
+ if (i == iStartBlockIndex) {
+ iCopyLength -= iStartInnerIndex;
+ iBufferPointer = iStartInnerIndex;
+ }
+ if (i == iEndBlockIndex) {
+ iCopyLength -= ((m_iAllocStep - 1) - iEndInnerIndex);
+ }
+ wchar_t* pBlockBuf = m_BlockArray[i].get();
+ memcpy(pBuf + iPointer, pBlockBuf + iBufferPointer,
+ iCopyLength * sizeof(wchar_t));
+ iPointer += iCopyLength;
+ }
+ wsTextData.ReleaseBuffer(iLength);
+}
+
+void CFX_BlockBuffer::TextDataIndex2BufIndex(const int32_t iIndex,
+ int32_t& iBlockIndex,
+ int32_t& iInnerIndex) const {
+ ASSERT(iIndex >= 0);
+ int32_t iRealIndex = m_iStartPosition + iIndex;
+ iBlockIndex = iRealIndex / m_iAllocStep;
+ iInnerIndex = iRealIndex % m_iAllocStep;
+}
+
+void CFX_BlockBuffer::ClearBuffer() {
+ m_iBufferSize = 0;
+ m_BlockArray.clear();
+}
diff --git a/core/fxcrt/cfx_blockbuffer.h b/core/fxcrt/cfx_blockbuffer.h
new file mode 100644
index 0000000000..dbf01a938a
--- /dev/null
+++ b/core/fxcrt/cfx_blockbuffer.h
@@ -0,0 +1,54 @@
+// 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_BLOCKBUFFER_H_
+#define CORE_FXCRT_CFX_BLOCKBUFFER_H_
+
+#include <stdint.h>
+
+#include <memory>
+#include <vector>
+
+#include "core/fxcrt/fx_string.h"
+
+class CFX_BlockBuffer {
+ public:
+ explicit CFX_BlockBuffer(int32_t iAllocStep = 1024 * 1024);
+ ~CFX_BlockBuffer();
+
+ bool InitBuffer(int32_t iBufferSize = 1024 * 1024);
+ bool IsInitialized() { return m_iBufferSize / m_iAllocStep >= 1; }
+
+ wchar_t* GetAvailableBlock(int32_t& iIndexInBlock);
+ inline int32_t GetAllocStep() const { return m_iAllocStep; }
+ inline int32_t& GetDataLengthRef() { return m_iDataLength; }
+
+ inline void Reset(bool bReserveData = true) {
+ if (!bReserveData)
+ m_iStartPosition = 0;
+ m_iDataLength = 0;
+ }
+
+ void SetTextChar(int32_t iIndex, wchar_t ch);
+ int32_t DeleteTextChars(int32_t iCount, bool bDirection = true);
+ void GetTextData(CFX_WideString& wsTextData,
+ int32_t iStart = 0,
+ int32_t iLength = -1) const;
+
+ private:
+ inline void TextDataIndex2BufIndex(const int32_t iIndex,
+ int32_t& iBlockIndex,
+ int32_t& iInnerIndex) const;
+ void ClearBuffer();
+
+ std::vector<std::unique_ptr<wchar_t, FxFreeDeleter>> m_BlockArray;
+ int32_t m_iDataLength;
+ int32_t m_iBufferSize;
+ int32_t m_iAllocStep;
+ int32_t m_iStartPosition;
+};
+
+#endif // CORE_FXCRT_CFX_BLOCKBUFFER_H_