Main MRPT website > C++ reference for MRPT 1.4.0
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-2016, 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> CSerializable* internal_ReadObject(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 
151  /** Copies a specified number of bytes from one stream to another. */
152  size_t CopyFrom(mrpt::utils::CStream* Source, size_t Count);
153 
154  /** Introduces a pure virtual method for moving to a specified position in the streamed resource.
155  * he Origin parameter indicates how to interpret the Offset parameter. Origin should be one of the following values:
156  * - sFromBeginning (Default) Offset is from the beginning of the resource. Seek moves to the position Offset. Offset must be >= 0.
157  * - sFromCurrent Offset is from the current position in the resource. Seek moves to Position + Offset.
158  * - 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.
159  * \return Seek returns the new value of the Position property.
160  */
161  virtual uint64_t Seek(uint64_t Offset, CStream::TSeekOrigin Origin = sFromBeginning) = 0;
162 
163  /** Returns the total amount of bytes in the stream.
164  */
165  virtual uint64_t getTotalBytesCount() = 0;
166 
167  /** Method for getting the current cursor position, where 0 is the first byte and TotalBytesCount-1 the last one.
168  */
169  virtual uint64_t getPosition() =0;
170 
171  /** Writes an object to the stream.
172  */
173  void WriteObject( const CSerializable *o );
174 
175  /** Reads an object from stream, its class determined at runtime, and returns a smart pointer to the object.
176  * \exception std::exception On I/O error or undefined class.
177  * \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.
178  */
179  CSerializablePtr ReadObject();
180 
181  /** Reads an object from stream, where its class must be the same
182  * as the supplied object, where the loaded object will be stored in.
183  * \exception std::exception On I/O error or different class found.
184  * \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.
185  */
186  void ReadObject(CSerializable *existingObj);
187 
188  /** Write an object to a stream in the binary MRPT format. */
189  CStream& operator << (const CSerializablePtr & pObj);
190  /** Write an object to a stream in the binary MRPT format. */
191  CStream& operator << (const CSerializable &obj);
192 
193  CStream& operator >> (CSerializablePtr &pObj);
195 
196 
197 
198  /** Writes a string to the stream in a textual form.
199  * \sa CStdOutStream
200  */
201  virtual int printf(const char *fmt,...) MRPT_printf_format_check(2,3); // The first argument (1) is "this" !!!
202 
203  /** Prints a vector in the format [A,B,C,...] using CStream::printf, and the fmt string for <b>each</b> vector element. */
204  template <typename T>
205  void printf_vector(const char *fmt, const std::vector<T> &V )
206  {
207  this->printf("[");
208  size_t N = V.size();
209  for (size_t i=0;i<N;i++)
210  {
211  this->printf(fmt,V[i]);
212  if (i!=(N-1)) this->printf(",");
213  }
214  this->printf("]");
215  }
216 
217  /** Send a message to the device.
218  * Note that only the low byte from the "type" field will be used.
219  *
220  * For frames of size < 255 the frame format is an array of bytes in this order:
221  * \code
222  * <START_FLAG> <HEADER> <LENGTH> <BODY> <END_FLAG>
223  * <START_FLAG> = 0x69
224  * <HEADER> = A header byte
225  * <LENGHT> = Number of bytes of BODY
226  * <BODY> = N x bytes
227  * <END_FLAG> = 0X96
228  * Total length = <LENGTH> + 4
229  * \endcode
230  *
231  * For frames of size > 255 the frame format is an array of bytes in this order:
232  * \code
233  * <START_FLAG> <HEADER> <HIBYTE(LENGTH)> <LOBYTE(LENGTH)> <BODY> <END_FLAG>
234  * <START_FLAG> = 0x79
235  * <HEADER> = A header byte
236  * <LENGHT> = Number of bytes of BODY
237  * <BODY> = N x bytes
238  * <END_FLAG> = 0X96
239  * Total length = <LENGTH> + 5
240  * \endcode
241  *
242  * \exception std::exception On communication errors
243  */
244  void sendMessage( const utils::CMessage &msg);
245 
246  /** Tries to receive a message from the device.
247  * \exception std::exception On communication errors
248  * \returns True if successful, false if there is no new data from the device (but communications seem to work fine)
249  * \sa The frame format is described in sendMessage()
250  */
251  bool receiveMessage( utils::CMessage &msg );
252 
253  /** Reads from the stream until a '\n' character is found ('\r' characters are ignored).
254  * \return false on EOF or any other read error.
255  */
256  bool getline(std::string &out_str);
257 
258 
259  }; // End of class def.
260 
261 
262  #define DECLARE_CSTREAM_READ_WRITE_SIMPLE_TYPE( T ) \
263  CStream BASE_IMPEXP & operator<<(mrpt::utils::CStream&out, const T &a); \
264  CStream BASE_IMPEXP & operator>>(mrpt::utils::CStream&in, T &a);
265 
266  // Definitions:
278 #ifdef HAVE_LONG_DOUBLE
280 #endif
281 
282  // Why this shouldn't be templatized?: There's a more modern system
283  // in MRPT that serializes any kind of vector<T>, deque<T>, etc... but
284  // to keep COMPATIBILITY with old serialized objects we must preserve
285  // the ones listed here:
286 
287  // Write --------------------
288  CStream BASE_IMPEXP & operator << (mrpt::utils::CStream&s, const char *a);
289  CStream BASE_IMPEXP & operator << (mrpt::utils::CStream&s, const std::string &str);
290 
298 
300  CStream BASE_IMPEXP & operator << (mrpt::utils::CStream&, const std::vector<std::string> &);
301 
302  #if MRPT_WORD_SIZE!=32 // If it's 32 bit, size_t <=> uint32_t
303  CStream BASE_IMPEXP & operator << (mrpt::utils::CStream&, const std::vector<size_t> &a);
304  #endif
305 
306  // Read --------------------
307  CStream BASE_IMPEXP & operator>>(mrpt::utils::CStream&in, char *a);
308  CStream BASE_IMPEXP & operator>>(mrpt::utils::CStream&in, std::string &str);
309 
318 
319  CStream BASE_IMPEXP & operator>>(mrpt::utils::CStream&in, std::vector<std::string> &a);
320 
321  // For backward compatibility, since in MRPT<0.8.1 vector_XXX and std::vector<XXX> were exactly equivalent, now there're not.
322  CStream BASE_IMPEXP & operator >> (mrpt::utils::CStream&s, std::vector<float> &a);
323  CStream BASE_IMPEXP & operator >> (mrpt::utils::CStream&s, std::vector<double> &a);
324  CStream BASE_IMPEXP & operator << (mrpt::utils::CStream&s, const std::vector<float> &a);
325  CStream BASE_IMPEXP & operator << (mrpt::utils::CStream&s, const std::vector<double> &a);
326 
327  #if MRPT_WORD_SIZE!=32 // If it's 32 bit, size_t <=> uint32_t
328  CStream BASE_IMPEXP & operator >> (mrpt::utils::CStream&s, std::vector<size_t> &a);
329  #endif
330 
331  } // End of namespace
332 } // End of namespace
333 
334 #endif
exceptions.h
mrpt::utils::CStream::WriteBufferFixEndianness
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
mrpt::vector_uint
std::vector< uint32_t > vector_uint
Definition: types_simple.h:28
mrpt::utils::operator>>
::mrpt::utils::CStream & operator>>(mrpt::utils::CStream &in, CImagePtr &pObj)
mrpt::vector_word
std::vector< uint16_t > vector_word
Definition: types_simple.h:27
mrpt
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
Definition: CParticleFilter.h:16
bits.h
core_defs.h
types_simple.h
mrpt::vector_byte
std::vector< uint8_t > vector_byte
Definition: types_simple.h:26
MRPT_printf_format_check
#define MRPT_printf_format_check(_FMT_, _VARARGS_)
Definition: mrpt_macros.h:379
mrpt::utils::reverseBytesInPlace
void reverseBytesInPlace(T &v_in_out)
Reverse the order of the bytes of a given type (useful for transforming btw little/big endian)
Definition: bits.h:124
mrpt::utils::CStream
This base class is used to provide a unified interface to files,memory buffers,..Please see the deriv...
Definition: CStream.h:38
mrpt::utils::CMessage
A class that contain generic messages, that can be sent and received from a "CClientTCPSocket" object...
Definition: CMessage.h:32
mrpt::vector_signed_byte
std::vector< int8_t > vector_signed_byte
Definition: types_simple.h:21
mrpt::utils::CSerializable
The virtual base class which provides a unified interface for all persistent objects in MRPT.
Definition: CSerializable.h:39
mrpt::vector_signed_word
std::vector< int16_t > vector_signed_word
Definition: types_simple.h:22
mrpt::vector_int
std::vector< int32_t > vector_int
Definition: types_simple.h:23
mrpt::utils::CStream::CStream
CStream()
Definition: CStream.h:65
mrpt::utils::CStream::ReadBufferImmediate
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
DECLARE_CSTREAM_READ_WRITE_SIMPLE_TYPE
#define DECLARE_CSTREAM_READ_WRITE_SIMPLE_TYPE(T)
Definition: CStream.h:262
mrpt::utils::CStream::ReadBufferFixEndianness
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
mrpt::utils::printf_vector
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
mrpt::utils::CStream::TSeekOrigin
TSeekOrigin
Used in CStream::Seek.
Definition: CStream.h:42
mrpt::vector_bool
std::vector< bool > vector_bool
A type for passing a vector of bools.
Definition: types_simple.h:29
mrpt::utils::operator<<
CStream BASE_IMPEXP & operator<<(mrpt::utils::CStream &s, const char *a)
CUncopiable.h
mrpt::vector_long
std::vector< int64_t > vector_long
Definition: types_simple.h:24



Page generated by Doxygen 1.8.16 for MRPT 1.4.0 SVN: at Mon Oct 14 22:32:58 UTC 2019