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