from filetypes.base import *

import malcat


class StreamHeader(Struct):

    def parse(self):
        yield String(4, name="Magic", zero_terminated=False)
        yield UInt32(name="HeaderSize")
        yield UInt32(name="PackedSize")
        yield UInt32(name="PackedCRC")
        yield UInt32(name="OriginalSize")
        yield UInt32(name="OriginalCRC")

class APLibAnalyzer(FileTypeAnalyzer):
    category = malcat.FileType.ARCHIVE
    name = "AP32"
    regexp = r"AP32\x18\x00\x00\x00"

    def unpack(self, vfile, password=None):
        dec = malcat.APLibDecompressor()
        return dec.decompress(self["Deflate stream"])

    def parse(self, hint):
        from binascii import crc32
        hdr = yield StreamHeader(category=Type.HEADER)
        packed_size = hdr["PackedSize"]
        if packed_size > self.remaining():
            raise FatalError("Truncated data")
        self.add_section("stream", self.tell(), packed_size)
        data = yield Bytes(packed_size, name="Deflate stream", category=Type.DATA)
        if hdr["PackedCRC"] != crc32(data):
            raise FatalError("Invalid packed crc")
        self.confirm()
        self.add_file("<packed content>", hdr["OriginalSize"], "unpack")


