From 931529bc7cc0d43eecbf000319c999fcfd241856 Mon Sep 17 00:00:00 2001 From: Elliot Nunn Date: Tue, 11 Dec 2018 17:18:41 +0800 Subject: [PATCH] Revise error model The problem is this: a user might want to edit a resource compressed using an unknown algorithm. This should fail by default, because after all, the resource is garbage. But the expert user (say Daniel wrote a new algo) might know better, and set the expand_err_ok attribute on a Resource object before accessing and editing its data attribute. --- macresources/FakeResDecompress.py | 3 ++- macresources/main.py | 18 ++++++++++++------ 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/macresources/FakeResDecompress.py b/macresources/FakeResDecompress.py index 0d0ff6e..9c0158e 100644 --- a/macresources/FakeResDecompress.py +++ b/macresources/FakeResDecompress.py @@ -15,11 +15,12 @@ def GetEncoding(inf): def DecompressResource(inf): # print('DecompressResource', GetEncoding(inf)) - GetEncoding(inf) # this will need to be called, of course + if GetEncoding(inf) == 'UnknownCompression': return inf return b'decompressed ' + inf def CompressResource(inf, encoding): # print('CompressResource', encoding) + if encoding == 'UnknownCompression': return inf if inf.startswith(b'decompressed '): inf = inf[16:] return inf diff --git a/macresources/main.py b/macresources/main.py index 8bf7fad..1fd1f8f 100644 --- a/macresources/main.py +++ b/macresources/main.py @@ -129,6 +129,7 @@ class Resource: self.attribs |= attribs self.data = data self.compression_format = None + self.expand_err_ok = False # Maintain a hidden cache of the compressed System 7 data that got loaded self._cache = None @@ -146,8 +147,8 @@ class Resource: def __getattr__(self, attrname): # fear not, this is only for evil System 7 resource compression if attrname == 'data': - if GetEncoding(self._cache) == 'UnknownCompression': - print('Warning: accessing %r %r, which is compressed in an unknown format' % (self.type, self.id)) + if GetEncoding(self._cache) == 'UnknownCompression' and not self.expand_err_ok: + raise ResExpandError('Tried to expand unknown format (%r %r) without setting expand_err_ok' % (self.type, self.id)) self.data = DecompressResource(self._cache) self._cache_hash = hash_mutable(self.data) @@ -170,13 +171,15 @@ class Resource: self._cache = CompressResource(self.data, self.compression_format) self._cache_hash = hash_mutable(self.data) - def _rez_repr(self, expand=False): - # decide now: what raw data will we slap down? + def _rez_repr(self, expand=False): # the Rez file will be annotated for re-compression if self.compression_format: if expand: - if self.compression_format == 'UnknownCompression': + if self.compression_format == 'UnknownCompression': # means I can have no data attribute attribs = ResourceAttrs(self.attribs | 1) # at lease Rez will produce the right file - data = self.data # will throw a warning + if 'data' in self.__dict__: + data = self.data + else: + data = self._cache compression_format = None # no comment else: attribs = ResourceAttrs(self.attribs & ~1) @@ -206,6 +209,9 @@ class Resource: return data, attribs +class ResExpandError(Exception): + pass + def parse_file(from_resfile, fake_header_rsrc=False): """Get an iterator of Resource objects from a binary resource file."""