Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(60)

Side by Side Diff: mojo/public/python/mojo_bindings/serialization.py

Issue 1218023006: Implement python mojo bindings unions. (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 # Copyright 2014 The Chromium Authors. All rights reserved. 1 # Copyright 2014 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 4
5 """Utility classes for serialization""" 5 """Utility classes for serialization"""
6 6
7 import struct 7 import struct
8 8
9 9
10 # Format of a header for a struct or an array. 10 # Format of a header for a struct, array or union.
11 HEADER_STRUCT = struct.Struct("<II") 11 HEADER_STRUCT = struct.Struct("<II")
12 12
13 # Format for a pointer.
14 POINTER_STRUCT = struct.Struct("<Q")
15
13 16
14 def Flatten(value): 17 def Flatten(value):
15 """Flattens nested lists/tuples into an one-level list. If value is not a 18 """Flattens nested lists/tuples into an one-level list. If value is not a
16 list/tuple, it is converted to an one-item list. For example, 19 list/tuple, it is converted to an one-item list. For example,
17 (1, 2, [3, 4, ('56', '7')]) is converted to [1, 2, 3, 4, '56', '7']; 20 (1, 2, [3, 4, ('56', '7')]) is converted to [1, 2, 3, 4, '56', '7'];
18 1 is converted to [1]. 21 1 is converted to [1].
19 """ 22 """
20 if isinstance(value, (list, tuple)): 23 if isinstance(value, (list, tuple)):
21 result = [] 24 result = []
22 for item in value: 25 for item in value:
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after
211 needed_padding = NeededPaddingForAlignment(index, group.GetAlignment()) 214 needed_padding = NeededPaddingForAlignment(index, group.GetAlignment())
212 if needed_padding: 215 if needed_padding:
213 codes.append('x' * needed_padding) 216 codes.append('x' * needed_padding)
214 index = index + needed_padding 217 index = index + needed_padding
215 codes.append(code) 218 codes.append(code)
216 index = index + group.GetByteSize() 219 index = index + group.GetByteSize()
217 alignment_needed = NeededPaddingForAlignment(index) 220 alignment_needed = NeededPaddingForAlignment(index)
218 if alignment_needed: 221 if alignment_needed:
219 codes.append('x' * alignment_needed) 222 codes.append('x' * alignment_needed)
220 return struct.Struct(''.join(codes)) 223 return struct.Struct(''.join(codes))
224
225
226 class UnionSerializer(object):
227 """
228 Helper class to serialize/deserialize a union.
229 """
230 def __init__(self, fields):
231 self._fields = {field.index: field for field in fields}
232
233 def SerializeInline(self, union, handle_offset):
234 data = bytearray()
235 field = self._fields[union.tag]
236
237 # Serialize the unions value and either
238 # 1. Return the serialized value itself as entry.
239 # 2. Append the serialized value to data and return 8 a pointer to the
240 # serialized value. (Assumes the data will immediately follow the union.)
241 (entry, handles) = field.field_type.Serialize(
242 union.data, 8, data, handle_offset)
243
244 # If the value contained in the union is itself a union, we append its
245 # serialized value to data and set entry to 8, a pointer to the data.
246 if field.field_type.IsUnion():
247 nested_union = bytearray(16)
248 HEADER_STRUCT.pack_into(nested_union, 0, entry[0], entry[1])
249 POINTER_STRUCT.pack_into(nested_union, 8, entry[2])
250
251 data = nested_union + data
252 entry = 8
253
254 return (16, union.tag, entry, data), handles
255
256 def Serialize(self, union, handle_offset):
257 (size, tag, entry, extra_data), handles = self.SerializeInline(
258 union, handle_offset)
259 data = bytearray(16)
260 data.extend(extra_data)
261
262 field = self._fields[union.tag]
263
264 HEADER_STRUCT.pack_into(data, 0, size, tag)
265 typecode = field.GetTypeCode()
266
267 # If the value is a nested union, we store a 64 bits pointer to it.
268 if field.field_type.IsUnion():
269 typecode = 'Q'
270
271 struct.pack_into('<%s' % typecode, data, 8, entry)
272 return data, handles
273
274 def Deserialize(self, context, union_class):
275 if len(context.data) < HEADER_STRUCT.size:
276 raise DeserializationException(
277 'Available data too short to contain header.')
278 (size, tag) = HEADER_STRUCT.unpack_from(context.data)
279 if size == 0:
280 return None
281
282 if size != 16:
283 raise DeserializationException('Invalid union size %s' % size)
284
285 field = self._fields[tag]
qsr 2015/07/20 21:29:59 1) You should not be using private variable outsid
azani 2015/07/20 22:17:52 Done.
286 if field.field_type.IsUnion():
287 ptr = POINTER_STRUCT.unpack_from(context.data, 8)[0]
288 value = field.field_type.Deserialize(ptr, context.GetSubContext(ptr+8))
289 else:
290 raw_value = struct.unpack_from(
291 field.GetTypeCode(), context.data, 8)[0]
292 value = field.field_type.Deserialize(raw_value, context.GetSubContext(8))
293
294 union = union_class.__new__(union_class)
295 union._cur_field = field
296 union._data = value
297 return union
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698