changeset 377:70e2ed71b09c

Add meaningful exceptions in format parsing.
author Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
date Wed, 29 Aug 2012 18:34:28 +0200
parents 69ec72b990a4
children 11d895b6c0dc
files pytouhou/formats/__init__.py pytouhou/formats/anm0.py pytouhou/formats/pbg3.py pytouhou/formats/score.py pytouhou/formats/std.py pytouhou/formats/t6rp.py pytouhou/ui/music.py
diffstat 7 files changed, 28 insertions(+), 20 deletions(-) [+]
line wrap: on
line diff
--- a/pytouhou/formats/__init__.py
+++ b/pytouhou/formats/__init__.py
@@ -3,3 +3,9 @@
 This package provides modules to handle the various proprietary file formats
 used by Touhou games.
 """
+
+class WrongFormatError(Exception):
+    pass
+
+class ChecksumError(Exception):
+    pass
--- a/pytouhou/formats/anm0.py
+++ b/pytouhou/formats/anm0.py
@@ -23,6 +23,8 @@ Almost everything rendered in the game i
 from struct import pack, unpack
 from pytouhou.utils.helpers import read_string, get_logger
 
+from pytouhou.formats import WrongFormatError
+
 
 logger = get_logger(__name__)
 
@@ -84,9 +86,8 @@ class ANM0(object):
         first_name_offset, unused, secondary_name_offset = unpack('<III', file.read(12))
         version, unknown2, thtxoffset, hasdata, nextoffset, zero2 = unpack('<IIIIII', file.read(24))
         if version != 0:
-            raise Exception #TODO
-        if (zero1, zero2) != (0, 0):
-            raise Exception #TODO
+            raise WrongFormatError(version)
+        assert (zero1, zero2) == (0, 0)
 
         sprite_offsets = [unpack('<I', file.read(4))[0] for i in range(nb_sprites)]
         script_offsets = [unpack('<II', file.read(8)) for i in range(nb_scripts)]
--- a/pytouhou/formats/pbg3.py
+++ b/pytouhou/formats/pbg3.py
@@ -28,6 +28,8 @@ import pytouhou.utils.lzss as lzss
 
 from pytouhou.utils.helpers import get_logger
 
+from pytouhou.formats import WrongFormatError
+
 logger = get_logger(__name__)
 
 
@@ -101,7 +103,7 @@ class PBG3(object):
 
         magic = file.read(4)
         if magic != b'PBG3':
-            raise Exception #TODO
+            raise WrongFormatError(magic)
 
         bitstream = PBG3BitStream(file)
         entries = {}
--- a/pytouhou/formats/score.py
+++ b/pytouhou/formats/score.py
@@ -17,6 +17,8 @@ from struct import pack, unpack, Struct
 from collections import namedtuple
 from io import BytesIO
 
+from pytouhou.formats import ChecksumError
+
 
 class TH6Score(object):
     entry_types = {
@@ -78,8 +80,9 @@ class TH6Score(object):
         # Verify checksum
         if verify:
             #TODO: is there more to it?
-            if checksum != sum(ord(c) for c in file.read()) & 0xFFFF:
-                raise Exception
+            real_sum = sum(ord(c) for c in file.read()) & 0xFFFF
+            if checksum != real_sum:
+                raise ChecksumError(checksum, real_sum)
             file.seek(4)
 
         # Read second-part header
--- a/pytouhou/formats/std.py
+++ b/pytouhou/formats/std.py
@@ -81,9 +81,8 @@ class Stage(object):
         stage = Stage()
 
         nb_models, nb_faces = unpack('<HH', file.read(4))
-        object_instances_offset, script_offset = unpack('<II', file.read(8))
-        if file.read(4) != b'\x00\x00\x00\x00':
-            raise Exception #TODO
+        object_instances_offset, script_offset, zero = unpack('<III', file.read(12))
+        assert zero == 0
 
         stage.name = read_string(file, 128, 'shift_jis')
 
@@ -116,8 +115,7 @@ class Stage(object):
                 unknown, size = unpack('<HH', file.read(4))
                 if unknown == 0xffff:
                     break
-                if size != 0x1c:
-                    raise Exception #TODO
+                assert size == 0x1c
                 script_index, x, y, z, width, height = unpack('<Hxxfffff', file.read(24))
                 model.quads.append((script_index, x, y, z, width, height))
             stage.models.append(model)
@@ -129,19 +127,17 @@ class Stage(object):
             obj_id, unknown, x, y, z = unpack('<HHfff', file.read(16))
             if (obj_id, unknown) == (0xffff, 0xffff):
                 break
-            if unknown != 256:
-                raise Exception #TODO
+            assert unknown == 256 #TODO: really?
             stage.object_instances.append((obj_id, x, y, z))
 
 
-        # Read other funny things (script)
+        # Read the script
         file.seek(script_offset)
         while True:
             frame, opcode, size = unpack('<IHH', file.read(8))
             if (frame, opcode, size) == (0xffffffff, 0xffff, 0xffff):
                 break
-            if size != 0x0c:
-                raise Exception #TODO
+            assert size == 0x0c
             data = file.read(size)
             if opcode in cls._instructions:
                 args = unpack('<%s' % cls._instructions[opcode][0], data)
--- a/pytouhou/formats/t6rp.py
+++ b/pytouhou/formats/t6rp.py
@@ -85,8 +85,8 @@ class T6RP(object):
         verify -- whether or not to verify the file's checksum (default True)
         """
 
-        if file.read(4) != b'T6RP':
-            raise Exception
+        magic = file.read(4)
+        assert magic == b'T6RP'
 
         replay = cls()
 
@@ -108,7 +108,7 @@ class T6RP(object):
             file.seek(15)
             real_sum = (sum(ord(c) for c in data) + 0x3f000318 + replay.key) & 0xffffffff
             if checksum != real_sum:
-                raise Exception('Checksum mismatch: %d ≠ %d.' % (checksum, real_sum))
+                raise ChecksumError(checksum, real_sum)
 
         replay.unknown3, = unpack('<B', file.read(1))
         replay.date = file.read(9) #read_string(file, 9, 'ascii')
--- a/pytouhou/ui/music.py
+++ b/pytouhou/ui/music.py
@@ -32,7 +32,7 @@ class InfiniteWaveSource(WaveSource):
         self._end = self.audio_format.bytes_per_sample * end
 
         if self._end > self._max_offset:
-            raise Exception #TODO
+            raise Exception('Music ends after the end of the file.')
 
         self._duration = None