1# Copyright (C) 2021-2022 Intel Corporation. 2# 3# SPDX-License-Identifier: BSD-3-Clause 4# 5 6import logging 7 8from .exception import * 9from .grammar import AML_EXT_OP_PREFIX 10 11class Stream: 12 def print_binary(self, base): 13 acc = f"[{hex(base):>8s}/{hex(len(self.data)):>8s}]" 14 converted = "" 15 for i in range(base, base + 16): 16 code = self.data[i] 17 acc += " %02x" % code 18 if code >= 0x20 and code <= 0x7E: 19 converted += chr(code) 20 else: 21 converted += "." 22 if i > base and ((i - base) % 4) == 3: 23 acc += " " 24 converted += " " 25 acc += f" '{converted}'" 26 logging.debug(acc) 27 28 def __init__(self, data): 29 self.data = data 30 self.current = 0 31 self.scopes = [len(data)] 32 33 def peek_integer(self, count): 34 if self.current + count > self.scopes[-1]: 35 raise ScopeMismatch 36 ret = 0 37 for i in range(0, count): 38 ret += (self.data[self.current + i] << (i * 8)) 39 return ret 40 41 def get_integer(self, count): 42 if self.current + count > self.scopes[-1]: 43 raise ScopeMismatch 44 ret = self.peek_integer(count) 45 self.current += count 46 return ret 47 48 def get_char(self): 49 if self.current + 1 > self.scopes[-1]: 50 raise ScopeMismatch 51 ret = chr(self.data[self.current]) 52 self.current += 1 53 return ret 54 55 def peek_opcode(self): 56 opcode = self.peek_integer(1) 57 if opcode == AML_EXT_OP_PREFIX: 58 opcode = self.peek_integer(2) 59 return (opcode, 2) 60 return (opcode, 1) 61 62 def get_opcode(self): 63 opcode = self.get_integer(1) 64 if opcode == AML_EXT_OP_PREFIX: 65 opcode += (self.get_integer(1) << 8) 66 return (opcode, 2) 67 return (opcode, 1) 68 69 def get_fixed_length_string(self, count): 70 if self.current + count > self.scopes[-1]: 71 raise ScopeMismatch 72 ret = self.data[self.current : self.current + count].decode("latin-1") 73 self.current += count 74 return ret 75 76 def get_string(self): 77 null = self.data.find(0x00, self.current) 78 assert null >= 0 79 if null + 1 > self.scopes[-1]: 80 raise ScopeMismatch 81 ret = self.data[self.current:null].decode("latin-1") 82 self.current = null + 1 83 return ret 84 85 def get_buffer(self): 86 cur = self.current 87 self.current = self.scopes[-1] 88 return self.data[cur:self.current] 89 90 def seek(self, offset, absolute=False): 91 if absolute: 92 self.current = offset 93 else: 94 self.current += offset 95 96 def at_end(self): 97 return self.current == self.scopes[-1] 98 99 def push_scope(self, size): 100 self.scopes.append(self.current + size) 101 102 def pop_scope(self, force=False): 103 if not force and not self.at_end(): 104 raise ScopeMismatch 105 self.scopes.pop() 106 107 def reset(self): 108 self.current = 0 109 self.scopes = [len(self.data)] 110 111 def dump(self): 112 self.print_binary(self.current - 48) 113 self.print_binary(self.current - 32) 114 self.print_binary(self.current - 16) 115 self.print_binary(self.current) 116