render method

void render(
  1. StringBuffer buffer
)

Renders this header into a the buffer wrapping it if necessary.

Implementation

void render(StringBuffer buffer) {
  final value = this.value;
  if (value == null) {
    buffer
      ..write(name)
      ..write(': \r\n');

    return;
  }
  final totalLength = value.length;
  var currentLineLength = name.length + ': '.length;
  buffer
    ..write(name)
    ..write(': ');
  if (currentLineLength + totalLength < MailConventions.textLineMaxLength) {
    buffer
      ..write(value)
      ..write('\r\n');

    return;
  }
  var startIndex = 0;
  while (startIndex < totalLength) {
    var chunkLength = MailConventions.textLineMaxLength - currentLineLength;
    if (startIndex + chunkLength >= totalLength) {
      // write reminder:
      buffer
        ..write(value.substring(startIndex).trim())
        ..write('\r\n');
      break;
    }
    var foundFoldingPoint = false;
    for (var i = startIndex + chunkLength; i > startIndex; i--) {
      final char = value.codeUnitAt(i);
      if (char == AsciiRunes.runeSemicolon ||
          char == AsciiRunes.runeSpace ||
          char == AsciiRunes.runeClosingParentheses ||
          char == AsciiRunes.runeClosingBracket ||
          char == AsciiRunes.runeGreaterThan ||
          char == AsciiRunes.runeComma) {
        chunkLength = i - startIndex + 1;
        foundFoldingPoint = true;
        break;
      }
    }
    if (!foundFoldingPoint) {
      // try to find a folding point after chunkLength
      // up to messageLineMaxLength
      for (var i = startIndex + chunkLength + 1; i < totalLength; i++) {
        if (currentLineLength + (i - startIndex) >=
            MailConventions.messageLineMaxLength) {
          chunkLength = i - startIndex;
          // avoid splitting surrogate pairs
          if (chunkLength > 0 &&
              value.codeUnitAt(startIndex + chunkLength - 1) >= 0xD800 &&
              value.codeUnitAt(startIndex + chunkLength - 1) <= 0xDBFF) {
            chunkLength--;
          }
          break;
        }
        final char = value.codeUnitAt(i);
        if (char == AsciiRunes.runeSemicolon ||
            char == AsciiRunes.runeSpace ||
            char == AsciiRunes.runeClosingParentheses ||
            char == AsciiRunes.runeClosingBracket ||
            char == AsciiRunes.runeGreaterThan ||
            char == AsciiRunes.runeComma) {
          chunkLength = i - startIndex + 1;
          foundFoldingPoint = true;
          break;
        }
      }
      if (!foundFoldingPoint && startIndex + chunkLength < totalLength) {
        // check if we can just take the rest of the string if it's under 998:
        if (currentLineLength + (totalLength - startIndex) <
            MailConventions.messageLineMaxLength) {
          chunkLength = totalLength - startIndex;
        }
      }
    }
    buffer
      ..write(value.substring(startIndex, startIndex + chunkLength).trim())
      ..write('\r\n');
    startIndex += chunkLength;
    if (startIndex < totalLength) {
      buffer.writeCharCode(AsciiRunes.runeTab);
      currentLineLength = 1;
    }
  }
}