patchDelta function

Uint8List patchDelta(
  1. Uint8List base,
  2. Uint8List delta
)

Implementation

Uint8List patchDelta(Uint8List base, Uint8List delta) {
  var copyLength = 0;
  var rvOffset = 0;

  var header = DeltaHeader.decode(delta);
  var offset = header.offset;

  // assert the size of the base buffer
  if (header.baseBufferSize != base.length) {
    throw Exception('Invalid base buffer length in header');
  }

  // pre allocate buffer to hold the results
  var rv = Uint8List(header.targetBufferSize);

  // start patching
  while (offset < delta.length) {
    var opcode = delta[offset++];
    if (_isCopyFromSrc(opcode)) {
      // copy instruction (copy bytes from base buffer to target buffer)
      var baseOffset = 0;
      copyLength = 0;

      // the state of the next bits will tell us information we need
      // to perform the copy
      // first we get the offset in the source buffer where
      // the copy will start
      if (opcode & 0x01 != 0) baseOffset = delta[offset++];
      if (opcode & 0x02 != 0) baseOffset |= delta[offset++] << 8;
      if (opcode & 0x04 != 0) baseOffset |= delta[offset++] << 16;
      if (opcode & 0x08 != 0) baseOffset |= delta[offset++] << 24;
      // now the amount of bytes to copy
      if (opcode & 0x10 != 0) copyLength = delta[offset++];
      if (opcode & 0x20 != 0) copyLength |= delta[offset++] << 8;
      if (opcode & 0x40 != 0) copyLength |= delta[offset++] << 16;
      if (copyLength == 0) copyLength = 0x10000;

      // copy the data
      var replacement = base.getRange(baseOffset, baseOffset + copyLength);
      _replaceRange(rv, rvOffset, replacement);
    } else if (_isCopyFromDelta(opcode)) {
      // insert instruction (copy bytes from delta buffer to target buffer)
      // amount to copy is specified by the opcode itself
      copyLength = opcode;

      assert(offset + copyLength <= delta.length);
      assert(rvOffset + copyLength <= rv.length);

      var replacement = delta.getRange(offset, offset + copyLength);
      _replaceRange(rv, rvOffset, replacement);
      offset += copyLength;
    } else {
      throw Exception('Invalid delta opcode');
    }

    // advance target position
    rvOffset += copyLength;
  }

  // assert the size of the target buffer
  if (rvOffset != rv.length) {
    throw Exception('Error patching the base buffer');
  }

  return rv;
}