OLD | NEW |
---|---|
1 # Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 # Use of this source code is governed by a BSD-style license that can be |
3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
4 | 4 |
5 """Utility classes for serialization""" | 5 """Utility classes for serialization""" |
6 | 6 |
7 import struct | 7 import struct |
8 | 8 |
9 | 9 |
10 # Format of a header for a struct or an array. | 10 # Format of a header for a struct or an array. |
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
211 needed_padding = NeededPaddingForAlignment(index, group.GetAlignment()) | 211 needed_padding = NeededPaddingForAlignment(index, group.GetAlignment()) |
212 if needed_padding: | 212 if needed_padding: |
213 codes.append('x' * needed_padding) | 213 codes.append('x' * needed_padding) |
214 index = index + needed_padding | 214 index = index + needed_padding |
215 codes.append(code) | 215 codes.append(code) |
216 index = index + group.GetByteSize() | 216 index = index + group.GetByteSize() |
217 alignment_needed = NeededPaddingForAlignment(index) | 217 alignment_needed = NeededPaddingForAlignment(index) |
218 if alignment_needed: | 218 if alignment_needed: |
219 codes.append('x' * alignment_needed) | 219 codes.append('x' * alignment_needed) |
220 return struct.Struct(''.join(codes)) | 220 return struct.Struct(''.join(codes)) |
221 | |
222 | |
223 class UnionSerializer(object): | |
224 """ | |
225 Helper class to serialize/deserialize a union. | |
226 """ | |
227 def __init__(self, fields): | |
228 self._fields = {field.index: field for field in fields} | |
229 | |
230 def SerializeInline(self, union, handle_offset): | |
231 data = bytearray() | |
232 field = self._fields[union.tag] | |
233 | |
234 (entry, handles) = field.field_type.Serialize( | |
235 union.data, 8, data, handle_offset) | |
236 | |
237 if hasattr(field.field_type, 'union_type'): | |
qsr
2015/07/16 09:35:26
I really don't like this.
Each time I see a CL fo
azani
2015/07/16 21:57:38
I can certainly see your point, but that would als
qsr
2015/07/17 10:53:58
Well, first of all this is a 8 bytes overhead at w
| |
238 nested_union = bytearray(16) | |
239 HEADER_STRUCT.pack_into(nested_union, 0, entry[0], entry[1]) | |
240 struct.pack_into('<Q', nested_union, 8, entry[2]) | |
qsr
2015/07/16 09:35:25
You should have a constant for this struct -> you
azani
2015/07/16 21:57:39
Done.
| |
241 | |
242 data = nested_union + data | |
243 entry = 8 | |
244 | |
245 return (16, union.tag, entry, data), handles | |
246 | |
247 def Serialize(self, union, handle_offset): | |
248 (size, tag, entry, extra_data), handles = self.SerializeInline( | |
249 union, handle_offset) | |
250 data = bytearray(16) | |
251 data.extend(extra_data) | |
252 | |
253 field = self._fields[union.tag] | |
254 | |
255 HEADER_STRUCT.pack_into(data, 0, size, tag) | |
256 typecode = field.GetTypeCode() | |
257 if hasattr(field.field_type, 'union_type'): | |
258 typecode = 'Q' | |
259 | |
260 struct.pack_into('<%s' % typecode, data, 8, entry) | |
261 return data, handles | |
262 | |
263 def Deserialize(self, context, union_class): | |
264 if len(context.data) < HEADER_STRUCT.size: | |
265 raise DeserializationException( | |
266 'Available data too short to contain header.') | |
267 (size, tag) = HEADER_STRUCT.unpack_from(context.data) | |
268 if size == 0: | |
269 return None | |
270 | |
271 if size != 16: | |
272 raise DeserializationException('Invalid union size %s' % size) | |
273 | |
274 field = self._fields[tag] | |
275 if hasattr(field.field_type, 'union_type'): | |
276 ptr = struct.unpack_from('<Q', context.data, 8)[0] | |
277 value = field.field_type.Deserialize(ptr, context.GetSubContext(ptr+8)) | |
278 else: | |
279 raw_value = struct.unpack_from( | |
280 field.GetTypeCode(), context.data, 8)[0] | |
281 value = field.field_type.Deserialize(raw_value, context.GetSubContext(8)) | |
282 | |
283 union = union_class.__new__(union_class) | |
284 union._tag = tag | |
285 union._data = value | |
286 return union | |
OLD | NEW |