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