Chromium Code Reviews| 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 |