Minimal module to decode AppleSingle files (the way resource files are

stored in the CVS repository). It can either decode resource/data forks
in the standard Mac way or decode only the resource fork but store
the result in the data fork (the MacOSX preferred way). Finder info
and all other stuff is ignored.
This commit is contained in:
Jack Jansen 2001-09-09 00:35:19 +00:00
parent f7adf2f473
commit a48d4eaddf
1 changed files with 101 additions and 0 deletions

101
Mac/Lib/applesingle.py Normal file
View File

@ -0,0 +1,101 @@
# applesingle - a module to decode AppleSingle files
import struct
import MacOS
import sys
Error="applesingle.Error"
verbose=0
# File header format: magic, version, unused, number of entries
AS_HEADER_FORMAT="ll16sh"
AS_HEADER_LENGTH=26
# The flag words for AppleSingle
AS_MAGIC=0x00051600
AS_VERSION=0x00020000
# Entry header format: id, offset, length
AS_ENTRY_FORMAT="lll"
AS_ENTRY_LENGTH=12
# The id values
AS_DATAFORK=1
AS_RESOURCEFORK=2
AS_IGNORE=(3,4,5,6,8,9,10,11,12,13,14,15)
def decode(input, output, resonly=0):
if type(input) == type(''):
input = open(input, 'rb')
# Should we also test for FSSpecs or FSRefs?
header = input.read(AS_HEADER_LENGTH)
print `header`
try:
magic, version, dummy, nentry = struct.unpack(AS_HEADER_FORMAT, header)
except ValueError, arg:
raise Error, "Unpack header error: %s"%arg
if verbose:
print 'Magic: 0x%8.8x'%magic
print 'Version: 0x%8.8x'%version
print 'Entries: %d'%nentry
if magic != AS_MAGIC:
raise Error, 'Unknown AppleSingle magic number 0x%8.8x'%magic
if version != AS_VERSION:
raise Error, 'Unknown AppleSingle version number 0x%8.8x'%version
if nentry <= 0:
raise Error, "AppleSingle file contains no forks"
headers = [input.read(AS_ENTRY_LENGTH) for i in range(nentry)]
didwork = 0
for hdr in headers:
try:
id, offset, length = struct.unpack(AS_ENTRY_FORMAT, hdr)
except ValueError, arg:
raise Error, "Unpack entry error: %s"%arg
if verbose:
print 'Fork %d, offset %d, length %d'%(id, offset, length)
input.seek(offset)
if length == 0:
data = ''
else:
data = input.read(length)
if len(data) != length:
raise Error, 'Short read: expected %d bytes got %d'%(length, len(data))
if id == AS_DATAFORK:
if verbose:
print ' (data fork)'
if not resonly:
didwork = 1
fp = open(output, 'wb')
fp.write(data)
fp.close()
elif id == AS_RESOURCEFORK:
didwork = 1
if verbose:
print ' (resource fork)'
if resonly:
fp = open(output, 'wb')
else:
fp = MacOS.openrf(output, 'wb')
fp.write(data)
fp.close()
elif id in AS_IGNORE:
if verbose:
print ' (ignored)'
else:
raise Error, 'Unknown fork type %d'%id
if not didwork:
raise Error, 'No useful forks found'
def _test():
if len(sys.argv) < 3 or sys.argv[1] == '-r' and len(sys.argv) != 4:
print 'Usage: applesingle.py [-r] applesinglefile decodedfile'
sys.exit(1)
if sys.argv[1] == '-r':
resonly = 1
del sys.argv[1]
else:
resonly = 0
decode(sys.argv[1], sys.argv[2], resonly=resonly)
if __name__ == '__main__':
_test()