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

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

Issue 2250183003: Make the fuchsia mojo/public repo the source of truth. (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Created 4 years, 4 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
(Empty)
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
3 # found in the LICENSE file.
4
5 """
6 The descriptors used to define generated elements of the mojo python bindings.
7 """
8
9 import array
10 import itertools
11 import struct
12
13 import mojo_bindings.reflection as reflection
14 import mojo_bindings.serialization as serialization
15
16 # pylint: disable=E0611,F0401
17 import mojo_system
18
19
20 class Type(object):
21 """Describes the type of a struct field or a method parameter,"""
22
23 def Convert(self, value): # pylint: disable=R0201
24 """
25 Convert the given value into its canonical representation, raising an
26 exception if the value cannot be converted.
27 """
28 return value
29
30 def GetDefaultValue(self, value):
31 """
32 Returns the default value for this type associated with the given value.
33 This method must be able to correcly handle value being None.
34 """
35 return self.Convert(value)
36
37 def IsUnion(self):
38 """
39 Returns true if the type is a union. This is necessary to be able to
40 identify a union when descriptor.py cannot be imported.
41 """
42 return False
43
44
45 class SerializableType(Type):
46 """Describe a type that can be serialized by itself."""
47
48 def __init__(self, typecode):
49 Type.__init__(self)
50 self.typecode = typecode
51 self.byte_size = struct.calcsize('<%s' % self.GetTypeCode())
52
53 def GetTypeCode(self):
54 """
55 Returns the type code (as defined by the struct module) used to encode
56 this type.
57 """
58 return self.typecode
59
60 def GetByteSize(self):
61 """
62 Returns the size of the encoding of this type.
63 """
64 return self.byte_size
65
66 def GetAlignment(self):
67 """
68 Returns the alignment required by the encoding of this type. By default it
69 is set to the byte size of the biggest packed value.
70 """
71 return max([struct.calcsize('<%s' % c) for c in self.GetTypeCode()])
72
73 def Serialize(self, value, data_offset, data, handle_offset):
74 """
75 Serialize a value of this type.
76
77 Args:
78 value: the value to serialize.
79 data_offset: the offset to the end of the data bytearray. Used to encode
80 pointers.
81 data: the bytearray to append additional data to.
82 handle_offset: the offset to use to encode handles.
83
84 Returns a a tuple where the first element is the value to encode, and the
85 second is the array of handles to add to the message.
86 """
87 raise NotImplementedError()
88
89 def Deserialize(self, value, context):
90 """
91 Deserialize a value of this type.
92
93 Args:
94 value: the base value for this type. This is always a numeric type, and
95 corresponds to the first element in the tuple returned by
96 Serialize.
97 data: the bytearray to retrieve additional data from.
98 handles: the array of handles contained in the message to deserialize.
99
100 Returns the deserialized value.
101 """
102 raise NotImplementedError()
103
104
105 class BooleanType(SerializableType):
106 """Type object for booleans"""
107
108 def Convert(self, value):
109 return bool(value)
110
111 def Serialize(self, value, data_offset, data, handle_offset):
112 return (_ConvertBooleansToByte([value]), [])
113
114 def Deserialize(self, value, context):
115 return _ConvertByteToBooleans(value, 1)[0]
116
117
118 class NumericType(SerializableType):
119 """Base Type object for all numeric types"""
120
121 def GetDefaultValue(self, value):
122 if value is None:
123 return self.Convert(0)
124 return self.Convert(value)
125
126 def Serialize(self, value, data_offset, data, handle_offset):
127 return (value, [])
128
129 def Deserialize(self, value, context):
130 return value
131
132
133 class IntegerType(NumericType):
134 """Type object for integer types."""
135
136 def __init__(self, typecode):
137 NumericType.__init__(self, typecode)
138 size = 8 * self.byte_size
139 signed = typecode.islower()
140 if signed:
141 self._min_value = -(1 << (size - 1))
142 self._max_value = (1 << (size - 1)) - 1
143 else:
144 self._min_value = 0
145 self._max_value = (1 << size) - 1
146
147 def Convert(self, value):
148 if value is None:
149 raise TypeError('None is not an integer.')
150 if not isinstance(value, (int, long)):
151 raise TypeError('%r is not an integer type' % value)
152 if value < self._min_value or value > self._max_value:
153 raise OverflowError('%r is not in the range [%d, %d]' %
154 (value, self._min_value, self._max_value))
155 return value
156
157
158 class FloatType(NumericType):
159 """Type object for floating point number types."""
160
161 def Convert(self, value):
162 if value is None:
163 raise TypeError('None is not an floating point number.')
164 if not isinstance(value, (int, long, float)):
165 raise TypeError('%r is not a numeric type' % value)
166 return float(value)
167
168
169 class UnionType(SerializableType):
170 """Base Type object for union."""
171
172 def __init__(self, union_type_getter, nullable=False):
173 SerializableType.__init__(self, 'IIQ')
174 self.nullable = nullable
175 self._union_type_getter = union_type_getter
176 self._union_type = None
177
178 def IsUnion(self):
179 return True
180
181 @property
182 def union_type(self):
183 if not self._union_type:
184 self._union_type = self._union_type_getter()
185 return self._union_type
186
187 def Serialize(self, value, data_offset, data, handle_offset):
188 if not value:
189 if not self.nullable:
190 raise serialization.SerializationException(
191 'Trying to serialize null for non nullable type.')
192 return ((0, 0, 0), [])
193
194 ((size, tag, entry, new_data), new_handles) = (
195 value.SerializeInline(handle_offset))
196 if len(new_data) > 0:
197 data.extend(new_data)
198 entry = data_offset - 8
199
200 return ((size, tag, entry), new_handles)
201
202 def Deserialize(self, value, context):
203 result = self.union_type.Deserialize(context)
204 if not result and not self.nullable:
205 raise serialization.DeserializationException(
206 'Trying to deserialize null for non nullable type.')
207 return result
208
209
210 class PointerType(SerializableType):
211 """Base Type object for pointers."""
212
213 def __init__(self, nullable=False):
214 SerializableType.__init__(self, 'Q')
215 self.nullable = nullable
216
217 def Serialize(self, value, data_offset, data, handle_offset):
218 if value is None and not self.nullable:
219 raise serialization.SerializationException(
220 'Trying to serialize null for non nullable type.')
221 if value is None:
222 return (0, [])
223 return self.SerializePointer(value, data_offset, data, handle_offset)
224
225 def Deserialize(self, value, context):
226 if value == 0:
227 if not self.nullable:
228 raise serialization.DeserializationException(
229 'Trying to deserialize null for non nullable type.')
230 return None
231 if value % 8 != 0:
232 raise serialization.DeserializationException(
233 'Pointer alignment is incorrect.')
234 sub_context = context.GetSubContext(value)
235 if len(sub_context.data) < serialization.HEADER_STRUCT.size:
236 raise serialization.DeserializationException(
237 'Available data too short to contain header.')
238 (size, nb_elements) = serialization.HEADER_STRUCT.unpack_from(
239 sub_context.data)
240 if len(sub_context.data) < size or size < serialization.HEADER_STRUCT.size:
241 raise serialization.DeserializationException('Header size is incorrect.')
242 sub_context.ClaimMemory(0, size)
243 return self.DeserializePointer(size, nb_elements, sub_context)
244
245 def SerializePointer(self, value, data_offset, data, handle_offset):
246 """Serialize the not null value."""
247 raise NotImplementedError()
248
249 def DeserializePointer(self, size, nb_elements, context):
250 raise NotImplementedError()
251
252
253 class StringType(PointerType):
254 """
255 Type object for strings.
256
257 Strings are represented as unicode, and the conversion is done using the
258 default encoding if a string instance is used.
259 """
260
261 def __init__(self, nullable=False):
262 PointerType.__init__(self, nullable)
263 self._array_type = NativeArrayType('B', nullable)
264
265 def Convert(self, value):
266 if value is None or isinstance(value, unicode):
267 return value
268 if isinstance(value, str):
269 return unicode(value)
270 raise TypeError('%r is not a string' % value)
271
272 def SerializePointer(self, value, data_offset, data, handle_offset):
273 string_array = array.array('b')
274 string_array.fromstring(value.encode('utf8'))
275 return self._array_type.SerializeArray(
276 string_array, data_offset, data, handle_offset)
277
278 def DeserializePointer(self, size, nb_elements, context):
279 string_array = self._array_type.DeserializeArray(size, nb_elements, context)
280 return unicode(string_array.tostring(), 'utf8')
281
282
283 class BaseHandleType(SerializableType):
284 """Type object for handles."""
285
286 def __init__(self, nullable=False, type_code='i'):
287 SerializableType.__init__(self, type_code)
288 self.nullable = nullable
289
290 def Serialize(self, value, data_offset, data, handle_offset):
291 handle = self.ToHandle(value)
292 if not handle.IsValid() and not self.nullable:
293 raise serialization.SerializationException(
294 'Trying to serialize null for non nullable type.')
295 if not handle.IsValid():
296 return (-1, [])
297 return (handle_offset, [handle])
298
299 def Deserialize(self, value, context):
300 if value == -1:
301 if not self.nullable:
302 raise serialization.DeserializationException(
303 'Trying to deserialize null for non nullable type.')
304 return self.FromHandle(mojo_system.Handle())
305 return self.FromHandle(context.ClaimHandle(value))
306
307 def FromHandle(self, handle):
308 raise NotImplementedError()
309
310 def ToHandle(self, value):
311 raise NotImplementedError()
312
313
314 class HandleType(BaseHandleType):
315 """Type object for handles."""
316
317 def Convert(self, value):
318 if value is None:
319 return mojo_system.Handle()
320 if not isinstance(value, mojo_system.Handle):
321 raise TypeError('%r is not a handle' % value)
322 return value
323
324 def FromHandle(self, handle):
325 return handle
326
327 def ToHandle(self, value):
328 return value
329
330
331 class InterfaceRequestType(BaseHandleType):
332 """Type object for interface requests."""
333
334 def Convert(self, value):
335 if value is None:
336 return reflection.InterfaceRequest(mojo_system.Handle())
337 if not isinstance(value, reflection.InterfaceRequest):
338 raise TypeError('%r is not an interface request' % value)
339 return value
340
341 def FromHandle(self, handle):
342 return reflection.InterfaceRequest(handle)
343
344 def ToHandle(self, value):
345 return value.PassMessagePipe()
346
347
348 class InterfaceType(BaseHandleType):
349 """Type object for interfaces."""
350
351 def __init__(self, interface_getter, nullable=False):
352 # handle (4 bytes) + version (4 bytes)
353 BaseHandleType.__init__(self, nullable, 'iI')
354 self._interface_getter = interface_getter
355 self._interface = None
356
357 def Convert(self, value):
358 if value is None or isinstance(value, self.interface):
359 return value
360 raise TypeError('%r is not an instance of ' % self.interface)
361
362 @property
363 def interface(self):
364 if not self._interface:
365 self._interface = self._interface_getter()
366 return self._interface
367
368 def Serialize(self, value, data_offset, data, handle_offset):
369 (encoded_handle, handles) = super(InterfaceType, self).Serialize(
370 value, data_offset, data, handle_offset)
371 if encoded_handle == -1:
372 version = 0
373 else:
374 version = self.interface.manager.version
375 if value and isinstance(value, reflection.InterfaceProxy):
376 version = value.manager.version
377 return ((encoded_handle, version), handles)
378
379 def Deserialize(self, value, context):
380 proxy = super(InterfaceType, self).Deserialize(value[0], context)
381 if proxy:
382 proxy.manager.version = value[1]
383 return proxy
384
385 def FromHandle(self, handle):
386 if handle.IsValid():
387 return self.interface.manager.Proxy(handle)
388 return None
389
390 def ToHandle(self, value):
391 if not value:
392 return mojo_system.Handle()
393 if isinstance(value, reflection.InterfaceProxy):
394 return value.manager.PassMessagePipe()
395 pipe = mojo_system.MessagePipe()
396 self.interface.manager.Bind(value, pipe.handle0)
397 return pipe.handle1
398
399
400 class BaseArrayType(PointerType):
401 """Abstract Type object for arrays."""
402
403 def __init__(self, nullable=False, length=0):
404 PointerType.__init__(self, nullable)
405 self.length = length
406
407 def SerializePointer(self, value, data_offset, data, handle_offset):
408 if self.length != 0 and len(value) != self.length:
409 raise serialization.SerializationException('Incorrect array size')
410 return self.SerializeArray(value, data_offset, data, handle_offset)
411
412 def SerializeArray(self, value, data_offset, data, handle_offset):
413 """Serialize the not null array."""
414 raise NotImplementedError()
415
416 def DeserializePointer(self, size, nb_elements, context):
417 if self.length != 0 and nb_elements != self.length:
418 raise serialization.DeserializationException('Incorrect array size')
419 if (size <
420 serialization.HEADER_STRUCT.size + self.SizeForLength(nb_elements)):
421 raise serialization.DeserializationException('Incorrect array size')
422 return self.DeserializeArray(size, nb_elements, context)
423
424 def DeserializeArray(self, size, nb_elements, context):
425 raise NotImplementedError()
426
427 def SizeForLength(self, nb_elements):
428 raise NotImplementedError()
429
430
431 class BooleanArrayType(BaseArrayType):
432
433 def __init__(self, nullable=False, length=0):
434 BaseArrayType.__init__(self, nullable, length)
435 self._array_type = NativeArrayType('B', nullable)
436
437 def Convert(self, value):
438 if value is None:
439 return value
440 return [TYPE_BOOL.Convert(x) for x in value]
441
442 def SerializeArray(self, value, data_offset, data, handle_offset):
443 groups = [value[i:i+8] for i in range(0, len(value), 8)]
444 converted = array.array('B', [_ConvertBooleansToByte(x) for x in groups])
445 return _SerializeNativeArray(converted, data_offset, data, len(value))
446
447 def DeserializeArray(self, size, nb_elements, context):
448 converted = self._array_type.DeserializeArray(size, nb_elements, context)
449 elements = list(itertools.islice(
450 itertools.chain.from_iterable(
451 [_ConvertByteToBooleans(x, 8) for x in converted]),
452 0,
453 nb_elements))
454 return elements
455
456 def SizeForLength(self, nb_elements):
457 return (nb_elements + 7) // 8
458
459
460 class GenericArrayType(BaseArrayType):
461 """Type object for arrays of pointers."""
462
463 def __init__(self, sub_type, nullable=False, length=0):
464 BaseArrayType.__init__(self, nullable, length)
465 assert isinstance(sub_type, SerializableType)
466 self.sub_type = sub_type
467
468 def Convert(self, value):
469 if value is None:
470 return value
471 return [self.sub_type.Convert(x) for x in value]
472
473 def SerializeArray(self, value, data_offset, data, handle_offset):
474 size = (serialization.HEADER_STRUCT.size +
475 self.sub_type.GetByteSize() * len(value))
476 data_end = len(data)
477 position = len(data) + serialization.HEADER_STRUCT.size
478 data.extend(bytearray(size +
479 serialization.NeededPaddingForAlignment(size)))
480 returned_handles = []
481 to_pack = []
482 for item in value:
483 (new_data, new_handles) = self.sub_type.Serialize(
484 item,
485 len(data) - position,
486 data,
487 handle_offset + len(returned_handles))
488 to_pack.extend(serialization.Flatten(new_data))
489 returned_handles.extend(new_handles)
490 position = position + self.sub_type.GetByteSize()
491
492 serialization.HEADER_STRUCT.pack_into(data, data_end, size, len(value))
493 # TODO(azani): Refactor so we don't have to create big formatting strings.
494 struct.pack_into(('%s' % self.sub_type.GetTypeCode()) * len(value),
495 data,
496 data_end + serialization.HEADER_STRUCT.size,
497 *to_pack)
498 return (data_offset, returned_handles)
499
500 def DeserializeArray(self, size, nb_elements, context):
501 # TODO(azani): Refactor so the format string isn't so big.
502 values = struct.unpack_from(
503 nb_elements * self.sub_type.GetTypeCode(),
504 buffer(context.data, serialization.HEADER_STRUCT.size))
505 values_per_element = len(self.sub_type.GetTypeCode())
506 assert nb_elements * values_per_element == len(values)
507
508 result = []
509 sub_context = context.GetSubContext(serialization.HEADER_STRUCT.size)
510 for index in xrange(nb_elements):
511 if values_per_element == 1:
512 value = values[index]
513 else:
514 value = tuple(values[index * values_per_element :
515 (index + 1) * values_per_element])
516 result.append(self.sub_type.Deserialize(
517 value,
518 sub_context))
519 sub_context = sub_context.GetSubContext(self.sub_type.GetByteSize())
520 return result
521
522 def SizeForLength(self, nb_elements):
523 return nb_elements * self.sub_type.GetByteSize();
524
525
526 class NativeArrayType(BaseArrayType):
527 """Type object for arrays of native types."""
528
529 def __init__(self, typecode, nullable=False, length=0):
530 BaseArrayType.__init__(self, nullable, length)
531 self.array_typecode = typecode
532 self.element_size = struct.calcsize('<%s' % self.array_typecode)
533
534 def Convert(self, value):
535 if value is None:
536 return value
537 if (isinstance(value, array.array) and
538 value.array_typecode == self.array_typecode):
539 return value
540 return array.array(self.array_typecode, value)
541
542 def SerializeArray(self, value, data_offset, data, handle_offset):
543 return _SerializeNativeArray(value, data_offset, data, len(value))
544
545 def DeserializeArray(self, size, nb_elements, context):
546 result = array.array(self.array_typecode)
547 result.fromstring(buffer(context.data,
548 serialization.HEADER_STRUCT.size,
549 size - serialization.HEADER_STRUCT.size))
550 return result
551
552 def SizeForLength(self, nb_elements):
553 return nb_elements * self.element_size
554
555
556 class StructType(PointerType):
557 """Type object for structs."""
558
559 def __init__(self, struct_type_getter, nullable=False):
560 PointerType.__init__(self)
561 self._struct_type_getter = struct_type_getter
562 self._struct_type = None
563 self.nullable = nullable
564
565 @property
566 def struct_type(self):
567 if not self._struct_type:
568 self._struct_type = self._struct_type_getter()
569 return self._struct_type
570
571 def Convert(self, value):
572 if value is None or isinstance(value, self.struct_type):
573 return value
574 raise TypeError('%r is not an instance of %r' % (value, self.struct_type))
575
576 def GetDefaultValue(self, value):
577 if value:
578 return self.struct_type()
579 return None
580
581 def SerializePointer(self, value, data_offset, data, handle_offset):
582 (new_data, new_handles) = value.Serialize(handle_offset)
583 data.extend(new_data)
584 return (data_offset, new_handles)
585
586 def DeserializePointer(self, size, nb_elements, context):
587 return self.struct_type.Deserialize(context)
588
589
590 class MapType(SerializableType):
591 """Type objects for maps."""
592
593 def __init__(self, key_type, value_type, nullable=False):
594 self._key_type = key_type
595 self._value_type = value_type
596 dictionary = {
597 '__metaclass__': reflection.MojoStructType,
598 '__module__': __name__,
599 'DESCRIPTOR': {
600 'fields': [
601 SingleFieldGroup('keys', MapType._GetArrayType(key_type), 0, 0),
602 SingleFieldGroup('values', MapType._GetArrayType(value_type), 1, 0),
603 ],
604 }
605 }
606 self.struct = reflection.MojoStructType('MapStruct', (object,), dictionary)
607 self.struct_type = StructType(lambda: self.struct, nullable)
608 SerializableType.__init__(self, self.struct_type.typecode)
609
610 def Convert(self, value):
611 if value is None:
612 return value
613 if isinstance(value, dict):
614 return dict([(self._key_type.Convert(x), self._value_type.Convert(y)) for
615 x, y in value.iteritems()])
616 raise TypeError('%r is not a dictionary.')
617
618 def Serialize(self, value, data_offset, data, handle_offset):
619 s = None
620 if value is not None:
621 keys, values = [], []
622 for key, value in value.iteritems():
623 keys.append(key)
624 values.append(value)
625 s = self.struct(keys=keys, values=values)
626 return self.struct_type.Serialize(s, data_offset, data, handle_offset)
627
628 def Deserialize(self, value, context):
629 s = self.struct_type.Deserialize(value, context)
630 if s:
631 if len(s.keys) != len(s.values):
632 raise serialization.DeserializationException(
633 'keys and values do not have the same length.')
634 return dict(zip(s.keys, s.values))
635 return None
636
637 @staticmethod
638 def _GetArrayType(t):
639 if t == TYPE_BOOL:
640 return BooleanArrayType()
641 else:
642 return GenericArrayType(t)
643
644
645 TYPE_BOOL = BooleanType('B')
646
647 TYPE_INT8 = IntegerType('b')
648 TYPE_INT16 = IntegerType('h')
649 TYPE_INT32 = IntegerType('i')
650 TYPE_INT64 = IntegerType('q')
651
652 TYPE_UINT8 = IntegerType('B')
653 TYPE_UINT16 = IntegerType('H')
654 TYPE_UINT32 = IntegerType('I')
655 TYPE_UINT64 = IntegerType('Q')
656
657 TYPE_FLOAT = FloatType('f')
658 TYPE_DOUBLE = FloatType('d')
659
660 TYPE_STRING = StringType()
661 TYPE_NULLABLE_STRING = StringType(True)
662
663 TYPE_HANDLE = HandleType()
664 TYPE_NULLABLE_HANDLE = HandleType(True)
665
666 TYPE_INTERFACE_REQUEST = InterfaceRequestType()
667 TYPE_NULLABLE_INTERFACE_REQUEST = InterfaceRequestType(True)
668
669
670 class FieldDescriptor(object):
671 """Describes a field in a generated struct."""
672
673 def __init__(self, name, field_type, index, version, default_value=None):
674 self.name = name
675 self.field_type = field_type
676 self.version = version
677 self.index = index
678 self._default_value = default_value
679
680 def GetDefaultValue(self):
681 return self.field_type.GetDefaultValue(self._default_value)
682
683
684 class FieldGroup(object):
685 """
686 Describe a list of field in the generated struct that must be
687 serialized/deserialized together.
688 """
689 def __init__(self, descriptors):
690 self.descriptors = descriptors
691
692 def GetDescriptors(self):
693 return self.descriptors
694
695 def GetTypeCode(self):
696 raise NotImplementedError()
697
698 def GetByteSize(self):
699 raise NotImplementedError()
700
701 def GetAlignment(self):
702 raise NotImplementedError()
703
704 def GetMinVersion(self):
705 raise NotImplementedError()
706
707 def GetMaxVersion(self):
708 raise NotImplementedError()
709
710 def Serialize(self, obj, data_offset, data, handle_offset):
711 raise NotImplementedError()
712
713 def Deserialize(self, value, context):
714 raise NotImplementedError()
715
716 def Filter(self, version):
717 raise NotImplementedError()
718
719
720 class SingleFieldGroup(FieldGroup, FieldDescriptor):
721 """A FieldGroup that contains a single FieldDescriptor."""
722
723 def __init__(self, name, field_type, index, version, default_value=None):
724 FieldDescriptor.__init__(
725 self, name, field_type, index, version, default_value)
726 FieldGroup.__init__(self, [self])
727
728 def GetTypeCode(self):
729 return self.field_type.GetTypeCode()
730
731 def GetByteSize(self):
732 return self.field_type.GetByteSize()
733
734 def GetAlignment(self):
735 return self.field_type.GetAlignment()
736
737 def GetMinVersion(self):
738 return self.version
739
740 def GetMaxVersion(self):
741 return self.version
742
743 def Serialize(self, obj, data_offset, data, handle_offset):
744 value = getattr(obj, self.name)
745 return self.field_type.Serialize(value, data_offset, data, handle_offset)
746
747 def Deserialize(self, value, context):
748 entity = self.field_type.Deserialize(value, context)
749 return { self.name: entity }
750
751 def Filter(self, version):
752 return self
753
754
755 class BooleanGroup(FieldGroup):
756 """A FieldGroup to pack booleans."""
757 def __init__(self, descriptors):
758 FieldGroup.__init__(self, descriptors)
759 self.min_version = min([descriptor.version for descriptor in descriptors])
760 self.max_version = max([descriptor.version for descriptor in descriptors])
761
762 def GetTypeCode(self):
763 return 'B'
764
765 def GetByteSize(self):
766 return 1
767
768 def GetAlignment(self):
769 return 1
770
771 def GetMinVersion(self):
772 return self.min_version
773
774 def GetMaxVersion(self):
775 return self.max_version
776
777 def Serialize(self, obj, data_offset, data, handle_offset):
778 value = _ConvertBooleansToByte(
779 [getattr(obj, field.name) for field in self.GetDescriptors()])
780 return (value, [])
781
782 def Deserialize(self, value, context):
783 values = itertools.izip_longest([x.name for x in self.descriptors],
784 _ConvertByteToBooleans(value),
785 fillvalue=False)
786 return dict(values)
787
788 def Filter(self, version):
789 return BooleanGroup(
790 filter(lambda d: d.version <= version, self.descriptors))
791
792
793 def _SerializeNativeArray(value, data_offset, data, length):
794 data_size = len(data)
795 data.extend(bytearray(serialization.HEADER_STRUCT.size))
796 data.extend(buffer(value))
797 data_length = len(data) - data_size
798 data.extend(bytearray(serialization.NeededPaddingForAlignment(data_length)))
799 serialization.HEADER_STRUCT.pack_into(data, data_size, data_length, length)
800 return (data_offset, [])
801
802
803 def _ConvertBooleansToByte(booleans):
804 """Pack a list of booleans into an integer."""
805 return reduce(lambda x, y: x * 2 + y, reversed(booleans), 0)
806
807
808 def _ConvertByteToBooleans(value, min_size=0):
809 """Unpack an integer into a list of booleans."""
810 res = []
811 while value:
812 res.append(bool(value&1))
813 value = value / 2
814 res.extend([False] * (min_size - len(res)))
815 return res
OLDNEW
« no previous file with comments | « mojo/public/python/mojo_bindings/__init__.py ('k') | mojo/public/python/mojo_bindings/interface_reflection.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698