def push(self, k): k = model.map_model_key(self.types, k) if k in self.visited: return assert k[1] != 'list-length' ty = k[0].type_of(k[1]) if type(ty) is idl.TyFrozenArray: length_k = (ty, 'list-length') if length_k not in self.visited: self.visited.add(length_k) # We eagerly get this to see if we need to include the field #print(f'processing length model immediately for {k}') length_m = self.process(length_k) self.processed(length_k, length_m) else: #print(f'already have length model for {k}') length_m = self.tables[length_k] if sum(length_m.symbol_to_code.keys()) == 0: # All of these are empty. #print(f'all symbols empty for {k}') return ty = ty.element_ty self.visited.add(k) if type(ty) is idl.TyInterface: self.processed(k, self.trivial(k, ty)) else: self.stack.append(k)
def _write(self, k, value): effective_key = model.map_model_key(self.types, k) m = self.tables[effective_key] code, length = m.symbol_to_code[value] #print(f'E{len(self.log)}', k, f'{code:b}', length, list(m.symbol_to_code.items()), value) self.log.append((effective_key, value)) for i in range(length): self.out.write(1, (code >> (length - i - 1)) & 1)
def visit_field(self, struct_ty, obj, i, attr): if attr.lazy: # Halt the walk here; this will appear in the lazy stream. # FIXME: When the ES6 IDL makes these types non-trivial, we may want to # write the type tag here and decode a specific type later. assert type(attr.resolved_ty) is idl.TyInterface, 'NYI' return self.field.append(model.map_model_key(self.types, (struct_ty, attr.name))) super().visit_field(struct_ty, obj, i, attr) self.field.pop()
def _read(self, key): effective_key = model.map_model_key(self.types, key) m = self.tables[effective_key] n_bits = 0 code = 0 while True: k = (code, n_bits) #print(f'D{len(self.log)}', key, f'{code:b}', k, list(m.code_to_symbol.items())) s = m.code_to_symbol.get(k) #print('symbol?', s) if s != None: self.log.append((effective_key, s)) return s code <<= 1 code |= self.inp.read(1) n_bits += 1