2019-08-22 19:19:10 +00:00
from . import dcmp0
from . import dcmp1
from . import dcmp2
2019-09-23 21:14:06 +00:00
from . common import DecompressError , CompressedApplicationHeaderInfo , CompressedHeaderInfo , CompressedSystemHeaderInfo
2019-08-22 19:19:10 +00:00
__all__ = [
" DecompressError " ,
" decompress " ,
]
2019-09-23 21:10:55 +00:00
2019-09-23 21:32:38 +00:00
# Maps 'dcmp' IDs to their corresponding Python implementations.
# Each decompressor has the signature (header_info: CompressedHeaderInfo, data: bytes, *, debug: bool=False) -> bytes.
DECOMPRESSORS = {
0 : dcmp0 . decompress ,
1 : dcmp1 . decompress ,
2 : dcmp2 . decompress ,
}
2019-08-22 19:19:10 +00:00
2019-09-23 21:50:29 +00:00
def decompress_parsed ( header_info : CompressedHeaderInfo , data : bytes , * , debug : bool = False ) - > bytes :
""" Decompress the given compressed resource data, whose header has already been removed and parsed into a CompressedHeaderInfo object. """
2019-09-23 21:10:55 +00:00
2019-09-23 21:32:38 +00:00
try :
decompress_func = DECOMPRESSORS [ header_info . dcmp_id ]
except KeyError :
raise DecompressError ( f " Unsupported ' dcmp ' ID: { header_info . dcmp_id } " )
2019-08-22 19:19:10 +00:00
2019-09-23 21:50:29 +00:00
decompressed = decompress_func ( header_info , data , debug = debug )
2019-09-23 21:10:55 +00:00
if len ( decompressed ) != header_info . decompressed_length :
raise DecompressError ( f " Actual length of decompressed data ( { len ( decompressed ) } ) does not match length stored in resource ( { header_info . decompressed_length } ) " )
2019-08-22 19:19:10 +00:00
return decompressed
2019-09-23 21:50:29 +00:00
def decompress ( data : bytes , * , debug : bool = False ) - > bytes :
""" Decompress the given compressed resource data. """
header_info = CompressedHeaderInfo . parse ( data )
if debug :
print ( f " Compressed resource data header: { header_info } " )
return decompress_parsed ( header_info , data [ header_info . header_length : ] , debug = debug )