00001
00002
00003
#ifndef CRYPTOPP_SECBLOCK_H
00004
#define CRYPTOPP_SECBLOCK_H
00005
00006
#include "config.h"
00007
#include "misc.h"
00008
#include <string.h>
00009
#include <assert.h>
00010
00011 NAMESPACE_BEGIN(CryptoPP)
00012
00013
00014
00015 template<class T>
00016 class AllocatorBase
00017 {
00018
public:
00019
typedef T value_type;
00020
typedef size_t size_type;
00021
#ifdef CRYPTOPP_MSVCRT6
00022
typedef ptrdiff_t difference_type;
00023
#else
00024
typedef std::ptrdiff_t difference_type;
00025
#endif
00026
typedef T * pointer;
00027
typedef const T * const_pointer;
00028
typedef T & reference;
00029
typedef const T & const_reference;
00030
00031 pointer address(reference r)
const {
return (&r);}
00032 const_pointer address(const_reference r)
const {
return (&r); }
00033
void construct(pointer p,
const T& val) {
new (p) T(val);}
00034
void destroy(pointer p) {p->~T();}
00035 size_type max_size()
const {
return ~size_type(0)/
sizeof(T);}
00036
00037
protected:
00038
static void CheckSize(size_t n)
00039 {
00040
if (n > ~size_t(0) /
sizeof(T))
00041
throw InvalidArgument(
"AllocatorBase: requested size would cause integer overflow");
00042 }
00043 };
00044
00045
#define CRYPTOPP_INHERIT_ALLOCATOR_TYPES \
00046
typedef typename AllocatorBase<T>::value_type value_type;\
00047
typedef typename AllocatorBase<T>::size_type size_type;\
00048
typedef typename AllocatorBase<T>::difference_type difference_type;\
00049
typedef typename AllocatorBase<T>::pointer pointer;\
00050
typedef typename AllocatorBase<T>::const_pointer const_pointer;\
00051
typedef typename AllocatorBase<T>::reference reference;\
00052
typedef typename AllocatorBase<T>::const_reference const_reference;
00053
00054
template <
class T,
class A>
00055
typename A::pointer StandardReallocate(A& a, T *p,
typename A::size_type oldSize,
typename A::size_type newSize,
bool preserve)
00056 {
00057
if (oldSize == newSize)
00058
return p;
00059
00060
if (preserve)
00061 {
00062 A b;
00063
typename A::pointer newPointer = b.allocate(newSize, NULL);
00064 memcpy(newPointer, p,
sizeof(T)*STDMIN(oldSize, newSize));
00065 a.deallocate(p, oldSize);
00066 std::swap(a, b);
00067
return newPointer;
00068 }
00069
else
00070 {
00071 a.deallocate(p, oldSize);
00072
return a.allocate(newSize, NULL);
00073 }
00074 }
00075
00076
template <
class T>
00077
class AllocatorWithCleanup :
public AllocatorBase<T>
00078 {
00079
public:
00080 CRYPTOPP_INHERIT_ALLOCATOR_TYPES
00081
00082 pointer allocate(size_type n,
const void * = NULL)
00083 {
00084 CheckSize(n);
00085
if (n == 0)
00086
return NULL;
00087
return new T[n];
00088 }
00089
00090
void deallocate(
void *p, size_type n)
00091 {
00092 memset(p, 0, n*
sizeof(T));
00093
delete [] (T *)p;
00094 }
00095
00096 pointer reallocate(T *p, size_type oldSize, size_type newSize,
bool preserve)
00097 {
00098
return StandardReallocate(*
this, p, oldSize, newSize, preserve);
00099 }
00100
00101
00102
00103
template <
class U>
struct rebind {
typedef AllocatorWithCleanup<U> other; };
00104 };
00105
00106 CRYPTOPP_DLL_TEMPLATE_CLASS AllocatorWithCleanup<byte>;
00107 CRYPTOPP_DLL_TEMPLATE_CLASS AllocatorWithCleanup<word16>;
00108 CRYPTOPP_DLL_TEMPLATE_CLASS AllocatorWithCleanup<word32>;
00109
00110
template <
class T>
00111
class NullAllocator :
public AllocatorBase<T>
00112 {
00113
public:
00114 CRYPTOPP_INHERIT_ALLOCATOR_TYPES
00115
00116 pointer allocate(size_type n,
const void * = NULL)
00117 {
00118 assert(
false);
00119
return NULL;
00120 }
00121
00122
void deallocate(
void *p, size_type n)
00123 {
00124 assert(
false);
00125 }
00126
00127 size_type max_size()
const {
return 0;}
00128 };
00129
00130
00131
00132
00133
template <
class T, size_t S,
class A = NullAllocator<T> >
00134
class FixedSizeAllocatorWithCleanup :
public AllocatorBase<T>
00135 {
00136
public:
00137 CRYPTOPP_INHERIT_ALLOCATOR_TYPES
00138
00139 FixedSizeAllocatorWithCleanup() : m_allocated(false) {}
00140
00141 pointer allocate(size_type n)
00142 {
00143
if (n <= S && !m_allocated)
00144 {
00145 m_allocated =
true;
00146
return m_array;
00147 }
00148
else
00149
return m_fallbackAllocator.allocate(n);
00150 }
00151
00152 pointer allocate(size_type n,
const void *hint)
00153 {
00154
if (n <= S && !m_allocated)
00155 {
00156 m_allocated =
true;
00157
return m_array;
00158 }
00159
else
00160
return m_fallbackAllocator.allocate(n, hint);
00161 }
00162
00163
void deallocate(
void *p, size_type n)
00164 {
00165
if (p == m_array)
00166 {
00167 assert(n <= S);
00168 assert(m_allocated);
00169 m_allocated =
false;
00170 memset(p, 0, n*
sizeof(T));
00171 }
00172
else
00173 m_fallbackAllocator.deallocate(p, n);
00174 }
00175
00176 pointer reallocate(pointer p, size_type oldSize, size_type newSize,
bool preserve)
00177 {
00178
if (p == m_array && newSize <= S)
00179 {
00180 assert(oldSize <= S);
00181
if (oldSize > newSize)
00182 memset(p + newSize, 0, (oldSize-newSize)*
sizeof(T));
00183
return p;
00184 }
00185
00186 pointer newPointer = allocate(newSize, NULL);
00187
if (preserve)
00188 memcpy(newPointer, p,
sizeof(T)*STDMIN(oldSize, newSize));
00189 deallocate(p, oldSize);
00190
return newPointer;
00191 }
00192
00193 size_type max_size()
const {
return STDMAX(m_fallbackAllocator.max_size(), S);}
00194
00195
private:
00196 T m_array[S];
00197 A m_fallbackAllocator;
00198
bool m_allocated;
00199 };
00200
00201
00202
template <
class T,
class A = AllocatorWithCleanup<T> >
00203 class SecBlock
00204 {
00205
public:
00206
explicit SecBlock(
unsigned int size=0)
00207 : m_size(size) {m_ptr = m_alloc.allocate(size, NULL);}
00208
SecBlock(
const SecBlock<T, A> &t)
00209 : m_size(t.m_size) {m_ptr = m_alloc.allocate(m_size, NULL); memcpy(m_ptr, t.m_ptr, m_size*
sizeof(T));}
00210
SecBlock(
const T *t,
unsigned int len)
00211 : m_size(len)
00212 {
00213 m_ptr = m_alloc.allocate(len, NULL);
00214
if (t == NULL)
00215 memset(m_ptr, 0, len*
sizeof(T));
00216
else
00217 memcpy(m_ptr, t, len*
sizeof(T));
00218 }
00219
00220 ~
SecBlock()
00221 {m_alloc.deallocate(m_ptr, m_size);}
00222
00223 operator const void *()
const
00224
{
return m_ptr;}
00225 operator void *()
00226 {
return m_ptr;}
00227
#if defined(__GNUC__) && __GNUC__ < 3 // reduce warnings
00228
operator const void *()
00229 {
return m_ptr;}
00230
#endif
00231
00232 operator const T *()
const
00233
{
return m_ptr;}
00234 operator T *()
00235 {
return m_ptr;}
00236
#if defined(__GNUC__) && __GNUC__ < 3 // reduce warnings
00237
operator const T *()
00238 {
return m_ptr;}
00239
#endif
00240
00241
template <
typename I>
00242 T *operator +(I offset)
00243 {
return m_ptr+offset;}
00244
00245
template <
typename I>
00246
const T *operator +(I offset)
const
00247
{
return m_ptr+offset;}
00248
00249
template <
typename I>
00250 T& operator[](I index)
00251 {assert(index >= 0 && (
unsigned int)index < m_size);
return m_ptr[index];}
00252
00253
template <
typename I>
00254
const T& operator[](I index)
const
00255
{assert(index >= 0 && (
unsigned int)index < m_size);
return m_ptr[index];}
00256
00257
typedef typename A::value_type value_type;
00258
typedef typename A::pointer iterator;
00259
typedef typename A::const_pointer const_iterator;
00260
typedef typename A::size_type size_type;
00261
00262 iterator begin()
00263 {
return m_ptr;}
00264 const_iterator begin()
const
00265
{
return m_ptr;}
00266 iterator end()
00267 {
return m_ptr+m_size;}
00268 const_iterator end()
const
00269
{
return m_ptr+m_size;}
00270
00271
typename A::pointer data() {
return m_ptr;}
00272
typename A::const_pointer data()
const {
return m_ptr;}
00273
00274 size_type size()
const {
return m_size;}
00275
bool empty()
const {
return m_size == 0;}
00276
00277
void Assign(
const T *t,
unsigned int len)
00278 {
00279 New(len);
00280 memcpy(m_ptr, t, len*
sizeof(T));
00281 }
00282
00283
void Assign(
const SecBlock<T, A> &t)
00284 {
00285 New(t.m_size);
00286 memcpy(m_ptr, t.m_ptr, m_size*
sizeof(T));
00287 }
00288
00289
SecBlock& operator=(
const SecBlock<T, A> &t)
00290 {
00291 Assign(t);
00292
return *
this;
00293 }
00294
00295
bool operator==(
const SecBlock<T, A> &t)
const
00296
{
00297
return m_size == t.m_size && memcmp(m_ptr, t.m_ptr, m_size*
sizeof(T)) == 0;
00298 }
00299
00300
bool operator!=(
const SecBlock<T, A> &t)
const
00301
{
00302
return !operator==(t);
00303 }
00304
00305
void New(
unsigned int newSize)
00306 {
00307 m_ptr = m_alloc.reallocate(m_ptr, m_size, newSize,
false);
00308 m_size = newSize;
00309 }
00310
00311
void CleanNew(
unsigned int newSize)
00312 {
00313 New(newSize);
00314 memset(m_ptr, 0, m_size*
sizeof(T));
00315 }
00316
00317
void Grow(
unsigned int newSize)
00318 {
00319
if (newSize > m_size)
00320 {
00321 m_ptr = m_alloc.reallocate(m_ptr, m_size, newSize,
true);
00322 m_size = newSize;
00323 }
00324 }
00325
00326
void CleanGrow(
unsigned int newSize)
00327 {
00328
if (newSize > m_size)
00329 {
00330 m_ptr = m_alloc.reallocate(m_ptr, m_size, newSize,
true);
00331 memset(m_ptr+m_size, 0, (newSize-m_size)*
sizeof(T));
00332 m_size = newSize;
00333 }
00334 }
00335
00336
void resize(
unsigned int newSize)
00337 {
00338 m_ptr = m_alloc.reallocate(m_ptr, m_size, newSize,
true);
00339 m_size = newSize;
00340 }
00341
00342
void swap(
SecBlock<T, A> &b)
00343 {
00344 std::swap(m_alloc, b.m_alloc);
00345 std::swap(m_size, b.m_size);
00346 std::swap(m_ptr, b.m_ptr);
00347 }
00348
00349
00350 A m_alloc;
00351
unsigned int m_size;
00352 T *m_ptr;
00353 };
00354
00355
typedef SecBlock<byte> SecByteBlock;
00356
typedef SecBlock<word> SecWordBlock;
00357
00358
template <
class T,
unsigned int S,
class A = FixedSizeAllocatorWithCleanup<T, S> >
00359
class FixedSizeSecBlock :
public SecBlock<T, A>
00360 {
00361
public:
00362
explicit FixedSizeSecBlock() :
SecBlock<T, A>(S) {}
00363 };
00364
00365
template <
class T,
unsigned int S,
class A = FixedSizeAllocatorWithCleanup<T, S, AllocatorWithCleanup<T> > >
00366
class SecBlockWithHint :
public SecBlock<T, A>
00367 {
00368
public:
00369
explicit SecBlockWithHint(
unsigned int size) :
SecBlock<T, A>(size) {}
00370 };
00371
00372
template<
class T,
class U>
00373
inline bool operator==(
const CryptoPP::AllocatorWithCleanup<T>&,
const CryptoPP::AllocatorWithCleanup<U>&) {
return (
true);}
00374
template<
class T,
class U>
00375
inline bool operator!=(
const CryptoPP::AllocatorWithCleanup<T>&,
const CryptoPP::AllocatorWithCleanup<U>&) {
return (
false);}
00376
00377 NAMESPACE_END
00378
00379 NAMESPACE_BEGIN(std)
00380 template <class T, class A>
00381 inline
void swap(CryptoPP::
SecBlock<T, A> &a, CryptoPP::
SecBlock<T, A> &b)
00382 {
00383 a.swap(b);
00384 }
00385
00386
#if defined(_STLPORT_VERSION) && !defined(_STLP_MEMBER_TEMPLATE_CLASSES)
00387
template <
class _Tp1,
class _Tp2>
00388
inline CryptoPP::AllocatorWithCleanup<_Tp2>&
00389 __stl_alloc_rebind(CryptoPP::AllocatorWithCleanup<_Tp1>& __a,
const _Tp2*)
00390 {
00391
return (CryptoPP::AllocatorWithCleanup<_Tp2>&)(__a);
00392 }
00393
#endif
00394
00395 NAMESPACE_END
00396
00397
#endif