1d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann// Copyright 2017 PDFium Authors. All rights reserved. 2d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann// Use of this source code is governed by a BSD-style license that can be 3d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann// found in the LICENSE file. 4d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 5d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com 6d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 7d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann#include "core/fxcrt/cfx_blockbuffer.h" 8d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 9d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann#include <algorithm> 10d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann#include <utility> 11d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 12d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannnamespace { 13d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 14d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannconst size_t kAllocStep = 1024 * 1024; 15d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 16d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann} // namespace 17d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 18d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. MoltmannCFX_BlockBuffer::CFX_BlockBuffer() 19d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann : m_DataLength(0), m_BufferSize(0), m_StartPosition(0) {} 20d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 21d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. MoltmannCFX_BlockBuffer::~CFX_BlockBuffer() {} 22d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 23d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannsize_t CFX_BlockBuffer::GetAllocStep() const { 24d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann return kAllocStep; 25d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann} 26d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 27d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannstd::pair<wchar_t*, size_t> CFX_BlockBuffer::GetAvailableBlock() { 28d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann if (m_BlockArray.empty()) 29d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann return {nullptr, 0}; 30d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 31d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann size_t realIndex = m_StartPosition + m_DataLength; 32d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann if (realIndex == m_BufferSize) { 33d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann m_BlockArray.emplace_back(FX_Alloc(wchar_t, kAllocStep)); 34d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann m_BufferSize += kAllocStep; 35d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann return {m_BlockArray.back().get(), 0}; 36d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann } 37d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann return {m_BlockArray[realIndex / kAllocStep].get(), realIndex % kAllocStep}; 38d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann} 39d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 40d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannbool CFX_BlockBuffer::InitBuffer() { 41d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann m_BlockArray.clear(); 42d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann m_BlockArray.emplace_back(FX_Alloc(wchar_t, kAllocStep)); 43d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann m_BufferSize = kAllocStep; 44d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann return true; 45d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann} 46d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 47d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannvoid CFX_BlockBuffer::SetTextChar(size_t index, wchar_t ch) { 48d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann size_t realIndex = m_StartPosition + index; 49d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann size_t blockIndex = realIndex / kAllocStep; 50d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann if (blockIndex >= m_BlockArray.size()) { 51d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann size_t newBlocks = blockIndex - m_BlockArray.size() + 1; 52d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann do { 53d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann m_BlockArray.emplace_back(FX_Alloc(wchar_t, kAllocStep)); 54d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann m_BufferSize += kAllocStep; 55d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann } while (--newBlocks); 56d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann } 57d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann wchar_t* pTextData = m_BlockArray[blockIndex].get(); 58d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann pTextData[realIndex % kAllocStep] = ch; 59d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann m_DataLength = std::max(m_DataLength, index + 1); 60d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann} 61d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 62d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannvoid CFX_BlockBuffer::DeleteTextChars(size_t count) { 63d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann if (count == 0) 64d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann return; 65d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 66d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann if (count >= m_DataLength) { 67d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann Reset(false); 68d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann return; 69d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann } 70d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann m_DataLength -= count; 71d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann} 72d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 73d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. MoltmannWideString CFX_BlockBuffer::GetTextData(size_t start, size_t length) const { 74d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann if (m_BufferSize <= m_StartPosition + 1 || length == 0) 75d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann return WideString(); 76d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 77d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann size_t maybeDataLength = m_BufferSize - 1 - m_StartPosition; 78d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann if (start > maybeDataLength) 79d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann return WideString(); 80d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann length = std::min(length, maybeDataLength); 81d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 82d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann WideString wsTextData; 83d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann wchar_t* pBuf = wsTextData.GetBuffer(length); 84d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann if (!pBuf) 85d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann return WideString(); 86d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 87d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann size_t startBlock = 0; 88d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann size_t startInner = 0; 89d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann std::tie(startBlock, startInner) = TextDataIndex2BufIndex(start); 90d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 91d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann size_t endBlock = 0; 92d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann size_t endInner = 0; 93d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann std::tie(endBlock, endInner) = TextDataIndex2BufIndex(start + length); 94d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 95d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann size_t pointer = 0; 96d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann for (size_t i = startBlock; i <= endBlock; ++i) { 97d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann size_t bufferPointer = 0; 98d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann size_t copyLength = kAllocStep; 99d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann if (i == startBlock) { 100d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann copyLength -= startInner; 101d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann bufferPointer = startInner; 102d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann } 103d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann if (i == endBlock) 104d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann copyLength -= ((kAllocStep - 1) - endInner); 105d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 106d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann wchar_t* pBlockBuf = m_BlockArray[i].get(); 107d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann memcpy(pBuf + pointer, pBlockBuf + bufferPointer, 108d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann copyLength * sizeof(wchar_t)); 109d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann pointer += copyLength; 110d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann } 111d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann wsTextData.ReleaseBuffer(length); 112d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann return wsTextData; 113d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann} 114d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 115d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannstd::pair<size_t, size_t> CFX_BlockBuffer::TextDataIndex2BufIndex( 116d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann const size_t iIndex) const { 117d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann ASSERT(iIndex >= 0); 118d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 119d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann size_t realIndex = m_StartPosition + iIndex; 120d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann return {realIndex / kAllocStep, realIndex % kAllocStep}; 121d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann} 122