Main MRPT website > C++ reference
MRPT logo
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-2014, 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/utils_defs.h>
13 #include <mrpt/utils/CUncopiable.h>
14 #include <mrpt/utils/CObject.h>
15 #include <mrpt/utils/exceptions.h>
16 
17 namespace mrpt
18 {
19  namespace utils
20  {
24 
25  /** This base class is used to provide a unified interface to
26  * files,memory buffers,..Please see the derived classes. This class is
27  * largely inspired by Borland VCL "TStream" class. <br><br>
28  * Apart of the "VCL like" methods, operators ">>" and "<<" have been
29  * defined so that simple types (int,bool,char,float,char *,std::string,...)
30  * can be directly written and read to and from any CStream easily.
31  * Please, it is recomendable to read CSerializable documentation also.
32  *
33  * \ingroup mrpt_base_grp
34  * \sa CFileStream, CMemoryStream,CSerializable
35  */
37  {
38  public:
39  /** Used in CStream::Seek
40  */
42  {
43  sFromBeginning = 0,
44  sFromCurrent = 1,
45  sFromEnd = 2
46  };
47 
48  protected:
49  /** Introduces a pure virtual method responsible for reading from the stream.
50  */
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  */
56  virtual size_t Write(const void *Buffer, size_t Count) = 0;
57  public:
58  /* Constructor
59  */
60  CStream() { }
61 
62  /* Destructor
63  */
64  virtual ~CStream();
65 
66  /** Reads a block of bytes from the stream into Buffer
67  * \exception std::exception On any error, or if ZERO bytes are read.
68  * \return The amound of bytes actually read.
69  * \note This method is endianness-dependent.
70  * \sa ReadBufferImmediate ; Important, see: ReadBufferFixEndianness,
71  */
72  size_t ReadBuffer(void *Buffer, size_t Count);
73 
74  /** 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.
75  * \param ElementCount The number of elements (not bytes) to read.
76  * \param ptr A pointer to the first output element in an array (or std::vector<>, etc...).
77  * \return The amound of *bytes* (not elements) actually read (under error situations, the last element may be invalid if the data stream abruptly ends).
78  * Example of usage:
79  * \code
80  * uint32_t N;
81  * s >> N;
82  * vector<float> vec(N);
83  * if (N)
84  * s.ReadBufferFixEndianness<float>(&vec[0],N);
85  * \endcode
86  * \exception std::exception On any error, or if ZERO bytes are read.
87  * \sa ReadBufferFixEndianness, ReadBuffer
88  */
89  template <typename T>
90  size_t ReadBufferFixEndianness(T *ptr, size_t ElementCount)
91  {
92  #if !MRPT_IS_BIG_ENDIAN
93  // little endian: no conversion needed.
94  return ReadBuffer(ptr,ElementCount*sizeof(T));
95  #else
96  // big endian: convert.
97  const size_t nread = ReadBuffer(ptr,ElementCount*sizeof(T));
98  for (size_t i=0;i<ElementCount;i++) mrpt::utils::reverseBytesInPlace(ptr[i]);
99  return nread;
100  #endif
101  }
102 
103 
104  /** 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).
105  * Note that this method will fallback to ReadBuffer() in most CStream classes but in some hardware-related classes.
106  * \exception std::exception On any error, or if ZERO bytes are read.
107  */
108  virtual size_t ReadBufferImmediate(void *Buffer, size_t Count) { return ReadBuffer(Buffer, Count); }
109 
110  /** Writes a block of bytes to the stream from Buffer.
111  * \exception std::exception On any error
112  * \sa Important, see: WriteBufferFixEndianness
113  * \note This method is endianness-dependent.
114  */
115  void WriteBuffer (const void *Buffer, size_t Count);
116 
117 
118 
119  /** Writes a sequence of elemental datatypes, taking care of reordering their bytes from the running architecture to MRPT stream standard (little endianness).
120  * \param ElementCount The number of elements (not bytes) to write.
121  * \param ptr A pointer to the first input element in an array (or std::vector<>, etc...).
122  * Example of usage:
123  * \code
124  * vector<float> vec = ...
125  * uint32_t N = vec.size();
126  * s << N
127  * if (N)
128  * s.WriteBufferFixEndianness<float>(&vec[0],N);
129  * \endcode
130  * \exception std::exception On any error
131  * \sa WriteBuffer
132  */
133  template <typename T>
134  void WriteBufferFixEndianness(const T *ptr, size_t ElementCount)
135  {
136  #if !MRPT_IS_BIG_ENDIAN
137  // little endian: no conversion needed.
138  return WriteBuffer(ptr,ElementCount*sizeof(T));
139  #else
140  // big endian: the individual "<<" functions already convert endiannes
141  for (size_t i=0;i<ElementCount;i++) (*this) << ptr[i];
142  #endif
143  }
144 
145 
146  /** Copies a specified number of bytes from one stream to another. */
147  size_t CopyFrom(CStream* Source, size_t Count);
148 
149  /** Introduces a pure virtual method for moving to a specified position in the streamed resource.
150  * he Origin parameter indicates how to interpret the Offset parameter. Origin should be one of the following values:
151  * - sFromBeginning (Default) Offset is from the beginning of the resource. Seek moves to the position Offset. Offset must be >= 0.
152  * - sFromCurrent Offset is from the current position in the resource. Seek moves to Position + Offset.
153  * - 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.
154  * \return Seek returns the new value of the Position property.
155  */
156  virtual uint64_t Seek(uint64_t Offset, CStream::TSeekOrigin Origin = sFromBeginning) = 0;
157 
158  /** Returns the total amount of bytes in the stream.
159  */
160  virtual uint64_t getTotalBytesCount() = 0;
161 
162  /** Method for getting the current cursor position, where 0 is the first byte and TotalBytesCount-1 the last one.
163  */
164  virtual uint64_t getPosition() =0;
165 
166  /** Writes an object to the stream.
167  */
168  void WriteObject( const CSerializable *o );
169 
170  /** Reads an object from stream, its class determined at runtime, and returns a smart pointer to the object.
171  * \exception std::exception On I/O error or undefined class.
172  * \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.
173  */
174  CSerializablePtr ReadObject();
175 
176  /** Reads an object from stream, where its class must be the same
177  * as the supplied object, where the loaded object will be stored in.
178  * \exception std::exception On I/O error or different class found.
179  * \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.
180  */
181  void ReadObject(CSerializable *existingObj);
182 
183  /** Write an object to a stream in the binary MRPT format. */
184  CStream& operator << (const CSerializablePtr & pObj);
185  /** Write an object to a stream in the binary MRPT format. */
186  CStream& operator << (const CSerializable &obj);
187 
190 
191 
192 
193  /** Writes a string to the stream in a textual form.
194  * \sa CStdOutStream
195  */
196  virtual int printf(const char *fmt,...) MRPT_printf_format_check(2,3); // The first argument (1) is "this" !!!
197 
198  /** Prints a vector in the format [A,B,C,...] using CStream::printf, and the fmt string for <b>each</b> vector element. */
199  template <typename T>
200  void printf_vector(const char *fmt, const std::vector<T> &V )
201  {
202  this->printf("[");
203  size_t N = V.size();
204  for (size_t i=0;i<N;i++)
205  {
206  this->printf(fmt,V[i]);
207  if (i!=(N-1)) this->printf(",");
208  }
209  this->printf("]");
210  }
211 
212  /** Send a message to the device.
213  * Note that only the low byte from the "type" field will be used.
214  *
215  * For frames of size < 255 the frame format is an array of bytes in this order:
216  * \code
217  * <START_FLAG> <HEADER> <LENGTH> <BODY> <END_FLAG>
218  * <START_FLAG> = 0x69
219  * <HEADER> = A header byte
220  * <LENGHT> = Number of bytes of BODY
221  * <BODY> = N x bytes
222  * <END_FLAG> = 0X96
223  * Total length = <LENGTH> + 4
224  * \endcode
225  *
226  * For frames of size > 255 the frame format is an array of bytes in this order:
227  * \code
228  * <START_FLAG> <HEADER> <HIBYTE(LENGTH)> <LOBYTE(LENGTH)> <BODY> <END_FLAG>
229  * <START_FLAG> = 0x79
230  * <HEADER> = A header byte
231  * <LENGHT> = Number of bytes of BODY
232  * <BODY> = N x bytes
233  * <END_FLAG> = 0X96
234  * Total length = <LENGTH> + 5
235  * \endcode
236  *
237  * \exception std::exception On communication errors
238  */
239  void sendMessage( const utils::CMessage &msg);
240 
241  /** Tries to receive a message from the device.
242  * \exception std::exception On communication errors
243  * \returns True if successful, false if there is no new data from the device (but communications seem to work fine)
244  * \sa The frame format is described in sendMessage()
245  */
246  bool receiveMessage( utils::CMessage &msg );
247 
248  /** Reads from the stream until a '\n' character is found ('\r' characters are ignored).
249  * \return false on EOF or any other read error.
250  */
251  bool getline(std::string &out_str);
252 
253 
254  }; // End of class def.
255 
256 
257  #define DECLARE_CSTREAM_READ_WRITE_SIMPLE_TYPE( T ) \
258  CStream BASE_IMPEXP & operator<<(CStream&out, const T &a); \
259  CStream BASE_IMPEXP & operator>>(CStream&in, T &a);
260 
261  // Definitions:
273 #ifdef HAVE_LONG_DOUBLE
275 #endif
276 
277  // Why this shouldn't be templatized?: There's a more modern system
278  // in MRPT that serializes any kind of vector<T>, deque<T>, etc... but
279  // to keep COMPATIBILITY with old serialized objects we must preserve
280  // the ones listed here:
281 
282  // Write --------------------
283  CStream BASE_IMPEXP & operator << (CStream&s, const char *a);
284  CStream BASE_IMPEXP & operator << (CStream&s, const std::string &str);
285 
288 
296 
298  CStream BASE_IMPEXP & operator << (CStream&, const std::vector<std::string> &);
299 
300  #if MRPT_WORD_SIZE!=32 // If it's 32 bit, size_t <=> uint32_t
301  CStream BASE_IMPEXP & operator << (CStream&, const std::vector<size_t> &a);
302  #endif
303 
304  // Read --------------------
305  CStream BASE_IMPEXP & operator>>(CStream&in, char *a);
306  CStream BASE_IMPEXP & operator>>(CStream&in, std::string &str);
307 
310 
319 
320  CStream BASE_IMPEXP & operator>>(CStream&in, std::vector<std::string> &a);
321 
322  // For backward compatibility, since in MRPT<0.8.1 vector_XXX and std::vector<XXX> were exactly equivalent, now there're not.
323  CStream BASE_IMPEXP & operator >> (CStream&s, std::vector<float> &a);
324  CStream BASE_IMPEXP & operator >> (CStream&s, std::vector<double> &a);
325  CStream BASE_IMPEXP & operator << (CStream&s, const std::vector<float> &a);
326  CStream BASE_IMPEXP & operator << (CStream&s, const std::vector<double> &a);
327 
328  #if MRPT_WORD_SIZE!=32 // If it's 32 bit, size_t <=> uint32_t
329  CStream BASE_IMPEXP & operator >> (CStream&s, std::vector<size_t> &a);
330  #endif
331 
332  } // End of namespace
333 } // End of namespace
334 
335 #endif
std::vector< int32_t > vector_int
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:108
TSeekOrigin
Used in CStream::Seek.
Definition: CStream.h:41
The virtual base class which provides a unified interface for all persistent objects in MRPT...
Definition: CSerializable.h:32
class BASE_IMPEXP CStream
Definition: math_frwds.h:28
std::vector< bool > vector_bool
A type for passing a vector of bools.
STL namespace.
std::vector< int8_t > vector_signed_byte
std::vector< int16_t > vector_signed_word
std::vector< int64_t > vector_long
#define MRPT_printf_format_check(_FMT_, _VARARGS_)
::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:134
This base class is used to provide a unified interface to files,memory buffers,..Please see the deriv...
Definition: CStream.h:36
#define DECLARE_CSTREAM_READ_WRITE_SIMPLE_TYPE(T)
Definition: CStream.h:257
std::vector< uint8_t > vector_byte
dynamicsize_vector< double > vector_double
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...
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
CStream BASE_IMPEXP & operator<<(CStream &s, const char *a)
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:90
std::vector< uint16_t > vector_word
void reverseBytesInPlace(T &v_in_out)
Reverse the order of the bytes of a given type (useful for transforming btw little/big endian) ...
std::vector< uint32_t > vector_uint
dynamicsize_vector< float > vector_float
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.1.0 SVN: at lun oct 28 00:54:49 CET 2019 Hosted on:
SourceForge.net Logo