ยปCore Development>Code coverage>Lib/plat-mac/applesingle.py

Python code coverage for Lib/plat-mac/applesingle.py

#countcontent
1n/ar"""Routines to decode AppleSingle files
2n/a"""
3n/a
4n/afrom warnings import warnpy3k
5n/awarnpy3k("In 3.x, the applesingle module is removed.", stacklevel=2)
6n/a
7n/aimport struct
8n/aimport sys
9n/atry:
10n/a import MacOS
11n/a import Carbon.File
12n/aexcept:
13n/a class MacOS:
14n/a def openrf(path, mode):
15n/a return open(path + '.rsrc', mode)
16n/a openrf = classmethod(openrf)
17n/a class Carbon:
18n/a class File:
19n/a class FSSpec:
20n/a pass
21n/a class FSRef:
22n/a pass
23n/a class Alias:
24n/a pass
25n/a
26n/a# all of the errors in this module are really errors in the input
27n/a# so I think it should test positive against ValueError.
28n/aclass Error(ValueError):
29n/a pass
30n/a
31n/a# File header format: magic, version, unused, number of entries
32n/aAS_HEADER_FORMAT=">LL16sh"
33n/aAS_HEADER_LENGTH=26
34n/a# The flag words for AppleSingle
35n/aAS_MAGIC=0x00051600
36n/aAS_VERSION=0x00020000
37n/a
38n/a# Entry header format: id, offset, length
39n/aAS_ENTRY_FORMAT=">lll"
40n/aAS_ENTRY_LENGTH=12
41n/a
42n/a# The id values
43n/aAS_DATAFORK=1
44n/aAS_RESOURCEFORK=2
45n/aAS_IGNORE=(3,4,5,6,8,9,10,11,12,13,14,15)
46n/a
47n/aclass AppleSingle(object):
48n/a datafork = None
49n/a resourcefork = None
50n/a
51n/a def __init__(self, fileobj, verbose=False):
52n/a header = fileobj.read(AS_HEADER_LENGTH)
53n/a try:
54n/a magic, version, ig, nentry = struct.unpack(AS_HEADER_FORMAT, header)
55n/a except ValueError, arg:
56n/a raise Error, "Unpack header error: %s" % (arg,)
57n/a if verbose:
58n/a print 'Magic: 0x%8.8x' % (magic,)
59n/a print 'Version: 0x%8.8x' % (version,)
60n/a print 'Entries: %d' % (nentry,)
61n/a if magic != AS_MAGIC:
62n/a raise Error, "Unknown AppleSingle magic number 0x%8.8x" % (magic,)
63n/a if version != AS_VERSION:
64n/a raise Error, "Unknown AppleSingle version number 0x%8.8x" % (version,)
65n/a if nentry <= 0:
66n/a raise Error, "AppleSingle file contains no forks"
67n/a headers = [fileobj.read(AS_ENTRY_LENGTH) for i in xrange(nentry)]
68n/a self.forks = []
69n/a for hdr in headers:
70n/a try:
71n/a restype, offset, length = struct.unpack(AS_ENTRY_FORMAT, hdr)
72n/a except ValueError, arg:
73n/a raise Error, "Unpack entry error: %s" % (arg,)
74n/a if verbose:
75n/a print "Fork %d, offset %d, length %d" % (restype, offset, length)
76n/a fileobj.seek(offset)
77n/a data = fileobj.read(length)
78n/a if len(data) != length:
79n/a raise Error, "Short read: expected %d bytes got %d" % (length, len(data))
80n/a self.forks.append((restype, data))
81n/a if restype == AS_DATAFORK:
82n/a self.datafork = data
83n/a elif restype == AS_RESOURCEFORK:
84n/a self.resourcefork = data
85n/a
86n/a def tofile(self, path, resonly=False):
87n/a outfile = open(path, 'wb')
88n/a data = False
89n/a if resonly:
90n/a if self.resourcefork is None:
91n/a raise Error, "No resource fork found"
92n/a fp = open(path, 'wb')
93n/a fp.write(self.resourcefork)
94n/a fp.close()
95n/a elif (self.resourcefork is None and self.datafork is None):
96n/a raise Error, "No useful forks found"
97n/a else:
98n/a if self.datafork is not None:
99n/a fp = open(path, 'wb')
100n/a fp.write(self.datafork)
101n/a fp.close()
102n/a if self.resourcefork is not None:
103n/a fp = MacOS.openrf(path, '*wb')
104n/a fp.write(self.resourcefork)
105n/a fp.close()
106n/a
107n/adef decode(infile, outpath, resonly=False, verbose=False):
108n/a """decode(infile, outpath [, resonly=False, verbose=False])
109n/a
110n/a Creates a decoded file from an AppleSingle encoded file.
111n/a If resonly is True, then it will create a regular file at
112n/a outpath containing only the resource fork from infile.
113n/a Otherwise it will create an AppleDouble file at outpath
114n/a with the data and resource forks from infile. On platforms
115n/a without the MacOS module, it will create inpath and inpath+'.rsrc'
116n/a with the data and resource forks respectively.
117n/a
118n/a """
119n/a if not hasattr(infile, 'read'):
120n/a if isinstance(infile, Carbon.File.Alias):
121n/a infile = infile.ResolveAlias()[0]
122n/a
123n/a if hasattr(Carbon.File, "FSSpec"):
124n/a if isinstance(infile, (Carbon.File.FSSpec, Carbon.File.FSRef)):
125n/a infile = infile.as_pathname()
126n/a else:
127n/a if isinstance(infile, Carbon.File.FSRef):
128n/a infile = infile.as_pathname()
129n/a infile = open(infile, 'rb')
130n/a
131n/a asfile = AppleSingle(infile, verbose=verbose)
132n/a asfile.tofile(outpath, resonly=resonly)
133n/a
134n/adef _test():
135n/a if len(sys.argv) < 3 or sys.argv[1] == '-r' and len(sys.argv) != 4:
136n/a print 'Usage: applesingle.py [-r] applesinglefile decodedfile'
137n/a sys.exit(1)
138n/a if sys.argv[1] == '-r':
139n/a resonly = True
140n/a del sys.argv[1]
141n/a else:
142n/a resonly = False
143n/a decode(sys.argv[1], sys.argv[2], resonly=resonly)
144n/a
145n/aif __name__ == '__main__':
146n/a _test()