| OLD | NEW |
| 1 # Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 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 import module as mojom | 5 import module as mojom |
| 6 | 6 |
| 7 # This module provides a mechanism for determining the packed order and offsets | 7 # This module provides a mechanism for determining the packed order and offsets |
| 8 # of a mojom.Struct. | 8 # of a mojom.Struct. |
| 9 # | 9 # |
| 10 # ps = pack.PackedStruct(struct) | 10 # ps = pack.PackedStruct(struct) |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 44 if not kind in cls.kind_to_size: | 44 if not kind in cls.kind_to_size: |
| 45 raise Exception("Invalid kind: %s" % kind.spec) | 45 raise Exception("Invalid kind: %s" % kind.spec) |
| 46 return cls.kind_to_size[kind] | 46 return cls.kind_to_size[kind] |
| 47 | 47 |
| 48 def __init__(self, field, ordinal): | 48 def __init__(self, field, ordinal): |
| 49 self.field = field | 49 self.field = field |
| 50 self.ordinal = ordinal | 50 self.ordinal = ordinal |
| 51 self.size = self.GetSizeForKind(field.kind) | 51 self.size = self.GetSizeForKind(field.kind) |
| 52 self.offset = None | 52 self.offset = None |
| 53 self.bit = None | 53 self.bit = None |
| 54 self.in_hole = False |
| 54 | 55 |
| 55 | 56 |
| 56 # Returns the pad necessary to reserve space for alignment of |size|. | 57 # Returns the pad necessary to reserve space for alignment of |size|. |
| 57 def GetPad(offset, size): | 58 def GetPad(offset, size): |
| 58 return (size - (offset % size)) % size | 59 return (size - (offset % size)) % size |
| 59 | 60 |
| 60 | 61 |
| 61 # Returns a 2-tuple of the field offset and bit (for BOOLs) | 62 # Returns a 2-tuple of the field offset and bit (for BOOLs) |
| 62 def GetFieldOffset(field, last_field): | 63 def GetFieldOffset(field, last_field): |
| 63 if field.field.kind == mojom.BOOL and \ | 64 if field.field.kind == mojom.BOOL and \ |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 99 # Then find first slot that each field will fit. | 100 # Then find first slot that each field will fit. |
| 100 for src_field in src_fields[1:]: | 101 for src_field in src_fields[1:]: |
| 101 last_field = dst_fields[0] | 102 last_field = dst_fields[0] |
| 102 for i in xrange(1, len(dst_fields)): | 103 for i in xrange(1, len(dst_fields)): |
| 103 next_field = dst_fields[i] | 104 next_field = dst_fields[i] |
| 104 offset, bit = GetFieldOffset(src_field, last_field) | 105 offset, bit = GetFieldOffset(src_field, last_field) |
| 105 if offset + src_field.size <= next_field.offset: | 106 if offset + src_field.size <= next_field.offset: |
| 106 # Found hole. | 107 # Found hole. |
| 107 src_field.offset = offset | 108 src_field.offset = offset |
| 108 src_field.bit = bit | 109 src_field.bit = bit |
| 110 src_field.in_hole = True |
| 109 dst_fields.insert(i, src_field) | 111 dst_fields.insert(i, src_field) |
| 110 break | 112 break |
| 111 last_field = next_field | 113 last_field = next_field |
| 112 if src_field.offset is None: | 114 if src_field.offset is None: |
| 113 # Add to end | 115 # Add to end |
| 114 src_field.offset, src_field.bit = GetFieldOffset(src_field, last_field) | 116 src_field.offset, src_field.bit = GetFieldOffset(src_field, last_field) |
| 115 dst_fields.append(src_field) | 117 dst_fields.append(src_field) |
| 116 | 118 |
| 117 def GetTotalSize(self): | 119 def GetTotalSize(self): |
| 118 if not self.packed_fields: | 120 if not self.packed_fields: |
| (...skipping 21 matching lines...) Expand all Loading... |
| 140 limit_of_previous_field = packed_field.offset + packed_field.size | 142 limit_of_previous_field = packed_field.offset + packed_field.size |
| 141 | 143 |
| 142 for i in xrange(limit_of_previous_field, len(bytes)): | 144 for i in xrange(limit_of_previous_field, len(bytes)): |
| 143 bytes[i].is_padding = True | 145 bytes[i].is_padding = True |
| 144 | 146 |
| 145 for byte in bytes: | 147 for byte in bytes: |
| 146 # A given byte cannot both be padding and have a fields packed into it. | 148 # A given byte cannot both be padding and have a fields packed into it. |
| 147 assert not (byte.is_padding and byte.packed_fields) | 149 assert not (byte.is_padding and byte.packed_fields) |
| 148 | 150 |
| 149 return bytes | 151 return bytes |
| OLD | NEW |