summaryrefslogtreecommitdiff
path: root/rdiff-backup/rdiff_backup/iterfile.py
diff options
context:
space:
mode:
authorbescoto <bescoto@2b77aa54-bcbc-44c9-a7ec-4f6cf2b41109>2005-11-04 22:41:13 +0000
committerbescoto <bescoto@2b77aa54-bcbc-44c9-a7ec-4f6cf2b41109>2005-11-04 22:41:13 +0000
commit828d9e44d4417ca9ee3831919d6023492805b7a9 (patch)
tree773c464f98092b7fefc1b6b974f6e966f692f3ad /rdiff-backup/rdiff_backup/iterfile.py
parent070e5c4080dac3de8e26a7d5d7314ceb36d32440 (diff)
downloadrdiff-backup-828d9e44d4417ca9ee3831919d6023492805b7a9.tar.gz
Added metadata diffing, and an iterfile hash bugfix
git-svn-id: http://svn.savannah.nongnu.org/svn/rdiff-backup/trunk@669 2b77aa54-bcbc-44c9-a7ec-4f6cf2b41109
Diffstat (limited to 'rdiff-backup/rdiff_backup/iterfile.py')
-rw-r--r--rdiff-backup/rdiff_backup/iterfile.py47
1 files changed, 27 insertions, 20 deletions
diff --git a/rdiff-backup/rdiff_backup/iterfile.py b/rdiff-backup/rdiff_backup/iterfile.py
index 608f251..bed285a 100644
--- a/rdiff-backup/rdiff_backup/iterfile.py
+++ b/rdiff-backup/rdiff_backup/iterfile.py
@@ -44,6 +44,7 @@ class UnwrapFile:
"o" for an object,
"f" for file,
"c" for a continution of a file,
+ "h" for the close value of a file
"e" for an exception, or
None if no more data can be read.
@@ -57,7 +58,7 @@ class UnwrapFile:
assert None, "Header %s is only %d bytes" % (header, len(header))
type, length = header[0], C.str2long(header[1:])
buf = self.file.read(length)
- if type in ("o", "e"): return type, cPickle.loads(buf)
+ if type in ("o", "e", "h"): return type, cPickle.loads(buf)
else:
assert type in ("f", "c")
return type, buf
@@ -82,11 +83,7 @@ class IterWrappingFile(UnwrapFile):
type, data = self._get()
if not type: raise StopIteration
if type == "o" or type == "e": return data
- elif type == "f":
- file = IterVirtualFile(self, data)
- if data: self.currently_in_file = file
- else: self.currently_in_file = None
- return file
+ elif type == "f": return IterVirtualFile(self, data)
else: raise IterFileException("Bad file type %s" % type)
@@ -107,8 +104,10 @@ class IterVirtualFile(UnwrapFile):
"""
UnwrapFile.__init__(self, iwf.file)
self.iwf = iwf
+ iwf.currently_in_file = self
self.buffer = initial_data
self.closed = None
+ if not initial_data: self.set_close_val()
def read(self, length = -1):
"""Read length bytes from the file, updating buffers as necessary"""
@@ -140,15 +139,24 @@ class IterVirtualFile(UnwrapFile):
self.buffer += data
return 1
else:
- self.iwf.currently_in_file = None
+ self.set_close_val()
return None
+ def set_close_val(self):
+ """Read the close value and clear currently_in_file"""
+ assert self.iwf.currently_in_file
+ self.iwf.currently_in_file = None
+ type, object = self.iwf._get()
+ assert type == 'h', type
+ self.close_value = object
+
def close(self):
"""Currently just reads whats left and discards it"""
while self.iwf.currently_in_file:
self.addtobuffer()
self.buffer = ""
self.closed = 1
+ return self.close_value
class FileWrappingIter:
@@ -214,13 +222,16 @@ class FileWrappingIter:
buf = robust.check_common_error(self.read_error_handler,
self.currently_in_file.read,
[Globals.blocksize])
- if buf == "" or buf is None:
- self.currently_in_file.close()
- self.currently_in_file = None
- if buf is None: # error occurred above, encode exception
- prefix_letter = "e"
- buf = cPickle.dumps(self.last_exception, 1)
- total = "".join((prefix_letter, C.long2str(long(len(buf))), buf))
+ if buf is None: # error occurred above, encode exception
+ self.currently_in_file = None
+ excstr = cPickle.dumps(self.last_exception, 1)
+ total = "".join(('e', C.long2str(long(len(excstr))), excstr))
+ else:
+ total = "".join((prefix_letter, C.long2str(long(len(buf))), buf))
+ if buf == "": # end of file
+ cstr = cPickle.dumps(self.currently_in_file.close(), 1)
+ self.currently_in_file = None
+ total += "".join(('h', C.long2str(long(len(cstr))), cstr))
self.array_buf.fromstring(total)
def read_error_handler(self, exc, blocksize):
@@ -386,11 +397,7 @@ class FileToMiscIter(IterWrappingFile):
def get_file(self):
"""Read file object from file"""
type, data = self._get()
- if type == "f":
- file = IterVirtualFile(self, data)
- if data: self.currently_in_file = file
- else: self.currently_in_file = None
- return file
+ if type == "f": return IterVirtualFile(self, data)
assert type == "e", "Expected type e, got %s" % (type,)
assert isinstance(data, Exception)
return ErrorFile(data)
@@ -411,7 +418,7 @@ class FileToMiscIter(IterWrappingFile):
type, length = self.buf[0], C.str2long(self.buf[1:8])
data = self.buf[8:8+length]
self.buf = self.buf[8+length:]
- if type in "oer": return type, cPickle.loads(data)
+ if type in "oerh": return type, cPickle.loads(data)
else: return type, data