Skip to content

Commit 325f66b

Browse files
authored
KaitaiStream code cleanup (#18)
* KaitaiStream code cleanup * process_xor_* reimplemented for PY2, short code but no benchmarking * bytes_terminate, bytes_strip_right PY2 cleanup * process_xor_* uses some dgladkov's code
1 parent 160ac27 commit 325f66b

File tree

1 file changed

+16
-40
lines changed

1 file changed

+16
-40
lines changed

kaitaistruct.py

Lines changed: 16 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,13 @@ def __enter__(self):
2525
def __exit__(self, *args, **kwargs):
2626
self.close()
2727

28+
def close(self):
29+
self._io.close()
30+
2831
@classmethod
2932
def from_file(cls, filename):
30-
f = open(filename, 'rb')
31-
try:
33+
with open(filename, 'rb') as f:
3234
return cls(KaitaiStream(f))
33-
except Exception:
34-
# close file descriptor, then reraise the exception
35-
f.close()
36-
raise
3735

3836
@classmethod
3937
def from_bytes(cls, buf):
@@ -43,9 +41,6 @@ def from_bytes(cls, buf):
4341
def from_io(cls, io):
4442
return cls(KaitaiStream(io))
4543

46-
def close(self):
47-
self._io.close()
48-
4944

5045
class KaitaiStream(object):
5146
def __init__(self, io):
@@ -85,19 +80,14 @@ def size(self):
8580
# current file / StringIO size, thus we use the following
8681
# trick.
8782
io = self._io
88-
8983
# Remember our current position
9084
cur_pos = io.tell()
91-
9285
# Seek to the end of the File object
9386
io.seek(0, 2)
94-
9587
# Remember position, which is equal to the full length
9688
full_size = io.tell()
97-
9889
# Seek back to the current position
9990
io.seek(cur_pos)
100-
10191
return full_size
10292

10393
# ========================================================================
@@ -280,32 +270,30 @@ def ensure_fixed_contents(self, expected):
280270
actual = self._io.read(len(expected))
281271
if actual != expected:
282272
raise Exception(
283-
"unexpected fixed contents: got %s, was waiting for %s" %
284-
(str(actual), str(expected))
273+
"unexpected fixed contents: got %r, was waiting for %r" %
274+
(actual, expected)
285275
)
286276
return actual
287277

288278
@staticmethod
289-
def bytes_strip_right(src, pad_byte):
290-
new_len = len(src)
279+
def bytes_strip_right(data, pad_byte):
280+
new_len = len(data)
291281
if PY2:
292-
data = bytearray(src)
293-
else:
294-
data = src
282+
# data[...] must yield an integer, to compare with integer pad_byte
283+
data = bytearray(data)
295284

296285
while new_len > 0 and data[new_len - 1] == pad_byte:
297286
new_len -= 1
298287

299288
return data[:new_len]
300289

301290
@staticmethod
302-
def bytes_terminate(src, term, include_term):
291+
def bytes_terminate(data, term, include_term):
303292
new_len = 0
304-
max_len = len(src)
293+
max_len = len(data)
305294
if PY2:
306-
data = bytearray(src)
307-
else:
308-
data = src
295+
# data[...] must yield an integer, to compare with integer term
296+
data = bytearray(data)
309297

310298
while new_len < max_len and data[new_len] != term:
311299
new_len += 1
@@ -322,26 +310,14 @@ def bytes_terminate(src, term, include_term):
322310
@staticmethod
323311
def process_xor_one(data, key):
324312
if PY2:
325-
r = bytearray(data)
326-
for i in range(len(r)):
327-
r[i] ^= key
328-
return bytes(r)
313+
return bytes(bytearray(v ^ key for v in bytearray(data)))
329314
else:
330315
return bytes(v ^ key for v in data)
331316

332317
@staticmethod
333318
def process_xor_many(data, key):
334319
if PY2:
335-
r = bytearray(data)
336-
k = bytearray(key)
337-
ki = 0
338-
kl = len(k)
339-
for i in range(len(r)):
340-
r[i] ^= k[ki]
341-
ki += 1
342-
if ki >= kl:
343-
ki = 0
344-
return bytes(r)
320+
return bytes(bytearray(a ^ b for a, b in zip(bytearray(data), itertools.cycle(bytearray(key)))))
345321
else:
346322
return bytes(a ^ b for a, b in zip(data, itertools.cycle(key)))
347323

0 commit comments

Comments
 (0)