1 /*
2  * Copyright (c) 2004 X-Way Rights BV
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17  */
18 
19 /*!\file array.h
20  * \brief Array template class.
21  * \author Bob Deblier <bob.deblier@telenet.be>
22  * \ingroup CXX_m
23  */
24 
25 #ifndef _TEMPLATE_BEE_ARRAY_H
26 #define _TEMPLATE_BEE_ARRAY_H
27 
28 #include "beecrypt/api.h"
29 
30 #ifdef __cplusplus
31 
32 #include <new>
33 #include <cstring>
34 #include <cstdlib>
35 
36 namespace beecrypt {
37 	template<typename T> class array;
38 	template<typename T> array<T> operator+(const array<T>&, const array<T>&);
39 
40 	/*!\brief A basic array class.
41 	 * \warning Only use this class for arrays of primitive types or pointers.
42 	 */
43 	template<typename T> class array
44 	{
45 		friend array<T> operator+ <> (const array<T>&, const array<T>&);
46 
47 	protected:
48 		T* _data;
49 		int _size;
50 
51 	public:
array()52 		array() throw ()
53 		{
54 			_data = 0;
55 			_size = 0;
56 		}
throw(std::bad_alloc)57 		array(int size) throw (std::bad_alloc)
58 		{
59 			if (size > 0)
60 			{
61 				_data = (T*) calloc(size, sizeof(T));
62 				if (_data == 0)
63 					throw std::bad_alloc();
64 			}
65 			else
66 				_data = 0;
67 			_size = size;
68 		}
array(const T * data,int size)69 		array(const T* data, int size) throw (std::bad_alloc)
70 		{
71 			if (size > 0)
72 			{
73 				_data = (T*) malloc(size * sizeof(T));
74 				if (_data == 0)
75 					throw std::bad_alloc();
76 				_size = size;
77 				memcpy(_data, data, _size * sizeof(T));
78 			}
79 			else
80 			{
81 				_data = 0;
82 				_size = 0;
83 			}
84 		}
throw(std::bad_alloc)85 		array(const array& copy) throw (std::bad_alloc)
86 		{
87 			if (copy._size)
88 			{
89 				_data = (T*) malloc(copy._size * sizeof(T));
90 				if (_data == 0)
91 					throw std::bad_alloc();
92 				_size = copy._size;
93 				memcpy(_data, copy._data, _size * sizeof(T));
94 			}
95 			else
96 			{
97 				_data = 0;
98 				_size = 0;
99 			}
100 		}
throw()101 		~array() throw ()
102 		{
103 			if (_data)
104 			{
105 				free(_data);
106 				_data = 0;
107 			}
108 		}
109 
clone()110 		array* clone() const throw (std::bad_alloc)
111 		{
112 			return new array(*this);
113 		}
throw(std::bad_alloc)114 		const array& operator=(const array& set) throw (std::bad_alloc)
115 		{
116 			resize(set._size);
117 			if (_size)
118 				memcpy(_data, set._data, _size * sizeof(T));
119 
120 			return *this;
121 		}
122 		bool operator==(const array& cmp) const throw ()
123 		{
124 			if (_size != cmp._size)
125 				return false;
126 
127 			if (_size == 0 && cmp._size == 0)
128 				return true;
129 
130 			return !::memcmp(_data, cmp._data, _size * sizeof(T));
131 		}
132 		bool operator!=(const array& cmp) const throw ()
133 		{
134 			if (_size != cmp._size)
135 				return true;
136 
137 			if (_size == 0 && cmp._size == 0)
138 				return false;
139 
140 			return memcmp(_data, cmp._data, _size * sizeof(T));
141 		}
data()142 		inline T* data() throw ()
143 		{
144 			return _data;
145 		}
data()146 		inline const T* data() const throw ()
147 		{
148 			return _data;
149 		}
size()150 		inline int size() const throw ()
151 		{
152 			return _size;
153 		}
fill(T val)154 		void fill(T val) throw ()
155 		{
156 			for (int i = 0; i < _size; i++)
157 				_data[i] = val;
158 		}
replace(T * data,int size)159 		void replace(T* data, int size) throw ()
160 		{
161 			if (_data)
162 				free(_data);
163 
164 			_data = data;
165 			_size = size;
166 		}
swap(array & swp)167 		void swap(array& swp) throw ()
168 		{
169 			T* tmp_data = swp._data;
170 			int tmp_size = swp._size;
171 
172 			swp._data = _data;
173 			swp._size = _size;
174 
175 			_data = tmp_data;
176 			_size = tmp_size;
177 		}
resize(int newsize)178 		void resize(int newsize) throw (std::bad_alloc)
179 		{
180 			if (newsize > 0)
181 			{
182 				if (newsize != _size)
183 				{
184 					_data = (T*) (_data ? realloc(_data, newsize * sizeof(T)) : calloc(newsize, sizeof(T)));
185 					if (_data == 0)
186 						throw std::bad_alloc();
187 				}
188 			}
189 			else
190 			{
191 				if (_data)
192 				{
193 					free(_data);
194 					_data = 0;
195 				}
196 			}
197 			_size = newsize;
198 		}
throw()199 		inline T& operator[](int _n) throw ()
200 		{
201 			return _data[_n];
202 		}
throw()203 		inline const T operator[](int _n) const throw ()
204 		{
205 			return _data[_n];
206 		}
207 		const array& operator+=(const array& rhs) throw ()
208 		{
209 			if (rhs._size)
210 			{
211 				int _curr = _size;
212 				resize(_size+rhs._size);
213 				memcpy(_data+_curr, rhs._data, rhs._size * sizeof(T));
214 			}
215 			return *this;
216 		}
217 	};
218 
219 	template<typename T> array<T> operator+(const array<T>& lhs, const array<T>& rhs)
220 	{
221 		array<T> _con(lhs._size + rhs._size);
222 
223 		if (lhs._size)
224 			memcpy(_con._data, lhs._data, lhs._size * sizeof(T));
225 		if (rhs._size)
226 			memcpy(_con._data + lhs._size, rhs._data, rhs._size * sizeof(T));
227 
228 		return _con;
229 	}
230 
231 	typedef array<byte> bytearray;
232 	typedef array<jbyte> jbytearray;
233 	typedef array<jchar> jchararray;
234 }
235 
236 #endif
237 
238 #endif
239