Add PreDeserialize trait (#2683)

This commit is contained in:
Josh Faust 2010-05-04 20:04:59 +00:00
parent ca6e5fdd1f
commit 53978be4c2
6 changed files with 211 additions and 1 deletions

View File

@ -49,6 +49,30 @@
namespace ros
{
namespace serialization
{
// Additional serialization traits
template<typename M>
struct PreDeserializeParams
{
boost::shared_ptr<M> message;
boost::shared_ptr<std::map<std::string, std::string> > connection_header;
};
/**
* \brief called by the SubscriptionCallbackHelper after a message is instantiated but before that message is deserialized
*/
template<typename M>
struct PreDeserialize
{
static void notify(const PreDeserializeParams<M>& params)
{
}
};
}
template<typename T>
typename boost::enable_if<boost::is_base_of<ros::Message, T> >::type assignSubscriptionConnectionHeader(T* t, const boost::shared_ptr<M_string>& connection_header)
{
@ -132,6 +156,11 @@ public:
assignSubscriptionConnectionHeader(msg.get(), params.connection_header);
ser::PreDeserializeParams<NonConstType> predes_params;
predes_params.message = msg;
predes_params.connection_header = params.connection_header;
ser::PreDeserialize<NonConstType>::notify(predes_params);
ser::IStream stream(params.buffer, params.length);
ser::deserialize(stream, *msg);

View File

@ -40,6 +40,30 @@ namespace roslib
ROS_DECLARE_MESSAGE(Header);
}
#define ROS_IMPLEMENT_SIMPLE_TOPIC_TRAITS(msg, md5sum, datatype, definition) \
namespace ros \
{ \
namespace message_traits \
{ \
template<> struct MD5Sum<msg> \
{ \
static const char* value() { return md5sum; } \
static const char* value(const msg&) { return value(); } \
}; \
template<> struct DataType<msg> \
{ \
static const char* value() { return datatype; } \
static const char* value(const msg&) { return value(); } \
}; \
template<> struct Definition<msg> \
{ \
static const char* value() { return definition; } \
static const char* value(const msg&) { return value(); } \
}; \
} \
}
namespace ros
{
namespace message_traits

View File

@ -19,4 +19,9 @@ rosbuild_add_gtest(generated_messages src/generated_messages.cpp)
rosbuild_add_executable(builtin_types src/builtin_types.cpp)
rosbuild_declare_test(builtin_types)
rosbuild_add_gtest_build_flags(builtin_types)
rosbuild_add_rostest(test/builtin_types.xml)
rosbuild_add_rostest(test/builtin_types.test)
rosbuild_add_executable(pre_deserialize src/pre_deserialize.cpp)
rosbuild_declare_test(pre_deserialize)
rosbuild_add_gtest_build_flags(pre_deserialize)
rosbuild_add_rostest(test/pre_deserialize.test)

View File

@ -0,0 +1,147 @@
/*
* Copyright (c) 2010, Willow Garage, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of Willow Garage, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/* Author: Josh Faust */
/*
* Test PreDeserialize trait
*/
#include <gtest/gtest.h>
#include <ros/ros.h>
// To avoid the intraprocess optimization we use two messages
struct OutgoingMsg
{
};
struct IncomingMsg
{
IncomingMsg()
: touched(false)
{}
bool touched;
};
ROS_IMPLEMENT_SIMPLE_TOPIC_TRAITS(IncomingMsg, "my_md5sum", "test_roscpp_serialization/IncomingMsg", "\n");
ROS_IMPLEMENT_SIMPLE_TOPIC_TRAITS(OutgoingMsg, "my_md5sum", "test_roscpp_serialization/OutgoingMsg", "\n");
namespace ros
{
namespace serialization
{
template<>
struct Serializer<IncomingMsg>
{
template<typename Stream>
inline static void write(Stream& stream, const IncomingMsg& v)
{
}
template<typename Stream>
inline static void read(Stream& stream, IncomingMsg& v)
{
}
inline static uint32_t serializedLength(const IncomingMsg& v)
{
return 0;
}
};
template<>
struct Serializer<OutgoingMsg>
{
template<typename Stream>
inline static void write(Stream& stream, const OutgoingMsg& v)
{
}
template<typename Stream>
inline static void read(Stream& stream, OutgoingMsg& v)
{
}
inline static uint32_t serializedLength(const OutgoingMsg& v)
{
return 0;
}
};
template<>
struct PreDeserialize<IncomingMsg>
{
static void notify(const PreDeserializeParams<IncomingMsg>& params)
{
params.message->touched = true;
}
};
} // namespace serialization
} // namespace ros
boost::shared_ptr<IncomingMsg const> g_msg;
void callback(const boost::shared_ptr<IncomingMsg const>& msg)
{
g_msg = msg;
}
TEST(PreDeserialize, preDeserialize)
{
ros::NodeHandle nh;
ros::Publisher pub = nh.advertise<OutgoingMsg>("test", 0);
ros::Subscriber sub = nh.subscribe("test", 0, callback);
pub.publish(OutgoingMsg());
while (!g_msg)
{
ros::spinOnce();
ros::WallDuration(0.01).sleep();
}
EXPECT_TRUE(g_msg->touched);
}
int main(int argc, char** argv)
{
testing::InitGoogleTest(&argc, argv);
ros::init(argc, argv, "builtin_types");
ros::NodeHandle nh;
return RUN_ALL_TESTS();
}

View File

@ -0,0 +1,5 @@
<launch>
<test test-name="pre_deserialize" pkg="test_roscpp_serialization" type="pre_deserialize"/>
</launch>