rpcPeerText function

String rpcPeerText(
  1. String text, {
  2. bool asciiOnly = true,
  3. int? maxRunes,
})

text a peer sent, made safe to put in a log or an error message.

With asciiOnly, the default, every code point outside printable ASCII is escaped: the form for a protocol message, whose reader may not render anything else. Without it only rpcIsUnsafeCodePoints are, so Cyrillic or an emoji stays readable: the form for a log line.

Escapes are \n, \r, \t and \u{hex}, and a backslash is doubled, so a peer cannot write text that reads as an escape. With maxRunes, at most that many code points are kept, followed by ...: the length of peer text is the peer's to choose.

Implementation

String rpcPeerText(String text, {bool asciiOnly = true, int? maxRunes}) {
  bool escaped(int rune) =>
      rune == 0x5c ||
      rpcIsUnsafeCodePoint(rune) ||
      (asciiOnly && (rune < 0x20 || rune > 0x7e));

  // Most text needs nothing, and a console escapes every line it prints.
  if (maxRunes == null && !text.runes.any(escaped)) return text;

  final out = StringBuffer();
  var count = 0;
  for (final rune in text.runes) {
    if (maxRunes != null && count == maxRunes) {
      out.write('...');
      break;
    }
    count++;
    if (!escaped(rune)) {
      out.writeCharCode(rune);
      continue;
    }
    switch (rune) {
      case 0x5c:
        out.write(r'\\');
      case 0x0a:
        out.write(r'\n');
      case 0x0d:
        out.write(r'\r');
      case 0x09:
        out.write(r'\t');
      default:
        out.write('\\u{${rune.toRadixString(16)}}');
    }
  }
  return out.toString();
}