Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: BufferedSerial motor_sn7544
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
Generated on Wed Jul 13 2022 07:13:54 by
