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 Basic classes for input and output streams.
36 */
37 
38 #if !defined( OESS_2_IO_STREAM_HPP )
39 #define OESS_2_IO_STREAM_HPP
40 
41 #include <oess_2/io/h/declspec.hpp>
42 
43 #include <string>
44 
45 #include <oess_2/defs/h/types.hpp>
46 #include <oess_2/defs/h/quantity.hpp>
47 
48 namespace oess_2 {
49 
50 namespace io {
51 
52 //
53 // istream_t
54 //
55 
56 /*!
57 	\brief Base class for input binary stream.
58 
59 	Defines read operations for basic types.
60 
61 	\par v.2.1.0
62 	Since v2.1.0 ObjESSty supports only binary streams.
63 	Because of that there no any need of deep abstraction of
64 	stream classes. istream_t now is base class for abstract
65 	input binary stream.
66 */
67 class	OESS_2_IO_TYPE	istream_t {
68 	public :
69 		istream_t( const istream_t & ) = delete;
70 		istream_t( istream_t && ) = delete;
71 		istream_t & operator=( const istream_t & ) = delete;
72 		istream_t & operator=( istream_t && ) = delete;
73 
74 		istream_t();
75 		virtual ~istream_t();
76 
77 		/*!
78 		 * Read \a count items and store them into \a p.
79 		 */
80 		void
81 		read( oess_2::char_t * p, size_t count );
82 
83 		/*!
84 		 * Read \a count items and store them into \a p.
85 		 */
86 		void
87 		read( oess_2::schar_t * p, size_t count );
88 
89 		/*!
90 		 * Read \a count items and store them into \a p.
91 		 */
92 		void
93 		read( oess_2::uchar_t * p, size_t count );
94 
95 		/*!
96 		 * Read \a count items and store them into \a p.
97 		 */
98 		void
99 		read( oess_2::short_t * p, size_t count );
100 
101 		/*!
102 		 * Read \a count items and store them into \a p.
103 		 */
104 		void
105 		read( oess_2::ushort_t * p, size_t count );
106 
107 		/*!
108 		 * Read \a count items and store them into \a p.
109 		 */
110 		void
111 		read( oess_2::int_t * p, size_t count );
112 
113 		/*!
114 		 * Read \a count items and store them into \a p.
115 		 */
116 		void
117 		read( oess_2::uint_t * p, size_t count );
118 
119 		/*!
120 		 * Read \a count items and store them into \a p.
121 		 */
122 		void
123 		read( oess_2::long_t * p, size_t count );
124 
125 		/*!
126 		 * Read \a count items and store them into \a p.
127 		 */
128 		void
129 		read( oess_2::ulong_t * p, size_t count );
130 
131 		/*!
132 		 * Read \a count items and store them into \a p.
133 		 */
134 		void
135 		read( oess_2::single_t * p, size_t count );
136 
137 		/*!
138 		 * Read \a count items and store them into \a p.
139 		 */
140 		void
141 		read( oess_2::double_t * p, size_t count );
142 
143 		/*!
144 		 * Read a string from input stream and store it into \a p.
145 		 *
146 		 * Uses fixed-length representation of string size.
147 		 */
148 		void
149 		read_fixed_size_string( std::string & p );
150 
151 		/*!
152 		 * \since
153 		 * v.2.1.0
154 		 *
155 		 * Load string from the stream into \a p.
156 		 *
157 		 * Method uses string representation with variable width
158 		 * dimension field.
159 		 */
160 		void
161 		read_variable_size_string( std::string & p );
162 
163 		/*!
164 		 * \since
165 		 * v.1.4.0-b2.2
166 		 *
167 		 * \brief Load a quantity object from stream.
168 		 */
169 		void
170 		read( oess_2::defs::quantity_t & p );
171 
172 		/*!
173 		 * \since
174 		 * v.2.2.0
175 		 *
176 		 * \brief Load a bool value from stream.
177 		 */
178 		void
179 		read_bool( oess_2::bool_t & p );
180 
181 		/*!
182 		 * \since
183 		 * v.2.0.0
184 		 *
185 		 * \brief Read and throw away some bytes from stream.
186 		 *
187 		 * This method is useful if there is some data which must
188 		 * be skipped.
189 		 */
190 		void
191 		shift_bytes( size_t bytes_count );
192 
193 		//! Is it end of stream?
194 		virtual bool
195 		eof() const = 0;
196 
197 	protected :
198 		friend	class ibuffer_accessor_t;
199 		friend	class	isubstream_t;
200 
201 		//! Get the pointer from which data could be read.
202 		/*!
203 		 * Should throw an exception if there is no more data available
204 		 * for reading.
205 		 */
206 		virtual const oess_2::char_t *
207 		in_reserve(
208 			//! Count of items for read.
209 			size_t item_count,
210 			//! Size of one item in bytes.
211 			size_t item_size,
212 			//! Receiver for count of items available for reading.
213 			size_t & item_available ) = 0;
214 
215 		//! Complete the data read.
216 		/*!
217 		 * This method is called just after reading the data from
218 		 * pointer returned by in_reserve() method.
219 		 */
220 		virtual void
221 		in_shift(
222 			//! Count of items read.
223 			size_t item_count,
224 			//! Size of one item in bytes.
225 			size_t item_size ) = 0;
226 
227 	private :
228 		/*!
229 		 * \since
230 		 * v.2.1.0
231 		 *
232 		 * \brief Auxiliary method to load string contents.
233 		 */
234 		void
235 		read_string_content( std::string & receiver, size_t length );
236 };
237 
238 //
239 // ostream_t
240 //
241 
242 //! Base class for output binary stream.
243 class	OESS_2_IO_TYPE	ostream_t {
244 	public :
245 		ostream_t( const ostream_t & ) = delete;
246 		ostream_t( ostream_t && ) = delete;
247 		ostream_t & operator=( const ostream_t & ) = delete;
248 		ostream_t & operator=( ostream_t && ) = delete;
249 
250 		ostream_t();
251 		virtual ~ostream_t();
252 
253 		/*!
254 		 * Write \a count items from \a p into stream.
255 		 */
256 		void
257 		write( const oess_2::char_t * p, size_t count );
258 
259 		/*!
260 		 * Write \a count items from \a p into stream.
261 		 */
262 		void
263 		write( const oess_2::schar_t * p, size_t count );
264 
265 		/*!
266 		 * Write \a count items from \a p into stream.
267 		 */
268 		void
269 		write( const oess_2::uchar_t * p, size_t count );
270 
271 		/*!
272 		 * Write \a count items from \a p into stream.
273 		 */
274 		void
275 		write( const oess_2::short_t * p, size_t count );
276 
277 		/*!
278 		 * Write \a count items from \a p into stream.
279 		 */
280 		void
281 		write( const oess_2::ushort_t * p, size_t count );
282 
283 		/*!
284 		 * Write \a count items from \a p into stream.
285 		 */
286 		void
287 		write( const oess_2::int_t * p, size_t count );
288 
289 		/*!
290 		 * Write \a count items from \a p into stream.
291 		 */
292 		void
293 		write( const oess_2::uint_t * p, size_t count );
294 
295 		/*!
296 		 * Write \a count items from \a p into stream.
297 		 */
298 		void
299 		write( const oess_2::long_t * p, size_t count );
300 
301 		/*!
302 		 * Write \a count items from \a p into stream.
303 		 */
304 		void
305 		write( const oess_2::ulong_t * p, size_t count );
306 
307 		/*!
308 		 * Write \a count items from \a p into stream.
309 		 */
310 		void
311 		write( const oess_2::single_t * p, size_t count );
312 
313 		/*!
314 		 * Write \a count items from \a p into stream.
315 		 */
316 		void
317 		write( const oess_2::double_t * p, size_t count );
318 
319 		/*!
320 		 * \since v.2.1.0
321 		 * \brief Write string to the stream.
322 		 *
323 		 * String size field is writen as fixed-size 32-bit value.
324 		 */
325 		void
326 		write_fixed_size_string( const std::string & p );
327 
328 		/*!
329 		 * \since v.2.1.0
330 		 * \brief Write string to the stream.
331 		 *
332 		 * String size field is writen as variable width value.
333 		 */
334 		void
335 		write_variable_size_string( const std::string & p );
336 
337 		/*!
338 		 * \since
339 		 * v.1.4.0-b2.2
340 		 *
341 		 * \brief Write a quantity object into the stream.
342 		 */
343 		void
344 		write( const oess_2::defs::quantity_t & p );
345 
346 		/*!
347 		 * \since
348 		 * v.2.2.0
349 		 *
350 		 * \brief Write a bool value into the stream.
351 		 */
352 		void
353 		write_bool( const oess_2::bool_t & p );
354 
355 	protected :
356 		friend	class obuffer_accessor_t;
357 
358 		//! Get the pointer to writting some data into.
359 		/*!
360 		 * If there is no room for data an exception must be thrown.
361 		 */
362 		virtual oess_2::char_t *
363 		out_reserve(
364 			//! Count of items to be written.
365 			size_t item_count,
366 			//! Size of item in bytes.
367 			size_t item_size,
368 			//! Receiver for the count of items which could be written.
369 			size_t & item_available ) = 0;
370 
371 		//! Complete the write operation.
372 		/*!
373 		 * This method is called just after writting some data to
374 		 * the pointer returned by previous out_reserve() call.
375 		 */
376 		virtual void
377 		out_shift(
378 			//! Count of successfully written items.
379 			size_t item_count,
380 			//! Size of item in bytes.
381 			size_t item_size ) = 0;
382 };
383 
384 
385 //! Read single object from a stream.
386 inline istream_t &
operator >>(istream_t & s,oess_2::char_t & o)387 operator>>( istream_t & s, oess_2::char_t & o ) {
388 	s.read( &o, 1 );
389 	return s;
390 }
391 
392 //! Write single object to a stream.
393 inline ostream_t &
operator <<(ostream_t & s,const oess_2::char_t & o)394 operator<<( ostream_t & s, const oess_2::char_t & o ) {
395 	s.write( &o, 1 );
396 	return s;
397 }
398 
399 //! Read single object from a stream.
400 inline istream_t &
operator >>(istream_t & s,oess_2::schar_t & o)401 operator>>( istream_t & s, oess_2::schar_t & o ) {
402 	s.read( &o, 1 );
403 	return s;
404 }
405 
406 //! Write single object to a stream.
407 inline ostream_t &
operator <<(ostream_t & s,const oess_2::schar_t & o)408 operator<<( ostream_t & s, const oess_2::schar_t & o ) {
409 	s.write( &o, 1 );
410 	return s;
411 }
412 
413 //! Read single object from a stream.
414 inline istream_t &
operator >>(istream_t & s,oess_2::uchar_t & o)415 operator>>( istream_t & s, oess_2::uchar_t & o ) {
416 	s.read( &o, 1 );
417 	return s;
418 }
419 
420 //! Write single object to a stream.
421 inline ostream_t &
operator <<(ostream_t & s,const oess_2::uchar_t & o)422 operator<<( ostream_t & s, const oess_2::uchar_t & o ) {
423 	s.write( &o, 1 );
424 	return s;
425 }
426 
427 //! Read single object from a stream.
428 inline istream_t &
operator >>(istream_t & s,oess_2::bool_t & o)429 operator>>( istream_t & s, oess_2::bool_t & o ) {
430 	s.read_bool( o );
431 	return s;
432 }
433 
434 //! Write single object to a stream.
435 inline ostream_t &
operator <<(ostream_t & s,const oess_2::bool_t & o)436 operator<<( ostream_t & s, const oess_2::bool_t & o ) {
437 	s.write_bool( o );
438 	return s;
439 }
440 
441 //! Read single object from a stream.
442 inline istream_t &
operator >>(istream_t & s,oess_2::short_t & o)443 operator>>( istream_t & s, oess_2::short_t & o ) {
444 	s.read( &o, 1 );
445 	return s;
446 }
447 
448 //! Write single object to a stream.
449 inline ostream_t &
operator <<(ostream_t & s,const oess_2::short_t & o)450 operator<<( ostream_t & s, const oess_2::short_t & o ) {
451 	s.write( &o, 1 );
452 	return s;
453 }
454 
455 //! Read single object from a stream.
456 inline istream_t &
operator >>(istream_t & s,oess_2::ushort_t & o)457 operator>>( istream_t & s, oess_2::ushort_t & o ) {
458 	s.read( &o, 1 );
459 	return s;
460 }
461 
462 //! Write single object to a stream.
463 inline ostream_t &
operator <<(ostream_t & s,const oess_2::ushort_t & o)464 operator<<( ostream_t & s, const oess_2::ushort_t & o ) {
465 	s.write( &o, 1 );
466 	return s;
467 }
468 
469 //! Read single object from a stream.
470 inline istream_t &
operator >>(istream_t & s,oess_2::int_t & o)471 operator>>( istream_t & s, oess_2::int_t & o ) {
472 	s.read( &o, 1 );
473 	return s;
474 }
475 
476 //! Write single object to a stream.
477 inline ostream_t &
operator <<(ostream_t & s,const oess_2::int_t & o)478 operator<<( ostream_t & s, const oess_2::int_t & o ) {
479 	s.write( &o, 1 );
480 	return s;
481 }
482 
483 //! Read single object from a stream.
484 inline istream_t &
operator >>(istream_t & s,oess_2::uint_t & o)485 operator>>( istream_t & s, oess_2::uint_t & o ) {
486 	s.read( &o, 1 );
487 	return s;
488 }
489 
490 //! Write single object to a stream.
491 inline ostream_t &
operator <<(ostream_t & s,const oess_2::uint_t & o)492 operator<<( ostream_t & s, const oess_2::uint_t & o ) {
493 	s.write( &o, 1 );
494 	return s;
495 }
496 
497 //! Read single object from a stream.
498 inline istream_t &
operator >>(istream_t & s,oess_2::long_t & o)499 operator>>( istream_t & s, oess_2::long_t & o ) {
500 	s.read( &o, 1 );
501 	return s;
502 }
503 
504 //! Write single object to a stream.
505 inline ostream_t &
operator <<(ostream_t & s,const oess_2::long_t & o)506 operator<<( ostream_t & s, const oess_2::long_t & o ) {
507 	s.write( &o, 1 );
508 	return s;
509 }
510 
511 //! Read single object from a stream.
512 inline istream_t &
operator >>(istream_t & s,oess_2::ulong_t & o)513 operator>>( istream_t & s, oess_2::ulong_t & o ) {
514 	s.read( &o, 1 );
515 	return s;
516 }
517 
518 //! Write single object to a stream.
519 inline ostream_t &
operator <<(ostream_t & s,const oess_2::ulong_t & o)520 operator<<( ostream_t & s, const oess_2::ulong_t & o ) {
521 	s.write( &o, 1 );
522 	return s;
523 }
524 
525 //! Read single object from a stream.
526 inline istream_t &
operator >>(istream_t & s,oess_2::single_t & o)527 operator>>( istream_t & s, oess_2::single_t & o ) {
528 	s.read( &o, 1 );
529 	return s;
530 }
531 
532 //! Write single object to a stream.
533 inline ostream_t &
operator <<(ostream_t & s,const oess_2::single_t & o)534 operator<<( ostream_t & s, const oess_2::single_t & o ) {
535 	s.write( &o, 1 );
536 	return s;
537 }
538 
539 //! Read single object from a stream.
540 inline istream_t &
operator >>(istream_t & s,oess_2::double_t & o)541 operator>>( istream_t & s, oess_2::double_t & o ) {
542 	s.read( &o, 1 );
543 	return s;
544 }
545 
546 //! Write single object to a stream.
547 inline ostream_t &
operator <<(ostream_t & s,const oess_2::double_t & o)548 operator<<( ostream_t & s, const oess_2::double_t & o ) {
549 	s.write( &o, 1 );
550 	return s;
551 }
552 
553 /*!
554  * \brief Read single string object from stream.
555  *
556  * This operator assumes that string is stored with fixed-width
557  * size field. This if for compatibility reasons.
558  */
559 inline istream_t &
operator >>(istream_t & s,std::string & o)560 operator>>( istream_t & s, std::string & o ) {
561 	s.read_fixed_size_string( o );
562 	return s;
563 }
564 
565 /*!
566  * \brief Write single string object to stream.
567  *
568  * This operator writes string with fixed-width size field. This if for
569  * compatibility reasons.
570  */
571 inline ostream_t &
operator <<(ostream_t & s,const std::string & o)572 operator<<( ostream_t & s, const std::string & o ) {
573 	s.write_fixed_size_string( o );
574 	return s;
575 }
576 
577 //! Read single object from a stream.
578 inline istream_t &
operator >>(istream_t & s,oess_2::defs::quantity_t & o)579 operator>>( istream_t & s, oess_2::defs::quantity_t & o ) {
580 	s.read( o );
581 	return s;
582 }
583 
584 //! Write single object to a stream.
585 inline ostream_t &
operator <<(ostream_t & s,const oess_2::defs::quantity_t & o)586 operator<<( ostream_t & s, const oess_2::defs::quantity_t & o ) {
587 	s.write( o );
588 	return s;
589 }
590 
591 } /* namespace io */
592 
593 } /* namespace oess_2 */
594 
595 #endif
596 
597