14d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann// Copyright 2014 PDFium Authors. All rights reserved.
24d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann// Use of this source code is governed by a BSD-style license that can be
34d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann// found in the LICENSE file.
44d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
54d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
64d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
74d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#include "xfa/fde/cfde_txtedtbuf.h"
84d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
94d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#include <algorithm>
104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#include <utility>
114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#include "third_party/base/ptr_util.h"
134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#include "third_party/base/stl_util.h"
144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannnamespace {
164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannconst int kDefaultChunkSize = 1024;
184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}  // namespace
204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. MoltmannCFDE_TxtEdtBuf::CFDE_TxtEdtBuf() : m_chunkSize(kDefaultChunkSize), m_nTotal(0) {
224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  m_chunks.push_back(NewChunk());
234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. MoltmannCFDE_TxtEdtBuf::~CFDE_TxtEdtBuf() {}
264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannint32_t CFDE_TxtEdtBuf::GetChunkSize() const {
284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  return m_chunkSize;
294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannint32_t CFDE_TxtEdtBuf::GetTextLength() const {
324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  return m_nTotal;
334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid CFDE_TxtEdtBuf::SetText(const CFX_WideString& wsText) {
364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  ASSERT(!wsText.IsEmpty());
374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  Clear(false);
394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  int32_t nTextLength = wsText.GetLength();
404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  int32_t nNeedCount =
414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      ((nTextLength - 1) / GetChunkSize() + 1) - m_chunks.size();
424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  int32_t i = 0;
434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  for (i = 0; i < nNeedCount; i++)
444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    m_chunks.push_back(NewChunk());
454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  int32_t nTotalCount = m_chunks.size();
474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  const FX_WCHAR* lpSrcBuf = wsText.c_str();
484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  int32_t nLeave = nTextLength;
494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  int32_t nCopyedLength = GetChunkSize();
504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  for (i = 0; i < nTotalCount && nLeave > 0; i++) {
514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    if (nLeave < nCopyedLength) {
524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      nCopyedLength = nLeave;
534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    }
544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    ChunkHeader* chunk = m_chunks[i].get();
564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    FXSYS_memcpy(chunk->wChars.get(), lpSrcBuf,
574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                 nCopyedLength * sizeof(FX_WCHAR));
584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    nLeave -= nCopyedLength;
594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    lpSrcBuf += nCopyedLength;
604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    chunk->nUsed = nCopyedLength;
614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  }
624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  m_nTotal = nTextLength;
634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. MoltmannCFX_WideString CFDE_TxtEdtBuf::GetText() const {
664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  return GetRange(0, m_nTotal);
674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. MoltmannFX_WCHAR CFDE_TxtEdtBuf::GetCharByIndex(int32_t nIndex) const {
704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  ASSERT(nIndex >= 0 && nIndex < GetTextLength());
714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  ChunkHeader* pChunkHeader = nullptr;
734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  int32_t nTotal = 0;
744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  for (const auto& chunk : m_chunks) {
754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    pChunkHeader = chunk.get();
764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    nTotal += pChunkHeader->nUsed;
774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    if (nTotal > nIndex)
784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      break;
794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  }
804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  ASSERT(pChunkHeader);
814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  FX_WCHAR* buf = pChunkHeader->wChars.get();
834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  return buf[pChunkHeader->nUsed - (nTotal - nIndex)];
844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. MoltmannCFX_WideString CFDE_TxtEdtBuf::GetRange(int32_t nBegin, int32_t nLength) const {
874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  if (nLength == 0 || GetTextLength() == 0)
884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    return CFX_WideString();
894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  ASSERT(nBegin >= 0 && nLength > 0 && nBegin < GetTextLength() &&
914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         nBegin + nLength <= GetTextLength());
924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  int32_t chunkIndex = 0;
944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  int32_t charIndex = 0;
954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  std::tie(chunkIndex, charIndex) = Index2CP(nBegin);
964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  int32_t nLeave = nLength;
984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  int32_t nCount = m_chunks.size();
994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
1004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  CFX_WideString wsText;
1014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  FX_WCHAR* lpDstBuf = wsText.GetBuffer(nLength);
1024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  int32_t nChunkIndex = chunkIndex;
1034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
1044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  ChunkHeader* chunkHeader = m_chunks[nChunkIndex].get();
1054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  int32_t nCopyLength = chunkHeader->nUsed - charIndex;
1064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  FX_WCHAR* lpSrcBuf = chunkHeader->wChars.get() + charIndex;
1074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  while (nLeave > 0) {
1084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    if (nLeave <= nCopyLength) {
1094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      nCopyLength = nLeave;
1104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    }
1114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    FXSYS_memcpy(lpDstBuf, lpSrcBuf, nCopyLength * sizeof(FX_WCHAR));
1124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    nChunkIndex++;
1134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    if (nChunkIndex >= nCount) {
1144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      break;
1154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    }
1164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    chunkHeader = m_chunks[nChunkIndex].get();
1174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    lpSrcBuf = chunkHeader->wChars.get();
1184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    nLeave -= nCopyLength;
1194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    lpDstBuf += nCopyLength;
1204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    nCopyLength = chunkHeader->nUsed;
1214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  }
1224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  wsText.ReleaseBuffer();
1234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
1244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  return wsText;
1254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
1264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
1274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid CFDE_TxtEdtBuf::Insert(int32_t nPos,
1284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                            const FX_WCHAR* lpText,
1294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                            int32_t nLength) {
1304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  ASSERT(nPos >= 0 && nPos <= m_nTotal);
1314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  ASSERT(nLength > 0);
1324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
1334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  int32_t chunkIndex = 0;
1344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  int32_t charIndex = 0;
1354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  std::tie(chunkIndex, charIndex) = Index2CP(nPos);
1364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
1374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  int32_t nLengthTemp = nLength;
1384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  if (charIndex != 0) {
1394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    auto newChunk = NewChunk();
1404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
1414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    ChunkHeader* chunk = m_chunks[chunkIndex].get();
1424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    int32_t nCopy = chunk->nUsed - charIndex;
1434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
1444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    FXSYS_memcpy(newChunk->wChars.get(), chunk->wChars.get() + charIndex,
1454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                 nCopy * sizeof(FX_WCHAR));
1464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    chunk->nUsed -= nCopy;
1474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    chunkIndex++;
1484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
1494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    newChunk->nUsed = nCopy;
1504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    m_chunks.insert(m_chunks.begin() + chunkIndex, std::move(newChunk));
1514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    charIndex = 0;
1524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  }
1534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
1544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  if (chunkIndex != 0) {
1554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    ChunkHeader* chunk = m_chunks[chunkIndex - 1].get();
1564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    if (chunk->nUsed != GetChunkSize()) {
1574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      chunkIndex--;
1584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      int32_t nFree = GetChunkSize() - chunk->nUsed;
1594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      int32_t nCopy = std::min(nLengthTemp, nFree);
1604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      FXSYS_memcpy(chunk->wChars.get() + chunk->nUsed, lpText,
1614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                   nCopy * sizeof(FX_WCHAR));
1624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      lpText += nCopy;
1634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      nLengthTemp -= nCopy;
1644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      chunk->nUsed += nCopy;
1654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      chunkIndex++;
1664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    }
1674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  }
1684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
1694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  while (nLengthTemp > 0) {
1704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    auto chunk = NewChunk();
1714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
1724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    int32_t nCopy = std::min(nLengthTemp, GetChunkSize());
1734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    FXSYS_memcpy(chunk->wChars.get(), lpText, nCopy * sizeof(FX_WCHAR));
1744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    lpText += nCopy;
1754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    nLengthTemp -= nCopy;
1764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    chunk->nUsed = nCopy;
1774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    m_chunks.insert(m_chunks.begin() + chunkIndex, std::move(chunk));
1784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    chunkIndex++;
1794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  }
1804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  m_nTotal += nLength;
1814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
1824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
1834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid CFDE_TxtEdtBuf::Delete(int32_t nIndex, int32_t nLength) {
1844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  ASSERT(nLength > 0 && nIndex >= 0 && nIndex + nLength <= m_nTotal);
1854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
1864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  int32_t endChunkIndex = 0;
1874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  int32_t endCharIndex = 0;
1884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  std::tie(endChunkIndex, endCharIndex) = Index2CP(nIndex + nLength - 1);
1894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  m_nTotal -= nLength;
1904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
1914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  ChunkHeader* chunk = m_chunks[endChunkIndex].get();
1924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  int32_t nFirstPart = endCharIndex + 1;
1934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  int32_t nMovePart = chunk->nUsed - nFirstPart;
1944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  if (nMovePart != 0) {
1954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    int32_t nDelete = std::min(nFirstPart, nLength);
1964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    FXSYS_memmove(chunk->wChars.get() + nFirstPart - nDelete,
1974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  chunk->wChars.get() + nFirstPart,
1984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  nMovePart * sizeof(FX_WCHAR));
1994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    chunk->nUsed -= nDelete;
2004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    nLength -= nDelete;
2014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    endChunkIndex--;
2024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  }
2034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
2044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  while (nLength > 0) {
2054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    ChunkHeader* curChunk = m_chunks[endChunkIndex].get();
2064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    int32_t nDeleted = std::min(curChunk->nUsed, nLength);
2074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    curChunk->nUsed -= nDeleted;
2084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    if (curChunk->nUsed == 0)
2094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      m_chunks.erase(m_chunks.begin() + endChunkIndex);
2104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
2114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    nLength -= nDeleted;
2124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    endChunkIndex--;
2134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  }
2144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
2154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
2164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid CFDE_TxtEdtBuf::Clear(bool bRelease) {
2174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  if (bRelease) {
2184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    m_chunks.clear();
2194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  } else {
2204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    size_t i = 0;
2214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    while (i < m_chunks.size())
2224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      m_chunks[i++]->nUsed = 0;
2234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  }
2244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  m_nTotal = 0;
2254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
2264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
2274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid CFDE_TxtEdtBuf::SetChunkSizeForTesting(size_t size) {
2284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  ASSERT(size > 0);
2294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
2304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  m_chunkSize = size;
2314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  m_chunks.clear();
2324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  m_chunks.push_back(NewChunk());
2334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
2344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
2354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstd::tuple<int32_t, int32_t> CFDE_TxtEdtBuf::Index2CP(int32_t nIndex) const {
2364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  ASSERT(nIndex <= GetTextLength());
2374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
2384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  if (nIndex == m_nTotal) {
2394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    return std::tuple<int32_t, int32_t>(m_chunks.size() - 1,
2404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                                        m_chunks.back()->nUsed);
2414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  }
2424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
2434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  int32_t chunkIndex = 0;
2444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  int32_t nTotal = 0;
2454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  for (auto& chunk : m_chunks) {
2464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    nTotal += chunk->nUsed;
2474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    if (nTotal > nIndex)
2484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      break;
2494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    chunkIndex++;
2504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  }
2514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
2524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  int32_t charIndex = m_chunks[chunkIndex]->nUsed - (nTotal - nIndex);
2534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  return std::tuple<int32_t, int32_t>(chunkIndex, charIndex);
2544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
2554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
2564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstd::unique_ptr<CFDE_TxtEdtBuf::ChunkHeader> CFDE_TxtEdtBuf::NewChunk() {
2574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  auto chunk = pdfium::MakeUnique<ChunkHeader>();
2584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  chunk->wChars.reset(FX_Alloc(FX_WCHAR, GetChunkSize()));
2594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  chunk->nUsed = 0;
2604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  return chunk;
2614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
2624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
2634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. MoltmannCFDE_TxtEdtBuf::ChunkHeader::ChunkHeader() {}
2644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
2654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. MoltmannCFDE_TxtEdtBuf::ChunkHeader::~ChunkHeader() {}
2664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
2674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. MoltmannCFDE_TxtEdtBuf::Iterator::Iterator(CFDE_TxtEdtBuf* pBuf, FX_WCHAR wcAlias)
2684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    : m_pBuf(pBuf),
2694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      m_nCurChunk(0),
2704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      m_nCurIndex(0),
2714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      m_nIndex(0),
2724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      m_Alias(wcAlias) {
2734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  ASSERT(m_pBuf);
2744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
2754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
2764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. MoltmannCFDE_TxtEdtBuf::Iterator::~Iterator() {}
2774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
2784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannbool CFDE_TxtEdtBuf::Iterator::Next(bool bPrev) {
2794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  if (bPrev) {
2804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    if (m_nIndex == 0)
2814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return false;
2824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
2834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    ASSERT(m_nCurChunk < pdfium::CollectionSize<int32_t>(m_pBuf->m_chunks));
2844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
2854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    ChunkHeader* chunk = nullptr;
2864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    if (m_nCurIndex > 0) {
2874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      m_nCurIndex--;
2884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    } else {
2894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      while (m_nCurChunk > 0) {
2904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        --m_nCurChunk;
2914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        chunk = m_pBuf->m_chunks[m_nCurChunk].get();
2924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        if (chunk->nUsed > 0) {
2934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          m_nCurIndex = chunk->nUsed - 1;
2944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          break;
2954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
2964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      }
2974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    }
2984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    ASSERT(m_nCurChunk >= 0);
2994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    m_nIndex--;
3004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    return true;
3014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  } else {
3024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    if (m_nIndex >= (m_pBuf->m_nTotal - 1))
3034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return false;
3044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
3054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    ASSERT(m_nCurChunk < pdfium::CollectionSize<int32_t>(m_pBuf->m_chunks));
3064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    if (m_pBuf->m_chunks[m_nCurChunk]->nUsed != (m_nCurIndex + 1)) {
3074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      m_nCurIndex++;
3084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    } else {
3094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      int32_t nEnd = m_pBuf->m_chunks.size() - 1;
3104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      while (m_nCurChunk < nEnd) {
3114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        m_nCurChunk++;
3124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        ChunkHeader* chunkTemp = m_pBuf->m_chunks[m_nCurChunk].get();
3134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        if (chunkTemp->nUsed > 0) {
3144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          m_nCurIndex = 0;
3154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          break;
3164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
3174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      }
3184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    }
3194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    m_nIndex++;
3204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    return true;
3214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  }
3224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
3234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
3244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid CFDE_TxtEdtBuf::Iterator::SetAt(int32_t nIndex) {
3254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  ASSERT(nIndex >= 0 && nIndex < m_pBuf->m_nTotal);
3264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
3274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  std::tie(m_nCurChunk, m_nCurIndex) = m_pBuf->Index2CP(nIndex);
3284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  m_nIndex = nIndex;
3294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
3304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
3314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannint32_t CFDE_TxtEdtBuf::Iterator::GetAt() const {
3324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  return m_nIndex;
3334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
3344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
3354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. MoltmannFX_WCHAR CFDE_TxtEdtBuf::Iterator::GetChar() {
3364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  ASSERT(m_nIndex >= 0 && m_nIndex < m_pBuf->m_nTotal);
3374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  if (m_Alias == 0 || m_nIndex == (m_pBuf->m_nTotal - 1)) {
3384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    FX_WCHAR* buf = m_pBuf->m_chunks[m_nCurChunk]->wChars.get();
3394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    return buf[m_nCurIndex];
3404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  }
3414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  return m_Alias;
3424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
3434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
3444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannbool CFDE_TxtEdtBuf::Iterator::IsEOF(bool bTail) const {
3454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  return bTail ? m_nIndex == (m_pBuf->GetTextLength() - 2) : m_nIndex == 0;
3464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
3474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
3484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. MoltmannIFX_CharIter* CFDE_TxtEdtBuf::Iterator::Clone() {
3494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  CFDE_TxtEdtBuf::Iterator* pIter = new CFDE_TxtEdtBuf::Iterator(m_pBuf);
3504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  pIter->m_nCurChunk = m_nCurChunk;
3514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  pIter->m_nCurIndex = m_nCurIndex;
3524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  pIter->m_nIndex = m_nIndex;
3534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  pIter->m_Alias = m_Alias;
3544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  return pIter;
3554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
356