Skip to content

Commit

Permalink
Add methods for serialization
Browse files Browse the repository at this point in the history
  • Loading branch information
UserUnknownFactor committed Aug 10, 2020
1 parent 4b97420 commit 9341783
Showing 1 changed file with 141 additions and 13 deletions.
154 changes: 141 additions & 13 deletions kaitaistruct.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,9 @@ def size(self):
packer_u4le = struct.Struct('<I')
packer_u8le = struct.Struct('<Q')

# ------------------------------------------------------------------------
# Reading
# ------------------------------------------------------------------------
# ------------------------------------------------------------------------
# Signed
# ------------------------------------------------------------------------
Expand Down Expand Up @@ -213,6 +216,95 @@ def read_f4le(self):
def read_f8le(self):
return KaitaiStream.packer_f8le.unpack(self.read_bytes(8))[0]

# ------------------------------------------------------------------------
# Writing
# ------------------------------------------------------------------------
# ------------------------------------------------------------------------
# Signed
# ------------------------------------------------------------------------

def write_s1(self, data):
return self.write_bytes(KaitaiStream.packer_s1.pack(data))

# ........................................................................
# Big-endian
# ........................................................................

def write_s2be(self, data):
return self.write_bytes(KaitaiStream.packer_s2be.pack(data))

def write_s4be(self, data):
return self.write_bytes(KaitaiStream.packer_s4be.pack(data))

def write_s8be(self, data):
return self.write_bytes(KaitaiStream.packer_s8be.pack(data))

# ........................................................................
# Little-endian
# ........................................................................

def write_s2le(self, data):
return self.write_bytes(KaitaiStream.packer_s2le.pack(data))

def write_s4le(self, data):
return self.write_bytes(KaitaiStream.packer_s4le.pack(data))

def write_s8le(self, data):
return self.write_bytes(KaitaiStream.packer_s8le.pack(data))

# ------------------------------------------------------------------------
# Unsigned
# ------------------------------------------------------------------------

def write_u1(self, data):
return self.write_bytes(KaitaiStream.packer_u1.pack(data))

# ........................................................................
# Big-endian
# ........................................................................

def write_u2be(self, data):
return self.write_bytes(KaitaiStream.packer_u2be.pack(data))

def write_u4be(self, data):
return self.write_bytes(KaitaiStream.packer_u4be.pack(data))

def write_u8be(self, data):
return self.write_bytes(KaitaiStream.packer_u8be.pack(data))

# ........................................................................
# Little-endian
# ........................................................................

def write_u2le(self, data):
return self.write_bytes(KaitaiStream.packer_u2le.pack(data))

def write_u4le(self, data):
return self.write_bytes(KaitaiStream.packer_u4le.pack(data))

def write_u8le(self, data):
return self.write_bytes(KaitaiStream.packer_u8le.pack(data))

# ........................................................................
# Big-endian
# ........................................................................

def write_f4be(self, data):
return self.write_bytes(KaitaiStream.packer_f4be.pack(data))

def write_f8be(self, data):
return self.write_bytes(KaitaiStream.packer_f8be.pack(data))

# ........................................................................
# Little-endian
# ........................................................................

def write_f4le(self, data):
return self.write_bytes(KaitaiStream.packer_f4le.pack(data))

def write_f8le(self, data):
return self.write_bytes(KaitaiStream.packer_f8le.pack(data))

# ========================================================================
# Unaligned bit values
# ========================================================================
Expand Down Expand Up @@ -293,6 +385,45 @@ def read_bytes(self, n):
)
return r

def write_bytes(self, data):
if data is None:
return
nb = len(data)
if nb > 0 and self._io.write(data) != nb:
raise ValidationFailedError(
"not all of %d bytes written" %
(nb,), self._io, __file__
)

def write_terminator(self, term_byte):
self._io.write(KaitaiStream.packer_u1.pack(term_byte))

def write_padding(self, actual_size, size, pad_byte):
pad = size - actual_size
if pad > 0:
if pad_byte is not None:
self._io.write(KaitaiStream.packer_u1.pack(pad_byte) * pad)
else:
raise KaitaiStructError("no padding filler provided", __file__)

def write_bytes_term(self, data, size, term_byte, pad_byte):
if data is None or not size:
return
nb = len(data)
if nb < size:
if nb > 0 and self._io.write(data) != nb:
raise ValidationFailedError(
"not all of %d bytes written" %
(nb,), self._io, __file__
)
else:
raise ValidationFailedError(
"Writing %d bytes, but %d bytes (including terminator) were given" %
(size, nb + 1), self._io, __file__
)
self.write_terminator(term_byte)
self.write_padding(nb, size - 1, pad_byte)

def read_bytes_full(self):
return self._io.read()

Expand All @@ -302,7 +433,7 @@ def read_bytes_term(self, term, include_term, consume_term, eos_error):
c = self._io.read(1)
if c == b'':
if eos_error:
raise Exception(
raise EOFError(
"end of stream reached, but no terminator %d found" %
(term,)
)
Expand All @@ -320,10 +451,7 @@ def read_bytes_term(self, term, include_term, consume_term, eos_error):
def ensure_fixed_contents(self, expected):
actual = self._io.read(len(expected))
if actual != expected:
raise Exception(
"unexpected fixed contents: got %r, was waiting for %r" %
(actual, expected)
)
raise ValidationNotEqualError(expected, actual, self._io, __file__)
return actual

@staticmethod
Expand Down Expand Up @@ -375,9 +503,9 @@ def process_xor_many(data, key):
@staticmethod
def process_rotate_left(data, amount, group_size):
if group_size != 1:
raise Exception(
raise KaitaiStructError(
"unable to rotate group of %d bytes yet" %
(group_size,)
(group_size,), __file__
)

mask = group_size * 8 - 1
Expand Down Expand Up @@ -462,21 +590,21 @@ def __init__(self, expected, actual, io, src_path):

class ValidationLessThanError(ValidationFailedError):
"""Signals validation failure: we required "actual" value to be
greater than or equal to "min", but it turned out that it's not.
greater than or equal to "minimal", but it turned out that it's not.
"""
def __init__(self, min, actual, io, src_path):
def __init__(self, minimal, actual, io, src_path):
super(ValidationLessThanError, self).__init__("not in range, min %s, but got %s" % (repr(min), repr(actual)), io, src_path)
self.min = min
self.minimal = minimal
self.actual = actual


class ValidationGreaterThanError(ValidationFailedError):
"""Signals validation failure: we required "actual" value to be
less than or equal to "max", but it turned out that it's not.
less than or equal to "maximal", but it turned out that it's not.
"""
def __init__(self, max, actual, io, src_path):
def __init__(self, maximal, actual, io, src_path):
super(ValidationGreaterThanError, self).__init__("not in range, max %s, but got %s" % (repr(max), repr(actual)), io, src_path)
self.max = max
self.maximal = maximal
self.actual = actual


Expand Down

0 comments on commit 9341783

Please sign in to comment.