setupStreamHandlers static method

void setupStreamHandlers({
  1. required Stream<List<int>> stream,
  2. required String packageName,
  3. required IOSink outputSink,
  4. required int maxLineWidth,
  5. required List<int> indentBytes,
})

Implementation

static void setupStreamHandlers({
  required Stream<List<int>> stream,
  required String packageName,
  required IOSink outputSink,
  required int maxLineWidth,
  required List<int> indentBytes,
}) {
  final headerBytes = '[$packageName]\n'.codeUnits;
  var buffer = <int>[];
  var hasPendingHeader = false;

  stream.listen(
    (event) {
      if (event.isEmpty) return;

      buffer.addAll(event);
      var start = 0;
      var printedHeader = false;

      for (var i = 0; i < buffer.length; i++) {
        if (buffer[i] == newlineByte) {
          final lineBytes = buffer.sublist(start, i);
          final isEmpty =
              lineBytes.isEmpty ||
              (lineBytes.length == 1 && lineBytes[0] == 0x0D);

          if (!isEmpty) {
            if (!printedHeader) {
              outputSink.add(headerBytes);
              printedHeader = true;
              hasPendingHeader = false;
            }

            final wrappedLines = wrapLineWithAnsi(
              lineBytes,
              maxLineWidth,
              indentBytes,
            );

            for (final wrappedLine in wrappedLines) {
              outputSink.add(wrappedLine);
              outputSink.add(const [newlineByte]);
            }
          } else {
            if (printedHeader) {
              outputSink.add(const [newlineByte]);
            } else {
              hasPendingHeader = true;
            }
          }

          start = i + 1;
        }
      }

      buffer = buffer.sublist(start);
    },
    onDone: () {
      if (buffer.isNotEmpty) {
        if (!hasPendingHeader) {
          outputSink.add(headerBytes);
        }
        final wrappedLines = wrapLineWithAnsi(
          buffer,
          maxLineWidth,
          indentBytes,
        );
        for (final wrappedLine in wrappedLines) {
          outputSink.add(wrappedLine);
          outputSink.add(const [newlineByte]);
        }
      }
    },
  );
}