// 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 <utility>

namespace {

const size_t kAllocStep = 1024 * 1024;

}  // namespace

CFX_BlockBuffer::CFX_BlockBuffer()
    : m_DataLength(0), m_BufferSize(0), m_StartPosition(0) {}

CFX_BlockBuffer::~CFX_BlockBuffer() {}

size_t CFX_BlockBuffer::GetAllocStep() const {
  return kAllocStep;
}

std::pair<wchar_t*, size_t> CFX_BlockBuffer::GetAvailableBlock() {
  if (m_BlockArray.empty())
    return {nullptr, 0};

  size_t realIndex = m_StartPosition + m_DataLength;
  if (realIndex == m_BufferSize) {
    m_BlockArray.emplace_back(FX_Alloc(wchar_t, kAllocStep));
    m_BufferSize += kAllocStep;
    return {m_BlockArray.back().get(), 0};
  }
  return {m_BlockArray[realIndex / kAllocStep].get(), realIndex % kAllocStep};
}

bool CFX_BlockBuffer::InitBuffer() {
  m_BlockArray.clear();
  m_BlockArray.emplace_back(FX_Alloc(wchar_t, kAllocStep));
  m_BufferSize = kAllocStep;
  return true;
}

void CFX_BlockBuffer::SetTextChar(size_t index, wchar_t ch) {
  size_t realIndex = m_StartPosition + index;
  size_t blockIndex = realIndex / kAllocStep;
  if (blockIndex >= m_BlockArray.size()) {
    size_t newBlocks = blockIndex - m_BlockArray.size() + 1;
    do {
      m_BlockArray.emplace_back(FX_Alloc(wchar_t, kAllocStep));
      m_BufferSize += kAllocStep;
    } while (--newBlocks);
  }
  wchar_t* pTextData = m_BlockArray[blockIndex].get();
  pTextData[realIndex % kAllocStep] = ch;
  m_DataLength = std::max(m_DataLength, index + 1);
}

void CFX_BlockBuffer::DeleteTextChars(size_t count) {
  if (count == 0)
    return;

  if (count >= m_DataLength) {
    Reset(false);
    return;
  }
  m_DataLength -= count;
}

CFX_WideString CFX_BlockBuffer::GetTextData(size_t start, size_t length) const {
  if (m_BufferSize <= m_StartPosition + 1 || length == 0)
    return CFX_WideString();

  size_t maybeDataLength = m_BufferSize - 1 - m_StartPosition;
  if (start > maybeDataLength)
    return CFX_WideString();
  length = std::min(length, maybeDataLength);

  CFX_WideString wsTextData;
  wchar_t* pBuf = wsTextData.GetBuffer(length);
  if (!pBuf)
    return CFX_WideString();

  size_t startBlock = 0;
  size_t startInner = 0;
  std::tie(startBlock, startInner) = TextDataIndex2BufIndex(start);

  size_t endBlock = 0;
  size_t endInner = 0;
  std::tie(endBlock, endInner) = TextDataIndex2BufIndex(start + length);

  size_t pointer = 0;
  for (size_t i = startBlock; i <= endBlock; ++i) {
    size_t bufferPointer = 0;
    size_t copyLength = kAllocStep;
    if (i == startBlock) {
      copyLength -= startInner;
      bufferPointer = startInner;
    }
    if (i == endBlock)
      copyLength -= ((kAllocStep - 1) - endInner);

    wchar_t* pBlockBuf = m_BlockArray[i].get();
    memcpy(pBuf + pointer, pBlockBuf + bufferPointer,
           copyLength * sizeof(wchar_t));
    pointer += copyLength;
  }
  wsTextData.ReleaseBuffer(length);
  return wsTextData;
}

std::pair<size_t, size_t> CFX_BlockBuffer::TextDataIndex2BufIndex(
    const size_t iIndex) const {
  ASSERT(iIndex >= 0);

  size_t realIndex = m_StartPosition + iIndex;
  return {realIndex / kAllocStep, realIndex % kAllocStep};
}
