docs: def transfer(sendContext, receiveContext, chunkSize):
      """ Transfer (large) data from sender to receiver. """
      try:
          chunkSize = receiveContext.chunkSize
      except AttributeError:
          pass
  
      if sendContext is not None and receiveContext is not None:
          with receiveContext as writer:
              # Open reader after writer,
              # so any raised errors will abort write before writer closes.
              with sendContext as reader:
                  checkBefore = None
                  if hasattr(writer, 'skipChunk'):
                      checkBefore = hasattr(reader, 'checkSum')
  
                  while True:
                      if checkBefore is True:
                          (size, checkSum) = reader.checkSum(chunkSize)
  
                          if writer.skipChunk(size, checkSum):
                              reader.seek(size, io.SEEK_CUR)
                              continue
  
                      data = reader.read(chunkSize)
                      if len(data) == 0:
                          break
  
                      if checkBefore is False:
                          checkSum = hashlib.md5(data).hexdigest()
  
                          if writer.skipChunk(len(data), checkSum, data):
                              continue
  
                      writer.write(data)