• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2014 PDFium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6 
7 #include "core/fxcrt/fx_basic.h"
8 #include "third_party/base/numerics/safe_math.h"
9 
CFX_BasicArray(int unit_size)10 CFX_BasicArray::CFX_BasicArray(int unit_size)
11     : m_pData(nullptr), m_nSize(0), m_nMaxSize(0) {
12   if (unit_size < 0 || unit_size > (1 << 28)) {
13     m_nUnitSize = 4;
14   } else {
15     m_nUnitSize = unit_size;
16   }
17 }
~CFX_BasicArray()18 CFX_BasicArray::~CFX_BasicArray() {
19   FX_Free(m_pData);
20 }
SetSize(int nNewSize)21 bool CFX_BasicArray::SetSize(int nNewSize) {
22   if (nNewSize <= 0) {
23     FX_Free(m_pData);
24     m_pData = nullptr;
25     m_nSize = m_nMaxSize = 0;
26     return 0 == nNewSize;
27   }
28 
29   if (!m_pData) {
30     pdfium::base::CheckedNumeric<int> totalSize = nNewSize;
31     totalSize *= m_nUnitSize;
32     if (!totalSize.IsValid()) {
33       m_nSize = m_nMaxSize = 0;
34       return false;
35     }
36     m_pData =
37         FX_Alloc(uint8_t, pdfium::base::ValueOrDieForType<size_t>(totalSize));
38     m_nSize = m_nMaxSize = nNewSize;
39   } else if (nNewSize <= m_nMaxSize) {
40     if (nNewSize > m_nSize) {
41       FXSYS_memset(m_pData + m_nSize * m_nUnitSize, 0,
42                    (nNewSize - m_nSize) * m_nUnitSize);
43     }
44     m_nSize = nNewSize;
45   } else {
46     int nNewMax = nNewSize < m_nMaxSize ? m_nMaxSize : nNewSize;
47     pdfium::base::CheckedNumeric<int> totalSize = nNewMax;
48     totalSize *= m_nUnitSize;
49     if (!totalSize.IsValid() || nNewMax < m_nSize) {
50       return false;
51     }
52     uint8_t* pNewData = FX_Realloc(
53         uint8_t, m_pData, pdfium::base::ValueOrDieForType<size_t>(totalSize));
54     if (!pNewData) {
55       return false;
56     }
57     FXSYS_memset(pNewData + m_nSize * m_nUnitSize, 0,
58                  (nNewMax - m_nSize) * m_nUnitSize);
59     m_pData = pNewData;
60     m_nSize = nNewSize;
61     m_nMaxSize = nNewMax;
62   }
63   return true;
64 }
Append(const CFX_BasicArray & src)65 bool CFX_BasicArray::Append(const CFX_BasicArray& src) {
66   int nOldSize = m_nSize;
67   pdfium::base::CheckedNumeric<int> newSize = m_nSize;
68   newSize += src.m_nSize;
69   if (m_nUnitSize != src.m_nUnitSize || !newSize.IsValid() ||
70       !SetSize(newSize.ValueOrDie())) {
71     return false;
72   }
73 
74   FXSYS_memcpy(m_pData + nOldSize * m_nUnitSize, src.m_pData,
75                src.m_nSize * m_nUnitSize);
76   return true;
77 }
Copy(const CFX_BasicArray & src)78 bool CFX_BasicArray::Copy(const CFX_BasicArray& src) {
79   if (!SetSize(src.m_nSize)) {
80     return false;
81   }
82   FXSYS_memcpy(m_pData, src.m_pData, src.m_nSize * m_nUnitSize);
83   return true;
84 }
InsertSpaceAt(int nIndex,int nCount)85 uint8_t* CFX_BasicArray::InsertSpaceAt(int nIndex, int nCount) {
86   if (nIndex < 0 || nCount <= 0) {
87     return nullptr;
88   }
89   if (nIndex >= m_nSize) {
90     if (!SetSize(nIndex + nCount)) {
91       return nullptr;
92     }
93   } else {
94     int nOldSize = m_nSize;
95     if (!SetSize(m_nSize + nCount)) {
96       return nullptr;
97     }
98     FXSYS_memmove(m_pData + (nIndex + nCount) * m_nUnitSize,
99                   m_pData + nIndex * m_nUnitSize,
100                   (nOldSize - nIndex) * m_nUnitSize);
101     FXSYS_memset(m_pData + nIndex * m_nUnitSize, 0, nCount * m_nUnitSize);
102   }
103   return m_pData + nIndex * m_nUnitSize;
104 }
RemoveAt(int nIndex,int nCount)105 bool CFX_BasicArray::RemoveAt(int nIndex, int nCount) {
106   if (nIndex < 0 || nCount <= 0 || m_nSize < nIndex + nCount) {
107     return false;
108   }
109   int nMoveCount = m_nSize - (nIndex + nCount);
110   if (nMoveCount) {
111     FXSYS_memmove(m_pData + nIndex * m_nUnitSize,
112                   m_pData + (nIndex + nCount) * m_nUnitSize,
113                   nMoveCount * m_nUnitSize);
114   }
115   m_nSize -= nCount;
116   return true;
117 }
InsertAt(int nStartIndex,const CFX_BasicArray * pNewArray)118 bool CFX_BasicArray::InsertAt(int nStartIndex,
119                               const CFX_BasicArray* pNewArray) {
120   if (!pNewArray) {
121     return false;
122   }
123   if (pNewArray->m_nSize == 0) {
124     return true;
125   }
126   if (!InsertSpaceAt(nStartIndex, pNewArray->m_nSize)) {
127     return false;
128   }
129   FXSYS_memcpy(m_pData + nStartIndex * m_nUnitSize, pNewArray->m_pData,
130                pNewArray->m_nSize * m_nUnitSize);
131   return true;
132 }
GetDataPtr(int index) const133 const void* CFX_BasicArray::GetDataPtr(int index) const {
134   if (index < 0 || index >= m_nSize || !m_pData) {
135     return nullptr;
136   }
137   return m_pData + index * m_nUnitSize;
138 }
139