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

Side by Side Diff: mojo/public/bindings/pylib/generate/mojom_pack.py

Issue 226263002: Mojo: Move mojo/public/bindings to mojo/public/tools/bindings. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebased Created 6 years, 8 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 | Annotate | Revision Log
OLDNEW
(Empty)
1 # Copyright 2013 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 import mojom
6
7 # mojom_pack provides a mechanism for determining the packed order and offsets
8 # of a mojom.Struct.
9 #
10 # ps = mojom_pack.PackedStruct(struct)
11 # ps.packed_fields will access a list of PackedField objects, each of which
12 # will have an offset, a size and a bit (for mojom.BOOLs).
13
14 class PackedField(object):
15 kind_to_size = {
16 mojom.BOOL: 1,
17 mojom.INT8: 1,
18 mojom.UINT8: 1,
19 mojom.INT16: 2,
20 mojom.UINT16: 2,
21 mojom.INT32: 4,
22 mojom.UINT32: 4,
23 mojom.FLOAT: 4,
24 mojom.HANDLE: 4,
25 mojom.MSGPIPE: 4,
26 mojom.SHAREDBUFFER: 4,
27 mojom.DCPIPE: 4,
28 mojom.DPPIPE: 4,
29 mojom.INT64: 8,
30 mojom.UINT64: 8,
31 mojom.DOUBLE: 8,
32 mojom.STRING: 8
33 }
34
35 @classmethod
36 def GetSizeForKind(cls, kind):
37 if isinstance(kind, mojom.Array) or isinstance(kind, mojom.Struct):
38 return 8
39 if isinstance(kind, mojom.Interface):
40 kind = mojom.MSGPIPE
41 if isinstance(kind, mojom.Enum):
42 # TODO(mpcomplete): what about big enums?
43 return cls.kind_to_size[mojom.INT32]
44 if not kind in cls.kind_to_size:
45 raise Exception("Invalid kind: %s" % kind.spec)
46 return cls.kind_to_size[kind]
47
48 def __init__(self, field, ordinal):
49 self.field = field
50 self.ordinal = ordinal
51 self.size = self.GetSizeForKind(field.kind)
52 self.offset = None
53 self.bit = None
54
55
56 # Returns the pad necessary to reserve space for alignment of |size|.
57 def GetPad(offset, size):
58 return (size - (offset % size)) % size
59
60
61 # Returns a 2-tuple of the field offset and bit (for BOOLs)
62 def GetFieldOffset(field, last_field):
63 if field.field.kind == mojom.BOOL and \
64 last_field.field.kind == mojom.BOOL and \
65 last_field.bit < 7:
66 return (last_field.offset, last_field.bit + 1)
67
68 offset = last_field.offset + last_field.size
69 pad = GetPad(offset, field.size)
70 return (offset + pad, 0)
71
72
73 class PackedStruct(object):
74 def __init__(self, struct):
75 self.struct = struct
76 self.packed_fields = []
77
78 # No fields.
79 if (len(struct.fields) == 0):
80 return
81
82 # Start by sorting by ordinal.
83 src_fields = []
84 ordinal = 1
85 for field in struct.fields:
86 if field.ordinal is not None:
87 ordinal = field.ordinal
88 src_fields.append(PackedField(field, ordinal))
89 ordinal += 1
90 src_fields.sort(key=lambda field: field.ordinal)
91
92 src_field = src_fields[0]
93 src_field.offset = 0
94 src_field.bit = 0
95 # dst_fields will contain each of the fields, in increasing offset order.
96 dst_fields = self.packed_fields
97 dst_fields.append(src_field)
98
99 # Then find first slot that each field will fit.
100 for src_field in src_fields[1:]:
101 last_field = dst_fields[0]
102 for i in xrange(1, len(dst_fields)):
103 next_field = dst_fields[i]
104 offset, bit = GetFieldOffset(src_field, last_field)
105 if offset + src_field.size <= next_field.offset:
106 # Found hole.
107 src_field.offset = offset
108 src_field.bit = bit
109 dst_fields.insert(i, src_field)
110 break
111 last_field = next_field
112 if src_field.offset is None:
113 # Add to end
114 src_field.offset, src_field.bit = GetFieldOffset(src_field, last_field)
115 dst_fields.append(src_field)
116
117 def GetTotalSize(self):
118 if not self.packed_fields:
119 return 0;
120 last_field = self.packed_fields[-1]
121 offset = last_field.offset + last_field.size
122 pad = GetPad(offset, 8)
123 return offset + pad;
124
125
126 class ByteInfo(object):
127 def __init__(self):
128 self.is_padding = False
129 self.packed_fields = []
130
131
132 def GetByteLayout(packed_struct):
133 bytes = [ByteInfo() for i in xrange(packed_struct.GetTotalSize())]
134
135 limit_of_previous_field = 0
136 for packed_field in packed_struct.packed_fields:
137 for i in xrange(limit_of_previous_field, packed_field.offset):
138 bytes[i].is_padding = True
139 bytes[packed_field.offset].packed_fields.append(packed_field)
140 limit_of_previous_field = packed_field.offset + packed_field.size
141
142 for i in xrange(limit_of_previous_field, len(bytes)):
143 bytes[i].is_padding = True
144
145 for byte in bytes:
146 # A given byte cannot both be padding and have a fields packed into it.
147 assert not (byte.is_padding and byte.packed_fields)
148
149 return bytes
OLDNEW
« no previous file with comments | « mojo/public/bindings/pylib/generate/mojom_generator.py ('k') | mojo/public/bindings/pylib/generate/mojom_pack_tests.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698