Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members

secblock.h

00001 // secblock.h - written and placed in the public domain by Wei Dai 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> // CodeWarrior doesn't have memory.h 00009 #include <assert.h> 00010 00011 NAMESPACE_BEGIN(CryptoPP) 00012 00013 // ************** secure memory allocation *************** 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 // VS.NET STL enforces the policy of "All STL-compliant allocators have to provide a 00093 // template class member called rebind". 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 // this allocator can't be used with standard collections 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 //! a block of memory allocated using A 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 //private: 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

Generated on Wed Jul 28 08:07:08 2004 for Crypto++ by doxygen 1.3.7