diff_fromDelta method

List<Diff> diff_fromDelta(
  1. String text1,
  2. String delta
)

Given the original text1, and an encoded string which describes the operations required to transform text1 into text2, compute the full diff. text1 is the source string for the diff. delta is the delta text. Returns a List of Diff objects or null if invalid. Throws ArgumentError if invalid input.

Implementation

List<Diff> diff_fromDelta(String text1, String delta) {
  final diffs = <Diff>[];
  int pointer = 0; // Cursor in text1
  final tokens = delta.split('\t');
  for (String token in tokens) {
    if (token.length == 0) {
      // Blank tokens are ok (from a trailing \t).
      continue;
    }
    // Each token begins with a one character parameter which specifies the
    // operation of this token (delete, insert, equality).
    String param = token.substring(1);
    switch (token[0]) {
      case '+':
        // decode would change all "+" to " "
        param = param.replaceAll('+', '%2B');
        try {
          param = Uri.decodeFull(param);
        } on ArgumentError {
          // Malformed URI sequence.
          throw ArgumentError('Illegal escape in diff_fromDelta: $param');
        }
        diffs.add(Diff(Operation.insert, param));
        break;
      case '-':
      // Fall through.
      case '=':
        int n;
        try {
          n = int.parse(param);
        } on FormatException {
          throw ArgumentError('Invalid number in diff_fromDelta: $param');
        }
        if (n < 0) {
          throw ArgumentError(
              'Negative number in diff_fromDelta: $param');
        }
        String text;
        try {
          text = text1.substring(pointer, pointer += n);
        } on RangeError {
          throw ArgumentError('Delta length ($pointer)'
              ' larger than source text length (${text1.length}).');
        }
        if (token[0] == '=') {
          diffs.add(Diff(Operation.equal, text));
        } else {
          diffs.add(Diff(Operation.delete, text));
        }
        break;
      default:
        // Anything else is an error.
        throw ArgumentError(
            'Invalid diff operation in diff_fromDelta: ${token[0]}');
    }
  }
  if (pointer != text1.length) {
    throw ArgumentError('Delta length ($pointer)'
        ' smaller than source text length (${text1.length}).');
  }
  return diffs;
}