def rsyncdelta(bufstream, remotesignatures, blocksize=4096):
remote_weak, remote_strong = remotesignatures
match = True
matchblock = -1
deltaqueue = collections.deque()
while True:
if match and bufstream is not None:
window = collections.deque(bytes(bufstream.read(blocksize)))
checksum, a, b = weakchecksum(window)
try:
matchblock = remote_weak.index(checksum, matchblock + 1)
stronghash = hashlib.md5(bytes(window)).hexdigest()
if remote_strong[matchblock] == stronghash:
match = True
deltaqueue.append(matchblock)
if bufstream.closed:
break
continue
except ValueError:
match = False
try:
if bufstream:
newbyte = ord(bufstream.read(1))
window.append(newbyte)
except TypeError:
newbyte = 0
tailsize = bufstream.tell() % blocksize
bufstream = None
if bufstream is None and len(window) <= tailsize:
deltaqueue.append(window)
break
oldbyte = window.popleft()
checksum, a, b = rollingchecksum(oldbyte, newbyte, a, b, blocksize)
#assert checksum == weakchecksum(window)[0]
try:
deltaqueue[-1].append(oldbyte)
except (AttributeError, IndexError):
deltaqueue.append([oldbyte])
deltastructure = [blocksize]
for element in deltaqueue:
if isinstance(element, int):
deltastructure.append(element)
elif element:
deltastructure.append(bytes(element))
return deltastructure