summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--BUILD.gn2
-rw-r--r--xfa/fde/cfde_txtedtbuf.cpp356
-rw-r--r--xfa/fde/cfde_txtedtbuf.h56
-rw-r--r--xfa/fde/cfde_txtedtbuf_unittest.cpp2
-rw-r--r--xfa/fde/cfde_txtedtbufiter.cpp100
-rw-r--r--xfa/fde/cfde_txtedtbufiter.h35
-rw-r--r--xfa/fde/cfde_txtedtengine.cpp6
-rw-r--r--xfa/fde/cfde_txtedtpage.cpp7
-rw-r--r--xfa/fde/cfde_txtedtparag.cpp7
9 files changed, 263 insertions, 308 deletions
diff --git a/BUILD.gn b/BUILD.gn
index 73d0494cf6..221ff36243 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -1118,8 +1118,6 @@ if (pdf_enable_xfa) {
"xfa/fde/cfde_path.h",
"xfa/fde/cfde_txtedtbuf.cpp",
"xfa/fde/cfde_txtedtbuf.h",
- "xfa/fde/cfde_txtedtbufiter.cpp",
- "xfa/fde/cfde_txtedtbufiter.h",
"xfa/fde/cfde_txtedtdorecord_deleterange.cpp",
"xfa/fde/cfde_txtedtdorecord_deleterange.h",
"xfa/fde/cfde_txtedtdorecord_insert.cpp",
diff --git a/xfa/fde/cfde_txtedtbuf.cpp b/xfa/fde/cfde_txtedtbuf.cpp
index 36fc47e492..9bb16f6076 100644
--- a/xfa/fde/cfde_txtedtbuf.cpp
+++ b/xfa/fde/cfde_txtedtbuf.cpp
@@ -7,28 +7,26 @@
#include "xfa/fde/cfde_txtedtbuf.h"
#include <algorithm>
+#include <utility>
+#include "third_party/base/ptr_util.h"
+#include "third_party/base/stl_util.h"
#include "xfa/fgas/crt/fgas_memory.h"
namespace {
const int kDefaultChunkSize = 1024;
-const int kDefaultChunkCount = 2;
} // namespace
-CFDE_TxtEdtBuf::CFDE_TxtEdtBuf()
- : m_nChunkSize(kDefaultChunkSize), m_nTotal(0), m_bChanged(false) {
- ResetChunkBuffer(kDefaultChunkCount, m_nChunkSize);
+CFDE_TxtEdtBuf::CFDE_TxtEdtBuf() : m_chunkSize(kDefaultChunkSize), m_nTotal(0) {
+ m_chunks.push_back(NewChunk());
}
-CFDE_TxtEdtBuf::~CFDE_TxtEdtBuf() {
- Clear(true);
- m_Chunks.RemoveAll();
-}
+CFDE_TxtEdtBuf::~CFDE_TxtEdtBuf() {}
int32_t CFDE_TxtEdtBuf::GetChunkSize() const {
- return m_nChunkSize;
+ return m_chunkSize;
}
int32_t CFDE_TxtEdtBuf::GetTextLength() const {
@@ -41,31 +39,28 @@ void CFDE_TxtEdtBuf::SetText(const CFX_WideString& wsText) {
Clear(false);
int32_t nTextLength = wsText.GetLength();
int32_t nNeedCount =
- ((nTextLength - 1) / m_nChunkSize + 1) - m_Chunks.GetSize();
+ ((nTextLength - 1) / GetChunkSize() + 1) - m_chunks.size();
int32_t i = 0;
- for (i = 0; i < nNeedCount; i++) {
- FDE_CHUNKHEADER* lpChunk =
- static_cast<FDE_CHUNKHEADER*>(m_pAllocator->Alloc(
- sizeof(FDE_CHUNKHEADER) + (m_nChunkSize - 1) * sizeof(FX_WCHAR)));
- lpChunk->nUsed = 0;
- m_Chunks.Add(lpChunk);
- }
- int32_t nTotalCount = m_Chunks.GetSize();
+ for (i = 0; i < nNeedCount; i++)
+ m_chunks.push_back(NewChunk());
+
+ int32_t nTotalCount = m_chunks.size();
const FX_WCHAR* lpSrcBuf = wsText.c_str();
int32_t nLeave = nTextLength;
- int32_t nCopyedLength = m_nChunkSize;
+ int32_t nCopyedLength = GetChunkSize();
for (i = 0; i < nTotalCount && nLeave > 0; i++) {
if (nLeave < nCopyedLength) {
nCopyedLength = nLeave;
}
- FDE_CHUNKHEADER* lpChunk = m_Chunks[i];
- FXSYS_memcpy(lpChunk->wChars, lpSrcBuf, nCopyedLength * sizeof(FX_WCHAR));
+
+ ChunkHeader* chunk = m_chunks[i].get();
+ FXSYS_memcpy(chunk->wChars.get(), lpSrcBuf,
+ nCopyedLength * sizeof(FX_WCHAR));
nLeave -= nCopyedLength;
lpSrcBuf += nCopyedLength;
- lpChunk->nUsed = nCopyedLength;
+ chunk->nUsed = nCopyedLength;
}
m_nTotal = nTextLength;
- m_bChanged = true;
}
CFX_WideString CFDE_TxtEdtBuf::GetText() const {
@@ -74,19 +69,19 @@ CFX_WideString CFDE_TxtEdtBuf::GetText() const {
FX_WCHAR CFDE_TxtEdtBuf::GetCharByIndex(int32_t nIndex) const {
ASSERT(nIndex >= 0 && nIndex < GetTextLength());
- FDE_CHUNKHEADER* pChunkHeader = nullptr;
+
+ ChunkHeader* pChunkHeader = nullptr;
int32_t nTotal = 0;
- int32_t nCount = m_Chunks.GetSize();
- int32_t i = 0;
- for (i = 0; i < nCount; i++) {
- pChunkHeader = m_Chunks[i];
+ for (const auto& chunk : m_chunks) {
+ pChunkHeader = chunk.get();
nTotal += pChunkHeader->nUsed;
- if (nTotal > nIndex) {
+ if (nTotal > nIndex)
break;
- }
}
ASSERT(pChunkHeader);
- return pChunkHeader->wChars[pChunkHeader->nUsed - (nTotal - nIndex)];
+
+ FX_WCHAR* buf = pChunkHeader->wChars.get();
+ return buf[pChunkHeader->nUsed - (nTotal - nIndex)];
}
CFX_WideString CFDE_TxtEdtBuf::GetRange(int32_t nBegin, int32_t nLength) const {
@@ -96,17 +91,20 @@ CFX_WideString CFDE_TxtEdtBuf::GetRange(int32_t nBegin, int32_t nLength) const {
ASSERT(nBegin >= 0 && nLength > 0 && nBegin < GetTextLength() &&
nBegin + nLength <= GetTextLength());
- FDE_CHUNKPLACE cp;
- Index2CP(nBegin, cp);
+ int32_t chunkIndex = 0;
+ int32_t charIndex = 0;
+ std::tie(chunkIndex, charIndex) = Index2CP(nBegin);
+
int32_t nLeave = nLength;
- int32_t nCount = m_Chunks.GetSize();
+ int32_t nCount = m_chunks.size();
CFX_WideString wsText;
FX_WCHAR* lpDstBuf = wsText.GetBuffer(nLength);
- int32_t nChunkIndex = cp.nChunkIndex;
- FDE_CHUNKHEADER* lpChunkHeader = m_Chunks[nChunkIndex];
- int32_t nCopyLength = lpChunkHeader->nUsed - cp.nCharIndex;
- FX_WCHAR* lpSrcBuf = lpChunkHeader->wChars + cp.nCharIndex;
+ int32_t nChunkIndex = chunkIndex;
+
+ ChunkHeader* chunkHeader = m_chunks[nChunkIndex].get();
+ int32_t nCopyLength = chunkHeader->nUsed - charIndex;
+ FX_WCHAR* lpSrcBuf = chunkHeader->wChars.get() + charIndex;
while (nLeave > 0) {
if (nLeave <= nCopyLength) {
nCopyLength = nLeave;
@@ -116,11 +114,11 @@ CFX_WideString CFDE_TxtEdtBuf::GetRange(int32_t nBegin, int32_t nLength) const {
if (nChunkIndex >= nCount) {
break;
}
- lpChunkHeader = m_Chunks[nChunkIndex];
- lpSrcBuf = lpChunkHeader->wChars;
+ chunkHeader = m_chunks[nChunkIndex].get();
+ lpSrcBuf = chunkHeader->wChars.get();
nLeave -= nCopyLength;
lpDstBuf += nCopyLength;
- nCopyLength = lpChunkHeader->nUsed;
+ nCopyLength = chunkHeader->nUsed;
}
wsText.ReleaseBuffer();
@@ -133,150 +131,226 @@ void CFDE_TxtEdtBuf::Insert(int32_t nPos,
ASSERT(nPos >= 0 && nPos <= m_nTotal);
ASSERT(nLength > 0);
- FDE_CHUNKPLACE cp;
- Index2CP(nPos, cp);
+ int32_t chunkIndex = 0;
+ int32_t charIndex = 0;
+ std::tie(chunkIndex, charIndex) = Index2CP(nPos);
+
int32_t nLengthTemp = nLength;
- if (cp.nCharIndex != 0) {
- FDE_CHUNKHEADER* lpNewChunk =
- static_cast<FDE_CHUNKHEADER*>(m_pAllocator->Alloc(
- sizeof(FDE_CHUNKHEADER) + (m_nChunkSize - 1) * sizeof(FX_WCHAR)));
- FDE_CHUNKHEADER* lpChunk = m_Chunks[cp.nChunkIndex];
- int32_t nCopy = lpChunk->nUsed - cp.nCharIndex;
- FXSYS_memcpy(lpNewChunk->wChars, lpChunk->wChars + cp.nCharIndex,
+ if (charIndex != 0) {
+ auto newChunk = NewChunk();
+
+ ChunkHeader* chunk = m_chunks[chunkIndex].get();
+ int32_t nCopy = chunk->nUsed - charIndex;
+
+ FXSYS_memcpy(newChunk->wChars.get(), chunk->wChars.get() + charIndex,
nCopy * sizeof(FX_WCHAR));
- lpChunk->nUsed -= nCopy;
- cp.nChunkIndex++;
- m_Chunks.InsertAt(cp.nChunkIndex, lpNewChunk);
- lpNewChunk->nUsed = nCopy;
- cp.nCharIndex = 0;
+ chunk->nUsed -= nCopy;
+ chunkIndex++;
+
+ newChunk->nUsed = nCopy;
+ m_chunks.insert(m_chunks.begin() + chunkIndex, std::move(newChunk));
+ charIndex = 0;
}
- if (cp.nChunkIndex != 0) {
- FDE_CHUNKHEADER* lpChunk = m_Chunks[cp.nChunkIndex - 1];
- if (lpChunk->nUsed != m_nChunkSize) {
- cp.nChunkIndex--;
- int32_t nFree = m_nChunkSize - lpChunk->nUsed;
+
+ if (chunkIndex != 0) {
+ ChunkHeader* chunk = m_chunks[chunkIndex - 1].get();
+ if (chunk->nUsed != GetChunkSize()) {
+ chunkIndex--;
+ int32_t nFree = GetChunkSize() - chunk->nUsed;
int32_t nCopy = std::min(nLengthTemp, nFree);
- FXSYS_memcpy(lpChunk->wChars + lpChunk->nUsed, lpText,
+ FXSYS_memcpy(chunk->wChars.get() + chunk->nUsed, lpText,
nCopy * sizeof(FX_WCHAR));
lpText += nCopy;
nLengthTemp -= nCopy;
- lpChunk->nUsed += nCopy;
- cp.nChunkIndex++;
+ chunk->nUsed += nCopy;
+ chunkIndex++;
}
}
+
while (nLengthTemp > 0) {
- FDE_CHUNKHEADER* lpChunk =
- static_cast<FDE_CHUNKHEADER*>(m_pAllocator->Alloc(
- sizeof(FDE_CHUNKHEADER) + (m_nChunkSize - 1) * sizeof(FX_WCHAR)));
- ASSERT(lpChunk);
- int32_t nCopy = std::min(nLengthTemp, m_nChunkSize);
- FXSYS_memcpy(lpChunk->wChars, lpText, nCopy * sizeof(FX_WCHAR));
+ auto chunk = NewChunk();
+
+ int32_t nCopy = std::min(nLengthTemp, GetChunkSize());
+ FXSYS_memcpy(chunk->wChars.get(), lpText, nCopy * sizeof(FX_WCHAR));
lpText += nCopy;
nLengthTemp -= nCopy;
- lpChunk->nUsed = nCopy;
- m_Chunks.InsertAt(cp.nChunkIndex, lpChunk);
- cp.nChunkIndex++;
+ chunk->nUsed = nCopy;
+ m_chunks.insert(m_chunks.begin() + chunkIndex, std::move(chunk));
+ chunkIndex++;
}
m_nTotal += nLength;
- m_bChanged = true;
}
void CFDE_TxtEdtBuf::Delete(int32_t nIndex, int32_t nLength) {
ASSERT(nLength > 0 && nIndex >= 0 && nIndex + nLength <= m_nTotal);
- FDE_CHUNKPLACE cpEnd;
- Index2CP(nIndex + nLength - 1, cpEnd);
+
+ int32_t endChunkIndex = 0;
+ int32_t endCharIndex = 0;
+ std::tie(endChunkIndex, endCharIndex) = Index2CP(nIndex + nLength - 1);
m_nTotal -= nLength;
- FDE_CHUNKHEADER* lpChunk = m_Chunks[cpEnd.nChunkIndex];
- int32_t nFirstPart = cpEnd.nCharIndex + 1;
- int32_t nMovePart = lpChunk->nUsed - nFirstPart;
+
+ ChunkHeader* chunk = m_chunks[endChunkIndex].get();
+ int32_t nFirstPart = endCharIndex + 1;
+ int32_t nMovePart = chunk->nUsed - nFirstPart;
if (nMovePart != 0) {
int32_t nDelete = std::min(nFirstPart, nLength);
- FXSYS_memmove(lpChunk->wChars + nFirstPart - nDelete,
- lpChunk->wChars + nFirstPart, nMovePart * sizeof(FX_WCHAR));
- lpChunk->nUsed -= nDelete;
+ FXSYS_memmove(chunk->wChars.get() + nFirstPart - nDelete,
+ chunk->wChars.get() + nFirstPart,
+ nMovePart * sizeof(FX_WCHAR));
+ chunk->nUsed -= nDelete;
nLength -= nDelete;
- cpEnd.nChunkIndex--;
+ endChunkIndex--;
}
+
while (nLength > 0) {
- lpChunk = m_Chunks[cpEnd.nChunkIndex];
- int32_t nDeleted = std::min(lpChunk->nUsed, nLength);
- lpChunk->nUsed -= nDeleted;
- if (lpChunk->nUsed == 0) {
- m_pAllocator->Free(lpChunk);
- m_Chunks.RemoveAt(cpEnd.nChunkIndex);
- lpChunk = nullptr;
- }
+ ChunkHeader* curChunk = m_chunks[endChunkIndex].get();
+ int32_t nDeleted = std::min(curChunk->nUsed, nLength);
+ curChunk->nUsed -= nDeleted;
+ if (curChunk->nUsed == 0)
+ m_chunks.erase(m_chunks.begin() + endChunkIndex);
+
nLength -= nDeleted;
- cpEnd.nChunkIndex--;
+ endChunkIndex--;
}
- m_bChanged = true;
}
void CFDE_TxtEdtBuf::Clear(bool bRelease) {
- int32_t i = 0;
- int32_t nCount = m_Chunks.GetSize();
if (bRelease) {
- while (i < nCount) {
- m_pAllocator->Free(m_Chunks[i++]);
- }
- m_Chunks.RemoveAll();
+ m_chunks.clear();
} else {
- while (i < nCount) {
- m_Chunks[i++]->nUsed = 0;
- }
+ size_t i = 0;
+ while (i < m_chunks.size())
+ m_chunks[i++]->nUsed = 0;
}
m_nTotal = 0;
- m_bChanged = true;
-}
-
-void CFDE_TxtEdtBuf::ResetChunkBuffer(int32_t nDefChunkCount,
- int32_t nChunkSize) {
- ASSERT(nChunkSize);
- ASSERT(nDefChunkCount);
- m_Chunks.RemoveAll();
- m_nChunkSize = nChunkSize;
- int32_t nChunkLength =
- sizeof(FDE_CHUNKHEADER) + (m_nChunkSize - 1) * sizeof(FX_WCHAR);
- m_pAllocator = IFX_MemoryAllocator::Create(FX_ALLOCTYPE_Fixed, nDefChunkCount,
- nChunkLength);
- FDE_CHUNKHEADER* lpChunkHeader =
- static_cast<FDE_CHUNKHEADER*>(m_pAllocator->Alloc(nChunkLength));
- ASSERT(lpChunkHeader);
- lpChunkHeader->nUsed = 0;
- m_Chunks.Add(lpChunkHeader);
- m_nTotal = 0;
}
void CFDE_TxtEdtBuf::SetChunkSizeForTesting(size_t size) {
- Clear(true);
- ResetChunkBuffer(kDefaultChunkCount, size);
-}
+ ASSERT(size > 0);
-int32_t CFDE_TxtEdtBuf::CP2Index(const FDE_CHUNKPLACE& cp) const {
- int32_t nTotal = cp.nCharIndex;
- int32_t i = 0;
- for (i = 0; i < cp.nChunkIndex; i++) {
- nTotal += m_Chunks[i]->nUsed;
- }
- return nTotal;
+ m_chunkSize = size;
+ m_chunks.clear();
+ m_chunks.push_back(NewChunk());
}
-void CFDE_TxtEdtBuf::Index2CP(int32_t nIndex, FDE_CHUNKPLACE& cp) const {
+std::tuple<int32_t, int32_t> CFDE_TxtEdtBuf::Index2CP(int32_t nIndex) const {
ASSERT(nIndex <= GetTextLength());
+
if (nIndex == m_nTotal) {
- cp.nChunkIndex = m_Chunks.GetSize() - 1;
- cp.nCharIndex = m_Chunks[cp.nChunkIndex]->nUsed;
- return;
+ return std::tuple<int32_t, int32_t>(m_chunks.size() - 1,
+ m_chunks.back()->nUsed);
}
- int32_t i = 0;
+
+ int32_t chunkIndex = 0;
int32_t nTotal = 0;
- int32_t nCount = m_Chunks.GetSize();
- for (; i < nCount; i++) {
- nTotal += m_Chunks[i]->nUsed;
- if (nTotal > nIndex) {
+ for (auto& chunk : m_chunks) {
+ nTotal += chunk->nUsed;
+ if (nTotal > nIndex)
break;
+ chunkIndex++;
+ }
+
+ int32_t charIndex = m_chunks[chunkIndex]->nUsed - (nTotal - nIndex);
+ return std::tuple<int32_t, int32_t>(chunkIndex, charIndex);
+}
+
+std::unique_ptr<CFDE_TxtEdtBuf::ChunkHeader> CFDE_TxtEdtBuf::NewChunk() {
+ auto chunk = pdfium::MakeUnique<ChunkHeader>();
+ chunk->wChars.reset(FX_Alloc(FX_WCHAR, GetChunkSize()));
+ chunk->nUsed = 0;
+ return chunk;
+}
+
+CFDE_TxtEdtBuf::ChunkHeader::ChunkHeader() {}
+
+CFDE_TxtEdtBuf::ChunkHeader::~ChunkHeader() {}
+
+CFDE_TxtEdtBuf::Iterator::Iterator(CFDE_TxtEdtBuf* pBuf, FX_WCHAR wcAlias)
+ : m_pBuf(pBuf),
+ m_nCurChunk(0),
+ m_nCurIndex(0),
+ m_nIndex(0),
+ m_Alias(wcAlias) {
+ ASSERT(m_pBuf);
+}
+
+CFDE_TxtEdtBuf::Iterator::~Iterator() {}
+
+bool CFDE_TxtEdtBuf::Iterator::Next(bool bPrev) {
+ if (bPrev) {
+ if (m_nIndex == 0)
+ return false;
+
+ ASSERT(m_nCurChunk < pdfium::CollectionSize<int32_t>(m_pBuf->m_chunks));
+
+ ChunkHeader* chunk = nullptr;
+ if (m_nCurIndex > 0) {
+ m_nCurIndex--;
+ } else {
+ while (m_nCurChunk > 0) {
+ --m_nCurChunk;
+ chunk = m_pBuf->m_chunks[m_nCurChunk].get();
+ if (chunk->nUsed > 0) {
+ m_nCurIndex = chunk->nUsed - 1;
+ break;
+ }
+ }
}
+ ASSERT(m_nCurChunk >= 0);
+ m_nIndex--;
+ return true;
+ } else {
+ if (m_nIndex >= (m_pBuf->m_nTotal - 1))
+ return false;
+
+ ASSERT(m_nCurChunk < pdfium::CollectionSize<int32_t>(m_pBuf->m_chunks));
+ if (m_pBuf->m_chunks[m_nCurChunk]->nUsed != (m_nCurIndex + 1)) {
+ m_nCurIndex++;
+ } else {
+ int32_t nEnd = m_pBuf->m_chunks.size() - 1;
+ while (m_nCurChunk < nEnd) {
+ m_nCurChunk++;
+ ChunkHeader* chunkTemp = m_pBuf->m_chunks[m_nCurChunk].get();
+ if (chunkTemp->nUsed > 0) {
+ m_nCurIndex = 0;
+ break;
+ }
+ }
+ }
+ m_nIndex++;
+ return true;
}
- cp.nChunkIndex = i;
- cp.nCharIndex = m_Chunks[i]->nUsed - (nTotal - nIndex);
+}
+
+void CFDE_TxtEdtBuf::Iterator::SetAt(int32_t nIndex) {
+ ASSERT(nIndex >= 0 && nIndex < m_pBuf->m_nTotal);
+
+ std::tie(m_nCurChunk, m_nCurIndex) = m_pBuf->Index2CP(nIndex);
+ m_nIndex = nIndex;
+}
+
+int32_t CFDE_TxtEdtBuf::Iterator::GetAt() const {
+ return m_nIndex;
+}
+
+FX_WCHAR CFDE_TxtEdtBuf::Iterator::GetChar() {
+ ASSERT(m_nIndex >= 0 && m_nIndex < m_pBuf->m_nTotal);
+ if (m_Alias == 0 || m_nIndex == (m_pBuf->m_nTotal - 1)) {
+ FX_WCHAR* buf = m_pBuf->m_chunks[m_nCurChunk]->wChars.get();
+ return buf[m_nCurIndex];
+ }
+ return m_Alias;
+}
+
+bool CFDE_TxtEdtBuf::Iterator::IsEOF(bool bTail) const {
+ return bTail ? m_nIndex == (m_pBuf->GetTextLength() - 2) : m_nIndex == 0;
+}
+
+IFX_CharIter* CFDE_TxtEdtBuf::Iterator::Clone() {
+ CFDE_TxtEdtBuf::Iterator* pIter = new CFDE_TxtEdtBuf::Iterator(m_pBuf);
+ pIter->m_nCurChunk = m_nCurChunk;
+ pIter->m_nCurIndex = m_nCurIndex;
+ pIter->m_nIndex = m_nIndex;
+ pIter->m_Alias = m_Alias;
+ return pIter;
}
diff --git a/xfa/fde/cfde_txtedtbuf.h b/xfa/fde/cfde_txtedtbuf.h
index 63edbf6167..9eeee5632e 100644
--- a/xfa/fde/cfde_txtedtbuf.h
+++ b/xfa/fde/cfde_txtedtbuf.h
@@ -8,22 +8,48 @@
#define XFA_FDE_CFDE_TXTEDTBUF_H_
#include <memory>
+#include <tuple>
+#include <vector>
#include "core/fxcrt/fx_basic.h"
#include "core/fxcrt/fx_system.h"
+#include "xfa/fde/ifx_chariter.h"
-class IFX_MemoryAllocator;
class IFX_Pause;
class CFDE_TxtEdtBuf {
public:
+ class Iterator : public IFX_CharIter {
+ public:
+ explicit Iterator(CFDE_TxtEdtBuf* pBuf, FX_WCHAR wcAlias = 0);
+ ~Iterator() override;
+
+ bool Next(bool bPrev = false) override;
+ FX_WCHAR GetChar() override;
+
+ void SetAt(int32_t nIndex) override;
+ int32_t GetAt() const override;
+
+ bool IsEOF(bool bTail = true) const override;
+ IFX_CharIter* Clone() override;
+
+ private:
+ CFDE_TxtEdtBuf* m_pBuf;
+ int32_t m_nCurChunk;
+ int32_t m_nCurIndex;
+ int32_t m_nIndex;
+ FX_WCHAR m_Alias;
+ };
+
CFDE_TxtEdtBuf();
~CFDE_TxtEdtBuf();
int32_t GetChunkSize() const;
int32_t GetTextLength() const;
+
void SetText(const CFX_WideString& wsText);
CFX_WideString GetText() const;
+
FX_WCHAR GetCharByIndex(int32_t nIndex) const;
CFX_WideString GetRange(int32_t nBegin, int32_t nCount) const;
@@ -32,31 +58,25 @@ class CFDE_TxtEdtBuf {
void Clear(bool bRelease);
private:
- friend class CFDE_TxtEdtBufIter;
+ friend class Iterator;
friend class CFDE_TxtEdtBufTest;
- struct FDE_CHUNKHEADER {
- int32_t nUsed;
- FX_WCHAR wChars[1];
- };
+ class ChunkHeader {
+ public:
+ ChunkHeader();
+ ~ChunkHeader();
- struct FDE_CHUNKPLACE {
- int32_t nChunkIndex;
- int32_t nCharIndex;
+ int32_t nUsed;
+ std::unique_ptr<FX_WCHAR, FxFreeDeleter> wChars;
};
- void ResetChunkBuffer(int32_t nDefChunkCount, int32_t nChunkSize);
- int32_t CP2Index(const FDE_CHUNKPLACE& cp) const;
- void Index2CP(int32_t nIndex, FDE_CHUNKPLACE& cp) const;
-
void SetChunkSizeForTesting(size_t size);
+ std::tuple<int32_t, int32_t> Index2CP(int32_t nIndex) const;
+ std::unique_ptr<ChunkHeader> NewChunk();
- int32_t m_nChunkSize;
-
+ size_t m_chunkSize;
int32_t m_nTotal;
- bool m_bChanged;
- CFX_ArrayTemplate<FDE_CHUNKHEADER*> m_Chunks;
- std::unique_ptr<IFX_MemoryAllocator> m_pAllocator;
+ std::vector<std::unique_ptr<ChunkHeader>> m_chunks;
};
#endif // XFA_FDE_CFDE_TXTEDTBUF_H_
diff --git a/xfa/fde/cfde_txtedtbuf_unittest.cpp b/xfa/fde/cfde_txtedtbuf_unittest.cpp
index 7228b2ad03..9c564093e5 100644
--- a/xfa/fde/cfde_txtedtbuf_unittest.cpp
+++ b/xfa/fde/cfde_txtedtbuf_unittest.cpp
@@ -14,7 +14,7 @@ class CFDE_TxtEdtBufTest : public testing::Test {
buf_ = pdfium::MakeUnique<CFDE_TxtEdtBuf>();
buf_->SetChunkSizeForTesting(5);
}
- size_t ChunkCount() const { return buf_->m_Chunks.GetSize(); }
+ size_t ChunkCount() const { return buf_->m_chunks.size(); }
std::unique_ptr<CFDE_TxtEdtBuf> buf_;
};
diff --git a/xfa/fde/cfde_txtedtbufiter.cpp b/xfa/fde/cfde_txtedtbufiter.cpp
deleted file mode 100644
index e4544a3891..0000000000
--- a/xfa/fde/cfde_txtedtbufiter.cpp
+++ /dev/null
@@ -1,100 +0,0 @@
-// Copyright 2016 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 "xfa/fde/cfde_txtedtbufiter.h"
-
-#include "xfa/fde/cfde_txtedtbuf.h"
-
-CFDE_TxtEdtBufIter::CFDE_TxtEdtBufIter(CFDE_TxtEdtBuf* pBuf, FX_WCHAR wcAlias)
- : m_pBuf(pBuf),
- m_nCurChunk(0),
- m_nCurIndex(0),
- m_nIndex(0),
- m_Alias(wcAlias) {
- ASSERT(m_pBuf);
-}
-
-CFDE_TxtEdtBufIter::~CFDE_TxtEdtBufIter() {}
-
-bool CFDE_TxtEdtBufIter::Next(bool bPrev) {
- if (bPrev) {
- if (m_nIndex == 0) {
- return false;
- }
- ASSERT(m_nCurChunk < m_pBuf->m_Chunks.GetSize());
- CFDE_TxtEdtBuf::FDE_CHUNKHEADER* lpChunk = nullptr;
- if (m_nCurIndex > 0) {
- m_nCurIndex--;
- } else {
- while (m_nCurChunk > 0) {
- --m_nCurChunk;
- lpChunk = m_pBuf->m_Chunks[m_nCurChunk];
- if (lpChunk->nUsed > 0) {
- m_nCurIndex = lpChunk->nUsed - 1;
- break;
- }
- }
- }
- ASSERT(m_nCurChunk >= 0);
- m_nIndex--;
- return true;
- } else {
- if (m_nIndex >= (m_pBuf->m_nTotal - 1)) {
- return false;
- }
- ASSERT(m_nCurChunk < m_pBuf->m_Chunks.GetSize());
- CFDE_TxtEdtBuf::FDE_CHUNKHEADER* lpChunk = m_pBuf->m_Chunks[m_nCurChunk];
- if (lpChunk->nUsed != (m_nCurIndex + 1)) {
- m_nCurIndex++;
- } else {
- int32_t nEnd = m_pBuf->m_Chunks.GetSize() - 1;
- while (m_nCurChunk < nEnd) {
- m_nCurChunk++;
- CFDE_TxtEdtBuf::FDE_CHUNKHEADER* lpChunkTemp =
- m_pBuf->m_Chunks[m_nCurChunk];
- if (lpChunkTemp->nUsed > 0) {
- m_nCurIndex = 0;
- break;
- }
- }
- }
- m_nIndex++;
- return true;
- }
-}
-
-void CFDE_TxtEdtBufIter::SetAt(int32_t nIndex) {
- ASSERT(nIndex >= 0 && nIndex < m_pBuf->m_nTotal);
- CFDE_TxtEdtBuf::FDE_CHUNKPLACE cp;
- m_pBuf->Index2CP(nIndex, cp);
- m_nIndex = nIndex;
- m_nCurChunk = cp.nChunkIndex;
- m_nCurIndex = cp.nCharIndex;
-}
-
-int32_t CFDE_TxtEdtBufIter::GetAt() const {
- return m_nIndex;
-}
-
-FX_WCHAR CFDE_TxtEdtBufIter::GetChar() {
- ASSERT(m_nIndex >= 0 && m_nIndex < m_pBuf->m_nTotal);
- if (m_Alias == 0 || m_nIndex == (m_pBuf->m_nTotal - 1))
- return m_pBuf->m_Chunks[m_nCurChunk]->wChars[m_nCurIndex];
- return m_Alias;
-}
-
-bool CFDE_TxtEdtBufIter::IsEOF(bool bTail) const {
- return bTail ? m_nIndex == (m_pBuf->GetTextLength() - 2) : m_nIndex == 0;
-}
-
-IFX_CharIter* CFDE_TxtEdtBufIter::Clone() {
- CFDE_TxtEdtBufIter* pIter = new CFDE_TxtEdtBufIter(m_pBuf);
- pIter->m_nCurChunk = m_nCurChunk;
- pIter->m_nCurIndex = m_nCurIndex;
- pIter->m_nIndex = m_nIndex;
- pIter->m_Alias = m_Alias;
- return pIter;
-}
diff --git a/xfa/fde/cfde_txtedtbufiter.h b/xfa/fde/cfde_txtedtbufiter.h
deleted file mode 100644
index c536aafc82..0000000000
--- a/xfa/fde/cfde_txtedtbufiter.h
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2016 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 XFA_FDE_CFDE_TXTEDTBUFITER_H_
-#define XFA_FDE_CFDE_TXTEDTBUFITER_H_
-
-#include "core/fxcrt/fx_system.h"
-#include "xfa/fde/ifx_chariter.h"
-
-class CFDE_TxtEdtBuf;
-
-class CFDE_TxtEdtBufIter : public IFX_CharIter {
- public:
- explicit CFDE_TxtEdtBufIter(CFDE_TxtEdtBuf* pBuf, FX_WCHAR wcAlias = 0);
- ~CFDE_TxtEdtBufIter() override;
-
- bool Next(bool bPrev = false) override;
- FX_WCHAR GetChar() override;
- void SetAt(int32_t nIndex) override;
- int32_t GetAt() const override;
- bool IsEOF(bool bTail = true) const override;
- IFX_CharIter* Clone() override;
-
- private:
- CFDE_TxtEdtBuf* m_pBuf;
- int32_t m_nCurChunk;
- int32_t m_nCurIndex;
- int32_t m_nIndex;
- FX_WCHAR m_Alias;
-};
-
-#endif // XFA_FDE_CFDE_TXTEDTBUFITER_H_
diff --git a/xfa/fde/cfde_txtedtengine.cpp b/xfa/fde/cfde_txtedtengine.cpp
index 555df20b99..8bb944712a 100644
--- a/xfa/fde/cfde_txtedtengine.cpp
+++ b/xfa/fde/cfde_txtedtengine.cpp
@@ -10,7 +10,6 @@
#include "third_party/base/ptr_util.h"
#include "xfa/fde/cfde_txtedtbuf.h"
-#include "xfa/fde/cfde_txtedtbufiter.h"
#include "xfa/fde/cfde_txtedtdorecord_deleterange.h"
#include "xfa/fde/cfde_txtedtdorecord_insert.h"
#include "xfa/fde/cfde_txtedtpage.h"
@@ -706,7 +705,7 @@ CFDE_TxtEdtParag* CFDE_TxtEdtEngine::GetParag(int32_t nParagIndex) const {
IFX_CharIter* CFDE_TxtEdtEngine::CreateCharIter() {
if (!m_pTxtBuf)
return nullptr;
- return new CFDE_TxtEdtBufIter(m_pTxtBuf.get());
+ return new CFDE_TxtEdtBuf::Iterator(m_pTxtBuf.get());
}
int32_t CFDE_TxtEdtEngine::Line2Parag(int32_t nStartParag,
@@ -932,7 +931,8 @@ void CFDE_TxtEdtEngine::RebuildParagraphs() {
FX_WCHAR wChar = L' ';
int32_t nParagStart = 0;
int32_t nIndex = 0;
- std::unique_ptr<IFX_CharIter> pIter(new CFDE_TxtEdtBufIter(m_pTxtBuf.get()));
+ std::unique_ptr<IFX_CharIter> pIter(
+ new CFDE_TxtEdtBuf::Iterator(m_pTxtBuf.get()));
pIter->SetAt(0);
do {
wChar = pIter->GetChar();
diff --git a/xfa/fde/cfde_txtedtpage.cpp b/xfa/fde/cfde_txtedtpage.cpp
index ff19d12338..238dba2bcc 100644
--- a/xfa/fde/cfde_txtedtpage.cpp
+++ b/xfa/fde/cfde_txtedtpage.cpp
@@ -10,7 +10,6 @@
#include "third_party/base/ptr_util.h"
#include "xfa/fde/cfde_txtedtbuf.h"
-#include "xfa/fde/cfde_txtedtbufiter.h"
#include "xfa/fde/cfde_txtedtengine.h"
#include "xfa/fde/cfde_txtedtparag.h"
#include "xfa/fde/cfde_txtedttextset.h"
@@ -239,7 +238,7 @@ int32_t CFDE_TxtEdtPage::SelectWord(const CFX_PointF& fPoint, int32_t& nCount) {
return -1;
}
std::unique_ptr<CFX_WordBreak> pIter(new CFX_WordBreak);
- pIter->Attach(new CFDE_TxtEdtBufIter(pBuf));
+ pIter->Attach(new CFDE_TxtEdtBuf::Iterator(pBuf));
pIter->SetAt(nIndex);
nCount = pIter->GetWordLength();
return pIter->GetWordPos();
@@ -261,8 +260,8 @@ int32_t CFDE_TxtEdtPage::LoadPage(const CFX_RectF* pClipBox,
if (pParams->dwMode & FDE_TEXTEDITMODE_Password) {
wcAlias = m_pEditEngine->GetAliasChar();
}
- m_pIter.reset(
- new CFDE_TxtEdtBufIter(static_cast<CFDE_TxtEdtBuf*>(pBuf), wcAlias));
+ m_pIter.reset(new CFDE_TxtEdtBuf::Iterator(static_cast<CFDE_TxtEdtBuf*>(pBuf),
+ wcAlias));
CFX_TxtBreak* pBreak = m_pEditEngine->GetTextBreak();
pBreak->EndBreak(FX_TXTBREAK_ParagraphBreak);
pBreak->ClearBreakPieces();
diff --git a/xfa/fde/cfde_txtedtparag.cpp b/xfa/fde/cfde_txtedtparag.cpp
index 244add4e0a..f9f88bfb5d 100644
--- a/xfa/fde/cfde_txtedtparag.cpp
+++ b/xfa/fde/cfde_txtedtparag.cpp
@@ -9,7 +9,6 @@
#include <memory>
#include "xfa/fde/cfde_txtedtbuf.h"
-#include "xfa/fde/cfde_txtedtbufiter.h"
#include "xfa/fde/cfde_txtedtengine.h"
#include "xfa/fde/ifde_txtedtengine.h"
#include "xfa/fde/ifx_chariter.h"
@@ -41,8 +40,8 @@ void CFDE_TxtEdtParag::LoadParag() {
if (pParam->dwMode & FDE_TEXTEDITMODE_Password) {
wcAlias = m_pEngine->GetAliasChar();
}
- std::unique_ptr<IFX_CharIter> pIter(
- new CFDE_TxtEdtBufIter(static_cast<CFDE_TxtEdtBuf*>(pTxtBuf), wcAlias));
+ std::unique_ptr<IFX_CharIter> pIter(new CFDE_TxtEdtBuf::Iterator(
+ static_cast<CFDE_TxtEdtBuf*>(pTxtBuf), wcAlias));
pIter->SetAt(m_nCharStart);
int32_t nEndIndex = m_nCharStart + m_nCharCount;
CFX_ArrayTemplate<int32_t> LineBaseArr;
@@ -110,7 +109,7 @@ void CFDE_TxtEdtParag::CalcLines() {
uint32_t dwBreakStatus = FX_TXTBREAK_None;
int32_t nEndIndex = m_nCharStart + m_nCharCount;
std::unique_ptr<IFX_CharIter> pIter(
- new CFDE_TxtEdtBufIter(static_cast<CFDE_TxtEdtBuf*>(pTxtBuf)));
+ new CFDE_TxtEdtBuf::Iterator(static_cast<CFDE_TxtEdtBuf*>(pTxtBuf)));
pIter->SetAt(m_nCharStart);
bool bReload = false;
do {