convert method

  1. @override
String convert(
  1. Iterable<int> iterable, {
  2. List<int>? expected,
})
override

Converts input and returns the result of the conversion.

Implementation

@override
String convert(Iterable<int> iterable, {List<int>? expected}) {
  if (iterable.isEmpty && expected == null) {
    return "(no bytes)";
  }

  final sb = StringBuffer();
  sb.writeln(); // First blank line for alignment

  final list = iterable.toList();
  var maxLength = list.length;
  if (expected != null && expected.length > maxLength) {
    maxLength = expected.length;
  }

  void maybePrintDifferenceLine(int start, int end) {
    if (expected == null) return;

    var equal = true;
    for (var i = start; i < end; i++) {
      if (i >= list.length ||
          i >= expected.length ||
          list[i] != expected[i]) {
        equal = false;
        break;
      }
    }

    const prefix = "        ";
    sb.write("($start)".padLeft(prefix.length - 1, " "));
    if (equal) {
      // No difference → two blank lines for visual spacing
      sb.writeln();
      sb.writeln();
      return;
    }

    sb.write(" ");

    // Print diff markers
    var printExpectedBytes = false;
    int? firstAt;
    final lineSb = StringBuffer();
    for (var i = start; i < end; i++) {
      lineSb.write(getSpaceBefore(i));
      if (i >= list.length) {
        lineSb.write("^^"); // Byte missing in actual data
        printExpectedBytes = true;
        firstAt ??= i;
      } else if (i >= expected.length) {
        lineSb.write("--"); // Extra byte present
        firstAt ??= i;
      } else if (list[i] != expected[i]) {
        lineSb.write("^^"); // Byte mismatch
        printExpectedBytes = true;
        firstAt ??= i;
      } else {
        lineSb.write("  "); // Byte matches
      }
    }

    if (firstAt != null && firstAt > start) {
      lineSb.write("  <-- index of the first error: 0x");
      lineSb.write(firstAt.toRadixString(16).toUpperCase());
      lineSb.write(" (decimal: $firstAt)");
    }

    sb.writeln(lineSb.toString().trimRight());

    // Print expected byte values if necessary
    if (printExpectedBytes) {
      final expectedLine = StringBuffer(prefix);
      for (var i = start; i < end; i++) {
        expectedLine.write(getSpaceBefore(i));
        if (i < expected.length &&
            (i >= list.length || list[i] != expected[i])) {
          expectedLine.write(expected[i].toRadixString(16).padLeft(2, "0"));
        } else {
          expectedLine.write("  ");
        }
      }
      sb.writeln(expectedLine.toString().trimRight());
      sb.writeln();
    } else {
      sb.writeln();
    }
  }

  var rowStart = 0;
  for (var i = 0; i < maxLength; i++) {
    if (i % bytesPerRow == 0) {
      // Beginning of a new row
      if (i > 0) {
        sb.writeln();
        maybePrintDifferenceLine(rowStart, i);
        rowStart = i;
      }
      sb.write("0x");
      sb.write(i.toRadixString(16).padLeft(4, "0").toUpperCase());
      sb.write(": ");
    }

    sb.write(getSpaceBefore(i));
    if (i >= list.length) {
      sb.write(" ");
      continue;
    }

    final item = list[i];
    sb.write(item.toRadixString(16).padLeft(2, "0"));
  }

  sb.writeln();
  maybePrintDifferenceLine(rowStart, maxLength);
  return sb.toString();
}