This commit was manufactured by cvs2svn to create tag
[python/dscho.git] / Mac / Lib / applesingle.py
blobbee3318821116a6214c5d1fc05bd3873c7b815b5
1 # applesingle - a module to decode AppleSingle files
2 import struct
3 import MacOS
4 import sys
6 Error="applesingle.Error"
8 verbose=0
10 # File header format: magic, version, unused, number of entries
11 AS_HEADER_FORMAT="ll16sh"
12 AS_HEADER_LENGTH=26
13 # The flag words for AppleSingle
14 AS_MAGIC=0x00051600
15 AS_VERSION=0x00020000
17 # Entry header format: id, offset, length
18 AS_ENTRY_FORMAT="lll"
19 AS_ENTRY_LENGTH=12
21 # The id values
22 AS_DATAFORK=1
23 AS_RESOURCEFORK=2
24 AS_IGNORE=(3,4,5,6,8,9,10,11,12,13,14,15)
26 def decode(input, output, resonly=0):
27 if type(input) == type(''):
28 input = open(input, 'rb')
29 # Should we also test for FSSpecs or FSRefs?
30 header = input.read(AS_HEADER_LENGTH)
31 print `header`
32 try:
33 magic, version, dummy, nentry = struct.unpack(AS_HEADER_FORMAT, header)
34 except ValueError, arg:
35 raise Error, "Unpack header error: %s"%arg
36 if verbose:
37 print 'Magic: 0x%8.8x'%magic
38 print 'Version: 0x%8.8x'%version
39 print 'Entries: %d'%nentry
40 if magic != AS_MAGIC:
41 raise Error, 'Unknown AppleSingle magic number 0x%8.8x'%magic
42 if version != AS_VERSION:
43 raise Error, 'Unknown AppleSingle version number 0x%8.8x'%version
44 if nentry <= 0:
45 raise Error, "AppleSingle file contains no forks"
46 headers = [input.read(AS_ENTRY_LENGTH) for i in range(nentry)]
47 didwork = 0
48 for hdr in headers:
49 try:
50 id, offset, length = struct.unpack(AS_ENTRY_FORMAT, hdr)
51 except ValueError, arg:
52 raise Error, "Unpack entry error: %s"%arg
53 if verbose:
54 print 'Fork %d, offset %d, length %d'%(id, offset, length)
55 input.seek(offset)
56 if length == 0:
57 data = ''
58 else:
59 data = input.read(length)
60 if len(data) != length:
61 raise Error, 'Short read: expected %d bytes got %d'%(length, len(data))
62 if id == AS_DATAFORK:
63 if verbose:
64 print ' (data fork)'
65 if not resonly:
66 didwork = 1
67 fp = open(output, 'wb')
68 fp.write(data)
69 fp.close()
70 elif id == AS_RESOURCEFORK:
71 didwork = 1
72 if verbose:
73 print ' (resource fork)'
74 if resonly:
75 fp = open(output, 'wb')
76 else:
77 fp = MacOS.openrf(output, 'wb')
78 fp.write(data)
79 fp.close()
80 elif id in AS_IGNORE:
81 if verbose:
82 print ' (ignored)'
83 else:
84 raise Error, 'Unknown fork type %d'%id
85 if not didwork:
86 raise Error, 'No useful forks found'
88 def _test():
89 if len(sys.argv) < 3 or sys.argv[1] == '-r' and len(sys.argv) != 4:
90 print 'Usage: applesingle.py [-r] applesinglefile decodedfile'
91 sys.exit(1)
92 if sys.argv[1] == '-r':
93 resonly = 1
94 del sys.argv[1]
95 else:
96 resonly = 0
97 decode(sys.argv[1], sys.argv[2], resonly=resonly)
99 if __name__ == '__main__':
100 _test()