Seregon/PkgToolBox

Toolbox for analyzing and editing pkg application files for psp,ps3, ps4 and ps5, includes the most useful functions you might need.

Python/57.3 KB/No license
pkgtoolbox/core/utils.py
PkgToolBox / pkgtoolbox / core / utils.py
1import io
2import struct
3import zipfile
4import enum
5from typing import Optional
6 
7 
8class EndianType(enum.Enum):
9 BigEndian = "big"
10 LittleEndian = "little"
11 
12 
13class Utils:
14 @staticmethod
15 def hex2binary(hex_str: str) -> bytes:
16 return bytes.fromhex(hex_str)
17 
18 @staticmethod
19 def hex_to_binary(hex_string: str) -> bytes:
20 return bytes.fromhex(hex_string)
21 
22 @staticmethod
23 def hex_to_dec(hex_bytes: bytes, reverse: str = "") -> int:
24 if reverse == "reverse":
25 hex_bytes = hex_bytes[::-1]
26 return int.from_bytes(hex_bytes, byteorder="big")
27 
28 @staticmethod
29 def read_write_data(
30 file_to_use: str,
31 file_to_use2: str = "",
32 method_read_or_write_or_both: str = "",
33 method_binary_or_integer: str = "",
34 bin_data: Optional[bytes] = None,
35 bin_data2: int = 0,
36 offset: int = 0,
37 count: int = 0,
38 ):
39 if method_read_or_write_or_both == "r":
40 with open(file_to_use, "rb") as f:
41 return f.read()
42 elif method_read_or_write_or_both == "w":
43 with open(file_to_use, "ab") as f:
44 if method_binary_or_integer == "bi":
45 f.write(bin_data or b"")
46 elif method_binary_or_integer == "in":
47 f.write(struct.pack("i", bin_data2))
48 elif method_read_or_write_or_both == "b":
49 with open(file_to_use, "rb") as fr, open(file_to_use2, "ab") as fw:
50 fr.seek(offset)
51 buffer_size = 4096
52 while count > 0:
53 buffer = fr.read(min(buffer_size, count))
54 if not buffer:
55 break
56 fw.write(buffer)
57 count -= len(buffer)
58 
59 @staticmethod
60 def compare_bytes(a: bytes, b: bytes) -> bool:
61 return a == b
62 
63 @staticmethod
64 def extract_file_to_directory(zip_file_name: str, output_directory: str, member: str = None):
65 with zipfile.ZipFile(zip_file_name, "r") as zip_ref:
66 if member:
67 zip_ref.extract(member, output_directory)
68 else:
69 zip_ref.extractall(output_directory)
70 
71 @staticmethod
72 def byte_to_string(buff: bytes) -> str:
73 return buff.hex().upper()
74 
75 @staticmethod
76 def generate_stream_from_string(s: str) -> io.BytesIO:
77 return io.BytesIO(s.encode())
78 
79 @staticmethod
80 def read_uint32(stream: io.BytesIO) -> int:
81 return struct.unpack("<I", stream.read(4))[0]
82 
83 @staticmethod
84 def read_uint16(stream: io.BytesIO) -> int:
85 return struct.unpack("<H", stream.read(2))[0]
86 
87 @staticmethod
88 def read_ascii_string(stream: io.BytesIO, length: int) -> str:
89 return stream.read(length).decode("ascii")
90 
91 @staticmethod
92 def read_utf8_string(stream: io.BytesIO, length: int) -> str:
93 return stream.read(length).decode("utf-8")
94 
95 @staticmethod
96 def read_byte(stream: io.BytesIO, length: int) -> bytes:
97 return stream.read(length)
98