added function get_file_size and var _file_size to _Stream
authorChristian Herdtweck <christian.herdtweck@intra2net.com>
Wed, 8 Jun 2016 15:46:49 +0000 (17:46 +0200)
committerChristian Herdtweck <christian.herdtweck@intra2net.com>
Wed, 15 Jun 2016 11:18:02 +0000 (13:18 +0200)
deltatar/tarfile.py

index ad52e41..5630761 100644 (file)
@@ -390,6 +390,7 @@ class _Stream:
         self.aes_buf  = b""
         self.exception = None
         self.compresslevel = compresslevel
+        self.bytes_written = 0
 
         try:
             if comptype == "gz":
@@ -554,8 +555,9 @@ class _Stream:
 
     def __write_to_file(self, s):
         '''
-        Writes directly to the fileobj
+        Writes directly to the fileobj; updates self.bytes_written
         '''
+        self.bytes_written += len(s)
         self.fileobj.write(s)
 
     def __enc_write(self, s):
@@ -568,6 +570,31 @@ class _Stream:
             tow = self.encryption.encrypt(s)
         self.__write_to_file(tow)
 
+    def estim_file_size(self):
+        """ estimates size of file if closing it now
+
+        The result may differ greatly from the amount of data sent to write()
+        due to compression, encryption and buffering.
+
+        In tests the result (before calling close()) was up to 12k smaller than
+        the final file size if compression is being used because zlib/bz2
+        compressors do not allow inspection of their buffered data :-(
+
+        Still, we add 8 bytes for gz checksum, one encryption block size if
+        encryption is used and the size of our own buffer
+        """
+        if self.closed:
+            return self.bytes_written
+
+        result = self.bytes_written
+        if self.buf:
+            result += len(self.buf)
+        if self.comptype == 'gz':
+            result += 8   # 2 longs = 8 byte
+        if self.enctype == 'aes':
+            result += self.encryption.bs
+        return result
+
     def close(self, close_fileobj=True):
         """Close the _Stream object. No operation should be
            done on it afterwards.