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

Unified Diff: client/libs/ar/writer.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: Removing the hashbang line. 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
« client/libs/ar/reader.py ('K') | « client/libs/ar/reader.py ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: client/libs/ar/writer.py
diff --git a/client/libs/ar/writer.py b/client/libs/ar/writer.py
new file mode 100644
index 0000000000000000000000000000000000000000..19c10f6b1c0dee778f0efdb666783ad4a1178103
--- /dev/null
+++ b/client/libs/ar/writer.py
@@ -0,0 +1,109 @@
+# 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 shutil
+
+
+class ArWriter(object):
+ """Write an ar archive to the given output buffer."""
+
+ # Mode sentinels
+ MODE_HEADER = []
+ MODE_CONTENTS = []
+
+ def __init__(self, obuf):
+ self.obuf = obuf
+ self.obuf.write("!<arch>\n")
+ self.mode = ArWriter.MODE_HEADER
+ self.needspadding = False
+ self.bytesrequired = 0
+
+ def header(self, fp, size, modtime, ownerid, groupid, filemod):
+ """Write a file information to the archive."""
+ assert self.mode == ArWriter.MODE_HEADER
+ assert self.bytesrequired == 0
+
+ # File name, 16 bytes
+ self.obuf.write("#1/%-13s" % str(len(fp)))
M-A Ruel 2016/06/09 21:50:44 single quotes everywhere
mithro 2016/06/14 12:15:55 Done.
+ # Modtime, 12 bytes
+ self.obuf.write("%-12i" % modtime)
+ # Owner ID, 6 bytes
+ self.obuf.write("%-6i" % ownerid)
+ # Group ID, 6 bytes
+ self.obuf.write("%-6i" % groupid)
+ # File mode, 8 bytes
+ self.obuf.write("%-8o" % filemod)
+
+ datasize = size+len(fp)
+ # File size, 10 bytes
+ self.obuf.write("%-10s" % datasize)
+ # File magic, 2 bytes
+ self.obuf.write("\x60\n")
+
+ # Filename - BSD variant
+ self.obuf.write(fp)
+
+ self.mode = ArWriter.MODE_CONTENTS
+ self.bytesrequired = size
+ self.needspadding = datasize % 2 != 0
+
+ def _write(self, ibuf=None, s=None):
+ assert self.mode == ArWriter.MODE_CONTENTS
+ assert ibuf is not None or s is not None
+
+ if ibuf is not None:
+ start = ibuf.tell()
+ shutil.copyfileobj(ibuf, self.obuf)
+ end = ibuf.tell()
+ self.bytesrequired -= end-start
+
+ if s is not None:
+ self.obuf.write(s)
+ self.bytesrequired -= len(s)
+
+ if self.bytesrequired == 0:
+ if self.needspadding:
+ self.obuf.write("\n")
+ self.mode = ArWriter.MODE_HEADER
+
+ def write(self, ibuf_or_str):
+ """Write the file body to the archive."""
+ try:
+ self._write(ibuf=ibuf_or_str)
+ except AttributeError:
M-A Ruel 2016/06/09 21:50:44 ?
mithro 2016/06/14 12:15:55 Rather than trying to check if ibuf_or_str will wo
+ self._write(s=ibuf_or_str)
+
+ def close(self):
+ """Close the archive. Will close the output buffer."""
+ assert self.bytesrequired == 0
+ assert self.mode == ArWriter.MODE_HEADER
+ self.obuf.close()
+
+
+class ArDefaultWriter(ArWriter):
+ """Write an ar archive using defaults to the given output buffer.
+
+ Only a file's name and content are needed to create the archive, all of the
+ modification time, user, group and mode information will be set to default
+ values. This means that you don't need to perform an expensive stat the file.
+ """
+ DEFAULT_MODTIME = 1447140471
+ DEFAULT_USER = 1000
+ DEFAULT_GROUP = 1000
+ DEFAULT_MODE = 0100640 # 100640 -- Octal
+
+ def header(self, name, size,
+ modtime=None, ownerid=None, groupid=None, filemod=None):
+ assert modtime is None
+ assert ownerid is None
+ assert groupid is None
+ assert filemod is None
+ ArWriter.header(
+ self, name, size,
+ self.DEFAULT_MODTIME, self.DEFAULT_USER, self.DEFAULT_GROUP,
+ self.DEFAULT_MODE)
+
+ def add(self, name, data):
+ self.header(name, len(data))
+ self._write(s=data)
« client/libs/ar/reader.py ('K') | « client/libs/ar/reader.py ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698