xref: /aosp_15_r20/external/pdfium/third_party/agg23/agg_array.h (revision 3ac0a46f773bac49fa9476ec2b1cf3f8da5ec3a4)
1*3ac0a46fSAndroid Build Coastguard Worker 
2*3ac0a46fSAndroid Build Coastguard Worker //----------------------------------------------------------------------------
3*3ac0a46fSAndroid Build Coastguard Worker // Anti-Grain Geometry - Version 2.3
4*3ac0a46fSAndroid Build Coastguard Worker // Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
5*3ac0a46fSAndroid Build Coastguard Worker //
6*3ac0a46fSAndroid Build Coastguard Worker // Permission to copy, use, modify, sell and distribute this software
7*3ac0a46fSAndroid Build Coastguard Worker // is granted provided this copyright notice appears in all copies.
8*3ac0a46fSAndroid Build Coastguard Worker // This software is provided "as is" without express or implied
9*3ac0a46fSAndroid Build Coastguard Worker // warranty, and with no claim as to its suitability for any purpose.
10*3ac0a46fSAndroid Build Coastguard Worker //
11*3ac0a46fSAndroid Build Coastguard Worker //----------------------------------------------------------------------------
12*3ac0a46fSAndroid Build Coastguard Worker // Contact: [email protected]
13*3ac0a46fSAndroid Build Coastguard Worker //          [email protected]
14*3ac0a46fSAndroid Build Coastguard Worker //          http://www.antigrain.com
15*3ac0a46fSAndroid Build Coastguard Worker //----------------------------------------------------------------------------
16*3ac0a46fSAndroid Build Coastguard Worker #ifndef AGG_ARRAY_INCLUDED
17*3ac0a46fSAndroid Build Coastguard Worker #define AGG_ARRAY_INCLUDED
18*3ac0a46fSAndroid Build Coastguard Worker 
19*3ac0a46fSAndroid Build Coastguard Worker #include <string.h>
20*3ac0a46fSAndroid Build Coastguard Worker 
21*3ac0a46fSAndroid Build Coastguard Worker #include "agg_basics.h"
22*3ac0a46fSAndroid Build Coastguard Worker #include "core/fxcrt/fx_memory.h"  // For FXSYS_* macros.
23*3ac0a46fSAndroid Build Coastguard Worker 
24*3ac0a46fSAndroid Build Coastguard Worker namespace pdfium
25*3ac0a46fSAndroid Build Coastguard Worker {
26*3ac0a46fSAndroid Build Coastguard Worker namespace agg
27*3ac0a46fSAndroid Build Coastguard Worker {
28*3ac0a46fSAndroid Build Coastguard Worker template <class T>
29*3ac0a46fSAndroid Build Coastguard Worker class pod_array {
30*3ac0a46fSAndroid Build Coastguard Worker public:
31*3ac0a46fSAndroid Build Coastguard Worker     typedef T value_type;
~pod_array()32*3ac0a46fSAndroid Build Coastguard Worker     ~pod_array()
33*3ac0a46fSAndroid Build Coastguard Worker     {
34*3ac0a46fSAndroid Build Coastguard Worker         FX_Free(m_array);
35*3ac0a46fSAndroid Build Coastguard Worker     }
pod_array()36*3ac0a46fSAndroid Build Coastguard Worker     pod_array() : m_size(0), m_capacity(0), m_array(0) {}
37*3ac0a46fSAndroid Build Coastguard Worker     pod_array(unsigned cap, unsigned extra_tail = 0);
38*3ac0a46fSAndroid Build Coastguard Worker     pod_array(const pod_array<T>&);
39*3ac0a46fSAndroid Build Coastguard Worker     pod_array<T>& operator = (const pod_array<T>&);
40*3ac0a46fSAndroid Build Coastguard Worker     void capacity(unsigned cap, unsigned extra_tail = 0);
capacity()41*3ac0a46fSAndroid Build Coastguard Worker     unsigned capacity() const
42*3ac0a46fSAndroid Build Coastguard Worker     {
43*3ac0a46fSAndroid Build Coastguard Worker         return m_capacity;
44*3ac0a46fSAndroid Build Coastguard Worker     }
45*3ac0a46fSAndroid Build Coastguard Worker     void allocate(unsigned size, unsigned extra_tail = 0);
46*3ac0a46fSAndroid Build Coastguard Worker     void resize(unsigned new_size);
zero()47*3ac0a46fSAndroid Build Coastguard Worker     void zero() { memset(m_array, 0, sizeof(T) * m_size); }
add(const T & v)48*3ac0a46fSAndroid Build Coastguard Worker     void add(const T& v)
49*3ac0a46fSAndroid Build Coastguard Worker     {
50*3ac0a46fSAndroid Build Coastguard Worker         m_array[m_size++] = v;
51*3ac0a46fSAndroid Build Coastguard Worker     }
inc_size(unsigned size)52*3ac0a46fSAndroid Build Coastguard Worker     void inc_size(unsigned size)
53*3ac0a46fSAndroid Build Coastguard Worker     {
54*3ac0a46fSAndroid Build Coastguard Worker         m_size += size;
55*3ac0a46fSAndroid Build Coastguard Worker     }
size()56*3ac0a46fSAndroid Build Coastguard Worker     unsigned size()      const
57*3ac0a46fSAndroid Build Coastguard Worker     {
58*3ac0a46fSAndroid Build Coastguard Worker         return m_size;
59*3ac0a46fSAndroid Build Coastguard Worker     }
byte_size()60*3ac0a46fSAndroid Build Coastguard Worker     unsigned byte_size() const
61*3ac0a46fSAndroid Build Coastguard Worker     {
62*3ac0a46fSAndroid Build Coastguard Worker         return m_size * sizeof(T);
63*3ac0a46fSAndroid Build Coastguard Worker     }
64*3ac0a46fSAndroid Build Coastguard Worker     const T& operator [] (unsigned i) const
65*3ac0a46fSAndroid Build Coastguard Worker     {
66*3ac0a46fSAndroid Build Coastguard Worker         return m_array[i];
67*3ac0a46fSAndroid Build Coastguard Worker     }
68*3ac0a46fSAndroid Build Coastguard Worker     T& operator [] (unsigned i)
69*3ac0a46fSAndroid Build Coastguard Worker     {
70*3ac0a46fSAndroid Build Coastguard Worker         return m_array[i];
71*3ac0a46fSAndroid Build Coastguard Worker     }
at(unsigned i)72*3ac0a46fSAndroid Build Coastguard Worker     const T& at(unsigned i) const
73*3ac0a46fSAndroid Build Coastguard Worker     {
74*3ac0a46fSAndroid Build Coastguard Worker         return m_array[i];
75*3ac0a46fSAndroid Build Coastguard Worker     }
at(unsigned i)76*3ac0a46fSAndroid Build Coastguard Worker     T& at(unsigned i)
77*3ac0a46fSAndroid Build Coastguard Worker     {
78*3ac0a46fSAndroid Build Coastguard Worker         return m_array[i];
79*3ac0a46fSAndroid Build Coastguard Worker     }
value_at(unsigned i)80*3ac0a46fSAndroid Build Coastguard Worker     T  value_at(unsigned i) const
81*3ac0a46fSAndroid Build Coastguard Worker     {
82*3ac0a46fSAndroid Build Coastguard Worker         return m_array[i];
83*3ac0a46fSAndroid Build Coastguard Worker     }
data()84*3ac0a46fSAndroid Build Coastguard Worker     const T* data() const
85*3ac0a46fSAndroid Build Coastguard Worker     {
86*3ac0a46fSAndroid Build Coastguard Worker         return m_array;
87*3ac0a46fSAndroid Build Coastguard Worker     }
data()88*3ac0a46fSAndroid Build Coastguard Worker     T* data()
89*3ac0a46fSAndroid Build Coastguard Worker     {
90*3ac0a46fSAndroid Build Coastguard Worker         return m_array;
91*3ac0a46fSAndroid Build Coastguard Worker     }
remove_all()92*3ac0a46fSAndroid Build Coastguard Worker     void remove_all()
93*3ac0a46fSAndroid Build Coastguard Worker     {
94*3ac0a46fSAndroid Build Coastguard Worker         m_size = 0;
95*3ac0a46fSAndroid Build Coastguard Worker     }
cut_at(unsigned num)96*3ac0a46fSAndroid Build Coastguard Worker     void cut_at(unsigned num)
97*3ac0a46fSAndroid Build Coastguard Worker     {
98*3ac0a46fSAndroid Build Coastguard Worker         if(num < m_size) {
99*3ac0a46fSAndroid Build Coastguard Worker             m_size = num;
100*3ac0a46fSAndroid Build Coastguard Worker         }
101*3ac0a46fSAndroid Build Coastguard Worker     }
102*3ac0a46fSAndroid Build Coastguard Worker private:
103*3ac0a46fSAndroid Build Coastguard Worker     unsigned m_size;
104*3ac0a46fSAndroid Build Coastguard Worker     unsigned m_capacity;
105*3ac0a46fSAndroid Build Coastguard Worker     T*       m_array;
106*3ac0a46fSAndroid Build Coastguard Worker };
107*3ac0a46fSAndroid Build Coastguard Worker template<class T>
capacity(unsigned cap,unsigned extra_tail)108*3ac0a46fSAndroid Build Coastguard Worker void pod_array<T>::capacity(unsigned cap, unsigned extra_tail)
109*3ac0a46fSAndroid Build Coastguard Worker {
110*3ac0a46fSAndroid Build Coastguard Worker     m_size = 0;
111*3ac0a46fSAndroid Build Coastguard Worker     unsigned full_cap = cap + extra_tail;
112*3ac0a46fSAndroid Build Coastguard Worker     if(full_cap < cap) {
113*3ac0a46fSAndroid Build Coastguard Worker         FX_Free(m_array);
114*3ac0a46fSAndroid Build Coastguard Worker         m_array = 0;
115*3ac0a46fSAndroid Build Coastguard Worker         m_capacity = 0;
116*3ac0a46fSAndroid Build Coastguard Worker     } else if(full_cap > m_capacity) {
117*3ac0a46fSAndroid Build Coastguard Worker         FX_Free(m_array);
118*3ac0a46fSAndroid Build Coastguard Worker         m_array = FX_Alloc(T, full_cap);
119*3ac0a46fSAndroid Build Coastguard Worker         m_capacity = full_cap;
120*3ac0a46fSAndroid Build Coastguard Worker     }
121*3ac0a46fSAndroid Build Coastguard Worker }
122*3ac0a46fSAndroid Build Coastguard Worker template<class T>
allocate(unsigned size,unsigned extra_tail)123*3ac0a46fSAndroid Build Coastguard Worker void pod_array<T>::allocate(unsigned size, unsigned extra_tail)
124*3ac0a46fSAndroid Build Coastguard Worker {
125*3ac0a46fSAndroid Build Coastguard Worker     capacity(size, extra_tail);
126*3ac0a46fSAndroid Build Coastguard Worker     m_size = size;
127*3ac0a46fSAndroid Build Coastguard Worker }
128*3ac0a46fSAndroid Build Coastguard Worker template<class T>
resize(unsigned new_size)129*3ac0a46fSAndroid Build Coastguard Worker void pod_array<T>::resize(unsigned new_size)
130*3ac0a46fSAndroid Build Coastguard Worker {
131*3ac0a46fSAndroid Build Coastguard Worker     if(new_size > m_size) {
132*3ac0a46fSAndroid Build Coastguard Worker         if(new_size > m_capacity) {
133*3ac0a46fSAndroid Build Coastguard Worker             T* data = FX_AllocUninit(T, new_size);
134*3ac0a46fSAndroid Build Coastguard Worker             memcpy(data, m_array, m_size * sizeof(T));
135*3ac0a46fSAndroid Build Coastguard Worker             FX_Free(m_array);
136*3ac0a46fSAndroid Build Coastguard Worker             m_array = data;
137*3ac0a46fSAndroid Build Coastguard Worker         }
138*3ac0a46fSAndroid Build Coastguard Worker     } else {
139*3ac0a46fSAndroid Build Coastguard Worker         m_size = new_size;
140*3ac0a46fSAndroid Build Coastguard Worker     }
141*3ac0a46fSAndroid Build Coastguard Worker }
pod_array(unsigned cap,unsigned extra_tail)142*3ac0a46fSAndroid Build Coastguard Worker template<class T> pod_array<T>::pod_array(unsigned cap, unsigned extra_tail) :
143*3ac0a46fSAndroid Build Coastguard Worker     m_size(0), m_capacity(cap + extra_tail), m_array(FX_Alloc(T, m_capacity)) {}
pod_array(const pod_array<T> & v)144*3ac0a46fSAndroid Build Coastguard Worker template<class T> pod_array<T>::pod_array(const pod_array<T>& v) :
145*3ac0a46fSAndroid Build Coastguard Worker     m_size(v.m_size),
146*3ac0a46fSAndroid Build Coastguard Worker     m_capacity(v.m_capacity),
147*3ac0a46fSAndroid Build Coastguard Worker     m_array(v.m_capacity ? FX_Alloc(T, v.m_capacity) : 0)
148*3ac0a46fSAndroid Build Coastguard Worker {
149*3ac0a46fSAndroid Build Coastguard Worker   memcpy(m_array, v.m_array, sizeof(T) * v.m_size);
150*3ac0a46fSAndroid Build Coastguard Worker }
151*3ac0a46fSAndroid Build Coastguard Worker template<class T> pod_array<T>&
152*3ac0a46fSAndroid Build Coastguard Worker pod_array<T>::operator = (const pod_array<T>&v)
153*3ac0a46fSAndroid Build Coastguard Worker {
154*3ac0a46fSAndroid Build Coastguard Worker     allocate(v.m_size);
155*3ac0a46fSAndroid Build Coastguard Worker     if(v.m_size) {
156*3ac0a46fSAndroid Build Coastguard Worker       memcpy(m_array, v.m_array, sizeof(T) * v.m_size);
157*3ac0a46fSAndroid Build Coastguard Worker     }
158*3ac0a46fSAndroid Build Coastguard Worker     return *this;
159*3ac0a46fSAndroid Build Coastguard Worker }
160*3ac0a46fSAndroid Build Coastguard Worker template<class T, unsigned S = 6> class pod_deque
161*3ac0a46fSAndroid Build Coastguard Worker {
162*3ac0a46fSAndroid Build Coastguard Worker public:
163*3ac0a46fSAndroid Build Coastguard Worker     enum block_scale_e {
164*3ac0a46fSAndroid Build Coastguard Worker         block_shift = S,
165*3ac0a46fSAndroid Build Coastguard Worker         block_size  = 1 << block_shift,
166*3ac0a46fSAndroid Build Coastguard Worker         block_mask  = block_size - 1
167*3ac0a46fSAndroid Build Coastguard Worker     };
168*3ac0a46fSAndroid Build Coastguard Worker     typedef T value_type;
169*3ac0a46fSAndroid Build Coastguard Worker     ~pod_deque();
170*3ac0a46fSAndroid Build Coastguard Worker     pod_deque();
171*3ac0a46fSAndroid Build Coastguard Worker     pod_deque(unsigned block_ptr_inc);
172*3ac0a46fSAndroid Build Coastguard Worker     pod_deque(const pod_deque<T, S>& v);
173*3ac0a46fSAndroid Build Coastguard Worker     pod_deque<T, S>& operator = (const pod_deque<T, S>& v);
remove_all()174*3ac0a46fSAndroid Build Coastguard Worker     void remove_all()
175*3ac0a46fSAndroid Build Coastguard Worker     {
176*3ac0a46fSAndroid Build Coastguard Worker         m_size = 0;
177*3ac0a46fSAndroid Build Coastguard Worker     }
free_all()178*3ac0a46fSAndroid Build Coastguard Worker     void free_all()
179*3ac0a46fSAndroid Build Coastguard Worker     {
180*3ac0a46fSAndroid Build Coastguard Worker         free_tail(0);
181*3ac0a46fSAndroid Build Coastguard Worker     }
182*3ac0a46fSAndroid Build Coastguard Worker     void free_tail(unsigned size);
183*3ac0a46fSAndroid Build Coastguard Worker     void add(const T& val);
184*3ac0a46fSAndroid Build Coastguard Worker     void modify_last(const T& val);
185*3ac0a46fSAndroid Build Coastguard Worker     void remove_last();
186*3ac0a46fSAndroid Build Coastguard Worker     int allocate_continuous_block(unsigned num_elements);
add_array(const T * ptr,unsigned num_elem)187*3ac0a46fSAndroid Build Coastguard Worker     void add_array(const T* ptr, unsigned num_elem)
188*3ac0a46fSAndroid Build Coastguard Worker     {
189*3ac0a46fSAndroid Build Coastguard Worker         while(num_elem--) {
190*3ac0a46fSAndroid Build Coastguard Worker             add(*ptr++);
191*3ac0a46fSAndroid Build Coastguard Worker         }
192*3ac0a46fSAndroid Build Coastguard Worker     }
add_data(DataAccessor & data)193*3ac0a46fSAndroid Build Coastguard Worker     template<class DataAccessor> void add_data(DataAccessor& data)
194*3ac0a46fSAndroid Build Coastguard Worker     {
195*3ac0a46fSAndroid Build Coastguard Worker         while(data.size()) {
196*3ac0a46fSAndroid Build Coastguard Worker             add(*data);
197*3ac0a46fSAndroid Build Coastguard Worker             ++data;
198*3ac0a46fSAndroid Build Coastguard Worker         }
199*3ac0a46fSAndroid Build Coastguard Worker     }
cut_at(unsigned size)200*3ac0a46fSAndroid Build Coastguard Worker     void cut_at(unsigned size)
201*3ac0a46fSAndroid Build Coastguard Worker     {
202*3ac0a46fSAndroid Build Coastguard Worker         if(size < m_size) {
203*3ac0a46fSAndroid Build Coastguard Worker             m_size = size;
204*3ac0a46fSAndroid Build Coastguard Worker         }
205*3ac0a46fSAndroid Build Coastguard Worker     }
size()206*3ac0a46fSAndroid Build Coastguard Worker     unsigned size() const
207*3ac0a46fSAndroid Build Coastguard Worker     {
208*3ac0a46fSAndroid Build Coastguard Worker         return m_size;
209*3ac0a46fSAndroid Build Coastguard Worker     }
210*3ac0a46fSAndroid Build Coastguard Worker     const T& operator [] (unsigned i) const
211*3ac0a46fSAndroid Build Coastguard Worker     {
212*3ac0a46fSAndroid Build Coastguard Worker         return m_blocks[i >> block_shift][i & block_mask];
213*3ac0a46fSAndroid Build Coastguard Worker     }
214*3ac0a46fSAndroid Build Coastguard Worker     T& operator [] (unsigned i)
215*3ac0a46fSAndroid Build Coastguard Worker     {
216*3ac0a46fSAndroid Build Coastguard Worker         return m_blocks[i >> block_shift][i & block_mask];
217*3ac0a46fSAndroid Build Coastguard Worker     }
at(unsigned i)218*3ac0a46fSAndroid Build Coastguard Worker     const T& at(unsigned i) const
219*3ac0a46fSAndroid Build Coastguard Worker     {
220*3ac0a46fSAndroid Build Coastguard Worker         return m_blocks[i >> block_shift][i & block_mask];
221*3ac0a46fSAndroid Build Coastguard Worker     }
at(unsigned i)222*3ac0a46fSAndroid Build Coastguard Worker     T& at(unsigned i)
223*3ac0a46fSAndroid Build Coastguard Worker     {
224*3ac0a46fSAndroid Build Coastguard Worker         return m_blocks[i >> block_shift][i & block_mask];
225*3ac0a46fSAndroid Build Coastguard Worker     }
value_at(unsigned i)226*3ac0a46fSAndroid Build Coastguard Worker     T value_at(unsigned i) const
227*3ac0a46fSAndroid Build Coastguard Worker     {
228*3ac0a46fSAndroid Build Coastguard Worker         return m_blocks[i >> block_shift][i & block_mask];
229*3ac0a46fSAndroid Build Coastguard Worker     }
curr(unsigned idx)230*3ac0a46fSAndroid Build Coastguard Worker     const T& curr(unsigned idx) const
231*3ac0a46fSAndroid Build Coastguard Worker     {
232*3ac0a46fSAndroid Build Coastguard Worker         return (*this)[idx];
233*3ac0a46fSAndroid Build Coastguard Worker     }
curr(unsigned idx)234*3ac0a46fSAndroid Build Coastguard Worker     T& curr(unsigned idx)
235*3ac0a46fSAndroid Build Coastguard Worker     {
236*3ac0a46fSAndroid Build Coastguard Worker         return (*this)[idx];
237*3ac0a46fSAndroid Build Coastguard Worker     }
prev(unsigned idx)238*3ac0a46fSAndroid Build Coastguard Worker     const T& prev(unsigned idx) const
239*3ac0a46fSAndroid Build Coastguard Worker     {
240*3ac0a46fSAndroid Build Coastguard Worker         return (*this)[(idx + m_size - 1) % m_size];
241*3ac0a46fSAndroid Build Coastguard Worker     }
prev(unsigned idx)242*3ac0a46fSAndroid Build Coastguard Worker     T& prev(unsigned idx)
243*3ac0a46fSAndroid Build Coastguard Worker     {
244*3ac0a46fSAndroid Build Coastguard Worker         return (*this)[(idx + m_size - 1) % m_size];
245*3ac0a46fSAndroid Build Coastguard Worker     }
next(unsigned idx)246*3ac0a46fSAndroid Build Coastguard Worker     const T& next(unsigned idx) const
247*3ac0a46fSAndroid Build Coastguard Worker     {
248*3ac0a46fSAndroid Build Coastguard Worker         return (*this)[(idx + 1) % m_size];
249*3ac0a46fSAndroid Build Coastguard Worker     }
next(unsigned idx)250*3ac0a46fSAndroid Build Coastguard Worker     T& next(unsigned idx)
251*3ac0a46fSAndroid Build Coastguard Worker     {
252*3ac0a46fSAndroid Build Coastguard Worker         return (*this)[(idx + 1) % m_size];
253*3ac0a46fSAndroid Build Coastguard Worker     }
last()254*3ac0a46fSAndroid Build Coastguard Worker     const T& last() const
255*3ac0a46fSAndroid Build Coastguard Worker     {
256*3ac0a46fSAndroid Build Coastguard Worker         return (*this)[m_size - 1];
257*3ac0a46fSAndroid Build Coastguard Worker     }
last()258*3ac0a46fSAndroid Build Coastguard Worker     T& last()
259*3ac0a46fSAndroid Build Coastguard Worker     {
260*3ac0a46fSAndroid Build Coastguard Worker         return (*this)[m_size - 1];
261*3ac0a46fSAndroid Build Coastguard Worker     }
262*3ac0a46fSAndroid Build Coastguard Worker     unsigned byte_size() const;
block(unsigned nb)263*3ac0a46fSAndroid Build Coastguard Worker     const T* block(unsigned nb) const
264*3ac0a46fSAndroid Build Coastguard Worker     {
265*3ac0a46fSAndroid Build Coastguard Worker         return m_blocks[nb];
266*3ac0a46fSAndroid Build Coastguard Worker     }
267*3ac0a46fSAndroid Build Coastguard Worker public:
268*3ac0a46fSAndroid Build Coastguard Worker     void allocate_block(unsigned nb);
269*3ac0a46fSAndroid Build Coastguard Worker     T*   data_ptr();
270*3ac0a46fSAndroid Build Coastguard Worker     unsigned        m_size;
271*3ac0a46fSAndroid Build Coastguard Worker     unsigned        m_num_blocks;
272*3ac0a46fSAndroid Build Coastguard Worker     unsigned        m_max_blocks;
273*3ac0a46fSAndroid Build Coastguard Worker     T**             m_blocks;
274*3ac0a46fSAndroid Build Coastguard Worker     unsigned        m_block_ptr_inc;
275*3ac0a46fSAndroid Build Coastguard Worker };
~pod_deque()276*3ac0a46fSAndroid Build Coastguard Worker template<class T, unsigned S> pod_deque<T, S>::~pod_deque()
277*3ac0a46fSAndroid Build Coastguard Worker {
278*3ac0a46fSAndroid Build Coastguard Worker     if(m_num_blocks) {
279*3ac0a46fSAndroid Build Coastguard Worker         T** blk = m_blocks + m_num_blocks - 1;
280*3ac0a46fSAndroid Build Coastguard Worker         while(m_num_blocks--) {
281*3ac0a46fSAndroid Build Coastguard Worker             FX_Free(*blk);
282*3ac0a46fSAndroid Build Coastguard Worker             --blk;
283*3ac0a46fSAndroid Build Coastguard Worker         }
284*3ac0a46fSAndroid Build Coastguard Worker         FX_Free(m_blocks);
285*3ac0a46fSAndroid Build Coastguard Worker     }
286*3ac0a46fSAndroid Build Coastguard Worker }
287*3ac0a46fSAndroid Build Coastguard Worker template<class T, unsigned S>
free_tail(unsigned size)288*3ac0a46fSAndroid Build Coastguard Worker void pod_deque<T, S>::free_tail(unsigned size)
289*3ac0a46fSAndroid Build Coastguard Worker {
290*3ac0a46fSAndroid Build Coastguard Worker     if(size < m_size) {
291*3ac0a46fSAndroid Build Coastguard Worker         unsigned nb = (size + block_mask) >> block_shift;
292*3ac0a46fSAndroid Build Coastguard Worker         while(m_num_blocks > nb) {
293*3ac0a46fSAndroid Build Coastguard Worker             FX_Free(m_blocks[--m_num_blocks]);
294*3ac0a46fSAndroid Build Coastguard Worker         }
295*3ac0a46fSAndroid Build Coastguard Worker         m_size = size;
296*3ac0a46fSAndroid Build Coastguard Worker     }
297*3ac0a46fSAndroid Build Coastguard Worker }
pod_deque()298*3ac0a46fSAndroid Build Coastguard Worker template<class T, unsigned S> pod_deque<T, S>::pod_deque() :
299*3ac0a46fSAndroid Build Coastguard Worker     m_size(0),
300*3ac0a46fSAndroid Build Coastguard Worker     m_num_blocks(0),
301*3ac0a46fSAndroid Build Coastguard Worker     m_max_blocks(0),
302*3ac0a46fSAndroid Build Coastguard Worker     m_blocks(0),
303*3ac0a46fSAndroid Build Coastguard Worker     m_block_ptr_inc(block_size)
304*3ac0a46fSAndroid Build Coastguard Worker {
305*3ac0a46fSAndroid Build Coastguard Worker }
306*3ac0a46fSAndroid Build Coastguard Worker template<class T, unsigned S>
pod_deque(unsigned block_ptr_inc)307*3ac0a46fSAndroid Build Coastguard Worker pod_deque<T, S>::pod_deque(unsigned block_ptr_inc) :
308*3ac0a46fSAndroid Build Coastguard Worker     m_size(0),
309*3ac0a46fSAndroid Build Coastguard Worker     m_num_blocks(0),
310*3ac0a46fSAndroid Build Coastguard Worker     m_max_blocks(0),
311*3ac0a46fSAndroid Build Coastguard Worker     m_blocks(0),
312*3ac0a46fSAndroid Build Coastguard Worker     m_block_ptr_inc(block_ptr_inc)
313*3ac0a46fSAndroid Build Coastguard Worker {
314*3ac0a46fSAndroid Build Coastguard Worker }
315*3ac0a46fSAndroid Build Coastguard Worker template<class T, unsigned S>
pod_deque(const pod_deque<T,S> & v)316*3ac0a46fSAndroid Build Coastguard Worker pod_deque<T, S>::pod_deque(const pod_deque<T, S>& v) :
317*3ac0a46fSAndroid Build Coastguard Worker     m_size(v.m_size),
318*3ac0a46fSAndroid Build Coastguard Worker     m_num_blocks(v.m_num_blocks),
319*3ac0a46fSAndroid Build Coastguard Worker     m_max_blocks(v.m_max_blocks),
320*3ac0a46fSAndroid Build Coastguard Worker     m_blocks(v.m_max_blocks ? FX_Alloc(T*, v.m_max_blocks) : 0),
321*3ac0a46fSAndroid Build Coastguard Worker     m_block_ptr_inc(v.m_block_ptr_inc)
322*3ac0a46fSAndroid Build Coastguard Worker {
323*3ac0a46fSAndroid Build Coastguard Worker     unsigned i;
324*3ac0a46fSAndroid Build Coastguard Worker     for(i = 0; i < v.m_num_blocks; ++i) {
325*3ac0a46fSAndroid Build Coastguard Worker         m_blocks[i] = FX_AllocUninit(T, block_size);
326*3ac0a46fSAndroid Build Coastguard Worker         memcpy(m_blocks[i], v.m_blocks[i], block_size * sizeof(T));
327*3ac0a46fSAndroid Build Coastguard Worker     }
328*3ac0a46fSAndroid Build Coastguard Worker }
329*3ac0a46fSAndroid Build Coastguard Worker template<class T, unsigned S>
330*3ac0a46fSAndroid Build Coastguard Worker pod_deque<T, S>& pod_deque<T, S>::operator = (const pod_deque<T, S>& v)
331*3ac0a46fSAndroid Build Coastguard Worker {
332*3ac0a46fSAndroid Build Coastguard Worker     unsigned i;
333*3ac0a46fSAndroid Build Coastguard Worker     for(i = m_num_blocks; i < v.m_num_blocks; ++i) {
334*3ac0a46fSAndroid Build Coastguard Worker         allocate_block(i);
335*3ac0a46fSAndroid Build Coastguard Worker     }
336*3ac0a46fSAndroid Build Coastguard Worker     for(i = 0; i < v.m_num_blocks; ++i) {
337*3ac0a46fSAndroid Build Coastguard Worker       memcpy(m_blocks[i], v.m_blocks[i], block_size * sizeof(T));
338*3ac0a46fSAndroid Build Coastguard Worker     }
339*3ac0a46fSAndroid Build Coastguard Worker     m_size = v.m_size;
340*3ac0a46fSAndroid Build Coastguard Worker     return *this;
341*3ac0a46fSAndroid Build Coastguard Worker }
342*3ac0a46fSAndroid Build Coastguard Worker template<class T, unsigned S>
allocate_block(unsigned nb)343*3ac0a46fSAndroid Build Coastguard Worker void pod_deque<T, S>::allocate_block(unsigned nb)
344*3ac0a46fSAndroid Build Coastguard Worker {
345*3ac0a46fSAndroid Build Coastguard Worker     if(nb >= m_max_blocks) {
346*3ac0a46fSAndroid Build Coastguard Worker         T** new_blocks = FX_Alloc(T*, m_max_blocks + m_block_ptr_inc);
347*3ac0a46fSAndroid Build Coastguard Worker         if(m_blocks) {
348*3ac0a46fSAndroid Build Coastguard Worker           memcpy(new_blocks, m_blocks, m_num_blocks * sizeof(T*));
349*3ac0a46fSAndroid Build Coastguard Worker           FX_Free(m_blocks);
350*3ac0a46fSAndroid Build Coastguard Worker         }
351*3ac0a46fSAndroid Build Coastguard Worker         m_blocks = new_blocks;
352*3ac0a46fSAndroid Build Coastguard Worker         m_max_blocks += m_block_ptr_inc;
353*3ac0a46fSAndroid Build Coastguard Worker     }
354*3ac0a46fSAndroid Build Coastguard Worker     m_blocks[nb] = FX_Alloc(T, block_size);
355*3ac0a46fSAndroid Build Coastguard Worker     m_num_blocks++;
356*3ac0a46fSAndroid Build Coastguard Worker }
357*3ac0a46fSAndroid Build Coastguard Worker template<class T, unsigned S>
data_ptr()358*3ac0a46fSAndroid Build Coastguard Worker inline T* pod_deque<T, S>::data_ptr()
359*3ac0a46fSAndroid Build Coastguard Worker {
360*3ac0a46fSAndroid Build Coastguard Worker     unsigned nb = m_size >> block_shift;
361*3ac0a46fSAndroid Build Coastguard Worker     if(nb >= m_num_blocks) {
362*3ac0a46fSAndroid Build Coastguard Worker         allocate_block(nb);
363*3ac0a46fSAndroid Build Coastguard Worker     }
364*3ac0a46fSAndroid Build Coastguard Worker     return m_blocks[nb] + (m_size & block_mask);
365*3ac0a46fSAndroid Build Coastguard Worker }
366*3ac0a46fSAndroid Build Coastguard Worker template<class T, unsigned S>
add(const T & val)367*3ac0a46fSAndroid Build Coastguard Worker inline void pod_deque<T, S>::add(const T& val)
368*3ac0a46fSAndroid Build Coastguard Worker {
369*3ac0a46fSAndroid Build Coastguard Worker     *data_ptr() = val;
370*3ac0a46fSAndroid Build Coastguard Worker     ++m_size;
371*3ac0a46fSAndroid Build Coastguard Worker }
372*3ac0a46fSAndroid Build Coastguard Worker template<class T, unsigned S>
remove_last()373*3ac0a46fSAndroid Build Coastguard Worker inline void pod_deque<T, S>::remove_last()
374*3ac0a46fSAndroid Build Coastguard Worker {
375*3ac0a46fSAndroid Build Coastguard Worker     if(m_size) {
376*3ac0a46fSAndroid Build Coastguard Worker         --m_size;
377*3ac0a46fSAndroid Build Coastguard Worker     }
378*3ac0a46fSAndroid Build Coastguard Worker }
379*3ac0a46fSAndroid Build Coastguard Worker template<class T, unsigned S>
modify_last(const T & val)380*3ac0a46fSAndroid Build Coastguard Worker void pod_deque<T, S>::modify_last(const T& val)
381*3ac0a46fSAndroid Build Coastguard Worker {
382*3ac0a46fSAndroid Build Coastguard Worker     remove_last();
383*3ac0a46fSAndroid Build Coastguard Worker     add(val);
384*3ac0a46fSAndroid Build Coastguard Worker }
385*3ac0a46fSAndroid Build Coastguard Worker template<class T, unsigned S>
allocate_continuous_block(unsigned num_elements)386*3ac0a46fSAndroid Build Coastguard Worker int pod_deque<T, S>::allocate_continuous_block(unsigned num_elements)
387*3ac0a46fSAndroid Build Coastguard Worker {
388*3ac0a46fSAndroid Build Coastguard Worker     if(num_elements < block_size) {
389*3ac0a46fSAndroid Build Coastguard Worker         data_ptr();
390*3ac0a46fSAndroid Build Coastguard Worker         unsigned rest = block_size - (m_size & block_mask);
391*3ac0a46fSAndroid Build Coastguard Worker         unsigned index;
392*3ac0a46fSAndroid Build Coastguard Worker         if(num_elements <= rest) {
393*3ac0a46fSAndroid Build Coastguard Worker             index = m_size;
394*3ac0a46fSAndroid Build Coastguard Worker             m_size += num_elements;
395*3ac0a46fSAndroid Build Coastguard Worker             return index;
396*3ac0a46fSAndroid Build Coastguard Worker         }
397*3ac0a46fSAndroid Build Coastguard Worker         m_size += rest;
398*3ac0a46fSAndroid Build Coastguard Worker         data_ptr();
399*3ac0a46fSAndroid Build Coastguard Worker         index = m_size;
400*3ac0a46fSAndroid Build Coastguard Worker         m_size += num_elements;
401*3ac0a46fSAndroid Build Coastguard Worker         return index;
402*3ac0a46fSAndroid Build Coastguard Worker     }
403*3ac0a46fSAndroid Build Coastguard Worker     return -1;
404*3ac0a46fSAndroid Build Coastguard Worker }
405*3ac0a46fSAndroid Build Coastguard Worker template<class T, unsigned S>
byte_size()406*3ac0a46fSAndroid Build Coastguard Worker unsigned pod_deque<T, S>::byte_size() const
407*3ac0a46fSAndroid Build Coastguard Worker {
408*3ac0a46fSAndroid Build Coastguard Worker     return m_size * sizeof(T);
409*3ac0a46fSAndroid Build Coastguard Worker }
410*3ac0a46fSAndroid Build Coastguard Worker class pod_allocator
411*3ac0a46fSAndroid Build Coastguard Worker {
412*3ac0a46fSAndroid Build Coastguard Worker public:
remove_all()413*3ac0a46fSAndroid Build Coastguard Worker     void remove_all()
414*3ac0a46fSAndroid Build Coastguard Worker     {
415*3ac0a46fSAndroid Build Coastguard Worker         if(m_num_blocks) {
416*3ac0a46fSAndroid Build Coastguard Worker             int8u** blk = m_blocks + m_num_blocks - 1;
417*3ac0a46fSAndroid Build Coastguard Worker             while(m_num_blocks--) {
418*3ac0a46fSAndroid Build Coastguard Worker                 FX_Free(*blk);
419*3ac0a46fSAndroid Build Coastguard Worker                 --blk;
420*3ac0a46fSAndroid Build Coastguard Worker             }
421*3ac0a46fSAndroid Build Coastguard Worker             FX_Free(m_blocks);
422*3ac0a46fSAndroid Build Coastguard Worker         }
423*3ac0a46fSAndroid Build Coastguard Worker         m_num_blocks = 0;
424*3ac0a46fSAndroid Build Coastguard Worker         m_max_blocks = 0;
425*3ac0a46fSAndroid Build Coastguard Worker         m_blocks = 0;
426*3ac0a46fSAndroid Build Coastguard Worker         m_buf_ptr = 0;
427*3ac0a46fSAndroid Build Coastguard Worker         m_rest = 0;
428*3ac0a46fSAndroid Build Coastguard Worker     }
~pod_allocator()429*3ac0a46fSAndroid Build Coastguard Worker     ~pod_allocator()
430*3ac0a46fSAndroid Build Coastguard Worker     {
431*3ac0a46fSAndroid Build Coastguard Worker         remove_all();
432*3ac0a46fSAndroid Build Coastguard Worker     }
433*3ac0a46fSAndroid Build Coastguard Worker     pod_allocator(unsigned block_size, unsigned block_ptr_inc = 256 - 8) :
m_block_size(block_size)434*3ac0a46fSAndroid Build Coastguard Worker         m_block_size(block_size),
435*3ac0a46fSAndroid Build Coastguard Worker         m_block_ptr_inc(block_ptr_inc),
436*3ac0a46fSAndroid Build Coastguard Worker         m_num_blocks(0),
437*3ac0a46fSAndroid Build Coastguard Worker         m_max_blocks(0),
438*3ac0a46fSAndroid Build Coastguard Worker         m_blocks(0),
439*3ac0a46fSAndroid Build Coastguard Worker         m_buf_ptr(0),
440*3ac0a46fSAndroid Build Coastguard Worker         m_rest(0)
441*3ac0a46fSAndroid Build Coastguard Worker     {
442*3ac0a46fSAndroid Build Coastguard Worker     }
443*3ac0a46fSAndroid Build Coastguard Worker     int8u* allocate(unsigned size, unsigned alignment = 1)
444*3ac0a46fSAndroid Build Coastguard Worker     {
445*3ac0a46fSAndroid Build Coastguard Worker         if(size == 0) {
446*3ac0a46fSAndroid Build Coastguard Worker             return 0;
447*3ac0a46fSAndroid Build Coastguard Worker         }
448*3ac0a46fSAndroid Build Coastguard Worker         if(size <= m_rest) {
449*3ac0a46fSAndroid Build Coastguard Worker             int8u* ptr = m_buf_ptr;
450*3ac0a46fSAndroid Build Coastguard Worker             if(alignment > 1) {
451*3ac0a46fSAndroid Build Coastguard Worker                 unsigned align = (alignment - unsigned((size_t)ptr) % alignment) % alignment;
452*3ac0a46fSAndroid Build Coastguard Worker                 size += align;
453*3ac0a46fSAndroid Build Coastguard Worker                 ptr += align;
454*3ac0a46fSAndroid Build Coastguard Worker                 if(size <= m_rest) {
455*3ac0a46fSAndroid Build Coastguard Worker                     m_rest -= size;
456*3ac0a46fSAndroid Build Coastguard Worker                     m_buf_ptr += size;
457*3ac0a46fSAndroid Build Coastguard Worker                     return ptr;
458*3ac0a46fSAndroid Build Coastguard Worker                 }
459*3ac0a46fSAndroid Build Coastguard Worker                 allocate_block(size);
460*3ac0a46fSAndroid Build Coastguard Worker                 return allocate(size - align, alignment);
461*3ac0a46fSAndroid Build Coastguard Worker             }
462*3ac0a46fSAndroid Build Coastguard Worker             m_rest -= size;
463*3ac0a46fSAndroid Build Coastguard Worker             m_buf_ptr += size;
464*3ac0a46fSAndroid Build Coastguard Worker             return ptr;
465*3ac0a46fSAndroid Build Coastguard Worker         }
466*3ac0a46fSAndroid Build Coastguard Worker         allocate_block(size + alignment - 1);
467*3ac0a46fSAndroid Build Coastguard Worker         return allocate(size, alignment);
468*3ac0a46fSAndroid Build Coastguard Worker     }
469*3ac0a46fSAndroid Build Coastguard Worker private:
allocate_block(unsigned size)470*3ac0a46fSAndroid Build Coastguard Worker     void allocate_block(unsigned size)
471*3ac0a46fSAndroid Build Coastguard Worker     {
472*3ac0a46fSAndroid Build Coastguard Worker         if(size < m_block_size) {
473*3ac0a46fSAndroid Build Coastguard Worker             size = m_block_size;
474*3ac0a46fSAndroid Build Coastguard Worker         }
475*3ac0a46fSAndroid Build Coastguard Worker         if(m_num_blocks >= m_max_blocks) {
476*3ac0a46fSAndroid Build Coastguard Worker             int8u** new_blocks = FX_Alloc(int8u*, m_max_blocks + m_block_ptr_inc);
477*3ac0a46fSAndroid Build Coastguard Worker             if(m_blocks) {
478*3ac0a46fSAndroid Build Coastguard Worker               memcpy(new_blocks, m_blocks, m_num_blocks * sizeof(int8u*));
479*3ac0a46fSAndroid Build Coastguard Worker               FX_Free(m_blocks);
480*3ac0a46fSAndroid Build Coastguard Worker             }
481*3ac0a46fSAndroid Build Coastguard Worker             m_blocks = new_blocks;
482*3ac0a46fSAndroid Build Coastguard Worker             m_max_blocks += m_block_ptr_inc;
483*3ac0a46fSAndroid Build Coastguard Worker         }
484*3ac0a46fSAndroid Build Coastguard Worker         m_blocks[m_num_blocks] = m_buf_ptr = FX_Alloc(int8u, size);
485*3ac0a46fSAndroid Build Coastguard Worker         m_num_blocks++;
486*3ac0a46fSAndroid Build Coastguard Worker         m_rest = size;
487*3ac0a46fSAndroid Build Coastguard Worker     }
488*3ac0a46fSAndroid Build Coastguard Worker     unsigned m_block_size;
489*3ac0a46fSAndroid Build Coastguard Worker     unsigned m_block_ptr_inc;
490*3ac0a46fSAndroid Build Coastguard Worker     unsigned m_num_blocks;
491*3ac0a46fSAndroid Build Coastguard Worker     unsigned m_max_blocks;
492*3ac0a46fSAndroid Build Coastguard Worker     int8u**  m_blocks;
493*3ac0a46fSAndroid Build Coastguard Worker     int8u*   m_buf_ptr;
494*3ac0a46fSAndroid Build Coastguard Worker     unsigned m_rest;
495*3ac0a46fSAndroid Build Coastguard Worker };
496*3ac0a46fSAndroid Build Coastguard Worker enum quick_sort_threshold_e {
497*3ac0a46fSAndroid Build Coastguard Worker     quick_sort_threshold = 9
498*3ac0a46fSAndroid Build Coastguard Worker };
swap_elements(T & a,T & b)499*3ac0a46fSAndroid Build Coastguard Worker template<class T> inline void swap_elements(T& a, T& b)
500*3ac0a46fSAndroid Build Coastguard Worker {
501*3ac0a46fSAndroid Build Coastguard Worker     T temp = a;
502*3ac0a46fSAndroid Build Coastguard Worker     a = b;
503*3ac0a46fSAndroid Build Coastguard Worker     b = temp;
504*3ac0a46fSAndroid Build Coastguard Worker }
505*3ac0a46fSAndroid Build Coastguard Worker }
506*3ac0a46fSAndroid Build Coastguard Worker }  // namespace pdfium
507*3ac0a46fSAndroid Build Coastguard Worker #endif
508