mirror of
https://github.com/dgelessus/python-rsrcfork.git
synced 2025-07-04 07:23:54 +00:00
Compare commits
6 Commits
Author | SHA1 | Date | |
---|---|---|---|
bc4bad678a | |||
ee796d0eb1 | |||
3d802c570f | |||
f6e424674d | |||
5dbec5d905 | |||
c207703c9f |
15
README.rst
15
README.rst
@ -85,7 +85,8 @@ Command-line interface
|
|||||||
$ python3 -m rsrcfork /Users/Shared/Test.textClipping "'TEXT' (256)"
|
$ python3 -m rsrcfork /Users/Shared/Test.textClipping "'TEXT' (256)"
|
||||||
Resource 'TEXT' (256), unnamed, no attributes, 17 bytes:
|
Resource 'TEXT' (256), unnamed, no attributes, 17 bytes:
|
||||||
00000000 48 65 72 65 20 69 73 20 73 6f 6d 65 20 74 65 78 |Here is some tex|
|
00000000 48 65 72 65 20 69 73 20 73 6f 6d 65 20 74 65 78 |Here is some tex|
|
||||||
00000010 74 |t |
|
00000010 74 |t|
|
||||||
|
00000011
|
||||||
|
|
||||||
|
|
||||||
Limitations
|
Limitations
|
||||||
@ -138,6 +139,18 @@ __ https://archive.fo/
|
|||||||
Changelog
|
Changelog
|
||||||
---------
|
---------
|
||||||
|
|
||||||
|
Version 1.1.2
|
||||||
|
`````````````
|
||||||
|
|
||||||
|
* Added support for the resource file attributes "Resources Locked" and "Printer Driver MultiFinder Compatible" from ResEdit.
|
||||||
|
* Added more dummy constants for resource attributes with unknown meaning, so that resource files containing such attributes can be loaded without errors.
|
||||||
|
|
||||||
|
Version 1.1.1
|
||||||
|
`````````````
|
||||||
|
|
||||||
|
* Fixed overflow issue with empty resource files or empty resource type entries
|
||||||
|
* Changed ``_hexdump`` to behave more like ``hexdump -C``
|
||||||
|
|
||||||
Version 1.1.0
|
Version 1.1.0
|
||||||
`````````````
|
`````````````
|
||||||
|
|
||||||
|
24
rsrcfork.py
24
rsrcfork.py
@ -22,7 +22,7 @@ __all__ = [
|
|||||||
"open",
|
"open",
|
||||||
]
|
]
|
||||||
|
|
||||||
__version__ = "1.1.0"
|
__version__ = "1.1.2"
|
||||||
|
|
||||||
# Translation table to replace ASCII non-printable characters with periods.
|
# Translation table to replace ASCII non-printable characters with periods.
|
||||||
_TRANSLATE_NONPRINTABLES = {k: "." for k in [*range(0x20), 0x7f]}
|
_TRANSLATE_NONPRINTABLES = {k: "." for k in [*range(0x20), 0x7f]}
|
||||||
@ -79,6 +79,14 @@ STRUCT_RESOURCE_NAME_HEADER = struct.Struct(">B")
|
|||||||
class ResourceFileAttrs(enum.Flag):
|
class ResourceFileAttrs(enum.Flag):
|
||||||
"""Resource file attribute flags. The descriptions for these flags are taken from comments on the map*Bit and map* enum constants in <CarbonCore/Resources.h>."""
|
"""Resource file attribute flags. The descriptions for these flags are taken from comments on the map*Bit and map* enum constants in <CarbonCore/Resources.h>."""
|
||||||
|
|
||||||
|
mapResourcesLocked = 32768 # "Resources Locked" (undocumented, but available as a checkbox in ResEdit)
|
||||||
|
_UNKNOWN_16384 = 16384
|
||||||
|
_UNKNOWN_8192 = 8192
|
||||||
|
_UNKNOWN_4096 = 4096
|
||||||
|
_UNKNOWN_2048 = 2048
|
||||||
|
_UNKNOWN_1024 = 1024
|
||||||
|
_UNKNOWN_512 = 512
|
||||||
|
mapPrinterDriverMultiFinderCompatible = 256 # "Printer Driver MultiFinder Compatible" (undocumented, but available as a checkbox in ResEdit)
|
||||||
mapReadOnly = 128 # "is this file read-only?", "Resource file read-only"
|
mapReadOnly = 128 # "is this file read-only?", "Resource file read-only"
|
||||||
mapCompact = 64 # "Is a compact necessary?", "Compact resource file"
|
mapCompact = 64 # "Is a compact necessary?", "Compact resource file"
|
||||||
mapChanged = 32 # "Is it necessary to write map?", "Write map out at update"
|
mapChanged = 32 # "Is it necessary to write map?", "Write map out at update"
|
||||||
@ -345,14 +353,16 @@ class ResourceFile(collections.abc.Mapping):
|
|||||||
self._reference_counts: typing.MutableMapping[bytes, int] = collections.OrderedDict()
|
self._reference_counts: typing.MutableMapping[bytes, int] = collections.OrderedDict()
|
||||||
|
|
||||||
(type_list_length_m1,) = self._stream_unpack(STRUCT_RESOURCE_TYPE_LIST_HEADER)
|
(type_list_length_m1,) = self._stream_unpack(STRUCT_RESOURCE_TYPE_LIST_HEADER)
|
||||||
|
type_list_length = (type_list_length_m1 + 1) % 0x10000
|
||||||
|
|
||||||
for _ in range(type_list_length_m1 + 1):
|
for _ in range(type_list_length):
|
||||||
(
|
(
|
||||||
resource_type,
|
resource_type,
|
||||||
count_m1,
|
count_m1,
|
||||||
reflist_offset,
|
reflist_offset,
|
||||||
) = self._stream_unpack(STRUCT_RESOURCE_TYPE)
|
) = self._stream_unpack(STRUCT_RESOURCE_TYPE)
|
||||||
self._reference_counts[resource_type] = count_m1 + 1
|
count = (count_m1 + 1) % 0x10000
|
||||||
|
self._reference_counts[resource_type] = count
|
||||||
|
|
||||||
def _read_all_references(self):
|
def _read_all_references(self):
|
||||||
"""Read all resource references, starting at the current stream position."""
|
"""Read all resource references, starting at the current stream position."""
|
||||||
@ -575,7 +585,10 @@ def _hexdump(data: bytes):
|
|||||||
line = data[i:i + 16]
|
line = data[i:i + 16]
|
||||||
line_hex = " ".join(f"{byte:02x}" for byte in line)
|
line_hex = " ".join(f"{byte:02x}" for byte in line)
|
||||||
line_char = line.decode("MacRoman").translate(_TRANSLATE_NONPRINTABLES)
|
line_char = line.decode("MacRoman").translate(_TRANSLATE_NONPRINTABLES)
|
||||||
print(f"{i:08x} {line_hex:<{16*2+15}} |{line_char:<16}|")
|
print(f"{i:08x} {line_hex:<{16*2+15}} |{line_char}|")
|
||||||
|
|
||||||
|
if data:
|
||||||
|
print(f"{len(data):08x}")
|
||||||
|
|
||||||
def _raw_hexdump(data: bytes):
|
def _raw_hexdump(data: bytes):
|
||||||
for i in range(0, len(data), 16):
|
for i in range(0, len(data), 16):
|
||||||
@ -745,6 +758,7 @@ def main(args: typing.Sequence[str]):
|
|||||||
else:
|
else:
|
||||||
print("No file attributes")
|
print("No file attributes")
|
||||||
|
|
||||||
|
if len(rf) > 0:
|
||||||
print(f"{len(rf)} resource types:")
|
print(f"{len(rf)} resource types:")
|
||||||
for typecode, resources in rf.items():
|
for typecode, resources in rf.items():
|
||||||
restype = _bytes_escape(typecode, quote="'")
|
restype = _bytes_escape(typecode, quote="'")
|
||||||
@ -764,6 +778,8 @@ def main(args: typing.Sequence[str]):
|
|||||||
|
|
||||||
print(f"({resid}), {name}, {attrdesc}, {len(res.data)} bytes")
|
print(f"({resid}), {name}, {attrdesc}, {len(res.data)} bytes")
|
||||||
print()
|
print()
|
||||||
|
else:
|
||||||
|
print("No resource types (empty resource file)")
|
||||||
|
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
|
||||||
|
3
setup.py
3
setup.py
@ -7,7 +7,7 @@ with open("README.rst", "r", encoding="utf-8") as f:
|
|||||||
|
|
||||||
setuptools.setup(
|
setuptools.setup(
|
||||||
name="rsrcfork",
|
name="rsrcfork",
|
||||||
version="1.1.0",
|
version="1.1.2",
|
||||||
description="A pure Python library for reading old Macintosh resource manager data",
|
description="A pure Python library for reading old Macintosh resource manager data",
|
||||||
long_description=long_description,
|
long_description=long_description,
|
||||||
url="https://github.com/dgelessus/python-rsrcfork",
|
url="https://github.com/dgelessus/python-rsrcfork",
|
||||||
@ -26,5 +26,6 @@ setuptools.setup(
|
|||||||
"Programming Language :: Python :: 3.6",
|
"Programming Language :: Python :: 3.6",
|
||||||
],
|
],
|
||||||
keywords="rsrc fork resource manager macintosh mac macos",
|
keywords="rsrc fork resource manager macintosh mac macos",
|
||||||
|
python_requires=">=3.6",
|
||||||
py_modules=["rsrcfork"],
|
py_modules=["rsrcfork"],
|
||||||
)
|
)
|
||||||
|
Reference in New Issue
Block a user