Files
86Box-bios-tools/bios_extract/insyde-tools/util.py
2021-12-15 20:46:41 -03:00

169 lines
3.9 KiB
Python

#! /usr/bin/env python
from hashlib import md5
from sys import stdout
from pprint import pprint
def md5sum(data):
return md5(data).hexdigest()
class FindBadPosition(Exception):
"""Raised to disallow a position from appearing in the result list in `find_all`"""
pass
class FindStopSearching(Exception):
"""Stop searching in find_all"""
def __init__(self, result):
self.result = result
def from_b64(what):
return str.decode(what + "=" * (3 - len(what) % 3), "base64")
def hexbytes(bytes):
return " ".join(["%02x" % ord(c) for c in bytes])
def substitute(input, where, what):
return "".join([input[:where], what, input[where + len(what):]])
def find_all(buffer, what, callback=lambda x: x, start=0, stop=None):
if stop is None:
stop = len(buffer)
position = start
result = []
while position < stop and what in buffer[position:stop + 1]:
position = buffer.index(what, position, stop)
try:
result.append(callback(position))
except FindStopSearching, exc:
return exc.result
except FindBadPosition:
pass
position += 1
return result
def find_all_backwards(buffer, what, callback=lambda x: x, start=None, stop=0):
"Beware! This function is not fully tested. I should really write some unit tests for the edge cases"
if start is None:
start = len(buffer)
position = start
result = []
while position > stop and what in buffer[stop:position]:
position = buffer.rindex(what, stop, position)
try:
result.append(callback(position))
except FindStopSearching, exc:
return exc.result
except FindBadPosition:
pass
position += 1
return result
def read_with_progress(file_handle, total, chunk_size):
assert not total % chunk_size, "chunk_size must be a divisor of total!"
data = []
length = (80 - 6)
for i in xrange(0, total, chunk_size):
data.append(file_handle.read(chunk_size))
done = length * i // total
print "\r[ %s>%s ]" % ("-" * done, " " * (length - done)),
stdout.flush()
print "\r[ %s> ]" % ("-" * length)
return "".join(data)
from struct import unpack, Struct as pyStruct
class StructMeta(type):
def __new__(meta, classname, bases, classDict):
is_structitem = lambda x: isinstance(x[1], SI)
struct_items = filter(is_structitem, classDict.iteritems())
struct_items.sort(key=lambda x: x[1].position)
struct_format = "".join(map(lambda x: x[1].packstr, struct_items))
struct = pyStruct(struct_format)
def __init__(self, data):
data_tuple = struct.unpack_from(data)
for (name, structitem), item_data in zip(struct_items, data_tuple):
setattr(self, name, item_data)
self.rest_of_data = data[struct.size:]
#def repack(self):
cls = type.__new__(meta, classname, bases, classDict)
cls.py_struct = struct
cls.struct_size = struct.size
cls.__init__ = __init__
return cls
class SI(object):
"StructItem"
counter = 0
def __init__(self, packstr):
self.position = SI.counter
SI.counter += 1
self.packstr = packstr
class Struct(object):
__metaclass__ = StructMeta
def hexdump(s, sep=" "):
return sep.join(map(lambda x: "%02x" % ord(x), s))
def ascii(s):
s2 = ""
for c in s:
if ord(c) < 0x20 or ord(c) > 0x7e:
s2 += "."
else:
s2 += c
return s2
def pad(s, c, l):
if len(s) < l:
s += c * (l - len(s))
return s
def chexdump(s, ts="", off=0):
for i in range(0, len(s), 16):
print ts + "%08x %s %s |%s|" % (i + off, pad(hexdump(s[i:i + 8], ' '), " ", 23), pad(hexdump(s[i + 8:i + 16], ' '), " ", 23), pad(ascii(s[i:i + 16]), " ", 16))
if __name__ == "__main__":
s = Header("test")
print "I have something:", s