1 /*
2 
3 Copyright (c) 2002-2008, Yauheni Akhotnikau
4 Copyright (c) 2008-2016, The SObjectizer Project
5 All rights reserved.
6 
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions are met:
9 
10 - Redistributions of source code must retain the above copyright notice, this
11 list of conditions and the following disclaimer.
12 
13 - Redistributions in binary form must reproduce the above copyright notice, this
14 list of conditions and the following disclaimer in the documentation and/or
15 other materials provided with the distribution.
16 
17 - The name of the author may not be used to endorse or promote products derived
18 from this software without specific prior written permission.
19 
20 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
21 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
22 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
23 EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
25 OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
28 IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
29 OF SUCH DAMAGE.
30 
31 */
32 
33 /*!
34 	\file
35 	\brief mem_buf class.
36 */
37 
38 #if !defined( OESS_2_IO_MEM_BUF_HPP )
39 #define OESS_2_IO_MEM_BUF_HPP
40 
41 #include <oess_2/io/h/declspec.hpp>
42 
43 #include <oess_2/io/h/binbuffer.hpp>
44 
45 #include <vector>
46 #include <algorithm>
47 
48 namespace oess_2 {
49 
50 namespace io {
51 
52 #if defined( _MSC_VER )
53 	#pragma warning(push)
54 	#pragma warning(disable: 4251)
55 	#pragma warning(disable: 4275)
56 #endif
57 
58 //
59 // mem_buf_t
60 //
61 
62 //! Binary input/output stream with growing memory buffer.
63 /*!
64  * \note
65  * Copy operation copies the current position in source buffer too:
66 \code
67 oess_2::io::mem_buf_t buf1( 1024 );
68 oess_2::io::mem_buf_t buf2( 2048 );
69 
70 buf1.set_size( 256 );
71 buf1.set_pos( 26 );
72 
73 buf2.set_size( 512 );
74 buf2.set_pos( 384 );
75 
76 buf2 = buf1;
77 // 26 == buf2.pos()
78 \endcode
79  */
80 class	OESS_2_IO_TYPE	mem_buf_t :
81 	public ibinbuffer_t,
82 	public obinbuffer_t
83 {
84 	public :
85 		//! Default constructor.
86 		/*!
87 		 * Initial capacity is e_initial_capacity.
88 		 */
89 		mem_buf_t();
90 		//! Initializing constructor.
91 		mem_buf_t(
92 			//! Initial capacity of the buffer.
93 			size_t capacity );
94 		mem_buf_t(
95 			const mem_buf_t & o );
96 		virtual ~mem_buf_t();
97 
98 		mem_buf_t &
99 		operator=(
100 			const mem_buf_t & o );
101 
102 		enum {
103 			e_initial_capacity = 64
104 		};
105 
106 		//! The current capacity.
107 		virtual size_t
108 		capacity() const override;
109 
110 		//! Recreate buffer.
111 		/*!
112 		 * A new buffer is always allocated.
113 		 *
114 		 * If \a save_contents is true then the current buffer value
115 		 * is copied into the new buffer.
116 		 *
117 		 * Value of 'size' will be min(new_capacity, old_size).
118 		 *
119 		 * The current position become 0.
120 		 */
121 		void
122 		change_capacity(
123 			//! A new capacity of buffer.
124 			size_t new_capacity,
125 			//! Should the current content be saved?
126 			bool save_contents = true );
127 
128 		//! The current size of the buffer.
129 		/*!
130 		 * Returns amount of data written into the buffer.
131 		 */
132 		virtual size_t
133 		size() const override;
134 
135 		//! Change the amount of data in the buffer.
136 		/*!
137 		 * The current position become 0.
138 		 *
139 		 * The size is changed only of new_size <= capacity().
140 		 */
141 		void
142 		change_size(
143 			//! New data size.
144 			size_t new_size );
145 
146 		//! The current position in the buffer.
147 		virtual size_t
148 		pos() const override;
149 
150 		//! Change the current position.
151 		/*!
152 		 * The current position is changed only if pos <= size().
153 		 */
154 		void
155 		set_pos( size_t pos );
156 
157 		/*!
158 		 * \return true if pos() == size().
159 		 */
160 		virtual bool
161 		eof() const override;
162 
163 		//! A pointer to the beginning of the buffer.
164 		const oess_2::char_t *
165 		ptr() const;
166 
167 		//! A pointer to the current position in the buffer.
168 		const oess_2::char_t *
169 		current_ptr() const;
170 
171 		//! Copy a part of buffer content into another buffer.
172 		/*!
173 		 * \a count bytes from position \a from_pos are copied into
174 		 * position \a to_pos of buffer \a to.
175 		 *
176 		 * The current position in \a to buffer is not changed.
177 		 *
178 		 * \note
179 		 * The presence of data is not checked.
180 		 */
181 		void
182 		subbuf(
183 			//! Source position in this buffer.
184 			size_t from_pos,
185 			//! A buffer-receiver.
186 			mem_buf_t & to,
187 			//! Target position in buffer-receiver.
188 			size_t to_pos,
189 			//! Count of bytes to be copied.
190 			size_t count ) const;
191 
192 		//! Copy a part of buffer content into the specified memory location.
193 		/*!
194 		 * \a count bytes from position \a from_pos are copied into \a to.
195 		 *
196 		 * \note
197 		 * The presence of data is not checked.
198 		 */
199 		void
200 		subbuf(
201 			//! Source position in this buffer.
202 			size_t from_pos,
203 			//! Memory area to which data will be copied.
204 			void * to,
205 			//! Count of bytes to be copied.
206 			size_t count ) const;
207 
208 		//! Insertion of data.
209 		/*!
210 		 * Insertion of \a count bytes from buffer \a from starting from
211 		 * position \a from_pos into position \a to_pos.
212 		 * The current content at position \a to_pos is moved to
213 		 * position (to_pos+count).
214 		 *
215 		 * The current position become 0.
216 		 *
217 		 * \note
218 		 * The presence of data in \a from is not checked.
219 		 *
220 		 * \note
221 		 * Behavior if to_pos > size() is not defined.
222 		 */
223 		void
224 		insert(
225 			//! Postion for data insertion.
226 			size_t to_pos,
227 			//! A source for data to be inserted.
228 			const mem_buf_t & from,
229 			//! A position in source buffer.
230 			size_t from_pos,
231 			//! Count of data to be copied.
232 			size_t count );
233 
234 		//! Insertion of data.
235 		/*!
236 		 * Insertion of \a count bytes from memory area \a from into position
237 		 * \a to_pos. The current content at position \a to_pos is moved to
238 		 * position (to_pos+count).
239 		 *
240 		 * The current position become 0.
241 		 *
242 		 * \note
243 		 * The presence of data in \a from is not checked.
244 		 *
245 		 * \note
246 		 * Behavior if to_pos > size() is not defined.
247 		 */
248 		void
249 		insert(
250 			size_t to_pos,
251 			const void * from,
252 			size_t count );
253 
254 		//! Erase part of data from buffer.
255 		/*!
256 		 * \a count bytes from position \a from_offs are erased.
257 		 *
258 		 * \note
259 		 * Behavior if from_offs > size() or
260 		 * (from_offs + count > size()) is not defined.
261 		 */
262 		void
263 		erase(
264 			size_t from_offs,
265 			size_t count );
266 
267 		void
268 		swap(
269 			mem_buf_t & o );
270 
271 	protected :
272 		virtual const oess_2::char_t *
273 		in_reserve(
274 			size_t item_count,
275 			size_t item_size,
276 			size_t & item_available ) override;
277 
278 		virtual void
279 		in_shift(
280 			size_t item_count,
281 			size_t item_size ) override;
282 
283 		virtual oess_2::char_t *
284 		out_reserve(
285 			size_t item_count,
286 			size_t item_size,
287 			size_t & item_available ) override;
288 
289 		virtual void
290 		out_shift(
291 			size_t item_count,
292 			size_t item_size ) override;
293 
294 	private :
295 		std::vector<oess_2::char_t> m_buf;
296 
297 		size_t	m_size;
298 		size_t	m_pos;
299 };
300 
301 #if defined( _MSC_VER )
302 	#pragma warning(pop)
303 #endif
304 
305 } /* namespace io */
306 
307 } /* namespace oess_2 */
308 
309 #endif
310