Skip to content

Commit d4759d2

Browse files
committed
Add context manager methods to APK files.
1 parent 89c0f33 commit d4759d2

File tree

1 file changed

+29
-22
lines changed
  • recipes/android/src/android

1 file changed

+29
-22
lines changed

recipes/android/src/android/apk.py

Lines changed: 29 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,13 @@ def __init__(self, f, name, base, length):
1414
self.name = name
1515
self.f.seek(self.base)
1616

17+
def __enter__(self):
18+
return self
19+
20+
def __exit__(self, _type, value, tb):
21+
self.close()
22+
return False
23+
1724
def read(self, length=None):
1825

1926
maxlength = self.length - self.offset
@@ -24,7 +31,7 @@ def read(self, length=None):
2431
length = maxlength
2532

2633
if length:
27-
rv2 = self.f.read(length)
34+
rv2 = self.f.read(length)
2835
self.offset += len(rv2)
2936
else:
3037
rv2 = ""
@@ -76,7 +83,7 @@ def next(self):
7683
raise StopIteration()
7784

7885
return rv
79-
86+
8087
def flush(self):
8188
return
8289

@@ -93,10 +100,10 @@ def seek(self, offset, whence=0):
93100
offset = self.length
94101

95102
self.offset = offset
96-
103+
97104
if offset < 0:
98105
offset = 0
99-
106+
100107
self.f.seek(offset + self.base)
101108

102109
def tell(self):
@@ -111,64 +118,64 @@ def write(self, s):
111118

112119

113120
class APK(object):
114-
121+
115122
def __init__(self, apk=None, prefix="assets/"):
116123
"""
117124
Opens an apk file, and lets you read the assets out of it.
118-
125+
119126
`apk`
120127
The path to the file to open. If this is None, it defaults to the
121128
apk file we are run out of.
122-
129+
123130
`prefix`
124131
The prefix inside the apk file to read.
125132
"""
126133

127134
if apk is None:
128135
apk = os.environ["ANDROID_APK"]
129136
print "Opening APK %r" % apk
130-
137+
131138
self.apk = apk
132-
139+
133140
self.zf = zipfile.ZipFile(apk, "r")
134141

135142
# A map from unprefixed filename to ZipInfo object.
136143
self.info = { }
137-
144+
138145
for i in self.zf.infolist():
139146
fn = i.filename
140147
if not fn.startswith(prefix):
141148
continue
142-
149+
143150
fn = fn[len(prefix):]
144-
151+
145152
self.info[fn] = i
146-
153+
147154
def list(self):
148155
return sorted(self.info)
149-
156+
150157
def open(self, fn):
151-
158+
152159
if fn not in self.info:
153160
raise IOError("{0} not found in apk.".format(fn))
154-
161+
155162
info = self.info[fn]
156163

157164
if info.compress_type == zipfile.ZIP_STORED:
158-
165+
159166
f = file(self.apk, "rb")
160167
f.seek(info.header_offset)
161-
168+
162169
h = struct.unpack(zipfile.structFileHeader, f.read(zipfile.sizeFileHeader))
163-
164-
offset = (info.header_offset +
170+
171+
offset = (info.header_offset +
165172
zipfile.sizeFileHeader +
166173
h[zipfile._FH_FILENAME_LENGTH] +
167174
h[zipfile._FH_EXTRA_FIELD_LENGTH])
168-
175+
169176
return SubFile(
170177
f,
171-
self.apk,
178+
self.apk,
172179
offset,
173180
info.file_size)
174181

0 commit comments

Comments
 (0)