| 41 | |
| 42 | # Class definitions, to keep things classy |
| 43 | class Field(object): |
| 44 | def __init__(self, name, type_obj, |
| 45 | field_comments=[], optional=False): |
| 46 | self.name = name |
| 47 | self.type_obj = type_obj |
| 48 | self.count = 1 |
| 49 | self.len_field_of = None |
| 50 | self.len_field = None |
| 51 | self.implicit_len = False |
| 52 | |
| 53 | self.is_optional = optional |
| 54 | self.field_comments = field_comments |
| 55 | |
| 56 | def __deepcopy__(self, memo): |
| 57 | deepcopy_method = self.__deepcopy__ |
| 58 | self.__deepcopy__ = None |
| 59 | field = copy.deepcopy(self, memo) |
| 60 | self.__deepcopy__ = deepcopy_method |
| 61 | |
| 62 | field.type_obj = self.type_obj |
| 63 | return field |
| 64 | |
| 65 | def add_count(self, count): |
| 66 | self.count = int(count) |
| 67 | |
| 68 | def add_len_field(self, len_field): |
| 69 | self.count = False |
| 70 | # we cache our len-field's name |
| 71 | self.len_field = len_field.name |
| 72 | # the len-field caches our name |
| 73 | len_field.len_field_of = self.name |
| 74 | |
| 75 | def add_implicit_len(self): |
| 76 | self.count = False |
| 77 | self.implicit_len = True |
| 78 | |
| 79 | def is_array(self): |
| 80 | return self.count > 1 |
| 81 | |
| 82 | def is_varlen(self): |
| 83 | return not self.count |
| 84 | |
| 85 | def is_implicit_len(self): |
| 86 | return self.implicit_len |
| 87 | |
| 88 | def size(self, implicit_expression=None): |
| 89 | if self.count: |
| 90 | return self.count |
| 91 | if self.len_field: |
| 92 | return self.len_field |
| 93 | assert self.is_implicit_len() |
| 94 | assert implicit_expression |
| 95 | return implicit_expression |
| 96 | |
| 97 | def needs_context(self): |
| 98 | """ A field needs a context if it's varsized """ |
| 99 | return self.is_varlen() or self.type_obj.needs_context() |
| 100 | |