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

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):
qsr 2015/07/17 10:53:58 This code needs comments. I find it really hard to
azani 2015/07/17 20:38:15 I have added some comments. Let me know if they pr
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 (entry, handles) = field.field_type.Serialize(
238 union.data, 8, data, handle_offset)
239
240 if hasattr(field.field_type, 'union_type'):
qsr 2015/07/17 10:53:58 If you cannot do usual instanceof calls, then adds
azani 2015/07/17 20:38:15 Done.
241 nested_union = bytearray(16)
242 HEADER_STRUCT.pack_into(nested_union, 0, entry[0], entry[1])
243 POINTER_STRUCT.pack_into(nested_union, 8, entry[2])
244
245 data = nested_union + data
246 entry = 8
247
248 return (16, union.tag, entry, data), handles
qsr 2015/07/17 10:53:58 I am clearly missing something. Let say that you
azani 2015/07/17 20:38:16 In your exampled Serialize is PointerType.Serializ
249
250 def Serialize(self, union, handle_offset):
251 (size, tag, entry, extra_data), handles = self.SerializeInline(
252 union, handle_offset)
253 data = bytearray(16)
254 data.extend(extra_data)
255
256 field = self._fields[union.tag]
257
258 HEADER_STRUCT.pack_into(data, 0, size, tag)
259 typecode = field.GetTypeCode()
260 if hasattr(field.field_type, 'union_type'):
261 typecode = 'Q'
262
263 struct.pack_into('<%s' % typecode, data, 8, entry)
264 return data, handles
265
266 def Deserialize(self, context, union_class):
267 if len(context.data) < HEADER_STRUCT.size:
268 raise DeserializationException(
269 'Available data too short to contain header.')
270 (size, tag) = HEADER_STRUCT.unpack_from(context.data)
271 if size == 0:
272 return None
273
274 if size != 16:
275 raise DeserializationException('Invalid union size %s' % size)
276
277 field = self._fields[tag]
278 if hasattr(field.field_type, 'union_type'):
279 ptr = POINTER_STRUCT.unpack_from(context.data, 8)[0]
280 value = field.field_type.Deserialize(ptr, context.GetSubContext(ptr+8))
281 else:
282 raw_value = struct.unpack_from(
283 field.GetTypeCode(), context.data, 8)[0]
284 value = field.field_type.Deserialize(raw_value, context.GetSubContext(8))
285
286 union = union_class.__new__(union_class)
287 union._tag = tag
288 union._data = value
289 return union
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698