MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
block.hpp
1 /*
2  Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
3 
4  This program is free software; you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation; version 2 of the License.
7 
8  This program is distributed in the hope that it will be useful,
9  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  GNU General Public License for more details.
12 
13  You should have received a copy of the GNU General Public License
14  along with this program; see the file COPYING. If not, write to the
15  Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
16  MA 02110-1301 USA.
17 */
18 
19 
20 /* block.hpp provides word and byte blocks with configurable allocators
21 */
22 
23 
24 #ifndef TAO_CRYPT_BLOCK_HPP
25 #define TAO_CRYPT_BLOCK_HPP
26 
27 #include "misc.hpp"
28 #include <string.h> // memcpy
29 #include <stddef.h> // ptrdiff_t
30 
31 #ifdef USE_SYS_STL
32  #include <algorithm>
33 #else
34  #include "algorithm.hpp"
35 #endif
36 
37 
38 namespace STL = STL_NAMESPACE;
39 
40 
41 namespace TaoCrypt {
42 
43 
44 // a Base class for Allocators
45 template<class T>
47 {
48 public:
49  typedef T value_type;
50  typedef size_t size_type;
51  typedef ptrdiff_t difference_type;
52  typedef T* pointer;
53  typedef const T* const_pointer;
54  typedef T& reference;
55  typedef const T& const_reference;
56 
57  pointer address(reference r) const {return (&r);}
58  const_pointer address(const_reference r) const {return (&r); }
59  void construct(pointer p, const T& val) {new (p) T(val);}
60  void destroy(pointer p) {p->~T();}
61  size_type max_size() const {return ~size_type(0)/sizeof(T);}
62 protected:
63 };
64 
65 
66 // General purpose realloc
67 template<typename T, class A>
68 typename A::pointer StdReallocate(A& a, T* p, typename A::size_type oldSize,
69  typename A::size_type newSize, bool preserve)
70 {
71  if (oldSize == newSize)
72  return p;
73 
74  if (preserve) {
75  A b = A();
76  typename A::pointer newPointer = b.allocate(newSize, 0);
77  memcpy(newPointer, p, sizeof(T) * min((word32) oldSize, (word32) newSize));
78  a.deallocate(p, oldSize);
79  STL::swap(a, b);
80  return newPointer;
81  }
82  else {
83  a.deallocate(p, oldSize);
84  return a.allocate(newSize, 0);
85  }
86 }
87 
88 
89 // Allocator that zeros out memory on deletion
90 template <class T>
92 {
93 public:
94  typedef typename AllocatorBase<T>::pointer pointer;
95  typedef typename AllocatorBase<T>::size_type size_type;
96 
97  pointer allocate(size_type n, const void* = 0)
98  {
99  if (n > this->max_size())
100  return 0;
101  if (n == 0)
102  return 0;
103  return NEW_TC T[n];
104  }
105 
106  void deallocate(void* p, size_type n)
107  {
108  memset(p, 0, n * sizeof(T));
109  tcArrayDelete((T*)p);
110  }
111 
112  pointer reallocate(T* p, size_type oldSize, size_type newSize,
113  bool preserve)
114  {
115  return StdReallocate(*this, p, oldSize, newSize, preserve);
116  }
117 
118  // VS.NET STL enforces the policy of "All STL-compliant allocators have to
119  // provide a template class member called rebind".
120  template <class U> struct rebind { typedef AllocatorWithCleanup<U> other;};
121 };
122 
123 
124 // Block class template
125 template<typename T, class A = AllocatorWithCleanup<T> >
126 class Block {
127 public:
128  explicit Block(word32 s = 0) : sz_(s), buffer_(allocator_.allocate(sz_))
129  { CleanNew(sz_); }
130 
131  Block(const T* buff, word32 s) : sz_(s), buffer_(allocator_.allocate(sz_))
132  { memcpy(buffer_, buff, sz_ * sizeof(T)); }
133 
134  Block(const Block& that) : sz_(that.sz_), buffer_(allocator_.allocate(sz_))
135  { memcpy(buffer_, that.buffer_, sz_ * sizeof(T)); }
136 
137  Block& operator=(const Block& that) {
138  Block tmp(that);
139  Swap(tmp);
140  return *this;
141  }
142 
143  T& operator[] (word32 i) { return buffer_[i]; }
144  const T& operator[] (word32 i) const { return buffer_[i]; }
145 
146  T* operator+ (word32 i) { return buffer_ + i; }
147  const T* operator+ (word32 i) const { return buffer_ + i; }
148 
149  word32 size() const { return sz_; }
150 
151  T* get_buffer() const { return buffer_; }
152  T* begin() const { return get_buffer(); }
153 
154  void CleanGrow(word32 newSize)
155  {
156  if (newSize > sz_) {
157  buffer_ = allocator_.reallocate(buffer_, sz_, newSize, true);
158  memset(buffer_ + sz_, 0, (newSize - sz_) * sizeof(T));
159  sz_ = newSize;
160  }
161  }
162 
163  void CleanNew(word32 newSize)
164  {
165  New(newSize);
166  memset(buffer_, 0, sz_ * sizeof(T));
167  }
168 
169  void New(word32 newSize)
170  {
171  buffer_ = allocator_.reallocate(buffer_, sz_, newSize, false);
172  sz_ = newSize;
173  }
174 
175  void resize(word32 newSize)
176  {
177  buffer_ = allocator_.reallocate(buffer_, sz_, newSize, true);
178  sz_ = newSize;
179  }
180 
181  void Swap(Block& other) {
182  STL::swap(sz_, other.sz_);
183  STL::swap(buffer_, other.buffer_);
184  STL::swap(allocator_, other.allocator_);
185  }
186 
187  ~Block() { allocator_.deallocate(buffer_, sz_); }
188 private:
189  word32 sz_; // size in Ts
190  T* buffer_;
191  A allocator_;
192 };
193 
194 
195 typedef Block<byte> ByteBlock;
196 typedef Block<word> WordBlock;
197 typedef Block<word32> Word32Block;
198 
199 
200 } // namespace
201 
202 #endif // TAO_CRYPT_BLOCK_HPP