encodeNS static method

String encodeNS(
  1. String value, {
  2. bool multiLine = false,
  3. bool pre = false,
  4. bool space = false,
  5. bool entity = false,
})

A null-safety version of encode.

Implementation

static String encodeNS(String value,
    {bool multiLine = false, bool pre = false,
     bool space = false, bool entity = false}) {
  final len = value.length;
  if (len == 0) return value; //as it is

  final buf = new StringBuffer();
  int i = 0, j = 0;
  void flush(String text, [int? end]) {
    buf..write(value.substring(j, end ?? i))
      ..write(text);
    j = i + 1;
  }

  for (bool escape = false; i < len; ++i) {
    final cc = value.codeUnitAt(i);
    if (entity) {
      if (escape) {
        escape = false;
        if (cc == $amp) {
          flush('&amp;', i - 1);
          continue;
        } else if (cc == $backslash) {
          flush('');
          continue;
        }
        //fall thru
      } else if (cc == $amp) {
        final m = _reXmlEntity.matchAsPrefix(value, i);
        if (m != null) i = m.end - 1; //put entity to output directly
        else flush('&amp;');
        continue;
      } else if (cc == $backslash) {
        escape = true;
        continue;
      }
      //fall thru
    }

    var replace = _encBasic[cc];
    if (replace == null) {
      if (multiLine) replace = _encLine[cc];

      if (replace == null && (pre || space)) {
        var count$ = _encSpace[cc];
        if (count$ != null) {
          var count = count$;
          late int k;
          if (!pre) { //pre has higher priority than space
          //convert consecutive whitespaces to &nbsp; plus a space
            for (k = i; ++k < len;) {
              final diff = _encSpace[value.codeUnitAt(k)];
              if (diff == null) break;
              count += diff;
            }
            if (--count == 0) //we'll add extra space if pre at the end
              continue; //if single space, no special handling (optimize)
          }

          flush('');

          while (--count >= 0)
            buf.write('&nbsp;');

          if (!pre) {
            buf.write(' '); //a space for line-break here
            i = (j = k) - 1;
          }
          continue;
        }
      }
    }

    if (replace != null) flush(replace);
  }

  if (buf.isEmpty) return value;
  flush('');
  return buf.toString();
}