Main MRPT website > C++ reference
MRPT logo
CStream.h
Go to the documentation of this file.
1 /* +---------------------------------------------------------------------------+
2  | The Mobile Robot Programming Toolkit (MRPT) |
3  | |
4  | http://www.mrpt.org/ |
5  | |
6  | Copyright (c) 2005-2013, Individual contributors, see AUTHORS file |
7  | Copyright (c) 2005-2013, MAPIR group, University of Malaga |
8  | Copyright (c) 2012-2013, University of Almeria |
9  | All rights reserved. |
10  | |
11  | Redistribution and use in source and binary forms, with or without |
12  | modification, are permitted provided that the following conditions are |
13  | met: |
14  | * Redistributions of source code must retain the above copyright |
15  | notice, this list of conditions and the following disclaimer. |
16  | * Redistributions in binary form must reproduce the above copyright |
17  | notice, this list of conditions and the following disclaimer in the |
18  | documentation and/or other materials provided with the distribution. |
19  | * Neither the name of the copyright holders nor the |
20  | names of its contributors may be used to endorse or promote products |
21  | derived from this software without specific prior written permission.|
22  | |
23  | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
24  | 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
25  | TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR|
26  | PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE |
27  | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL|
28  | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR|
29  | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
30  | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
31  | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN |
32  | ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
33  | POSSIBILITY OF SUCH DAMAGE. |
34  +---------------------------------------------------------------------------+ */
35 #ifndef CSTREAM_H
36 #define CSTREAM_H
37 
38 #include <mrpt/utils/utils_defs.h>
39 #include <mrpt/utils/CUncopiable.h>
40 #include <mrpt/utils/CObject.h>
41 #include <mrpt/utils/exceptions.h>
42 
43 namespace mrpt
44 {
45  namespace utils
46  {
50 
51  /** This base class is used to provide a unified interface to
52  * files,memory buffers,..Please see the derived classes. This class is
53  * largely inspired by Borland VCL "TStream" class. <br><br>
54  * Apart of the "VCL like" methods, operators ">>" and "<<" have been
55  * defined so that simple types (int,bool,char,float,char *,std::string,...)
56  * can be directly written and read to and from any CStream easily.
57  * Please, it is recomendable to read CSerializable documentation also.
58  *
59  * \ingroup mrpt_base_grp
60  * \sa CFileStream, CMemoryStream,CSerializable
61  */
63  {
64  public:
65  /** Used in CStream::Seek
66  */
68  {
69  sFromBeginning = 0,
70  sFromCurrent = 1,
71  sFromEnd = 2
72  };
73 
74  protected:
75  /** Introduces a pure virtual method responsible for reading from the stream.
76  */
77  virtual size_t Read(void *Buffer, size_t Count) = 0;
78 
79  /** Introduces a pure virtual method responsible for writing to the stream.
80  * Write attempts to write up to Count bytes to Buffer, and returns the number of bytes actually written.
81  */
82  virtual size_t Write(const void *Buffer, size_t Count) = 0;
83  public:
84  /* Constructor
85  */
86  CStream() { }
87 
88  /* Destructor
89  */
90  virtual ~CStream();
91 
92  /** Reads a block of bytes from the stream into Buffer
93  * \exception std::exception On any error, or if ZERO bytes are read.
94  * \return The amound of bytes actually read.
95  * \note This method is endianness-dependent.
96  * \sa ReadBufferImmediate ; Important, see: ReadBufferFixEndianness,
97  */
98  size_t ReadBuffer(void *Buffer, size_t Count);
99 
100  /** 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.
101  * \param ElementCount The number of elements (not bytes) to read.
102  * \param ptr A pointer to the first output element in an array (or std::vector<>, etc...).
103  * \return The amound of *bytes* (not elements) actually read (under error situations, the last element may be invalid if the data stream abruptly ends).
104  * Example of usage:
105  * \code
106  * uint32_t N;
107  * s >> N;
108  * vector<float> vec(N);
109  * if (N)
110  * s.ReadBufferFixEndianness<float>(&vec[0],N);
111  * \endcode
112  * \exception std::exception On any error, or if ZERO bytes are read.
113  * \sa ReadBufferFixEndianness, ReadBuffer
114  */
115  template <typename T>
116  size_t ReadBufferFixEndianness(T *ptr, size_t ElementCount)
117  {
118  #if !MRPT_IS_BIG_ENDIAN
119  // little endian: no conversion needed.
120  return ReadBuffer(ptr,ElementCount*sizeof(T));
121  #else
122  // big endian: convert.
123  const size_t nread = ReadBuffer(ptr,ElementCount*sizeof(T));
124  for (size_t i=0;i<ElementCount;i++) mrpt::utils::reverseBytesInPlace(ptr[i]);
125  return nread;
126  #endif
127  }
128 
129 
130  /** 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).
131  * Note that this method will fallback to ReadBuffer() in most CStream classes but in some hardware-related classes.
132  * \exception std::exception On any error, or if ZERO bytes are read.
133  */
134  virtual size_t ReadBufferImmediate(void *Buffer, size_t Count) { return ReadBuffer(Buffer, Count); }
135 
136  /** Writes a block of bytes to the stream from Buffer.
137  * \exception std::exception On any error
138  * \sa Important, see: WriteBufferFixEndianness
139  * \note This method is endianness-dependent.
140  */
141  void WriteBuffer (const void *Buffer, size_t Count);
142 
143 
144 
145  /** Writes a sequence of elemental datatypes, taking care of reordering their bytes from the running architecture to MRPT stream standard (little endianness).
146  * \param ElementCount The number of elements (not bytes) to write.
147  * \param ptr A pointer to the first input element in an array (or std::vector<>, etc...).
148  * Example of usage:
149  * \code
150  * vector<float> vec = ...
151  * uint32_t N = vec.size();
152  * s << N
153  * if (N)
154  * s.WriteBufferFixEndianness<float>(&vec[0],N);
155  * \endcode
156  * \exception std::exception On any error
157  * \sa WriteBuffer
158  */
159  template <typename T>
160  void WriteBufferFixEndianness(const T *ptr, size_t ElementCount)
161  {
162  #if !MRPT_IS_BIG_ENDIAN
163  // little endian: no conversion needed.
164  return WriteBuffer(ptr,ElementCount*sizeof(T));
165  #else
166  // big endian: the individual "<<" functions already convert endiannes
167  for (size_t i=0;i<ElementCount;i++) (*this) << ptr[i];
168  #endif
169  }
170 
171 
172  /** Copies a specified number of bytes from one stream to another. */
173  size_t CopyFrom(CStream* Source, size_t Count);
174 
175  /** Introduces a pure virtual method for moving to a specified position in the streamed resource.
176  * he Origin parameter indicates how to interpret the Offset parameter. Origin should be one of the following values:
177  * - sFromBeginning (Default) Offset is from the beginning of the resource. Seek moves to the position Offset. Offset must be >= 0.
178  * - sFromCurrent Offset is from the current position in the resource. Seek moves to Position + Offset.
179  * - 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.
180  * \return Seek returns the new value of the Position property.
181  */
182  virtual uint64_t Seek(uint64_t Offset, CStream::TSeekOrigin Origin = sFromBeginning) = 0;
183 
184  /** Returns the total amount of bytes in the stream.
185  */
186  virtual uint64_t getTotalBytesCount() = 0;
187 
188  /** Method for getting the current cursor position, where 0 is the first byte and TotalBytesCount-1 the last one.
189  */
190  virtual uint64_t getPosition() =0;
191 
192  /** Writes an object to the stream.
193  */
194  void WriteObject( const CSerializable *o );
195 
196  /** Reads an object from stream, its class determined at runtime, and returns a smart pointer to the object.
197  * \exception std::exception On I/O error or undefined class.
198  * \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.
199  */
200  CSerializablePtr ReadObject();
201 
202  /** Reads an object from stream, where its class must be the same
203  * as the supplied object, where the loaded object will be stored in.
204  * \exception std::exception On I/O error or different class found.
205  * \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.
206  */
207  void ReadObject(CSerializable *existingObj);
208 
209  /** Write an object to a stream in the binary MRPT format. */
210  CStream& operator << (const CSerializablePtr & pObj);
211  /** Write an object to a stream in the binary MRPT format. */
212  CStream& operator << (const CSerializable &obj);
213 
216 
217 
218 
219  /** Writes a string to the stream in a textual form.
220  * \sa CStdOutStream
221  */
222  virtual int printf(const char *fmt,...) MRPT_printf_format_check(2,3); // The first argument (1) is "this" !!!
223 
224  /** Prints a vector in the format [A,B,C,...] using CStream::printf, and the fmt string for <b>each</b> vector element. */
225  template <typename T>
226  void printf_vector(const char *fmt, const std::vector<T> &V )
227  {
228  this->printf("[");
229  size_t N = V.size();
230  for (size_t i=0;i<N;i++)
231  {
232  this->printf(fmt,V[i]);
233  if (i!=(N-1)) this->printf(",");
234  }
235  this->printf("]");
236  }
237 
238  /** Send a message to the device.
239  * Note that only the low byte from the "type" field will be used.
240  *
241  * For frames of size < 255 the frame format is an array of bytes in this order:
242  * \code
243  * <START_FLAG> <HEADER> <LENGTH> <BODY> <END_FLAG>
244  * <START_FLAG> = 0x69
245  * <HEADER> = A header byte
246  * <LENGHT> = Number of bytes of BODY
247  * <BODY> = N x bytes
248  * <END_FLAG> = 0X96
249  * Total length = <LENGTH> + 4
250  * \endcode
251  *
252  * For frames of size > 255 the frame format is an array of bytes in this order:
253  * \code
254  * <START_FLAG> <HEADER> <HIBYTE(LENGTH)> <LOBYTE(LENGTH)> <BODY> <END_FLAG>
255  * <START_FLAG> = 0x79
256  * <HEADER> = A header byte
257  * <LENGHT> = Number of bytes of BODY
258  * <BODY> = N x bytes
259  * <END_FLAG> = 0X96
260  * Total length = <LENGTH> + 5
261  * \endcode
262  *
263  * \exception std::exception On communication errors
264  */
265  void sendMessage( const utils::CMessage &msg);
266 
267  /** Tries to receive a message from the device.
268  * \exception std::exception On communication errors
269  * \returns True if successful, false if there is no new data from the device (but communications seem to work fine)
270  * \sa The frame format is described in sendMessage()
271  */
272  bool receiveMessage( utils::CMessage &msg );
273 
274  /** Reads from the stream until a '\n' character is found ('\r' characters are ignored).
275  * \return false on EOF or any other read error.
276  */
277  bool getline(std::string &out_str);
278 
279 
280  }; // End of class def.
281 
282 
283  #define DECLARE_CSTREAM_READ_WRITE_SIMPLE_TYPE( T ) \
284  CStream BASE_IMPEXP & operator<<(CStream&out, const T &a); \
285  CStream BASE_IMPEXP & operator>>(CStream&in, T &a);
286 
287  // Definitions:
299 #ifdef HAVE_LONG_DOUBLE
301 #endif
302 
303  // Why this shouldn't be templatized?: There's a more modern system
304  // in MRPT that serializes any kind of vector<T>, deque<T>, etc... but
305  // to keep COMPATIBILITY with old serialized objects we must preserve
306  // the ones listed here:
307 
308  // Write --------------------
309  CStream BASE_IMPEXP & operator << (CStream&s, const char *a);
310  CStream BASE_IMPEXP & operator << (CStream&s, const std::string &str);
311 
314 
322 
324  CStream BASE_IMPEXP & operator << (CStream&, const std::vector<std::string> &);
325 
326  #if MRPT_WORD_SIZE!=32 // If it's 32 bit, size_t <=> uint32_t
327  CStream BASE_IMPEXP & operator << (CStream&, const std::vector<size_t> &a);
328  #endif
329 
330  // Read --------------------
331  CStream BASE_IMPEXP & operator>>(CStream&in, char *a);
332  CStream BASE_IMPEXP & operator>>(CStream&in, std::string &str);
333 
336 
345 
346  CStream BASE_IMPEXP & operator>>(CStream&in, std::vector<std::string> &a);
347 
348  // For backward compatibility, since in MRPT<0.8.1 vector_XXX and std::vector<XXX> were exactly equivalent, now there're not.
349  CStream BASE_IMPEXP & operator >> (CStream&s, std::vector<float> &a);
350  CStream BASE_IMPEXP & operator >> (CStream&s, std::vector<double> &a);
351  CStream BASE_IMPEXP & operator << (CStream&s, const std::vector<float> &a);
352  CStream BASE_IMPEXP & operator << (CStream&s, const std::vector<double> &a);
353 
354  #if MRPT_WORD_SIZE!=32 // If it's 32 bit, size_t <=> uint32_t
355  CStream BASE_IMPEXP & operator >> (CStream&s, std::vector<size_t> &a);
356  #endif
357 
358  } // End of namespace
359 } // End of namespace
360 
361 #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:134
TSeekOrigin
Used in CStream::Seek.
Definition: CStream.h:67
The virtual base class which provides a unified interface for all persistent objects in MRPT...
Definition: CSerializable.h:58
class BASE_IMPEXP CStream
Definition: math_frwds.h:54
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:160
This base class is used to provide a unified interface to files,memory buffers,..Please see the deriv...
Definition: CStream.h:62
#define DECLARE_CSTREAM_READ_WRITE_SIMPLE_TYPE(T)
Definition: CStream.h:283
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:116
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:55



Page generated by Doxygen 1.8.14 for MRPT 1.0.2 SVN: at lun oct 28 00:52:41 CET 2019 Hosted on:
SourceForge.net Logo