Pipe Inpection Robot / Mbed OS capstone_finish

Dependencies:   BufferedSerial motor_sn7544

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers serialization.h Source File

serialization.h

00001 /*
00002  * Copyright (C) 2009, Willow Garage, Inc.
00003  *
00004  * Redistribution and use in source and binary forms, with or without
00005  * modification, are permitted provided that the following conditions are met:
00006  *   * Redistributions of source code must retain the above copyright notice,
00007  *     this list of conditions and the following disclaimer.
00008  *   * Redistributions in binary form must reproduce the above copyright
00009  *     notice, this list of conditions and the following disclaimer in the
00010  *     documentation and/or other materials provided with the distribution.
00011  *   * Neither the names of Willow Garage, Inc. nor the names of its
00012  *     contributors may be used to endorse or promote products derived from
00013  *     this software without specific prior written permission.
00014  *
00015  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00016  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00017  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00018  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00019  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00020  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00021  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00022  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00023  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00024  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00025  * POSSIBILITY OF SUCH DAMAGE.
00026  */
00027 
00028 #ifndef ROSCPP_SERIALIZATION_H
00029 #define ROSCPP_SERIALIZATION_H
00030 
00031 #include "roscpp_serialization_macros.h"
00032 
00033 #include <ros/types.h>
00034 #include <ros/time.h>
00035 
00036 #include "serialized_message.h"
00037 #include "ros/message_traits.h"
00038 #include "ros/builtin_message_traits.h"
00039 #include "ros/exception.h"
00040 #include "ros/datatypes.h"
00041 
00042 #include <vector>
00043 #include <map>
00044 
00045 #include <boost/array.hpp>
00046 #include <boost/call_traits.hpp>
00047 #include <boost/utility/enable_if.hpp>
00048 #include <boost/mpl/and.hpp>
00049 #include <boost/mpl/or.hpp>
00050 #include <boost/mpl/not.hpp>
00051 
00052 #include <cstring>
00053 
00054 #define ROS_NEW_SERIALIZATION_API 1
00055 
00056 /**
00057  * \brief Declare your serializer to use an allInOne member instead of requiring 3 different serialization
00058  * functions.
00059  *
00060  * The allinone method has the form:
00061 \verbatim
00062 template<typename Stream, typename T>
00063 inline static void allInOne(Stream& stream, T t)
00064 {
00065   stream.next(t.a);
00066   stream.next(t.b);
00067   ...
00068 }
00069 \endverbatim
00070  *
00071  * The only guarantee given is that Stream::next(T) is defined.
00072  */
00073 #define ROS_DECLARE_ALLINONE_SERIALIZER \
00074   template<typename Stream, typename T> \
00075   inline static void write(Stream& stream, const T& t) \
00076   { \
00077     allInOne<Stream, const T&>(stream, t); \
00078   } \
00079   \
00080   template<typename Stream, typename T> \
00081   inline static void read(Stream& stream, T& t) \
00082   { \
00083     allInOne<Stream, T&>(stream, t); \
00084   } \
00085   \
00086   template<typename T> \
00087   inline static uint32_t serializedLength(const T& t) \
00088   { \
00089     LStream stream; \
00090     allInOne<LStream, const T&>(stream, t); \
00091     return stream.getLength(); \
00092   }
00093 
00094 namespace ros
00095 {
00096 namespace serialization
00097 {
00098 namespace mt = message_traits;
00099 namespace mpl = boost::mpl;
00100 
00101 class ROSCPP_SERIALIZATION_DECL StreamOverrunException : public ros::Exception
00102 {
00103 public:
00104   StreamOverrunException(const std::string& what)
00105   : Exception(what)
00106   {}
00107 };
00108 
00109 ROSCPP_SERIALIZATION_DECL void throwStreamOverrun();
00110 
00111 /**
00112  * \brief Templated serialization class.  Default implementation provides backwards compatibility with
00113  * old message types.
00114  *
00115  * Specializing the Serializer class is the only thing you need to do to get the ROS serialization system
00116  * to work with a type.
00117  */
00118 template<typename T>
00119 struct Serializer
00120 {
00121   /**
00122    * \brief Write an object to the stream.  Normally the stream passed in here will be a ros::serialization::OStream
00123    */
00124   template<typename Stream>
00125   inline static void write(Stream& stream, typename boost::call_traits<T>::param_type t)
00126   {
00127     t.serialize(stream.getData(), 0);
00128   }
00129 
00130   /**
00131    * \brief Read an object from the stream.  Normally the stream passed in here will be a ros::serialization::IStream
00132    */
00133   template<typename Stream>
00134   inline static void read(Stream& stream, typename boost::call_traits<T>::reference t)
00135   {
00136     t.deserialize(stream.getData());
00137   }
00138 
00139   /**
00140    * \brief Determine the serialized length of an object.
00141    */
00142   inline static uint32_t serializedLength(typename boost::call_traits<T>::param_type t)
00143   {
00144     return t.serializationLength();
00145   }
00146 };
00147 
00148 /**
00149  * \brief Serialize an object.  Stream here should normally be a ros::serialization::OStream
00150  */
00151 template<typename T, typename Stream>
00152 inline void serialize(Stream& stream, const T& t)
00153 {
00154   Serializer<T>::write(stream, t);
00155 }
00156 
00157 /**
00158  * \brief Deserialize an object.  Stream here should normally be a ros::serialization::IStream
00159  */
00160 template<typename T, typename Stream>
00161 inline void deserialize(Stream& stream, T& t)
00162 {
00163   Serializer<T>::read(stream, t);
00164 }
00165 
00166 /**
00167  * \brief Determine the serialized length of an object
00168  */
00169 template<typename T>
00170 inline uint32_t serializationLength(const T& t)
00171 {
00172   return Serializer<T>::serializedLength(t);
00173 }
00174 
00175 #define ROS_CREATE_SIMPLE_SERIALIZER(Type) \
00176   template<> struct Serializer<Type> \
00177   { \
00178     template<typename Stream> inline static void write(Stream& stream, const Type v) \
00179     { \
00180       memcpy(stream.advance(sizeof(v)), &v, sizeof(v) ); \
00181     } \
00182     \
00183     template<typename Stream> inline static void read(Stream& stream, Type& v) \
00184     { \
00185       memcpy(&v, stream.advance(sizeof(v)), sizeof(v) ); \
00186     } \
00187     \
00188     inline static uint32_t serializedLength(const Type&) \
00189       { \
00190       return sizeof(Type); \
00191     } \
00192 };
00193 
00194 ROS_CREATE_SIMPLE_SERIALIZER(uint8_t)
00195 ROS_CREATE_SIMPLE_SERIALIZER(int8_t)
00196 ROS_CREATE_SIMPLE_SERIALIZER(uint16_t)
00197 ROS_CREATE_SIMPLE_SERIALIZER(int16_t)
00198 ROS_CREATE_SIMPLE_SERIALIZER(uint32_t)
00199 ROS_CREATE_SIMPLE_SERIALIZER(int32_t)
00200 ROS_CREATE_SIMPLE_SERIALIZER(uint64_t)
00201 ROS_CREATE_SIMPLE_SERIALIZER(int64_t)
00202 ROS_CREATE_SIMPLE_SERIALIZER(float)
00203 ROS_CREATE_SIMPLE_SERIALIZER(double)
00204 
00205 /**
00206  * \brief Serializer specialized for bool (serialized as uint8)
00207  */
00208 template<> struct Serializer<bool>
00209 {
00210   template<typename Stream> inline static void write(Stream& stream, const bool v)
00211   {
00212     uint8_t b = (uint8_t)v;
00213     memcpy(stream.advance(1), &b, 1 );
00214   }
00215 
00216   template<typename Stream> inline static void read(Stream& stream, bool& v)
00217   {
00218     uint8_t b;
00219     memcpy(&b, stream.advance(1), 1 );
00220     v = (bool)b;
00221   }
00222 
00223   inline static uint32_t serializedLength(bool)
00224   {
00225     return 1;
00226   }
00227 };
00228 
00229 /**
00230  * \brief  Serializer specialized for std::string
00231  */
00232 template<class ContainerAllocator>
00233 struct Serializer<std::basic_string<char, std::char_traits<char>, ContainerAllocator> >
00234 {
00235   typedef std::basic_string<char, std::char_traits<char>, ContainerAllocator> StringType;
00236 
00237   template<typename Stream>
00238   inline static void write(Stream& stream, const StringType& str)
00239   {
00240     size_t len = str.size();
00241     stream.next((uint32_t)len);
00242 
00243     if (len > 0)
00244     {
00245       memcpy(stream.advance((uint32_t)len), str.data(), len);
00246     }
00247   }
00248 
00249   template<typename Stream>
00250   inline static void read(Stream& stream, StringType& str)
00251   {
00252     uint32_t len;
00253     stream.next(len);
00254     if (len > 0)
00255     {
00256       str = StringType((char*)stream.advance(len), len);
00257     }
00258     else
00259     {
00260       str.clear();
00261     }
00262   }
00263 
00264   inline static uint32_t serializedLength(const StringType& str)
00265   {
00266     return 4 + (uint32_t)str.size();
00267   }
00268 };
00269 
00270 /**
00271  * \brief Serializer specialized for ros::Time
00272  */
00273 template<>
00274 struct Serializer<ros::Time>
00275 {
00276   template<typename Stream>
00277   inline static void write(Stream& stream, const ros::Time& v)
00278   {
00279     stream.next(v.sec);
00280     stream.next(v.nsec);
00281   }
00282 
00283   template<typename Stream>
00284   inline static void read(Stream& stream, ros::Time& v)
00285   {
00286     stream.next(v.sec);
00287     stream.next(v.nsec);
00288   }
00289 
00290   inline static uint32_t serializedLength(const ros::Time&)
00291   {
00292     return 8;
00293   }
00294 };
00295 
00296 /**
00297  * \brief Serializer specialized for ros::Duration
00298  */
00299 template<>
00300 struct Serializer<ros::Duration>
00301 {
00302   template<typename Stream>
00303   inline static void write(Stream& stream, const ros::Duration& v)
00304   {
00305     stream.next(v.sec);
00306     stream.next(v.nsec);
00307   }
00308 
00309   template<typename Stream>
00310   inline static void read(Stream& stream, ros::Duration& v)
00311   {
00312     stream.next(v.sec);
00313     stream.next(v.nsec);
00314   }
00315 
00316   inline static uint32_t serializedLength(const ros::Duration&)
00317   {
00318     return 8;
00319   }
00320 };
00321 
00322 /**
00323  * \brief Vector serializer.  Default implementation does nothing
00324  */
00325 template<typename T, class ContainerAllocator, class Enabled = void>
00326 struct VectorSerializer
00327 {};
00328 
00329 /**
00330  * \brief Vector serializer, specialized for non-fixed-size, non-simple types
00331  */
00332 template<typename T, class ContainerAllocator>
00333 struct VectorSerializer<T, ContainerAllocator, typename boost::disable_if<mt::IsFixedSize<T> >::type >
00334 {
00335   typedef std::vector<T, typename ContainerAllocator::template rebind<T>::other> VecType;
00336   typedef typename VecType::iterator IteratorType;
00337   typedef typename VecType::const_iterator ConstIteratorType;
00338 
00339   template<typename Stream>
00340   inline static void write(Stream& stream, const VecType& v)
00341   {
00342     stream.next((uint32_t)v.size());
00343     ConstIteratorType it = v.begin();
00344     ConstIteratorType end = v.end();
00345     for (; it != end; ++it)
00346     {
00347       stream.next(*it);
00348     }
00349   }
00350 
00351   template<typename Stream>
00352   inline static void read(Stream& stream, VecType& v)
00353   {
00354     uint32_t len;
00355     stream.next(len);
00356     v.resize(len);
00357     IteratorType it = v.begin();
00358     IteratorType end = v.end();
00359     for (; it != end; ++it)
00360     {
00361       stream.next(*it);
00362     }
00363   }
00364 
00365   inline static uint32_t serializedLength(const VecType& v)
00366   {
00367     uint32_t size = 4;
00368     ConstIteratorType it = v.begin();
00369     ConstIteratorType end = v.end();
00370     for (; it != end; ++it)
00371     {
00372       size += serializationLength(*it);
00373     }
00374 
00375     return size;
00376   }
00377 };
00378 
00379 /**
00380  * \brief Vector serializer, specialized for fixed-size simple types
00381  */
00382 template<typename T, class ContainerAllocator>
00383 struct VectorSerializer<T, ContainerAllocator, typename boost::enable_if<mt::IsSimple<T> >::type >
00384 {
00385   typedef std::vector<T, typename ContainerAllocator::template rebind<T>::other> VecType;
00386   typedef typename VecType::iterator IteratorType;
00387   typedef typename VecType::const_iterator ConstIteratorType;
00388 
00389   template<typename Stream>
00390   inline static void write(Stream& stream, const VecType& v)
00391   {
00392     uint32_t len = (uint32_t)v.size();
00393     stream.next(len);
00394     if (!v.empty())
00395     {
00396       const uint32_t data_len = len * (uint32_t)sizeof(T);
00397       memcpy(stream.advance(data_len), &v.front(), data_len);
00398     }
00399   }
00400 
00401   template<typename Stream>
00402   inline static void read(Stream& stream, VecType& v)
00403   {
00404     uint32_t len;
00405     stream.next(len);
00406     v.resize(len);
00407 
00408     if (len > 0)
00409     {
00410       const uint32_t data_len = (uint32_t)sizeof(T) * len;
00411       memcpy(&v.front(), stream.advance(data_len), data_len);
00412     }
00413   }
00414 
00415   inline static uint32_t serializedLength(const VecType& v)
00416   {
00417     return 4 + v.size() * (uint32_t)sizeof(T);
00418   }
00419 };
00420 
00421 /**
00422  * \brief Vector serializer, specialized for fixed-size non-simple types
00423  */
00424 template<typename T, class ContainerAllocator>
00425 struct VectorSerializer<T, ContainerAllocator, typename boost::enable_if<mpl::and_<mt::IsFixedSize<T>, mpl::not_<mt::IsSimple<T> > > >::type >
00426 {
00427   typedef std::vector<T, typename ContainerAllocator::template rebind<T>::other> VecType;
00428   typedef typename VecType::iterator IteratorType;
00429   typedef typename VecType::const_iterator ConstIteratorType;
00430 
00431   template<typename Stream>
00432   inline static void write(Stream& stream, const VecType& v)
00433   {
00434     stream.next((uint32_t)v.size());
00435     ConstIteratorType it = v.begin();
00436     ConstIteratorType end = v.end();
00437     for (; it != end; ++it)
00438     {
00439       stream.next(*it);
00440     }
00441   }
00442 
00443   template<typename Stream>
00444   inline static void read(Stream& stream, VecType& v)
00445   {
00446     uint32_t len;
00447     stream.next(len);
00448     v.resize(len);
00449     IteratorType it = v.begin();
00450     IteratorType end = v.end();
00451     for (; it != end; ++it)
00452     {
00453       stream.next(*it);
00454     }
00455   }
00456 
00457   inline static uint32_t serializedLength(const VecType& v)
00458   {
00459     uint32_t size = 4;
00460     if (!v.empty())
00461     {
00462       uint32_t len_each = serializationLength(v.front());
00463       size += len_each * (uint32_t)v.size();
00464     }
00465 
00466     return size;
00467   }
00468 };
00469 
00470 /**
00471  * \brief serialize version for std::vector
00472  */
00473 template<typename T, class ContainerAllocator, typename Stream>
00474 inline void serialize(Stream& stream, const std::vector<T, ContainerAllocator>& t)
00475 {
00476   VectorSerializer<T, ContainerAllocator>::write(stream, t);
00477 }
00478 
00479 /**
00480  * \brief deserialize version for std::vector
00481  */
00482 template<typename T, class ContainerAllocator, typename Stream>
00483 inline void deserialize(Stream& stream, std::vector<T, ContainerAllocator>& t)
00484 {
00485   VectorSerializer<T, ContainerAllocator>::read(stream, t);
00486 }
00487 
00488 /**
00489  * \brief serializationLength version for std::vector
00490  */
00491 template<typename T, class ContainerAllocator>
00492 inline uint32_t serializationLength(const std::vector<T, ContainerAllocator>& t)
00493 {
00494   return VectorSerializer<T, ContainerAllocator>::serializedLength(t);
00495 }
00496 
00497 /**
00498  * \brief Array serializer, default implementation does nothing
00499  */
00500 template<typename T, size_t N, class Enabled = void>
00501 struct ArraySerializer
00502 {};
00503 
00504 /**
00505  * \brief Array serializer, specialized for non-fixed-size, non-simple types
00506  */
00507 template<typename T, size_t N>
00508 struct ArraySerializer<T, N, typename boost::disable_if<mt::IsFixedSize<T> >::type>
00509 {
00510   typedef boost::array<T, N > ArrayType;
00511   typedef typename ArrayType::iterator IteratorType;
00512   typedef typename ArrayType::const_iterator ConstIteratorType;
00513 
00514   template<typename Stream>
00515   inline static void write(Stream& stream, const ArrayType& v)
00516   {
00517     ConstIteratorType it = v.begin();
00518     ConstIteratorType end = v.end();
00519     for (; it != end; ++it)
00520     {
00521       stream.next(*it);
00522     }
00523   }
00524 
00525   template<typename Stream>
00526   inline static void read(Stream& stream, ArrayType& v)
00527   {
00528     IteratorType it = v.begin();
00529     IteratorType end = v.end();
00530     for (; it != end; ++it)
00531     {
00532       stream.next(*it);
00533     }
00534   }
00535 
00536   inline static uint32_t serializedLength(const ArrayType& v)
00537   {
00538     uint32_t size = 0;
00539     ConstIteratorType it = v.begin();
00540     ConstIteratorType end = v.end();
00541     for (; it != end; ++it)
00542     {
00543       size += serializationLength(*it);
00544     }
00545 
00546     return size;
00547   }
00548 };
00549 
00550 /**
00551  * \brief Array serializer, specialized for fixed-size, simple types
00552  */
00553 template<typename T, size_t N>
00554 struct ArraySerializer<T, N, typename boost::enable_if<mt::IsSimple<T> >::type>
00555 {
00556   typedef boost::array<T, N > ArrayType;
00557   typedef typename ArrayType::iterator IteratorType;
00558   typedef typename ArrayType::const_iterator ConstIteratorType;
00559 
00560   template<typename Stream>
00561   inline static void write(Stream& stream, const ArrayType& v)
00562   {
00563     const uint32_t data_len = N * sizeof(T);
00564     memcpy(stream.advance(data_len), &v.front(), data_len);
00565   }
00566 
00567   template<typename Stream>
00568   inline static void read(Stream& stream, ArrayType& v)
00569   {
00570     const uint32_t data_len = N * sizeof(T);
00571     memcpy(&v.front(), stream.advance(data_len), data_len);
00572   }
00573 
00574   inline static uint32_t serializedLength(const ArrayType&)
00575   {
00576     return N * sizeof(T);
00577   }
00578 };
00579 
00580 /**
00581  * \brief Array serializer, specialized for fixed-size, non-simple types
00582  */
00583 template<typename T, size_t N>
00584 struct ArraySerializer<T, N, typename boost::enable_if<mpl::and_<mt::IsFixedSize<T>, mpl::not_<mt::IsSimple<T> > > >::type>
00585 {
00586   typedef boost::array<T, N > ArrayType;
00587   typedef typename ArrayType::iterator IteratorType;
00588   typedef typename ArrayType::const_iterator ConstIteratorType;
00589 
00590   template<typename Stream>
00591   inline static void write(Stream& stream, const ArrayType& v)
00592   {
00593     ConstIteratorType it = v.begin();
00594     ConstIteratorType end = v.end();
00595     for (; it != end; ++it)
00596     {
00597       stream.next(*it);
00598     }
00599   }
00600 
00601   template<typename Stream>
00602   inline static void read(Stream& stream, ArrayType& v)
00603   {
00604     IteratorType it = v.begin();
00605     IteratorType end = v.end();
00606     for (; it != end; ++it)
00607     {
00608       stream.next(*it);
00609     }
00610   }
00611 
00612   inline static uint32_t serializedLength(const ArrayType& v)
00613   {
00614     return serializationLength(v.front()) * N;
00615   }
00616 };
00617 
00618 /**
00619  * \brief serialize version for boost::array
00620  */
00621 template<typename T, size_t N, typename Stream>
00622 inline void serialize(Stream& stream, const boost::array<T, N>& t)
00623 {
00624   ArraySerializer<T, N>::write(stream, t);
00625 }
00626 
00627 /**
00628  * \brief deserialize version for boost::array
00629  */
00630 template<typename T, size_t N, typename Stream>
00631 inline void deserialize(Stream& stream, boost::array<T, N>& t)
00632 {
00633   ArraySerializer<T, N>::read(stream, t);
00634 }
00635 
00636 /**
00637  * \brief serializationLength version for boost::array
00638  */
00639 template<typename T, size_t N>
00640 inline uint32_t serializationLength(const boost::array<T, N>& t)
00641 {
00642   return ArraySerializer<T, N>::serializedLength(t);
00643 }
00644 
00645 /**
00646  * \brief Enum
00647  */
00648 namespace stream_types
00649 {
00650 enum StreamType
00651 {
00652   Input,
00653   Output,
00654   Length
00655 };
00656 }
00657 typedef stream_types::StreamType StreamType;
00658 
00659 /**
00660  * \brief Stream base-class, provides common functionality for IStream and OStream
00661  */
00662 struct ROSCPP_SERIALIZATION_DECL Stream
00663 {
00664   /*
00665    * \brief Returns a pointer to the current position of the stream
00666    */
00667   inline uint8_t* getData() { return data_; }
00668   /**
00669    * \brief Advances the stream, checking bounds, and returns a pointer to the position before it
00670    * was advanced.
00671    * \throws StreamOverrunException if len would take this stream past the end of its buffer
00672    */
00673   ROS_FORCE_INLINE uint8_t* advance(uint32_t len)
00674   {
00675     uint8_t* old_data = data_;
00676     data_ += len;
00677     if (data_ > end_)
00678     {
00679       // Throwing directly here causes a significant speed hit due to the extra code generated
00680       // for the throw statement
00681       throwStreamOverrun();
00682     }
00683     return old_data;
00684   }
00685 
00686   /**
00687    * \brief Returns the amount of space left in the stream
00688    */
00689   inline uint32_t getLength() { return (uint32_t)(end_ - data_); }
00690 
00691 protected:
00692   Stream(uint8_t* _data, uint32_t _count)
00693   : data_(_data)
00694   , end_(_data + _count)
00695   {}
00696 
00697 private:
00698   uint8_t* data_;
00699   uint8_t* end_;
00700 };
00701 
00702 /**
00703  * \brief Input stream
00704  */
00705 struct ROSCPP_SERIALIZATION_DECL IStream : public Stream
00706 {
00707   static const StreamType stream_type = stream_types::Input;
00708 
00709   IStream(uint8_t* data, uint32_t count)
00710   : Stream(data, count)
00711   {}
00712 
00713   /**
00714    * \brief Deserialize an item from this input stream
00715    */
00716   template<typename T>
00717   ROS_FORCE_INLINE void next(T& t)
00718   {
00719     deserialize(*this, t);
00720   }
00721 
00722   template<typename T>
00723   ROS_FORCE_INLINE IStream& operator>>(T& t)
00724   {
00725     deserialize(*this, t);
00726     return *this;
00727   }
00728 };
00729 
00730 /**
00731  * \brief Output stream
00732  */
00733 struct ROSCPP_SERIALIZATION_DECL OStream : public Stream
00734 {
00735   static const StreamType stream_type = stream_types::Output;
00736 
00737   OStream(uint8_t* data, uint32_t count)
00738   : Stream(data, count)
00739   {}
00740 
00741   /**
00742    * \brief Serialize an item to this output stream
00743    */
00744   template<typename T>
00745   ROS_FORCE_INLINE void next(const T& t)
00746   {
00747     serialize(*this, t);
00748   }
00749 
00750   template<typename T>
00751   ROS_FORCE_INLINE OStream& operator<<(const T& t)
00752   {
00753     serialize(*this, t);
00754     return *this;
00755   }
00756 };
00757 
00758 
00759 /**
00760  * \brief Length stream
00761  *
00762  * LStream is not what you would normally think of as a stream, but it is used in order to support
00763  * allinone serializers.
00764  */
00765 struct ROSCPP_SERIALIZATION_DECL LStream
00766 {
00767   static const StreamType stream_type = stream_types::Length;
00768 
00769   LStream()
00770   : count_(0)
00771   {}
00772 
00773   /**
00774    * \brief Add the length of an item to this length stream
00775    */
00776   template<typename T>
00777   ROS_FORCE_INLINE void next(const T& t)
00778   {
00779     count_ += serializationLength(t);
00780   }
00781 
00782   /**
00783    * \brief increment the length by len
00784    */
00785   ROS_FORCE_INLINE uint32_t advance(uint32_t len)
00786   {
00787     uint32_t old = count_;
00788     count_ += len;
00789     return old;
00790   }
00791 
00792   /**
00793    * \brief Get the total length of this tream
00794    */
00795   inline uint32_t getLength() { return count_; }
00796 
00797 private:
00798   uint32_t count_;
00799 };
00800 
00801 /**
00802  * \brief Serialize a message
00803  */
00804 template<typename M>
00805 inline SerializedMessage serializeMessage(const M& message)
00806 {
00807   SerializedMessage m;
00808   uint32_t len = serializationLength(message);
00809   m.num_bytes = len + 4;
00810   m.buf.reset(new uint8_t[m.num_bytes]);
00811 
00812   OStream s(m.buf.get(), (uint32_t)m.num_bytes);
00813   serialize(s, (uint32_t)m.num_bytes - 4);
00814   m.message_start = s.getData();
00815   serialize(s, message);
00816 
00817   return m;
00818 }
00819 
00820 /**
00821  * \brief Serialize a service response
00822  */
00823 template<typename M>
00824 inline SerializedMessage serializeServiceResponse(bool ok, const M& message)
00825 {
00826   SerializedMessage m;
00827 
00828   if (ok)
00829   {
00830     uint32_t len = serializationLength(message);
00831     m.num_bytes = len + 5;
00832     m.buf.reset(new uint8_t[m.num_bytes]);
00833 
00834     OStream s(m.buf.get(), (uint32_t)m.num_bytes);
00835     serialize(s, (uint8_t)ok);
00836     serialize(s, (uint32_t)m.num_bytes - 5);
00837     serialize(s, message);
00838   }
00839   else
00840   {
00841     uint32_t len = serializationLength(message);
00842     m.num_bytes = len + 1;
00843     m.buf.reset(new uint8_t[m.num_bytes]);
00844 
00845     OStream s(m.buf.get(), (uint32_t)m.num_bytes);
00846     serialize(s, (uint8_t)ok);
00847     serialize(s, message);
00848   }
00849 
00850   return m;
00851 }
00852 
00853 /**
00854  * \brief Deserialize a message.  If includes_length is true, skips the first 4 bytes
00855  */
00856 template<typename M>
00857 inline void deserializeMessage(const SerializedMessage& m, M& message)
00858 {
00859   IStream s(m.message_start, m.num_bytes - (m.message_start - m.buf.get()));
00860   deserialize(s, message);
00861 }
00862 
00863 
00864 // Additional serialization traits
00865 
00866 template<typename M>
00867 struct PreDeserializeParams
00868 {
00869   boost::shared_ptr<M> message;
00870   boost::shared_ptr<std::map<std::string, std::string> > connection_header;
00871 };
00872 
00873 /**
00874  * \brief called by the SubscriptionCallbackHelper after a message is
00875  * instantiated but before that message is deserialized
00876  */
00877 template<typename M>
00878 struct PreDeserialize
00879 {
00880   static void notify(const PreDeserializeParams<M>&) { }
00881 };
00882 
00883 } // namespace serialization
00884 
00885 } // namespace ros
00886 
00887 #endif // ROSCPP_SERIALIZATION_H