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
Utilities/system.py
PkgToolBox / Utilities / system.py
1import struct
2from enum import Enum
3from io import BytesIO
4
5class EndianType(Enum):
6 BigEndian = 'big'
7 LittleEndian = 'little'
8
9class EndianIO:
10 def __init__(self, file_name=None, endian_type=EndianType.LittleEndian, file_mode='r+b', file_access='r+b', file_share=None, stream=None, byte_array=None):
11 self.file_name = file_name
12 self.endian_type = endian_type
13 self.file_mode = file_mode
14 self.file_access = file_access
15 self.file_share = file_share
16 self.stream = stream
17 self.byte_array = byte_array
18 self.opened = False
19 self.in_stream = None
20 self.out_stream = None
21
22 if file_name:
23 self.stream = open(file_name, file_mode)
24 elif byte_array:
25 self.stream = BytesIO(byte_array)
26 elif stream:
27 self.stream = stream
28
29 if self.stream:
30 self.open()
31
32 def open(self):
33 if self.opened:
34 self.close()
35 if self.stream:
36 self.in_stream = EndianReader(self.stream, self.endian_type)
37 self.out_stream = EndianWriter(self.stream, self.endian_type)
38 self.opened = True
39
40 def close(self):
41 if self.opened:
42 self.stream.close()
43 self.opened = False
44
45 def seek_to(self, position, origin=0):
46 self.stream.seek(position, origin)
47
48 def to_array(self):
49 if isinstance(self.stream, BytesIO):
50 return self.stream.getvalue()
51 else:
52 self.stream.seek(0)
53 return self.stream.read()
54
55 @property
56 def position(self):
57 return self.stream.tell()
58
59 @position.setter
60 def position(self, value):
61 self.stream.seek(value)
62
63 def __del__(self):
64 self.close()
65
66class EndianReader:
67 def __init__(self, stream, endian_type=EndianType.LittleEndian):
68 self.stream = stream
69 self.endian_type = endian_type
70
71 def seek_to(self, position, origin=0):
72 self.stream.seek(position, origin)
73
74 def read_bytes(self, count):
75 return self.stream.read(count)
76
77 def read_int16(self):
78 return struct.unpack(self.endian_type.value + 'h', self.read_bytes(2))[0]
79
80 def read_uint16(self):
81 return struct.unpack(self.endian_type.value + 'H', self.read_bytes(2))[0]
82
83 def read_int32(self):
84 return struct.unpack(self.endian_type.value + 'i', self.read_bytes(4))[0]
85
86 def read_uint32(self):
87 return struct.unpack(self.endian_type.value + 'I', self.read_bytes(4))[0]
88
89 def read_int64(self):
90 return struct.unpack(self.endian_type.value + 'q', self.read_bytes(8))[0]
91
92 def read_uint64(self):
93 return struct.unpack(self.endian_type.value + 'Q', self.read_bytes(8))[0]
94
95 def read_float(self):
96 return struct.unpack(self.endian_type.value + 'f', self.read_bytes(4))[0]
97
98 def read_double(self):
99 return struct.unpack(self.endian_type.value + 'd', self.read_bytes(8))[0]
100
101 def read_string(self, length):
102 return self.read_bytes(length).decode('ascii').replace('\0', '')
103
104 def read_unicode_string(self, length):
105 return self.read_bytes(length * 2).decode('utf-16').replace('\0', '')
106
107class EndianWriter:
108 def __init__(self, stream, endian_type=EndianType.LittleEndian):
109 self.stream = stream
110 self.endian_type = endian_type
111
112 def seek_to(self, position, origin=0):
113 self.stream.seek(position, origin)
114
115 def write_bytes(self, data):
116 self.stream.write(data)
117
118 def write_int16(self, value):
119 self.write_bytes(struct.pack(self.endian_type.value + 'h', value))
120
121 def write_uint16(self, value):
122 self.write_bytes(struct.pack(self.endian_type.value + 'H', value))
123
124 def write_int32(self, value):
125 self.write_bytes(struct.pack(self.endian_type.value + 'i', value))
126
127 def write_uint32(self, value):
128 self.write_bytes(struct.pack(self.endian_type.value + 'I', value))
129
130 def write_int64(self, value):
131 self.write_bytes(struct.pack(self.endian_type.value + 'q', value))
132
133 def write_uint64(self, value):
134 self.write_bytes(struct.pack(self.endian_type.value + 'Q', value))
135
136 def write_float(self, value):
137 self.write_bytes(struct.pack(self.endian_type.value + 'f', value))
138
139 def write_double(self, value):
140 self.write_bytes(struct.pack(self.endian_type.value + 'd', value))
141
142 def write_string(self, value):
143 self.write_bytes(value.encode('ascii'))
144
145 def write_unicode_string(self, value):
146 self.write_bytes(value.encode('utf-16'))
147
148# End of Selection