~zooko/cryptopp/trunk

« back to all changes in this revision

Viewing changes to secblock.h

  • Committer: weidai
  • Date: 2011-01-07 01:30:24 UTC
  • Revision ID: svn-v4:57ff6487-cd31-0410-9ec3-f628ee90f5f0:trunk/c5:522
fix for compiling with Clang from Marshall Clow

Show diffs side-by-side

added added

removed removed

Lines of Context:
5
5
 
6
6
#include "config.h"
7
7
#include "misc.h"
8
 
#include <string.h>             // CodeWarrior doesn't have memory.h
9
8
#include <assert.h>
10
9
 
11
10
NAMESPACE_BEGIN(CryptoPP)
65
64
 
66
65
        if (preserve)
67
66
        {
68
 
                A b;
69
 
                typename A::pointer newPointer = b.allocate(newSize, NULL);
 
67
                typename A::pointer newPointer = a.allocate(newSize, NULL);
70
68
                memcpy_s(newPointer, sizeof(T)*newSize, p, sizeof(T)*STDMIN(oldSize, newSize));
71
69
                a.deallocate(p, oldSize);
72
 
                std::swap(a, b);
73
70
                return newPointer;
74
71
        }
75
72
        else
83
80
#pragma warning(pop)
84
81
#endif
85
82
 
86
 
template <class T>
 
83
template <class T, bool T_Align16 = false>
87
84
class AllocatorWithCleanup : public AllocatorBase<T>
88
85
{
89
86
public:
91
88
 
92
89
        pointer allocate(size_type n, const void * = NULL)
93
90
        {
94
 
                CheckSize(n);
 
91
                this->CheckSize(n);
95
92
                if (n == 0)
96
93
                        return NULL;
97
 
                return new T[n];
 
94
 
 
95
#if CRYPTOPP_BOOL_ALIGN16_ENABLED
 
96
                if (T_Align16 && n*sizeof(T) >= 16)
 
97
                        return (pointer)AlignedAllocate(n*sizeof(T));
 
98
#endif
 
99
 
 
100
                return (pointer)UnalignedAllocate(n*sizeof(T));
98
101
        }
99
102
 
100
103
        void deallocate(void *p, size_type n)
101
104
        {
102
 
                memset(p, 0, n*sizeof(T));
103
 
                delete [] (T *)p;
 
105
                SecureWipeArray((pointer)p, n);
 
106
 
 
107
#if CRYPTOPP_BOOL_ALIGN16_ENABLED
 
108
                if (T_Align16 && n*sizeof(T) >= 16)
 
109
                        return AlignedDeallocate(p);
 
110
#endif
 
111
 
 
112
                UnalignedDeallocate(p);
104
113
        }
105
114
 
106
115
        pointer reallocate(T *p, size_type oldSize, size_type newSize, bool preserve)
110
119
 
111
120
        // VS.NET STL enforces the policy of "All STL-compliant allocators have to provide a
112
121
        // template class member called rebind".
113
 
    template <class U> struct rebind { typedef AllocatorWithCleanup<U> other; };
 
122
    template <class U> struct rebind { typedef AllocatorWithCleanup<U, T_Align16> other; };
 
123
#if _MSC_VER >= 1500
 
124
        AllocatorWithCleanup() {}
 
125
        template <class U, bool A> AllocatorWithCleanup(const AllocatorWithCleanup<U, A> &) {}
 
126
#endif
114
127
};
115
128
 
116
129
CRYPTOPP_DLL_TEMPLATE_CLASS AllocatorWithCleanup<byte>;
117
130
CRYPTOPP_DLL_TEMPLATE_CLASS AllocatorWithCleanup<word16>;
118
131
CRYPTOPP_DLL_TEMPLATE_CLASS AllocatorWithCleanup<word32>;
 
132
CRYPTOPP_DLL_TEMPLATE_CLASS AllocatorWithCleanup<word64>;
 
133
#if CRYPTOPP_BOOL_X86
 
134
CRYPTOPP_DLL_TEMPLATE_CLASS AllocatorWithCleanup<word, true>;   // for Integer
 
135
#endif
119
136
 
120
137
template <class T>
121
138
class NullAllocator : public AllocatorBase<T>
140
157
// This allocator can't be used with standard collections because
141
158
// they require that all objects of the same allocator type are equivalent.
142
159
// So this is for use with SecBlock only.
143
 
template <class T, size_t S, class A = NullAllocator<T> >
 
160
template <class T, size_t S, class A = NullAllocator<T>, bool T_Align16 = false>
144
161
class FixedSizeAllocatorWithCleanup : public AllocatorBase<T>
145
162
{
146
163
public:
150
167
 
151
168
        pointer allocate(size_type n)
152
169
        {
 
170
                assert(IsAlignedOn(m_array, 8));
 
171
 
153
172
                if (n <= S && !m_allocated)
154
173
                {
155
174
                        m_allocated = true;
156
 
                        return m_array;
 
175
                        return GetAlignedArray();
157
176
                }
158
177
                else
159
178
                        return m_fallbackAllocator.allocate(n);
164
183
                if (n <= S && !m_allocated)
165
184
                {
166
185
                        m_allocated = true;
167
 
                        return m_array;
 
186
                        return GetAlignedArray();
168
187
                }
169
188
                else
170
189
                        return m_fallbackAllocator.allocate(n, hint);
172
191
 
173
192
        void deallocate(void *p, size_type n)
174
193
        {
175
 
                if (p == m_array)
 
194
                if (p == GetAlignedArray())
176
195
                {
177
196
                        assert(n <= S);
178
197
                        assert(m_allocated);
179
198
                        m_allocated = false;
180
 
                        memset(p, 0, n*sizeof(T));
 
199
                        SecureWipeArray((pointer)p, n);
181
200
                }
182
201
                else
183
202
                        m_fallbackAllocator.deallocate(p, n);
185
204
 
186
205
        pointer reallocate(pointer p, size_type oldSize, size_type newSize, bool preserve)
187
206
        {
188
 
                if (p == m_array && newSize <= S)
 
207
                if (p == GetAlignedArray() && newSize <= S)
189
208
                {
190
209
                        assert(oldSize <= S);
191
210
                        if (oldSize > newSize)
192
 
                                memset(p + newSize, 0, (oldSize-newSize)*sizeof(T));
 
211
                                SecureWipeArray(p+newSize, oldSize-newSize);
193
212
                        return p;
194
213
                }
195
214
 
203
222
        size_type max_size() const {return STDMAX(m_fallbackAllocator.max_size(), S);}
204
223
 
205
224
private:
 
225
#ifdef __BORLANDC__
 
226
        T* GetAlignedArray() {return m_array;}
206
227
        T m_array[S];
 
228
#else
 
229
        T* GetAlignedArray() {return (CRYPTOPP_BOOL_ALIGN16_ENABLED && T_Align16) ? (T*)(((byte *)m_array) + (0-(size_t)m_array)%16) : m_array;}
 
230
        CRYPTOPP_ALIGN_DATA(8) T m_array[(CRYPTOPP_BOOL_ALIGN16_ENABLED && T_Align16) ? S+8/sizeof(T) : S];
 
231
#endif
207
232
        A m_fallbackAllocator;
208
233
        bool m_allocated;
209
234
};
218
243
        typedef typename A::const_pointer const_iterator;
219
244
        typedef typename A::size_type size_type;
220
245
 
221
 
    explicit SecBlock(size_type size=0)
 
246
        explicit SecBlock(size_type size=0)
222
247
                : m_size(size) {m_ptr = m_alloc.allocate(size, NULL);}
223
248
        SecBlock(const SecBlock<T, A> &t)
224
249
                : m_size(t.m_size) {m_ptr = m_alloc.allocate(m_size, NULL); memcpy_s(m_ptr, m_size*sizeof(T), t.m_ptr, m_size*sizeof(T));}
227
252
        {
228
253
                m_ptr = m_alloc.allocate(len, NULL);
229
254
                if (t == NULL)
230
 
                        memset(m_ptr, 0, len*sizeof(T));
 
255
                        memset_z(m_ptr, 0, len*sizeof(T));
231
256
                else
232
257
                        memcpy(m_ptr, t, len*sizeof(T));
233
258
        }
235
260
        ~SecBlock()
236
261
                {m_alloc.deallocate(m_ptr, m_size);}
237
262
 
 
263
#ifdef __BORLANDC__
 
264
        operator T *() const
 
265
                {return (T*)m_ptr;}
 
266
#else
238
267
        operator const void *() const
239
268
                {return m_ptr;}
240
269
        operator void *()
241
270
                {return m_ptr;}
242
 
#if defined(__GNUC__) && __GNUC__ < 3   // reduce warnings
243
 
        operator const void *()
244
 
                {return m_ptr;}
245
 
#endif
246
271
 
247
272
        operator const T *() const
248
273
                {return m_ptr;}
249
274
        operator T *()
250
275
                {return m_ptr;}
251
 
#if defined(__GNUC__) && __GNUC__ < 3   // reduce warnings
252
 
        operator const T *()
253
 
                {return m_ptr;}
254
276
#endif
255
277
 
256
278
//      T *operator +(size_type offset)
280
302
        size_type size() const {return m_size;}
281
303
        bool empty() const {return m_size == 0;}
282
304
 
 
305
        byte * BytePtr() {return (byte *)m_ptr;}
 
306
        const byte * BytePtr() const {return (const byte *)m_ptr;}
283
307
        size_type SizeInBytes() const {return m_size*sizeof(T);}
284
308
 
 
309
        //! set contents and size
285
310
        void Assign(const T *t, size_type len)
286
311
        {
287
312
                New(len);
288
313
                memcpy_s(m_ptr, m_size*sizeof(T), t, len*sizeof(T));
289
314
        }
290
315
 
 
316
        //! copy contents and size from another SecBlock
291
317
        void Assign(const SecBlock<T, A> &t)
292
318
        {
293
 
                New(t.m_size);
294
 
                memcpy_s(m_ptr, m_size*sizeof(T), t.m_ptr, m_size*sizeof(T));
 
319
                if (this != &t)
 
320
                {
 
321
                        New(t.m_size);
 
322
                        memcpy_s(m_ptr, m_size*sizeof(T), t.m_ptr, m_size*sizeof(T));
 
323
                }
295
324
        }
296
325
 
297
326
        SecBlock<T, A>& operator=(const SecBlock<T, A> &t)
300
329
                return *this;
301
330
        }
302
331
 
 
332
        // append to this object
303
333
        SecBlock<T, A>& operator+=(const SecBlock<T, A> &t)
304
334
        {
305
335
                size_type oldSize = m_size;
308
338
                return *this;
309
339
        }
310
340
 
 
341
        // append operator
311
342
        SecBlock<T, A> operator+(const SecBlock<T, A> &t)
312
343
        {
313
344
                SecBlock<T, A> result(m_size+t.m_size);
318
349
 
319
350
        bool operator==(const SecBlock<T, A> &t) const
320
351
        {
321
 
                return m_size == t.m_size && memcmp(m_ptr, t.m_ptr, m_size*sizeof(T)) == 0;
 
352
                return m_size == t.m_size && VerifyBufsEqual(m_ptr, t.m_ptr, m_size*sizeof(T));
322
353
        }
323
354
 
324
355
        bool operator!=(const SecBlock<T, A> &t) const
326
357
                return !operator==(t);
327
358
        }
328
359
 
 
360
        //! change size, without preserving contents
329
361
        void New(size_type newSize)
330
362
        {
331
363
                m_ptr = m_alloc.reallocate(m_ptr, m_size, newSize, false);
332
364
                m_size = newSize;
333
365
        }
334
366
 
 
367
        //! change size and set contents to 0
335
368
        void CleanNew(size_type newSize)
336
369
        {
337
370
                New(newSize);
338
 
                memset(m_ptr, 0, m_size*sizeof(T));
 
371
                memset_z(m_ptr, 0, m_size*sizeof(T));
339
372
        }
340
373
 
 
374
        //! change size only if newSize > current size. contents are preserved
341
375
        void Grow(size_type newSize)
342
376
        {
343
377
                if (newSize > m_size)
347
381
                }
348
382
        }
349
383
 
 
384
        //! change size only if newSize > current size. contents are preserved and additional area is set to 0
350
385
        void CleanGrow(size_type newSize)
351
386
        {
352
387
                if (newSize > m_size)
357
392
                }
358
393
        }
359
394
 
 
395
        //! change size and preserve contents
360
396
        void resize(size_type newSize)
361
397
        {
362
398
                m_ptr = m_alloc.reallocate(m_ptr, m_size, newSize, true);
363
399
                m_size = newSize;
364
400
        }
365
401
 
 
402
        //! swap contents and size with another SecBlock
366
403
        void swap(SecBlock<T, A> &b)
367
404
        {
368
405
                std::swap(m_alloc, b.m_alloc);
377
414
};
378
415
 
379
416
typedef SecBlock<byte> SecByteBlock;
 
417
typedef SecBlock<byte, AllocatorWithCleanup<byte, true> > AlignedSecByteBlock;
380
418
typedef SecBlock<word> SecWordBlock;
381
419
 
 
420
//! a SecBlock with fixed size, allocated statically
382
421
template <class T, unsigned int S, class A = FixedSizeAllocatorWithCleanup<T, S> >
383
422
class FixedSizeSecBlock : public SecBlock<T, A>
384
423
{
386
425
        explicit FixedSizeSecBlock() : SecBlock<T, A>(S) {}
387
426
};
388
427
 
 
428
template <class T, unsigned int S, bool T_Align16 = true>
 
429
class FixedSizeAlignedSecBlock : public FixedSizeSecBlock<T, S, FixedSizeAllocatorWithCleanup<T, S, NullAllocator<T>, T_Align16> >
 
430
{
 
431
};
 
432
 
 
433
//! a SecBlock that preallocates size S statically, and uses the heap when this size is exceeded
389
434
template <class T, unsigned int S, class A = FixedSizeAllocatorWithCleanup<T, S, AllocatorWithCleanup<T> > >
390
435
class SecBlockWithHint : public SecBlock<T, A>
391
436
{
393
438
        explicit SecBlockWithHint(size_t size) : SecBlock<T, A>(size) {}
394
439
};
395
440
 
396
 
template<class T, class U>
397
 
inline bool operator==(const CryptoPP::AllocatorWithCleanup<T>&, const CryptoPP::AllocatorWithCleanup<U>&) {return (true);}
398
 
template<class T, class U>
399
 
inline bool operator!=(const CryptoPP::AllocatorWithCleanup<T>&, const CryptoPP::AllocatorWithCleanup<U>&) {return (false);}
 
441
template<class T, bool A, class U, bool B>
 
442
inline bool operator==(const CryptoPP::AllocatorWithCleanup<T, A>&, const CryptoPP::AllocatorWithCleanup<U, B>&) {return (true);}
 
443
template<class T, bool A, class U, bool B>
 
444
inline bool operator!=(const CryptoPP::AllocatorWithCleanup<T, A>&, const CryptoPP::AllocatorWithCleanup<U, B>&) {return (false);}
400
445
 
401
446
NAMESPACE_END
402
447
 
407
452
        a.swap(b);
408
453
}
409
454
 
410
 
#if defined(_STLPORT_VERSION) && !defined(_STLP_MEMBER_TEMPLATE_CLASSES)
 
455
#if defined(_STLP_DONT_SUPPORT_REBIND_MEMBER_TEMPLATE) || (defined(_STLPORT_VERSION) && !defined(_STLP_MEMBER_TEMPLATE_CLASSES))
 
456
// working for STLport 5.1.3 and MSVC 6 SP5
411
457
template <class _Tp1, class _Tp2>
412
458
inline CryptoPP::AllocatorWithCleanup<_Tp2>&
413
459
__stl_alloc_rebind(CryptoPP::AllocatorWithCleanup<_Tp1>& __a, const _Tp2*)