OLD | NEW |
---|---|
1 // Copyright 2014 PDFium Authors. All rights reserved. | 1 // Copyright 2014 PDFium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
6 | 6 |
7 #include "xfa/fde/cfde_txtedtbuf.h" | 7 #include "xfa/fde/cfde_txtedtbuf.h" |
8 | 8 |
9 #include <algorithm> | 9 #include <algorithm> |
10 | 10 |
(...skipping 19 matching lines...) Expand all Loading... | |
30 int32_t CFDE_TxtEdtBuf::GetChunkSize() const { | 30 int32_t CFDE_TxtEdtBuf::GetChunkSize() const { |
31 return m_nChunkSize; | 31 return m_nChunkSize; |
32 } | 32 } |
33 | 33 |
34 int32_t CFDE_TxtEdtBuf::GetTextLength() const { | 34 int32_t CFDE_TxtEdtBuf::GetTextLength() const { |
35 return m_nTotal; | 35 return m_nTotal; |
36 } | 36 } |
37 | 37 |
38 void CFDE_TxtEdtBuf::SetText(const CFX_WideString& wsText) { | 38 void CFDE_TxtEdtBuf::SetText(const CFX_WideString& wsText) { |
39 ASSERT(!wsText.IsEmpty()); | 39 ASSERT(!wsText.IsEmpty()); |
40 | |
40 Clear(false); | 41 Clear(false); |
41 int32_t nTextLength = wsText.GetLength(); | 42 int32_t nTextLength = wsText.GetLength(); |
42 int32_t nNeedCount = | 43 int32_t nNeedCount = |
43 ((nTextLength - 1) / m_nChunkSize + 1) - m_Chunks.GetSize(); | 44 ((nTextLength - 1) / m_nChunkSize + 1) - m_Chunks.GetSize(); |
44 int32_t i = 0; | 45 int32_t i = 0; |
45 for (i = 0; i < nNeedCount; i++) { | 46 for (i = 0; i < nNeedCount; i++) { |
46 FDE_CHUNKHEADER* lpChunk = | 47 FDE_CHUNKHEADER* lpChunk = |
47 static_cast<FDE_CHUNKHEADER*>(m_pAllocator->Alloc( | 48 static_cast<FDE_CHUNKHEADER*>(m_pAllocator->Alloc( |
48 sizeof(FDE_CHUNKHEADER) + (m_nChunkSize - 1) * sizeof(FX_WCHAR))); | 49 sizeof(FDE_CHUNKHEADER) + (m_nChunkSize - 1) * sizeof(FX_WCHAR))); |
49 lpChunk->nUsed = 0; | 50 lpChunk->nUsed = 0; |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
82 nTotal += pChunkHeader->nUsed; | 83 nTotal += pChunkHeader->nUsed; |
83 if (nTotal > nIndex) { | 84 if (nTotal > nIndex) { |
84 break; | 85 break; |
85 } | 86 } |
86 } | 87 } |
87 ASSERT(pChunkHeader); | 88 ASSERT(pChunkHeader); |
88 return pChunkHeader->wChars[pChunkHeader->nUsed - (nTotal - nIndex)]; | 89 return pChunkHeader->wChars[pChunkHeader->nUsed - (nTotal - nIndex)]; |
89 } | 90 } |
90 | 91 |
91 CFX_WideString CFDE_TxtEdtBuf::GetRange(int32_t nBegin, int32_t nLength) const { | 92 CFX_WideString CFDE_TxtEdtBuf::GetRange(int32_t nBegin, int32_t nLength) const { |
93 if (nLength == 0 || GetTextLength() == 0) | |
94 return CFX_WideString(); | |
95 | |
96 ASSERT(nBegin >= 0 && nLength > 0 && nBegin < GetTextLength() && | |
97 nBegin + nLength <= GetTextLength()); | |
Tom Sepez
2017/01/09 21:07:27
nit: this could overflow, but since its just an as
dsinclair
2017/01/09 21:19:59
Acknowledged.
| |
98 | |
92 FDE_CHUNKPLACE cp; | 99 FDE_CHUNKPLACE cp; |
93 Index2CP(nBegin, cp); | 100 Index2CP(nBegin, cp); |
94 int32_t nLeave = nLength; | 101 int32_t nLeave = nLength; |
95 int32_t nCount = m_Chunks.GetSize(); | 102 int32_t nCount = m_Chunks.GetSize(); |
96 | 103 |
97 CFX_WideString wsText; | 104 CFX_WideString wsText; |
98 FX_WCHAR* lpDstBuf = wsText.GetBuffer(nLength); | 105 FX_WCHAR* lpDstBuf = wsText.GetBuffer(nLength); |
99 int32_t nChunkIndex = cp.nChunkIndex; | 106 int32_t nChunkIndex = cp.nChunkIndex; |
100 FDE_CHUNKHEADER* lpChunkHeader = m_Chunks[nChunkIndex]; | 107 FDE_CHUNKHEADER* lpChunkHeader = m_Chunks[nChunkIndex]; |
101 int32_t nCopyLength = lpChunkHeader->nUsed - cp.nCharIndex; | 108 int32_t nCopyLength = lpChunkHeader->nUsed - cp.nCharIndex; |
(...skipping 15 matching lines...) Expand all Loading... | |
117 } | 124 } |
118 wsText.ReleaseBuffer(); | 125 wsText.ReleaseBuffer(); |
119 | 126 |
120 return wsText; | 127 return wsText; |
121 } | 128 } |
122 | 129 |
123 void CFDE_TxtEdtBuf::Insert(int32_t nPos, | 130 void CFDE_TxtEdtBuf::Insert(int32_t nPos, |
124 const FX_WCHAR* lpText, | 131 const FX_WCHAR* lpText, |
125 int32_t nLength) { | 132 int32_t nLength) { |
126 ASSERT(nPos >= 0 && nPos <= m_nTotal); | 133 ASSERT(nPos >= 0 && nPos <= m_nTotal); |
134 ASSERT(nLength > 0); | |
135 | |
127 FDE_CHUNKPLACE cp; | 136 FDE_CHUNKPLACE cp; |
128 Index2CP(nPos, cp); | 137 Index2CP(nPos, cp); |
129 int32_t nLengthTemp = nLength; | 138 int32_t nLengthTemp = nLength; |
130 if (cp.nCharIndex != 0) { | 139 if (cp.nCharIndex != 0) { |
131 FDE_CHUNKHEADER* lpNewChunk = | 140 FDE_CHUNKHEADER* lpNewChunk = |
132 static_cast<FDE_CHUNKHEADER*>(m_pAllocator->Alloc( | 141 static_cast<FDE_CHUNKHEADER*>(m_pAllocator->Alloc( |
133 sizeof(FDE_CHUNKHEADER) + (m_nChunkSize - 1) * sizeof(FX_WCHAR))); | 142 sizeof(FDE_CHUNKHEADER) + (m_nChunkSize - 1) * sizeof(FX_WCHAR))); |
134 FDE_CHUNKHEADER* lpChunk = m_Chunks[cp.nChunkIndex]; | 143 FDE_CHUNKHEADER* lpChunk = m_Chunks[cp.nChunkIndex]; |
135 int32_t nCopy = lpChunk->nUsed - cp.nCharIndex; | 144 int32_t nCopy = lpChunk->nUsed - cp.nCharIndex; |
136 FXSYS_memcpy(lpNewChunk->wChars, lpChunk->wChars + cp.nCharIndex, | 145 FXSYS_memcpy(lpNewChunk->wChars, lpChunk->wChars + cp.nCharIndex, |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
213 m_Chunks.RemoveAll(); | 222 m_Chunks.RemoveAll(); |
214 } else { | 223 } else { |
215 while (i < nCount) { | 224 while (i < nCount) { |
216 m_Chunks[i++]->nUsed = 0; | 225 m_Chunks[i++]->nUsed = 0; |
217 } | 226 } |
218 } | 227 } |
219 m_nTotal = 0; | 228 m_nTotal = 0; |
220 m_bChanged = true; | 229 m_bChanged = true; |
221 } | 230 } |
222 | 231 |
223 bool CFDE_TxtEdtBuf::Optimize(IFX_Pause* pPause) { | |
224 if (m_bChanged == false) { | |
225 return true; | |
226 } | |
227 if (m_nTotal == 0) { | |
228 return true; | |
229 } | |
230 int32_t nCount = m_Chunks.GetSize(); | |
231 if (nCount == 0) { | |
232 return true; | |
233 } | |
234 int32_t i = 0; | |
235 for (; i < nCount; i++) { | |
236 FDE_CHUNKHEADER* lpChunk = m_Chunks[i]; | |
237 if (lpChunk->nUsed == 0) { | |
238 m_pAllocator->Free(lpChunk); | |
239 m_Chunks.RemoveAt(i); | |
240 --i; | |
241 --nCount; | |
242 } | |
243 } | |
244 if (pPause && pPause->NeedToPauseNow()) | |
245 return false; | |
246 | |
247 FDE_CHUNKHEADER* lpPreChunk = m_Chunks[0]; | |
248 FDE_CHUNKHEADER* lpCurChunk = nullptr; | |
249 for (i = 1; i < nCount; i++) { | |
250 lpCurChunk = m_Chunks[i]; | |
251 if (lpPreChunk->nUsed + lpCurChunk->nUsed <= m_nChunkSize) { | |
252 FXSYS_memcpy(lpPreChunk->wChars + lpPreChunk->nUsed, lpCurChunk->wChars, | |
253 lpCurChunk->nUsed * sizeof(FX_WCHAR)); | |
254 lpPreChunk->nUsed += lpCurChunk->nUsed; | |
255 m_pAllocator->Free(lpCurChunk); | |
256 m_Chunks.RemoveAt(i); | |
257 --i; | |
258 --nCount; | |
259 } else { | |
260 lpPreChunk = lpCurChunk; | |
261 } | |
262 if (pPause && pPause->NeedToPauseNow()) | |
263 return false; | |
264 } | |
265 m_bChanged = false; | |
266 return true; | |
267 } | |
268 | |
269 void CFDE_TxtEdtBuf::ResetChunkBuffer(int32_t nDefChunkCount, | 232 void CFDE_TxtEdtBuf::ResetChunkBuffer(int32_t nDefChunkCount, |
270 int32_t nChunkSize) { | 233 int32_t nChunkSize) { |
271 ASSERT(nChunkSize); | 234 ASSERT(nChunkSize); |
272 ASSERT(nDefChunkCount); | 235 ASSERT(nDefChunkCount); |
273 m_Chunks.RemoveAll(); | 236 m_Chunks.RemoveAll(); |
274 m_nChunkSize = nChunkSize; | 237 m_nChunkSize = nChunkSize; |
275 int32_t nChunkLength = | 238 int32_t nChunkLength = |
276 sizeof(FDE_CHUNKHEADER) + (m_nChunkSize - 1) * sizeof(FX_WCHAR); | 239 sizeof(FDE_CHUNKHEADER) + (m_nChunkSize - 1) * sizeof(FX_WCHAR); |
277 m_pAllocator = IFX_MemoryAllocator::Create(FX_ALLOCTYPE_Fixed, nDefChunkCount, | 240 m_pAllocator = IFX_MemoryAllocator::Create(FX_ALLOCTYPE_Fixed, nDefChunkCount, |
278 nChunkLength); | 241 nChunkLength); |
279 FDE_CHUNKHEADER* lpChunkHeader = | 242 FDE_CHUNKHEADER* lpChunkHeader = |
280 static_cast<FDE_CHUNKHEADER*>(m_pAllocator->Alloc(nChunkLength)); | 243 static_cast<FDE_CHUNKHEADER*>(m_pAllocator->Alloc(nChunkLength)); |
281 ASSERT(lpChunkHeader); | 244 ASSERT(lpChunkHeader); |
282 lpChunkHeader->nUsed = 0; | 245 lpChunkHeader->nUsed = 0; |
283 m_Chunks.Add(lpChunkHeader); | 246 m_Chunks.Add(lpChunkHeader); |
284 m_nTotal = 0; | 247 m_nTotal = 0; |
285 } | 248 } |
286 | 249 |
250 void CFDE_TxtEdtBuf::SetChunkSizeForTesting(size_t size) { | |
251 ResetChunkBuffer(kDefaultChunkCount, size); | |
252 } | |
253 | |
287 int32_t CFDE_TxtEdtBuf::CP2Index(const FDE_CHUNKPLACE& cp) const { | 254 int32_t CFDE_TxtEdtBuf::CP2Index(const FDE_CHUNKPLACE& cp) const { |
288 int32_t nTotal = cp.nCharIndex; | 255 int32_t nTotal = cp.nCharIndex; |
289 int32_t i = 0; | 256 int32_t i = 0; |
290 for (i = 0; i < cp.nChunkIndex; i++) { | 257 for (i = 0; i < cp.nChunkIndex; i++) { |
291 nTotal += m_Chunks[i]->nUsed; | 258 nTotal += m_Chunks[i]->nUsed; |
292 } | 259 } |
293 return nTotal; | 260 return nTotal; |
294 } | 261 } |
295 | 262 |
296 void CFDE_TxtEdtBuf::Index2CP(int32_t nIndex, FDE_CHUNKPLACE& cp) const { | 263 void CFDE_TxtEdtBuf::Index2CP(int32_t nIndex, FDE_CHUNKPLACE& cp) const { |
297 ASSERT(nIndex <= GetTextLength()); | 264 ASSERT(nIndex <= GetTextLength()); |
298 if (nIndex == m_nTotal) { | 265 if (nIndex == m_nTotal) { |
299 cp.nChunkIndex = m_Chunks.GetSize() - 1; | 266 cp.nChunkIndex = m_Chunks.GetSize() - 1; |
300 cp.nCharIndex = m_Chunks[cp.nChunkIndex]->nUsed; | 267 cp.nCharIndex = m_Chunks[cp.nChunkIndex]->nUsed; |
301 return; | 268 return; |
302 } | 269 } |
303 int32_t i = 0; | 270 int32_t i = 0; |
304 int32_t nTotal = 0; | 271 int32_t nTotal = 0; |
305 int32_t nCount = m_Chunks.GetSize(); | 272 int32_t nCount = m_Chunks.GetSize(); |
306 for (; i < nCount; i++) { | 273 for (; i < nCount; i++) { |
307 nTotal += m_Chunks[i]->nUsed; | 274 nTotal += m_Chunks[i]->nUsed; |
308 if (nTotal > nIndex) { | 275 if (nTotal > nIndex) { |
309 break; | 276 break; |
310 } | 277 } |
311 } | 278 } |
312 cp.nChunkIndex = i; | 279 cp.nChunkIndex = i; |
313 cp.nCharIndex = m_Chunks[i]->nUsed - (nTotal - nIndex); | 280 cp.nCharIndex = m_Chunks[i]->nUsed - (nTotal - nIndex); |
314 } | 281 } |
OLD | NEW |