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

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

Issue 570563002: mojo: Starting serialization for python bindings. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 3 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 """Utility classes for serialization"""
6
7 import struct
8
9
10 # Format of a header for a struct or an array.
11 HEADER_STRUCT = struct.Struct("=II")
12
13
14 class SerializationException(Exception):
15 """Error when strying to serialize a struct."""
16 pass
17
18
19 class Serialization(object):
20 """
21 Helper class to serialize/deserialize a struct.
22 """
23 def __init__(self, groups):
24 self._groups = groups
25 self.version = _GetVersion(groups)
26 main_struct = _GetStruct(groups)
27 self.size = HEADER_STRUCT.size + main_struct.size
28 self._struct_per_version = {
29 self.version: main_struct,
30 }
31
32 def _GetMainStruct(self):
33 return self._GetStruct(self.version)
34
35 def _GetStruct(self, version):
36 # If asking for a greater ver
37 version = min(version, self.version)
38 if version not in self._struct_per_version:
39 self._struct_per_version[version] = _GetStruct(_FilterGroups(self._groups,
40 version))
41 return self._struct_per_version[version]
42
43 def Serialize(self, obj, handle_offset):
44 """
45 Serialize the given obj. handle_offset is the the first value to use when
46 encoding handles.
47 """
48 handles = []
49 data = bytearray(self.size)
50 HEADER_STRUCT.pack_into(data, 0, self.size, self.version)
51 position = HEADER_STRUCT.size
52 to_pack = []
53 for group in self._groups:
54 position = position + NeededPaddingForAlignment(position,
55 group.GetByteSize())
56 (entry, new_handles) = group.Serialize(
57 obj,
58 len(data) - position,
59 data,
60 handle_offset + len(handles))
61 to_pack.append(entry)
62 handles.extend(new_handles)
63 position = position + group.GetByteSize()
64 self._GetMainStruct().pack_into(data, HEADER_STRUCT.size, *to_pack)
65 return (data, handles)
66
67
68 def NeededPaddingForAlignment(value, alignment=8):
69 """Returns the padding necessary to align value with the given alignment."""
sdefresne 2014/09/15 08:46:54 nit: this method could return a tuple padding_leng
qsr 2014/09/15 11:01:53 Not really. It is used that way only once, but I u
sdefresne 2014/09/15 11:14:46 Make sense, thank you for the justification.
qsr 2014/09/15 11:42:00 Acknowledged.
70 if value % alignment:
71 return alignment - (value % alignment)
72 return 0
73
74
75 def _GetVersion(groups):
76 return reduce(lambda x, y: x+y, [len(x.descriptors) for x in groups])
sdefresne 2014/09/15 08:46:54 nit: "reduce(lambda x, y: x+y, [...])" can be rewr
qsr 2014/09/15 11:01:53 Done.
77
78
79 def _FilterGroups(groups, version):
80 return [group for group in groups if group.version < version]
81
82
83 def _GetStruct(groups):
84 index = 0
85 codes = [ '=' ]
86 for group in groups:
87 code = group.GetTypeCode()
88 size = group.GetByteSize()
89 needed_padding = NeededPaddingForAlignment(index, size)
90 if needed_padding:
91 codes.append('x' * needed_padding)
92 index = index + needed_padding
93 codes.append(code)
94 index = index + size
95 end_alignment = index % 8
sdefresne 2014/09/15 08:46:54 nit: you can use NeededPaddingForAlignment here.
qsr 2014/09/15 11:01:53 Done.
96 if end_alignment:
97 codes.append('x' * (8 - end_alignment))
98 return struct.Struct(''.join(codes))
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698