/usr/lib/python2.7/dist-packages/rospy/msg.py is in python-rospy 1.11.16-3.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 | # Software License Agreement (BSD License)
#
# Copyright (c) 2008, 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.
#
# Revision $Id$
"""Internal use: Support for ROS messages, including network serialization routines"""
import types
import time
import struct
import logging
import traceback
import genpy
import rospy.exceptions
import rospy.names
class AnyMsg(genpy.Message):
"""
Message class to use for subscribing to any topic regardless
of type. Incoming messages are not deserialized. Instead, the raw
serialized data can be accssed via the buff property.
This class is meant to be used by advanced users only.
"""
_md5sum = rospy.names.TOPIC_ANYTYPE
_type = rospy.names.TOPIC_ANYTYPE
_has_header = False
_full_text = ''
__slots__ = ['_buff']
def __init__(self, *args):
"""
Constructor. Does not accept any arguments.
"""
if len(args) != 0:
raise rospy.exceptions.ROSException("AnyMsg does not accept arguments")
self._buff = None
def serialize(self, buff):
"""AnyMsg provides an implementation so that a node can forward messages w/o (de)serialization"""
if self._buff is None:
raise rospy.exceptions("AnyMsg is not initialized")
else:
buff.write(self._buff)
def deserialize(self, str):
"""Copies raw buffer into self._buff"""
self._buff = str
return self
def args_kwds_to_message(data_class, args, kwds):
"""
Given a data class, take in the args and kwds of a function call and return the appropriate
data_class instance.
If kwds are specified, a new data_class instance will be created with keyword-style init.
If there is only a single arg and it is of the correct type, it
will be returned. AnyMsg is considered to match all data_class
types.
Otherwise, args will be used as args for a new message instance.
@param data_class: Message class that will be used to instantiate new instances, if necessary.
@type data_class: Message class
@param args: function args
@type args: sequence
@param kwds: function kwds
@type kwds: dict
@raise TypeError: if args and kwds are both specified
"""
if args and kwds:
raise TypeError("publish() can be called with arguments or keywords, but not both.")
elif kwds:
return data_class(**kwds)
else:
if len(args) == 1:
arg = args[0]
# #2584: have to compare on md5sum as isinstance check can fail in dyngen case
if hasattr(arg, '_md5sum') and (arg._md5sum == data_class._md5sum or isinstance(arg, AnyMsg)):
return arg
# If the argument is a message, make sure that it matches
# the type of the first field. This means that the
# data_class has fields and that the type matches. This
# branch isn't necessary but provides more useful
# information to users
elif isinstance(arg, genpy.Message):
if len(data_class._slot_types) == 0:
raise TypeError("expected [] but got [%s]"%arg._type)
elif arg._type != data_class._slot_types[0]:
raise TypeError("expected [%s] but got [%s]"%(data_class._slot_types[0], arg._type))
return data_class(*args)
else:
return data_class(*args)
def serialize_message(b, seq, msg):
"""
Serialize the message to the buffer
@param b: buffer to write to. WARNING: buffer will be reset after call
@type b: StringIO
@param msg: message to write
@type msg: Message
@param seq: current sequence number (for headers)
@type seq: int: current sequence number (for headers)
@raise ROSSerializationException: if unable to serialize
message. This is usually due to a type error with one of the
fields.
"""
start = b.tell()
b.seek(start+4) #reserve 4-bytes for length
#update Header object in top-level message
if getattr(msg.__class__, "_has_header", False):
header = msg.header
header.seq = seq
# default value for frame_id is '0'
if header.frame_id is None:
header.frame_id = "0"
#serialize the message data
try:
msg.serialize(b)
except struct.error as e:
raise rospy.exceptions.ROSSerializationException(e)
#write 4-byte packet length
# -4 don't include size of length header
end = b.tell()
size = end - 4 - start
b.seek(start)
b.write(struct.pack('<I', size))
b.seek(end)
def deserialize_messages(b, msg_queue, data_class, queue_size=None, max_msgs=None, start=0):
"""
Read all messages off the buffer
@param b: buffer to read data from
@type b: StringIO
@param msg_queue: queue to append deserialized data to
@type msg_queue: list
@param data_class: message deserialization class
@type data_class: Message class
@param queue_size: message queue size. all but the last
queue_size messages are discarded if this parameter is specified.
@type queue_size: int
@param start: starting position to read in b
@type start: int
@param max_msgs int: maximum number of messages to deserialize or None
@type max_msgs: int
@raise genpy.DeserializationError: if an error/exception occurs during deserialization
"""
try:
pos = start
btell = b.tell()
left = btell - pos
# check to see if we even have a message
if left < 4:
return
# read in each message from the buffer as a string. each
# message is preceded by a 4-byte integer length. the
# serialized messages are appended to buff.
b.seek(pos)
buffs = []
# size of message
size = -1
while (size < 0 and left >= 4) or (size > -1 and left >= size):
# - read in the packet length
# NOTE: size is not inclusive of itself.
if size < 0 and left >= 4:
(size,) = struct.unpack('<I', b.read(4))
left -= 4
# - deserialize the complete buffer
if size > -1 and left >= size:
buffs.append(b.read(size))
pos += size + 4
left = btell - pos
size = -1
if max_msgs and len(buffs) >= max_msgs:
break
#Before we deserialize, prune our buffers baed on the
#queue_size rules.
if queue_size is not None:
buffs = buffs[-queue_size:]
# Deserialize the messages into msg_queue, then trim the
# msg_queue as specified.
for q in buffs:
data = data_class()
msg_queue.append(data.deserialize(q))
if queue_size is not None:
del msg_queue[:-queue_size]
#update buffer b to its correct write position.
if btell == pos:
#common case: no leftover data, reset the buffer
b.seek(start)
b.truncate(start)
else:
if pos != start:
#next packet is stuck in our buffer, copy it to the
#beginning of our buffer to keep things simple
b.seek(pos)
leftovers = b.read(btell-pos)
b.truncate(start + len(leftovers))
b.seek(start)
b.write(leftovers)
else:
b.seek(btell)
except Exception as e:
logging.getLogger('rospy.msg').error("cannot deserialize message: EXCEPTION %s", traceback.format_exc())
raise genpy.DeserializationError("cannot deserialize: %s"%str(e))
|