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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: mojo/public/python/mojo/bindings/serialization.py
diff --git a/mojo/public/python/mojo/bindings/serialization.py b/mojo/public/python/mojo/bindings/serialization.py
new file mode 100644
index 0000000000000000000000000000000000000000..5daad85f5aaf0687b1b3f41547a87ce71dfd3c67
--- /dev/null
+++ b/mojo/public/python/mojo/bindings/serialization.py
@@ -0,0 +1,98 @@
+# Copyright 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Utility classes for serialization"""
+
+import struct
+
+
+# Format of a header for a struct or an array.
+HEADER_STRUCT = struct.Struct("=II")
+
+
+class SerializationException(Exception):
+ """Error when strying to serialize a struct."""
+ pass
+
+
+class Serialization(object):
+ """
+ Helper class to serialize/deserialize a struct.
+ """
+ def __init__(self, groups):
+ self._groups = groups
+ self.version = _GetVersion(groups)
+ main_struct = _GetStruct(groups)
+ self.size = HEADER_STRUCT.size + main_struct.size
+ self._struct_per_version = {
+ self.version: main_struct,
+ }
+
+ def _GetMainStruct(self):
+ return self._GetStruct(self.version)
+
+ def _GetStruct(self, version):
+ # If asking for a greater ver
+ version = min(version, self.version)
+ if version not in self._struct_per_version:
+ self._struct_per_version[version] = _GetStruct(_FilterGroups(self._groups,
+ version))
+ return self._struct_per_version[version]
+
+ def Serialize(self, obj, handle_offset):
+ """
+ Serialize the given obj. handle_offset is the the first value to use when
+ encoding handles.
+ """
+ handles = []
+ data = bytearray(self.size)
+ HEADER_STRUCT.pack_into(data, 0, self.size, self.version)
+ position = HEADER_STRUCT.size
+ to_pack = []
+ for group in self._groups:
+ position = position + NeededPaddingForAlignment(position,
+ group.GetByteSize())
+ (entry, new_handles) = group.Serialize(
+ obj,
+ len(data) - position,
+ data,
+ handle_offset + len(handles))
+ to_pack.append(entry)
+ handles.extend(new_handles)
+ position = position + group.GetByteSize()
+ self._GetMainStruct().pack_into(data, HEADER_STRUCT.size, *to_pack)
+ return (data, handles)
+
+
+def NeededPaddingForAlignment(value, alignment=8):
+ """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.
+ if value % alignment:
+ return alignment - (value % alignment)
+ return 0
+
+
+def _GetVersion(groups):
+ 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.
+
+
+def _FilterGroups(groups, version):
+ return [group for group in groups if group.version < version]
+
+
+def _GetStruct(groups):
+ index = 0
+ codes = [ '=' ]
+ for group in groups:
+ code = group.GetTypeCode()
+ size = group.GetByteSize()
+ needed_padding = NeededPaddingForAlignment(index, size)
+ if needed_padding:
+ codes.append('x' * needed_padding)
+ index = index + needed_padding
+ codes.append(code)
+ index = index + size
+ 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.
+ if end_alignment:
+ codes.append('x' * (8 - end_alignment))
+ return struct.Struct(''.join(codes))

Powered by Google App Engine
This is Rietveld 408576698