OLD | NEW |
---|---|
(Empty) | |
1 # Copyright 2016 The LUCI Authors. All rights reserved. | |
2 # Use of this source code is governed under the Apache License, Version 2.0 | |
3 # that can be found in the LICENSE file. | |
4 | |
5 import os | |
6 import struct | |
7 | |
8 from .writer import ArDefaultWriter | |
9 | |
10 def assert_eq(e, a): | |
11 """ | |
12 >>> assert_eq(1, 1) | |
13 >>> assert_eq(1, 2) | |
14 Traceback (most recent call last): | |
15 ... | |
16 AssertionError: 1 (1) != 2 (2) | |
17 >>> assert_eq(1, "1") | |
18 Traceback (most recent call last): | |
19 ... | |
20 AssertionError: 1 (1) != 1 ('1') | |
21 """ | |
22 assert e == a, "%s (%r) != %s (%r)" % (e, e, a, a) | |
23 | |
24 | |
25 class ArDefaultReader(object): | |
26 """Read an ar archive created with default values.""" | |
27 | |
28 # BSD Variant AR file | |
29 | |
30 def __init__(self, ibuf, check=False): | |
31 self.check = check | |
M-A Ruel
2016/06/14 13:26:17
I'd prefer self._check and self._ibuf
mithro
2016/06/16 11:37:11
Obsolete.
| |
32 if self.check: | |
33 try: | |
34 assert False | |
35 raise ValueError('check mode can\'t be used when asserts are disabled') | |
36 except AssertionError: | |
37 pass | |
38 | |
39 self.ibuf = ibuf | |
40 assert self.ibuf.read(8) == "!<arch>\n" | |
41 | |
42 def __iter__(self): | |
43 # We generate the default values because comparing strings is cheaper then | |
44 # parsing them. | |
45 check = self.check | |
46 if check: | |
47 dmodtime = "%-6i" % ArDefaultWriter.DEFAULT_MODTIME | |
48 duid = "%-6i" % ArDefaultWriter.DEFAULT_USER | |
49 dgid = "%-6i" % ArDefaultWriter.DEFAULT_GROUP | |
50 dmode = "%-6i" % ArDefaultWriter.DEFAULT_MODE | |
51 | |
52 while True: | |
53 header = self.ibuf.read(60) | |
54 if not header: | |
55 return | |
56 | |
57 name, modtime, uid, gid, mode, size, magic = struct.unpack( | |
58 "16s 12s 6s 6s 8s 10s 2s", header) | |
59 | |
60 assert name.startswith("#1/"), name | |
61 filename_size = int(name[3:]) | |
62 if check: | |
63 assert_eq(dmodtime, modtime) | |
M-A Ruel
2016/06/14 13:26:16
+2
mithro
2016/06/16 11:37:11
Obsolete.
| |
64 assert_eq(duid, uid) | |
65 assert_eq(dgid, gid) | |
66 assert_eq(dmode, mode) | |
67 data_size = int(size) | |
68 assert_eq("\x60\n", magic) | |
69 | |
70 file_size = data_size - filename_size | |
71 fp = self.ibuf.read(filename_size) | |
72 | |
73 start = self.ibuf.tell() | |
74 yield fp, file_size, self.ibuf | |
75 end = self.ibuf.tell() | |
76 | |
77 read = end - start | |
78 # If the reader didn't touch the input buffer, seek past the file. | |
79 if read == 0: | |
M-A Ruel
2016/06/14 13:26:17
if not read:
| |
80 self.ibuf.seek(file_size, os.SEEK_CUR) | |
81 else: | |
82 assert read == file_size | |
83 | |
84 if data_size % 2 != 0: | |
M-A Ruel
2016/06/14 13:26:17
if data_size % 2:
| |
85 padding = self.ibuf.read(1) | |
86 assert padding == "\n" | |
87 | |
88 | |
89 if __name__ == "__main__": | |
90 import doctest | |
91 doctest.testmod() | |
OLD | NEW |