Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(768)

Unified Diff: client/libs/ar/reader.py

Issue 2049523004: luci-py: Tools for working with BSD style ar archives. (Closed) Base URL: https://github.com/luci/luci-py.git@master
Patch Set: Fixing for Maruel's review. Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: client/libs/ar/reader.py
diff --git a/client/libs/ar/reader.py b/client/libs/ar/reader.py
new file mode 100644
index 0000000000000000000000000000000000000000..4e0a3f803c86368d37c1f015c846240ef8d3c71a
--- /dev/null
+++ b/client/libs/ar/reader.py
@@ -0,0 +1,91 @@
+# Copyright 2016 The LUCI Authors. All rights reserved.
+# Use of this source code is governed under the Apache License, Version 2.0
+# that can be found in the LICENSE file.
+
+import os
+import struct
+
+from .writer import ArDefaultWriter
+
+def assert_eq(e, a):
+ """
+ >>> assert_eq(1, 1)
+ >>> assert_eq(1, 2)
+ Traceback (most recent call last):
+ ...
+ AssertionError: 1 (1) != 2 (2)
+ >>> assert_eq(1, "1")
+ Traceback (most recent call last):
+ ...
+ AssertionError: 1 (1) != 1 ('1')
+ """
+ assert e == a, "%s (%r) != %s (%r)" % (e, e, a, a)
+
+
+class ArDefaultReader(object):
+ """Read an ar archive created with default values."""
+
+ # BSD Variant AR file
+
+ def __init__(self, ibuf, check=False):
+ 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.
+ if self.check:
+ try:
+ assert False
+ raise ValueError('check mode can\'t be used when asserts are disabled')
+ except AssertionError:
+ pass
+
+ self.ibuf = ibuf
+ assert self.ibuf.read(8) == "!<arch>\n"
+
+ def __iter__(self):
+ # We generate the default values because comparing strings is cheaper then
+ # parsing them.
+ check = self.check
+ if check:
+ dmodtime = "%-6i" % ArDefaultWriter.DEFAULT_MODTIME
+ duid = "%-6i" % ArDefaultWriter.DEFAULT_USER
+ dgid = "%-6i" % ArDefaultWriter.DEFAULT_GROUP
+ dmode = "%-6i" % ArDefaultWriter.DEFAULT_MODE
+
+ while True:
+ header = self.ibuf.read(60)
+ if not header:
+ return
+
+ name, modtime, uid, gid, mode, size, magic = struct.unpack(
+ "16s 12s 6s 6s 8s 10s 2s", header)
+
+ assert name.startswith("#1/"), name
+ filename_size = int(name[3:])
+ if check:
+ assert_eq(dmodtime, modtime)
M-A Ruel 2016/06/14 13:26:16 +2
mithro 2016/06/16 11:37:11 Obsolete.
+ assert_eq(duid, uid)
+ assert_eq(dgid, gid)
+ assert_eq(dmode, mode)
+ data_size = int(size)
+ assert_eq("\x60\n", magic)
+
+ file_size = data_size - filename_size
+ fp = self.ibuf.read(filename_size)
+
+ start = self.ibuf.tell()
+ yield fp, file_size, self.ibuf
+ end = self.ibuf.tell()
+
+ read = end - start
+ # If the reader didn't touch the input buffer, seek past the file.
+ if read == 0:
M-A Ruel 2016/06/14 13:26:17 if not read:
+ self.ibuf.seek(file_size, os.SEEK_CUR)
+ else:
+ assert read == file_size
+
+ if data_size % 2 != 0:
M-A Ruel 2016/06/14 13:26:17 if data_size % 2:
+ padding = self.ibuf.read(1)
+ assert padding == "\n"
+
+
+if __name__ == "__main__":
+ import doctest
+ doctest.testmod()

Powered by Google App Engine
This is Rietveld 408576698