121 lines
No EOL
3.9 KiB
Python
121 lines
No EOL
3.9 KiB
Python
import struct
|
|
import sys
|
|
import os
|
|
from argparse import ArgumentParser
|
|
|
|
try:
|
|
import colorama
|
|
from colorama import Fore, Style
|
|
colorama.init()
|
|
TRESET = Style.RESET_ALL
|
|
TGREEN = Fore.GREEN
|
|
TGREENLIT = Style.BRIGHT + Fore.GREEN
|
|
TYELLOW = Fore.YELLOW
|
|
TYELLOWLIT = Style.BRIGHT + Fore.YELLOW
|
|
TRED = Fore.RED
|
|
TREDLIT = Style.BRIGHT + Fore.RED
|
|
|
|
except ImportError:
|
|
TRESET = ''
|
|
TGREEN = ''
|
|
TGREENLIT = ''
|
|
TYELLOW = ''
|
|
TYELLOWLIT = ''
|
|
TRED = ''
|
|
TREDLIT = ''
|
|
|
|
def read_sbyte(f): return struct.unpack("b", f.read(1))[0]
|
|
def write_sbyte(f, val): f.write(struct.pack("b", val))
|
|
def read_sint16(f): return struct.unpack(">h", f.read(2))[0]
|
|
def write_sint16(f, val): f.write(struct.pack(">h", val))
|
|
def read_sint32(f): return struct.unpack(">i", f.read(4))[0]
|
|
def write_sint32(f, val): f.write(struct.pack(">i", val))
|
|
def read_ubyte(f): return struct.unpack("B", f.read(1))[0]
|
|
def write_ubyte(f, val): f.write(struct.pack("B", val))
|
|
def read_uint16(f): return struct.unpack(">H", f.read(2))[0]
|
|
def write_uint16(f, val): f.write(struct.pack(">H", val))
|
|
def read_uint32(f): return struct.unpack(">I", f.read(4))[0]
|
|
def write_uint32(f, val): f.write(struct.pack(">I", val))
|
|
def read_float(f): return struct.unpack(">f", f.read(4))[0]
|
|
def write_float(f, val): f.write(struct.pack(">f", val))
|
|
def read_double(f): return struct.unpack(">d", f.read(4))[0]
|
|
def write_double(f, val): f.write(struct.pack(">d", val))
|
|
def read_bool(f, vSize=1): return struct.unpack("B", f.read(vSize))[0] > 0
|
|
def write_bool(f, val, vSize=1):
|
|
if val is True: f.write(b'\x00'*(vSize-1) + b'\x01')
|
|
else: f.write(b'\x00' * vSize)
|
|
|
|
def get_alignment(number, align: int):
|
|
if number % align != 0:
|
|
return align - (number % align)
|
|
else:
|
|
return 0
|
|
|
|
def get_size(f, offset=0):
|
|
""" Return a stream's size in bytes """
|
|
f.seek(0, 2)
|
|
return f.tell() + offset
|
|
|
|
def get_file_alignment(f, alignment: int):
|
|
""" Return file alignment, 0 = aligned, non zero = misaligned """
|
|
return get_alignment(get_size(f), alignment)
|
|
|
|
def align_file(f, alignment: int, fillchar='00'):
|
|
""" Align a file to be the specified size """
|
|
f.write(bytes.fromhex(fillchar * get_file_alignment(f, alignment)))
|
|
|
|
def color_text(text: str, textToColor: list=[('', None)], defaultColor: str=None):
|
|
currentColor = None
|
|
formattedText = ''
|
|
|
|
format = False
|
|
for itemPair in textToColor:
|
|
if itemPair[0] != '' and itemPair[1] is not None:
|
|
format = True
|
|
break
|
|
|
|
if not format:
|
|
return defaultColor + text + TRESET
|
|
|
|
for char in text:
|
|
handled = False
|
|
for itemPair in textToColor:
|
|
if (char in itemPair[0] or '\*' in itemPair[0]) and itemPair[1] is not None:
|
|
if currentColor != itemPair[1]:
|
|
formattedText += TRESET
|
|
formattedText += itemPair[1]
|
|
currentColor = itemPair[1]
|
|
handled = True
|
|
|
|
elif defaultColor is not None:
|
|
formattedText += TRESET
|
|
formattedText += defaultColor
|
|
currentColor = defaultColor
|
|
|
|
elif currentColor is not None:
|
|
formattedText += TRESET
|
|
currentColor = None
|
|
|
|
if handled:
|
|
break
|
|
|
|
formattedText += char
|
|
|
|
return formattedText + TRESET
|
|
|
|
class CommandLineParser(ArgumentParser):
|
|
|
|
def error(self, message: str, prefix: str=None, print_usage=True, exit=True):
|
|
if print_usage:
|
|
self.print_usage(sys.stderr)
|
|
|
|
if prefix is None:
|
|
if exit:
|
|
self.exit(2, f'{self.prog}: error: {message}\n')
|
|
else:
|
|
self._print_message(f'{self.prog}: error: {message}\n')
|
|
else:
|
|
if exit:
|
|
self.exit(2, f'{prefix} {message}\n')
|
|
else:
|
|
self._print_message(f'{prefix} {message}\n') |