00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 import roslib
00030 import roslib.message
00031 import roslib.msgs
00032
00033 import genpy
00034 import rospy
00035 import struct
00036 from itertools import izip
00037 from cStringIO import StringIO
00038
00039
00040 class EndOfBuffer(BaseException):
00041 pass
00042
00043
00044 class TranslatorError(ValueError):
00045 pass
00046
00047
00048 class Handler(object):
00049 def field(self, msg):
00050 return getattr(msg, self.name)
00051
00052 def preserialize(self, msg):
00053 pass
00054
00055
00056 class SubMessageHandler(Handler):
00057 def __init__(self, field):
00058 self.name = field.name
00059 self.msg_cls = roslib.message.get_message_class(field.type)
00060
00061 def deserialize(self, buff, msg):
00062 self.field(msg).translator().deserialize(buff)
00063
00064 def serialize(self, buff, msg):
00065 self.field(msg).translator().serialize(buff)
00066
00067
00068 class FixedFieldsHandler(Handler):
00069 def __init__(self, fields):
00070 struct_strs = ['<']
00071
00072
00073 def pattern(field):
00074 try:
00075 return genpy.base.SIMPLE_TYPES_DICT[field.type]
00076 except KeyError:
00077 if field.base_type in ['uint8', 'char'] and field.array_len is not None:
00078 return "%is" % field.array_len
00079 else:
00080 raise
00081
00082 struct_strs.extend([pattern(f) for f in fields])
00083 self.struct = struct.Struct(''.join(struct_strs))
00084 self.names = [f.name for f in fields]
00085 self.size = self.struct.size
00086
00087 def serialize(self, buff, msg):
00088 buff.write(self.struct.pack(*[getattr(msg, name) for name in self.names]))
00089
00090 def deserialize(self, buff, msg):
00091 st = buff.read(self.struct.size)
00092 if st == '':
00093 return
00094 values = self.struct.unpack(st)
00095 for name, value in izip(self.names, values):
00096 setattr(msg, name, value)
00097
00098
00099 class SubMessageArrayHandler(Handler):
00100 struct_uint16 = struct.Struct('<H')
00101 struct_uint8 = struct.Struct('<B')
00102
00103 def __init__(self, field):
00104 self.name = field.name
00105 self.name_count = "%s_count" % self.name
00106 self.msg_cls = roslib.message.get_message_class(field.base_type)
00107 self.submessage_size = self.msg_cls().translator().size
00108
00109 def deserialize(self, buff, msg):
00110 if hasattr(msg, self.name_count):
00111
00112 length = getattr(msg, self.name_count) * self.submessage_size
00113 data = StringIO(buff.read(length))
00114 else:
00115
00116 data = buff
00117
00118
00119 array = self.field(msg)
00120 array[:] = []
00121
00122 try:
00123 while True:
00124 submessage = self.msg_cls()
00125 submessage.translator().deserialize(data)
00126 array.append(submessage)
00127 except EndOfBuffer:
00128 pass
00129
00130 def serialize(self, buff, msg):
00131 for submessage in self.field(msg):
00132 submessage.translator().serialize(buff)
00133
00134 def preserialize(self, msg):
00135 if hasattr(msg, self.name_count):
00136 setattr(msg, self.name_count, len(self.field(msg)))
00137
00138
00139 class VariableStringHandler(Handler):
00140 struct_bytes = struct.Struct('<H')
00141
00142 def __init__(self, field):
00143 self.name = field.name
00144
00145 def deserialize(self, buff, msg):
00146 length = self.struct_bytes.unpack(buff.read(self.struct_bytes.size))[0]
00147 setattr(msg, self.name, str(buff.read(length)))
00148
00149
00150 class Translator:
00151 def __init__(self, msg_cls):
00152 self.handlers = []
00153 self.size = None
00154
00155 cls_name, spec = roslib.msgs.load_by_type(msg_cls._type)
00156
00157 fixed_fields = []
00158 for field in spec.parsed_fields():
00159 if field.type == 'novatel_msgs/CommonHeader':
00160
00161 continue
00162
00163 if genpy.base.is_simple(field.base_type) and (field.array_len is not None or not field.is_array):
00164
00165 fixed_fields.append(field)
00166 else:
00167
00168
00169 if len(fixed_fields) > 0:
00170 self.handlers.append(FixedFieldsHandler(fixed_fields))
00171 fixed_fields = []
00172
00173
00174 if field.type == 'string' or (field.base_type == 'uint8' and field.is_array):
00175 self.handlers.append(VariableStringHandler(field))
00176 elif field.is_array:
00177 self.handlers.append(SubMessageArrayHandler(field))
00178 else:
00179 self.handlers.append(SubMessageHandler(field))
00180
00181 if len(fixed_fields) > 0:
00182 self.handlers.append(FixedFieldsHandler(fixed_fields))
00183
00184 if len(self.handlers) == 1 and hasattr(self.handlers[0], 'size'):
00185 self.size = self.handlers[0].size
00186
00187
00188 class TranslatorProxy:
00189 def __init__(self, translator, msg):
00190 self.translator = translator
00191 self.size = translator.size
00192 self.msg = msg
00193
00194 def deserialize(self, buff):
00195 try:
00196 for handler in self.translator.handlers:
00197 handler.deserialize(buff, self.msg)
00198 except struct.error as e:
00199 raise TranslatorError(e)
00200
00201 def serialize(self, buff):
00202 try:
00203 for handler in self.translator.handlers:
00204 handler.serialize(buff, self.msg)
00205 except struct.error as e:
00206 raise TranslatorError(e)
00207
00208 def preserialize(self):
00209 for handler in self.translator.handlers:
00210 handler.preserialize(self.msg)
00211
00212
00213 def translator(self):
00214 if not hasattr(self.__class__, "_translator"):
00215 self.__class__._translator = Translator(self.__class__)
00216 return TranslatorProxy(self.__class__._translator, self)
00217
00218 roslib.message.Message.translator = translator