encodeHeader method

  1. @override
String encodeHeader(
  1. String text, {
  2. int nameLength = 0,
  3. bool fromStart = false,
})
override

Encodes the header text in base64 only if required.

text specifies the text to be encoded. Set the optional fromStart to true in case the encoding should start at the beginning of the text and not in the middle. Set the nameLength for ensuring there is enough place for the name of the encoding.

Implementation

@override
String encodeHeader(
  String text, {
  int nameLength = 0,
  bool fromStart = false,
}) {
  final runes = List.from(text.runes, growable: false);
  var numberOfRunesAbove7Bit = 0;
  var startIndex = -1;
  var endIndex = -1;
  for (var runeIndex = 0; runeIndex < runes.length; runeIndex++) {
    final rune = runes[runeIndex];
    if (rune > 128) {
      numberOfRunesAbove7Bit++;
      if (startIndex == -1) {
        startIndex = runeIndex;
        endIndex = runeIndex;
      } else {
        endIndex = runeIndex;
      }
    }
  }
  if (numberOfRunesAbove7Bit == 0) {
    return text;
  } else {
    const qpWordHead = '=?utf8?B?';
    const qpWordTail = '?=';
    const qpWordDelimiterSize = qpWordHead.length + qpWordTail.length;
    if (fromStart) {
      startIndex = 0;
      endIndex = text.length - 1;
    }
    // Available space for the current encoded word
    var qpWordSize = MailConventions.encodedWordMaxLength -
        qpWordDelimiterSize -
        startIndex -
        (nameLength + 2);
    final buffer = StringBuffer();
    if (startIndex > 0) {
      buffer.write(text.substring(0, startIndex));
    }
    final textToEncode =
        fromStart ? text : text.substring(startIndex, endIndex + 1);
    final encoded = encodeText(textToEncode, wrap: false);
    buffer.write(qpWordHead);
    if (encoded.length < qpWordSize) {
      buffer.write(encoded);
    } else {
      // Reuses startIndex for folding
      startIndex = 0;
      while (startIndex < encoded.length) {
        final chunk = startIndex + qpWordSize > encoded.length
            ? encoded.substring(startIndex)
            : encoded.substring(startIndex, startIndex + qpWordSize);
        buffer.write(chunk);
        startIndex += qpWordSize;
        if (startIndex < encoded.length) {
          buffer
            ..write(qpWordTail)
            // NOTE Per specification, a CRLF should be inserted here,
            // but the folding occurs on the rendering function.
            // Here we leave only the WSP marker
            // to separate each q-encoded word.
            // ..writeCharCode(AsciiRunes.runeCarriageReturn)
            // ..writeCharCode(AsciiRunes.runeLineFeed)
            // Assumes per default a single leading space for header folding
            ..writeCharCode(AsciiRunes.runeSpace)
            ..write(qpWordHead);
          qpWordSize =
              MailConventions.encodedWordMaxLength - qpWordDelimiterSize - 1;
        }
      }
    }
    buffer.write(qpWordTail);
    if (endIndex < text.length - 1) {
      buffer.write(text.substring(endIndex + 1));
    }

    return buffer.toString();
  }
}