def generate_signature(fp, updatefunc): fp.seek(0) # Magic updatefunc(fp.read(4)) # index_offset updatefunc(fp.read(4)) # file size updatefunc(fp.read(8)) # number of signatures num_sigs = fp.read(4) updatefunc(num_sigs) num_sigs = unpackint(num_sigs) for i in range(num_sigs): # signature algo updatefunc(fp.read(4)) # signature size sigsize = fp.read(4) updatefunc(sigsize) sigsize = unpackint(sigsize) # Read this, but don't update the signature with it fp.read(sigsize) # Read the rest of the file for block in read_file(fp): updatefunc(block)
def add(self, path, name=None, fileobj=None, mode=None): """Adds `path` compressed with BZ2 to this MAR file. If `name` is set, the file is named with `name` in the MAR, otherwise use the normalized version of `path`. If `fileobj` is set, file data is read from it, otherwise the file located at `path` will be opened and read. If `flags` is set, it will be used as the permission flags in the MAR, otherwise the permissions of `path` will be used. """ if self.mode != "w": raise ValueError("File not opened for writing") if os.path.isdir(path): self.add_dir(path) return info = MarInfo() info.name = name or os.path.normpath(path) info.size = 0 if not fileobj: info.flags = os.stat(path).st_mode & 0o777 else: info.flags = mode info._offset = self.index_offset if not fileobj: f = open(path, 'rb') else: f = fileobj comp = bz2.BZ2Compressor(9) self.fileobj.seek(self.index_offset) for block in read_file(f, 512 * 1024): block = comp.compress(block) info.size += len(block) self.fileobj.write(block) block = comp.flush() info.size += len(block) self.fileobj.write(block) self.index_offset += info.size self.rewrite_index = True self.members.append(info)
def add(self, path, name=None, fileobj=None, flags=None): """Adds `path` to this MAR file. If `name` is set, the file is named with `name` in the MAR, otherwise use the normalized version of `path`. If `fileobj` is set, file data is read from it, otherwise the file located at `path` will be opened and read. If `flags` is set, it will be used as the permission flags in the MAR, otherwise the permissions of `path` will be used. """ if self.mode != "w": raise ValueError("File not opened for writing") # If path refers to a directory, add all the files inside of it if os.path.isdir(path): self.add_dir(path) return info = MarInfo() info._offset = self.index_offset info.size = 0 if not fileobj: fileobj = open(path, 'rb') info.flags = flags or os.stat(path).st_mode & 0o777 info.name = name or os.path.normpath(path) else: assert flags info.flags = flags info.name = name or path self.fileobj.seek(self.index_offset) for block in read_file(fileobj): self.fileobj.write(block) info.size += len(block) # Shift our index, and mark that we have to re-write it on close self.index_offset += info.size self.rewrite_index = True self.members.append(info)
def test_read_file(): data = [] for block in read_file(open(__file__, 'rb')): data.append(block) assert b''.join(data) == open(__file__, 'rb').read()