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