Hi,

here's a small parser for archive files used by the Project: Starfighter
game... The format is really not widely used :-) and the original game
website has disappeared already; but writing this parser was good for
training, and maybe you'd like to add it to Hachoir. You can also find
the patch at https://bitbucket.org/oliver_g/hachoir/src/0f1b8b65dfac .

Also, a test file is attached, which is also used for the hachoir-parser
test case.

Thanks,
Oliver

Attachment: paktest.pak
Description: Binary data

# HG changeset patch
# User Oliver Gerlich <oliver.gerl...@gmx.de>
# Date 1319131489 -7200
# Branch prs-pak
# Node ID 0f1b8b65dfac325de5d8bd7cee0a6cb12cb11dba
# Parent  b662b521c8b04b4347c1fa739f6bf05b6aaa616c
add parser for PAK files from "Project: Starfighter" game

diff -r b662b521c8b0 -r 0f1b8b65dfac hachoir-parser/hachoir_parser/archive/__init__.py
--- a/hachoir-parser/hachoir_parser/archive/__init__.py	Tue Sep 27 18:57:24 2011 +0200
+++ b/hachoir-parser/hachoir_parser/archive/__init__.py	Thu Oct 20 19:24:49 2011 +0200
@@ -11,3 +11,4 @@
 from hachoir_parser.archive.mar import MarFile
 from hachoir_parser.archive.mozilla_ar import MozillaArchive
 from hachoir_parser.archive.zlib import ZlibData
+from hachoir_parser.archive.prs_pak import PRSPakFile
diff -r b662b521c8b0 -r 0f1b8b65dfac hachoir-parser/hachoir_parser/archive/prs_pak.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hachoir-parser/hachoir_parser/archive/prs_pak.py	Thu Oct 20 19:24:49 2011 +0200
@@ -0,0 +1,46 @@
+"""
+Parallel Realities Starfighter .pak file parser
+
+See http://www.parallelrealities.co.uk/projects/starfighter.php
+or svn://svn.debian.org/svn/pkg-games/packages/trunk/starfighter/
+
+Author: Oliver Gerlich
+"""
+
+from hachoir_parser import Parser
+from hachoir_core.field import (ParserError,
+    UInt32, String, SubFile, FieldSet)
+from hachoir_core.endian import LITTLE_ENDIAN
+from hachoir_core.text_handler import filesizeHandler
+
+class FileEntry(FieldSet):
+    def createFields(self):
+        yield String(self, "filename", 56, truncate="\0")
+        yield filesizeHandler(UInt32(self, "size"))
+        yield SubFile(self, "data", self["size"].value, filename=self["filename"].value)
+
+    def createDescription(self):
+        return self["filename"].value
+
+class PRSPakFile(Parser):
+    PARSER_TAGS = {
+        "id": "prs_pak",
+        "category": "archive",
+        "file_ext": ("pak",),
+        "mime": (u"application/octet-stream",),
+        "min_size": 4*8, # just the identifier
+        "magic": (('PACK', 0),),
+        "description": "Parallel Realities Starfighter .pak archive",
+    }
+
+    endian = LITTLE_ENDIAN
+
+    def validate(self):
+        return (self.stream.readBytes(0, 4) == 'PACK')
+
+    def createFields(self):
+        yield String(self, "magic", 4)
+
+        # all remaining data must be file entries:
+        while self.current_size < self._size:
+            yield FileEntry(self, "file[]")
diff -r b662b521c8b0 -r 0f1b8b65dfac hachoir-parser/tests/download_testcase.py
--- a/hachoir-parser/tests/download_testcase.py	Tue Sep 27 18:57:24 2011 +0200
+++ b/hachoir-parser/tests/download_testcase.py	Thu Oct 20 19:24:49 2011 +0200
@@ -90,6 +90,7 @@
     (u"radpoor.doc", 103936, "114835a03be92e02029c74ece1162c3e"),
     (u"quicktime.mp4", 245779, "dc77a8de8c091c19d86df74280f6feb7"),
     (u"swat.blp", 55753, "a47a2d6ef61c9005c3f5faf1bca253af"),
+    (u"paktest.pak", 10464, "53ded116d139dbb172280f9e267ad3ed"),
 )
 
 def stringMD5(text):
diff -r b662b521c8b0 -r 0f1b8b65dfac hachoir-parser/tests/run_testcase.py
--- a/hachoir-parser/tests/run_testcase.py	Tue Sep 27 18:57:24 2011 +0200
+++ b/hachoir-parser/tests/run_testcase.py	Thu Oct 20 19:24:49 2011 +0200
@@ -463,6 +463,13 @@
     checkValue(parser, "jpeg_header_len", 10),
 )
 
+def checkPrsPak(parser): return (
+    checkValue(parser, "/file[0]/filename", "hachoir/png_331x90x8_truncated.png"),
+    checkValue(parser, "/file[0]/size", 100),
+    checkValue(parser, "/file[1]/filename", "hachoir/small_text.tar"),
+    checkValue(parser, "/file[1]/size", 10240),
+)
+
 def checkFile(filename, check_parser):
     sys.stdout.write("  - Create parser: ")
     sys.stdout.flush()
@@ -631,6 +638,7 @@
     # radpoor.doc
     # quicktime.mp4
     (u"swat.blp", checkSwat),
+    (u"paktest.pak", checkPrsPak),
 )
 
 if __name__ == "__main__":

Reply via email to