translator.py
Go to the documentation of this file.
1 #! /usr/bin/env python
2 # -*- coding: utf-8 -*-
3 
4 # Software License Agreement (BSD)
5 #
6 # file @translator.py
7 # authors Mike Purvis <mpurvis@clearpathrobotics.com>
8 # NovAtel <novatel.com/support>
9 # copyright Copyright (c) 2012, Clearpath Robotics, Inc., All rights reserved.
10 # Copyright (c) 2014, NovAtel Inc., All rights reserved.
11 #
12 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that
13 # the following conditions are met:
14 # * Redistributions of source code must retain the above copyright notice, this list of conditions and the
15 # following disclaimer.
16 # * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
17 # following disclaimer in the documentation and/or other materials provided with the distribution.
18 # * Neither the name of Clearpath Robotics nor the names of its contributors may be used to endorse or promote
19 # products derived from this software without specific prior written permission.
20 #
21 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WAR-
22 # RANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, IN-
24 # DIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
25 # OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26 # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 
29 import roslib
30 import roslib.message
31 import roslib.msgs
32 
33 import genpy
34 import rospy
35 import struct
36 from itertools import izip
37 from cStringIO import StringIO
38 
39 
40 class EndOfBuffer(BaseException):
41  pass
42 
43 
44 class TranslatorError(ValueError):
45  pass
46 
47 
48 class Handler(object):
49  def field(self, msg):
50  return getattr(msg, self.name)
51 
52  def preserialize(self, msg):
53  pass
54 
55 
56 class SubMessageHandler(Handler):
57  def __init__(self, field):
58  self.name = field.name
59  self.msg_cls = roslib.message.get_message_class(field.type)
60 
61  def deserialize(self, buff, msg):
62  self.field(msg).translator().deserialize(buff)
63 
64  def serialize(self, buff, msg):
65  self.field(msg).translator().serialize(buff)
66 
67 
69  def __init__(self, fields):
70  struct_strs = ['<']
71 
72  # serial vs ethernet
73  def pattern(field):
74  try:
75  return genpy.base.SIMPLE_TYPES_DICT[field.type]
76  except KeyError:
77  if field.base_type in ['uint8', 'char'] and field.array_len is not None:
78  return "%is" % field.array_len
79  else:
80  raise
81 
82  struct_strs.extend([pattern(f) for f in fields])
83  self.struct = struct.Struct(''.join(struct_strs))
84  self.names = [f.name for f in fields]
85  self.size = self.struct.size
86 
87  def serialize(self, buff, msg):
88  buff.write(self.struct.pack(*[getattr(msg, name) for name in self.names]))
89 
90  def deserialize(self, buff, msg):
91  st = buff.read(self.struct.size)
92  if st == '':
93  return
94  values = self.struct.unpack(st)
95  for name, value in izip(self.names, values):
96  setattr(msg, name, value)
97 
98 
100  struct_uint16 = struct.Struct('<H')
101  struct_uint8 = struct.Struct('<B')
102 
103  def __init__(self, field):
104  self.name = field.name
105  self.name_count = "%s_count" % self.name
106  self.msg_cls = roslib.message.get_message_class(field.base_type)
107  self.submessage_size = self.msg_cls().translator().size
108 
109  def deserialize(self, buff, msg):
110  if hasattr(msg, self.name_count):
111  # Another field specifies number of array items to deserialize.
112  length = getattr(msg, self.name_count) * self.submessage_size
113  data = StringIO(buff.read(length))
114  else:
115  # Consume as much as we can straight from the buffer.
116  data = buff
117 
118  # Find and empty the array to be populated.
119  array = self.field(msg)
120  array[:] = []
121 
122  try:
123  while True:
124  submessage = self.msg_cls()
125  submessage.translator().deserialize(data)
126  array.append(submessage)
127  except EndOfBuffer:
128  pass
129 
130  def serialize(self, buff, msg):
131  for submessage in self.field(msg):
132  submessage.translator().serialize(buff)
133 
134  def preserialize(self, msg):
135  if hasattr(msg, self.name_count):
136  setattr(msg, self.name_count, len(self.field(msg)))
137 
138 
140  struct_bytes = struct.Struct('<H')
141 
142  def __init__(self, field):
143  self.name = field.name
144 
145  def deserialize(self, buff, msg):
146  length = self.struct_bytes.unpack(buff.read(self.struct_bytes.size))[0]
147  setattr(msg, self.name, str(buff.read(length)))
148 
149 
151  def __init__(self, msg_cls):
152  self.handlers = []
153  self.size = None
154 
155  cls_name, spec = roslib.msgs.load_by_type(msg_cls._type)
156 
157  fixed_fields = []
158  for field in spec.parsed_fields():
159  if field.type == 'novatel_msgs/CommonHeader':
160  # Deserializing the header happens elsewhere.
161  continue
162 
163  if genpy.base.is_simple(field.base_type) and (field.array_len is not None or not field.is_array):
164  # Simple types and fixed-length character arrays.
165  fixed_fields.append(field)
166  else:
167  # Before dealing with this non-simple field, add a handler for the fixed fields
168  # encountered so far.
169  if len(fixed_fields) > 0:
170  self.handlers.append(FixedFieldsHandler(fixed_fields))
171  fixed_fields = []
172 
173  # Handle this other type.
174  if field.type == 'string' or (field.base_type == 'uint8' and field.is_array):
175  self.handlers.append(VariableStringHandler(field))
176  elif field.is_array:
177  self.handlers.append(SubMessageArrayHandler(field))
178  else:
179  self.handlers.append(SubMessageHandler(field))
180 
181  if len(fixed_fields) > 0:
182  self.handlers.append(FixedFieldsHandler(fixed_fields))
183 
184  if len(self.handlers) == 1 and hasattr(self.handlers[0], 'size'):
185  self.size = self.handlers[0].size
186 
187 
189  def __init__(self, translator, msg):
190  self.translator = translator
191  self.size = translator.size
192  self.msg = msg
193 
194  def deserialize(self, buff):
195  try:
196  for handler in self.translator.handlers:
197  handler.deserialize(buff, self.msg)
198  except struct.error as e:
199  raise TranslatorError(e)
200 
201  def serialize(self, buff):
202  try:
203  for handler in self.translator.handlers:
204  handler.serialize(buff, self.msg)
205  except struct.error as e:
206  raise TranslatorError(e)
207 
208  def preserialize(self):
209  for handler in self.translator.handlers:
210  handler.preserialize(self.msg)
211 
212 
213 def translator(self):
214  if not hasattr(self.__class__, "_translator"):
215  self.__class__._translator = Translator(self.__class__)
216  return TranslatorProxy(self.__class__._translator, self)
217 
218 roslib.message.Message.translator = translator


novatel_span_driver
Author(s): NovAtel Support
autogenerated on Wed Apr 3 2019 02:52:53