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

Side by Side Diff: mojo/public/tools/bindings/pylib/mojom/generate/pack.py

Issue 814543006: Move //mojo/{public, edk} underneath //third_party (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase Created 5 years, 11 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 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 module as mojom
6
7 # This module provides a mechanism for determining the packed order and offsets
8 # of a mojom.Struct.
9 #
10 # ps = 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.NULLABLE_HANDLE: 4,
30 mojom.NULLABLE_MSGPIPE: 4,
31 mojom.NULLABLE_SHAREDBUFFER: 4,
32 mojom.NULLABLE_DCPIPE: 4,
33 mojom.NULLABLE_DPPIPE: 4,
34 mojom.INT64: 8,
35 mojom.UINT64: 8,
36 mojom.DOUBLE: 8,
37 mojom.STRING: 8,
38 mojom.NULLABLE_STRING: 8
39 }
40
41 @classmethod
42 def GetSizeForKind(cls, kind):
43 if isinstance(kind, (mojom.Array, mojom.Map, mojom.Struct)):
44 return 8
45 if isinstance(kind, mojom.Interface) or \
46 isinstance(kind, mojom.InterfaceRequest):
47 kind = mojom.MSGPIPE
48 if isinstance(kind, mojom.Enum):
49 # TODO(mpcomplete): what about big enums?
50 return cls.kind_to_size[mojom.INT32]
51 if not kind in cls.kind_to_size:
52 raise Exception("Invalid kind: %s" % kind.spec)
53 return cls.kind_to_size[kind]
54
55 def __init__(self, field, index, ordinal):
56 """
57 Args:
58 field: the original field.
59 index: the position of the original field in the struct.
60 ordinal: the ordinal of the field for serialization.
61 """
62 self.field = field
63 self.index = index
64 self.ordinal = ordinal
65 self.size = self.GetSizeForKind(field.kind)
66 self.offset = None
67 self.bit = None
68
69
70 # Returns the pad necessary to reserve space for alignment of |size|.
71 def GetPad(offset, size):
72 return (size - (offset % size)) % size
73
74
75 # Returns a 2-tuple of the field offset and bit (for BOOLs)
76 def GetFieldOffset(field, last_field):
77 if field.field.kind == mojom.BOOL and \
78 last_field.field.kind == mojom.BOOL and \
79 last_field.bit < 7:
80 return (last_field.offset, last_field.bit + 1)
81
82 offset = last_field.offset + last_field.size
83 pad = GetPad(offset, field.size)
84 return (offset + pad, 0)
85
86
87 class PackedStruct(object):
88 def __init__(self, struct):
89 self.struct = struct
90 self.packed_fields = []
91
92 # No fields.
93 if (len(struct.fields) == 0):
94 return
95
96 # Start by sorting by ordinal.
97 src_fields = []
98 ordinal = 0
99 for index, field in enumerate(struct.fields):
100 if field.ordinal is not None:
101 ordinal = field.ordinal
102 src_fields.append(PackedField(field, index, ordinal))
103 ordinal += 1
104 src_fields.sort(key=lambda field: field.ordinal)
105
106 src_field = src_fields[0]
107 src_field.offset = 0
108 src_field.bit = 0
109 # dst_fields will contain each of the fields, in increasing offset order.
110 dst_fields = self.packed_fields
111 dst_fields.append(src_field)
112
113 # Then find first slot that each field will fit.
114 for src_field in src_fields[1:]:
115 last_field = dst_fields[0]
116 for i in xrange(1, len(dst_fields)):
117 next_field = dst_fields[i]
118 offset, bit = GetFieldOffset(src_field, last_field)
119 if offset + src_field.size <= next_field.offset:
120 # Found hole.
121 src_field.offset = offset
122 src_field.bit = bit
123 dst_fields.insert(i, src_field)
124 break
125 last_field = next_field
126 if src_field.offset is None:
127 # Add to end
128 src_field.offset, src_field.bit = GetFieldOffset(src_field, last_field)
129 dst_fields.append(src_field)
130
131 def GetTotalSize(self):
132 if not self.packed_fields:
133 return 0
134 last_field = self.packed_fields[-1]
135 offset = last_field.offset + last_field.size
136 pad = GetPad(offset, 8)
137 return offset + pad
138
139
140 class ByteInfo(object):
141 def __init__(self):
142 self.is_padding = False
143 self.packed_fields = []
144
145
146 def GetByteLayout(packed_struct):
147 bytes = [ByteInfo() for i in xrange(packed_struct.GetTotalSize())]
148
149 limit_of_previous_field = 0
150 for packed_field in packed_struct.packed_fields:
151 for i in xrange(limit_of_previous_field, packed_field.offset):
152 bytes[i].is_padding = True
153 bytes[packed_field.offset].packed_fields.append(packed_field)
154 limit_of_previous_field = packed_field.offset + packed_field.size
155
156 for i in xrange(limit_of_previous_field, len(bytes)):
157 bytes[i].is_padding = True
158
159 for byte in bytes:
160 # A given byte cannot both be padding and have a fields packed into it.
161 assert not (byte.is_padding and byte.packed_fields)
162
163 return bytes
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698