Main MRPT website > C++ reference for MRPT 1.5.7
CStream.h
Go to the documentation of this file.
1 /* +---------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | http://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2017, Individual contributors, see AUTHORS file |
6  | See: http://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See details in http://www.mrpt.org/License |
8  +---------------------------------------------------------------------------+ */
9 #ifndef CSTREAM_H
10 #define CSTREAM_H
11 
12 #include <mrpt/utils/core_defs.h>
14 #include <mrpt/utils/CUncopiable.h>
15 #include <mrpt/utils/exceptions.h>
16 #include <mrpt/utils/bits.h> // reverseBytesInPlace()
17 #include <vector>
18 
19 namespace mrpt
20 {
21  namespace utils
22  {
23  class CSerializable;
24  struct CSerializablePtr;
25  class CMessage;
26 
27  /** This base class is used to provide a unified interface to
28  * files,memory buffers,..Please see the derived classes. This class is
29  * largely inspired by Borland VCL "TStream" class. <br><br>
30  * Apart of the "VCL like" methods, operators ">>" and "<<" have been
31  * defined so that simple types (int,bool,char,float,char *,std::string,...)
32  * can be directly written and read to and from any CStream easily.
33  * Please, it is recomendable to read CSerializable documentation also.
34  *
35  * \ingroup mrpt_base_grp
36  * \sa CFileStream, CMemoryStream,CSerializable
37  */
39  {
40  public:
41  /** Used in CStream::Seek */
43  {
44  sFromBeginning = 0,
45  sFromCurrent = 1,
46  sFromEnd = 2
47  };
48 
49  protected:
50  /** Introduces a pure virtual method responsible for reading from the stream. */
51  virtual size_t Read(void *Buffer, size_t Count) = 0;
52 
53  /** Introduces a pure virtual method responsible for writing to the stream.
54  * Write attempts to write up to Count bytes to Buffer, and returns the number of bytes actually written. */
55  virtual size_t Write(const void *Buffer, size_t Count) = 0;
56 
57  /** A common template code for both versions of CStream::ReadObject()
58  * - EXISTING_OBJ=true -> read in the object passed as argument
59  * - EXISTING_OBJ=false -> build a new object and return it */
60  template <bool EXISTING_OBJ> void internal_ReadObject(CSerializablePtr &newObj, CSerializable *existingObj = NULL);
61 
62  public:
63  /* Constructor
64  */
65  CStream() { }
66 
67  /* Destructor
68  */
69  virtual ~CStream();
70 
71  /** Reads a block of bytes from the stream into Buffer
72  * \exception std::exception On any error, or if ZERO bytes are read.
73  * \return The amound of bytes actually read.
74  * \note This method is endianness-dependent.
75  * \sa ReadBufferImmediate ; Important, see: ReadBufferFixEndianness,
76  */
77  size_t ReadBuffer(void *Buffer, size_t Count);
78 
79  /** Reads a sequence of elemental datatypes, taking care of reordering their bytes from the MRPT stream standard (little endianness) to the format of the running architecture.
80  * \param ElementCount The number of elements (not bytes) to read.
81  * \param ptr A pointer to the first output element in an array (or std::vector<>, etc...).
82  * \return The amound of *bytes* (not elements) actually read (under error situations, the last element may be invalid if the data stream abruptly ends).
83  * Example of usage:
84  * \code
85  * uint32_t N;
86  * s >> N;
87  * vector<float> vec(N);
88  * if (N)
89  * s.ReadBufferFixEndianness<float>(&vec[0],N);
90  * \endcode
91  * \exception std::exception On any error, or if ZERO bytes are read.
92  * \sa ReadBufferFixEndianness, ReadBuffer
93  */
94  template <typename T>
95  size_t ReadBufferFixEndianness(T *ptr, size_t ElementCount)
96  {
97  #if !MRPT_IS_BIG_ENDIAN
98  // little endian: no conversion needed.
99  return ReadBuffer(ptr,ElementCount*sizeof(T));
100  #else
101  // big endian: convert.
102  const size_t nread = ReadBuffer(ptr,ElementCount*sizeof(T));
103  for (size_t i=0;i<ElementCount;i++) mrpt::utils::reverseBytesInPlace(ptr[i]);
104  return nread;
105  #endif
106  }
107 
108 
109  /** Reads a block of bytes from the stream into Buffer, and returns the amound of bytes actually read, without waiting for more extra bytes to arrive (just those already enqued in the stream).
110  * Note that this method will fallback to ReadBuffer() in most CStream classes but in some hardware-related classes.
111  * \exception std::exception On any error, or if ZERO bytes are read.
112  */
113  virtual size_t ReadBufferImmediate(void *Buffer, size_t Count) { return ReadBuffer(Buffer, Count); }
114 
115  /** Writes a block of bytes to the stream from Buffer.
116  * \exception std::exception On any error
117  * \sa Important, see: WriteBufferFixEndianness
118  * \note This method is endianness-dependent.
119  */
120  void WriteBuffer (const void *Buffer, size_t Count);
121 
122 
123 
124  /** Writes a sequence of elemental datatypes, taking care of reordering their bytes from the running architecture to MRPT stream standard (little endianness).
125  * \param ElementCount The number of elements (not bytes) to write.
126  * \param ptr A pointer to the first input element in an array (or std::vector<>, etc...).
127  * Example of usage:
128  * \code
129  * vector<float> vec = ...
130  * uint32_t N = vec.size();
131  * s << N
132  * if (N)
133  * s.WriteBufferFixEndianness<float>(&vec[0],N);
134  * \endcode
135  * \exception std::exception On any error
136  * \sa WriteBuffer
137  */
138  template <typename T>
139  void WriteBufferFixEndianness(const T *ptr, size_t ElementCount)
140  {
141  #if !MRPT_IS_BIG_ENDIAN
142  // little endian: no conversion needed.
143  return WriteBuffer(ptr,ElementCount*sizeof(T));
144  #else
145  // big endian: the individual "<<" functions already convert endiannes
146  for (size_t i=0;i<ElementCount;i++) (*this) << ptr[i];
147  #endif
148  }
149 
150  /** Introduces a pure virtual method for moving to a specified position in the streamed resource.
151  * he Origin parameter indicates how to interpret the Offset parameter. Origin should be one of the following values:
152  * - sFromBeginning (Default) Offset is from the beginning of the resource. Seek moves to the position Offset. Offset must be >= 0.
153  * - sFromCurrent Offset is from the current position in the resource. Seek moves to Position + Offset.
154  * - sFromEnd Offset is from the end of the resource. Offset must be <= 0 to indicate a number of bytes before the end of the file.
155  * \return Seek returns the new value of the Position property.
156  */
157  virtual uint64_t Seek(int64_t Offset, CStream::TSeekOrigin Origin = sFromBeginning) = 0;
158 
159  /** Returns the total amount of bytes in the stream.
160  */
161  virtual uint64_t getTotalBytesCount() = 0;
162 
163  /** Method for getting the current cursor position, where 0 is the first byte and TotalBytesCount-1 the last one.
164  */
165  virtual uint64_t getPosition() =0;
166 
167  /** Writes an object to the stream.
168  */
169  void WriteObject( const CSerializable *o );
170 
171  /** Reads an object from stream, its class determined at runtime, and returns a smart pointer to the object.
172  * \exception std::exception On I/O error or undefined class.
173  * \exception mrpt::utils::CExceptionEOF On an End-Of-File condition found at a correct place: an EOF that abruptly finishes in the middle of one object raises a plain std::exception instead.
174  */
175  CSerializablePtr ReadObject();
176 
177  /** Reads an object from stream, where its class must be the same
178  * as the supplied object, where the loaded object will be stored in.
179  * \exception std::exception On I/O error or different class found.
180  * \exception mrpt::utils::CExceptionEOF On an End-Of-File condition found at a correct place: an EOF that abruptly finishes in the middle of one object raises a plain std::exception instead.
181  */
182  void ReadObject(CSerializable *existingObj);
183 
184  /** Write an object to a stream in the binary MRPT format. */
185  CStream& operator << (const CSerializablePtr & pObj);
186  /** Write an object to a stream in the binary MRPT format. */
188 
189  CStream& operator >> (CSerializablePtr &pObj);
191 
192  /** Read a value from a stream stored in a type different of the target variable, making the conversion via static_cast. Useful for coding backwards compatible de-serialization blocks */
193  template <typename STORED_TYPE, typename CAST_TO_TYPE>
194  void ReadAsAndCastTo(CAST_TO_TYPE &read_here) {
195  STORED_TYPE var;
196  (*this) >> var;
197  read_here = static_cast<CAST_TO_TYPE>(var);
198  }
199 
200  /** Writes a string to the stream in a textual form.
201  * \sa CStdOutStream
202  */
203  virtual int printf(const char *fmt,...) MRPT_printf_format_check(2,3); // The first argument (1) is "this" !!!
204 
205  /** Prints a vector in the format [A,B,C,...] using CStream::printf, and the fmt string for <b>each</b> vector element `T`.
206  * \tparam CONTAINER_TYPE can be any vector<T>, deque<T> or alike. */
207  template <typename CONTAINER_TYPE>
208  void printf_vector(const char *fmt, const CONTAINER_TYPE &V, char separator = ',' )
209  {
210  this->printf("[");
211  const size_t N = V.size();
212  for (size_t i=0;i<N;i++)
213  {
214  this->printf(fmt,V[i]);
215  if (i!=(N-1)) this->printf("%c",separator);
216  }
217  this->printf("]");
218  }
219 
220  /** Send a message to the device.
221  * Note that only the low byte from the "type" field will be used.
222  *
223  * For frames of size < 255 the frame format is an array of bytes in this order:
224  * \code
225  * <START_FLAG> <HEADER> <LENGTH> <BODY> <END_FLAG>
226  * <START_FLAG> = 0x69
227  * <HEADER> = A header byte
228  * <LENGHT> = Number of bytes of BODY
229  * <BODY> = N x bytes
230  * <END_FLAG> = 0X96
231  * Total length = <LENGTH> + 4
232  * \endcode
233  *
234  * For frames of size > 255 the frame format is an array of bytes in this order:
235  * \code
236  * <START_FLAG> <HEADER> <HIBYTE(LENGTH)> <LOBYTE(LENGTH)> <BODY> <END_FLAG>
237  * <START_FLAG> = 0x79
238  * <HEADER> = A header byte
239  * <LENGHT> = Number of bytes of BODY
240  * <BODY> = N x bytes
241  * <END_FLAG> = 0X96
242  * Total length = <LENGTH> + 5
243  * \endcode
244  *
245  * \exception std::exception On communication errors
246  */
247  void sendMessage( const utils::CMessage &msg);
248 
249  /** Tries to receive a message from the device.
250  * \exception std::exception On communication errors
251  * \returns True if successful, false if there is no new data from the device (but communications seem to work fine)
252  * \sa The frame format is described in sendMessage()
253  */
254  bool receiveMessage( utils::CMessage &msg );
255 
256  /** Reads from the stream until a '\n' character is found ('\r' characters are ignored).
257  * \return false on EOF or any other read error.
258  */
259  bool getline(std::string &out_str);
260 
261 
262  }; // End of class def.
263 
264 
265  #define DECLARE_CSTREAM_READ_WRITE_SIMPLE_TYPE( T ) \
266  CStream BASE_IMPEXP & operator<<(mrpt::utils::CStream&out, const T &a); \
267  CStream BASE_IMPEXP & operator>>(mrpt::utils::CStream&in, T &a);
268 
269  // Definitions:
281 #ifdef HAVE_LONG_DOUBLE
283 #endif
284 
285  // Why this shouldn't be templatized?: There's a more modern system
286  // in MRPT that serializes any kind of vector<T>, deque<T>, etc... but
287  // to keep COMPATIBILITY with old serialized objects we must preserve
288  // the ones listed here:
289 
290  // Write --------------------
291  CStream BASE_IMPEXP & operator << (mrpt::utils::CStream&s, const char *a);
293 
301 
303  CStream BASE_IMPEXP & operator << (mrpt::utils::CStream&, const std::vector<std::string> &);
304 
305  #if MRPT_WORD_SIZE!=32 // If it's 32 bit, size_t <=> uint32_t
306  CStream BASE_IMPEXP & operator << (mrpt::utils::CStream&, const std::vector<size_t> &a);
307  #endif
308 
309  // Read --------------------
310  CStream BASE_IMPEXP & operator>>(mrpt::utils::CStream&in, char *a);
312 
321 
322  CStream BASE_IMPEXP & operator>>(mrpt::utils::CStream&in, std::vector<std::string> &a);
323 
324  // For backward compatibility, since in MRPT<0.8.1 vector_XXX and std::vector<XXX> were exactly equivalent, now there're not.
325  CStream BASE_IMPEXP & operator >> (mrpt::utils::CStream&s, std::vector<float> &a);
326  CStream BASE_IMPEXP & operator >> (mrpt::utils::CStream&s, std::vector<double> &a);
327  CStream BASE_IMPEXP & operator << (mrpt::utils::CStream&s, const std::vector<float> &a);
328  CStream BASE_IMPEXP & operator << (mrpt::utils::CStream&s, const std::vector<double> &a);
329 
330  #if MRPT_WORD_SIZE!=32 // If it's 32 bit, size_t <=> uint32_t
331  CStream BASE_IMPEXP & operator >> (mrpt::utils::CStream&s, std::vector<size_t> &a);
332  #endif
333 
334  } // End of namespace
335 } // End of namespace
336 
337 #endif
unsigned __int16 uint16_t
Definition: rptypes.h:46
std::vector< uint32_t > vector_uint
Definition: types_simple.h:28
virtual size_t ReadBufferImmediate(void *Buffer, size_t Count)
Reads a block of bytes from the stream into Buffer, and returns the amound of bytes actually read...
Definition: CStream.h:113
std::vector< uint8_t > vector_byte
Definition: types_simple.h:26
void BASE_IMPEXP reverseBytesInPlace(bool &v_in_out)
Reverse the order of the bytes of a given type (useful for transforming btw little/big endian) ...
TSeekOrigin
Used in CStream::Seek.
Definition: CStream.h:42
The virtual base class which provides a unified interface for all persistent objects in MRPT...
Definition: CSerializable.h:39
signed char int8_t
Definition: rptypes.h:42
GLdouble s
Definition: glext.h:3602
GLsizei GLsizei GLuint * obj
Definition: glext.h:3902
std::vector< int8_t > vector_signed_byte
Definition: types_simple.h:21
#define MRPT_printf_format_check(_FMT_, _VARARGS_)
std::vector< bool > vector_bool
A type for passing a vector of bools.
Definition: types_simple.h:29
unsigned char uint8_t
Definition: rptypes.h:43
std::vector< int64_t > vector_long
Definition: types_simple.h:24
::mrpt::utils::CStream & operator>>(mrpt::utils::CStream &in, CImagePtr &pObj)
void WriteBufferFixEndianness(const T *ptr, size_t ElementCount)
Writes a sequence of elemental datatypes, taking care of reordering their bytes from the running arch...
Definition: CStream.h:139
This base class is used to provide a unified interface to files,memory buffers,..Please see the deriv...
Definition: CStream.h:38
__int16 int16_t
Definition: rptypes.h:45
#define DECLARE_CSTREAM_READ_WRITE_SIMPLE_TYPE(T)
Definition: CStream.h:265
__int64 int64_t
Definition: rptypes.h:51
CStream BASE_IMPEXP & operator<<(mrpt::utils::CStream &s, const char *a)
Definition: CStream.cpp:130
GLsizei const GLchar ** string
Definition: glext.h:3919
__int32 int32_t
Definition: rptypes.h:48
unsigned __int64 uint64_t
Definition: rptypes.h:52
void ReadAsAndCastTo(CAST_TO_TYPE &read_here)
Read a value from a stream stored in a type different of the target variable, making the conversion v...
Definition: CStream.h:194
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
void printf_vector(const char *fmt, const std::vector< T > &V)
Prints a vector in the format [A,B,C,...] to std::cout, and the fmt string for each vector element...
Definition: printf_vector.h:54
size_t ReadBufferFixEndianness(T *ptr, size_t ElementCount)
Reads a sequence of elemental datatypes, taking care of reordering their bytes from the MRPT stream s...
Definition: CStream.h:95
std::vector< uint16_t > vector_word
Definition: types_simple.h:27
std::vector< int16_t > vector_signed_word
Definition: types_simple.h:22
GLuint in
Definition: glext.h:6301
std::vector< int32_t > vector_int
Definition: types_simple.h:23
unsigned __int32 uint32_t
Definition: rptypes.h:49
GLubyte GLubyte GLubyte a
Definition: glext.h:5575
A class that contain generic messages, that can be sent and received from a "CClientTCPSocket" object...
Definition: CMessage.h:29



Page generated by Doxygen 1.8.14 for MRPT 1.5.7 Git: 5902e14cc Wed Apr 24 15:04:01 2019 +0200 at lun oct 28 01:39:17 CET 2019