convertSingleRow method

String? convertSingleRow(
  1. StringBuffer sb,
  2. List? rowValues, {
  3. String? fieldDelimiter,
  4. String? textDelimiter,
  5. String? textEndDelimiter,
  6. String? eol,
  7. bool? delimitAllFields,
  8. dynamic convertNullTo,
  9. bool returnString = true,
})

Converts a list of values representing a row into a value separated string.

If rowValues is empty or null, returns "".

If the optional fieldDelimiter and textDelimiter is not specified (null) uses this.fieldDelimiter and this.textDelimiter.

All values of the rowValues are joined with fieldDelimiter. If such a value contains the fieldDelimiter itself the value is surrounded with textDelimiter.

If in such a case the value also contains textDelimiter those textDelimiter instances are doubled (see Definition of the CSV Format Rule 7 rfc4180).

If returnString is true (default), returns the converted String. Otherwise output is only written to provided StringBuffer sb. Set to false to improve performance.

Implementation

String? convertSingleRow(StringBuffer sb, List? rowValues,
    {String? fieldDelimiter,
    String? textDelimiter,
    String? textEndDelimiter,
    String? eol,
    bool? delimitAllFields,
    var convertNullTo,
    bool returnString = true}) {
  if (rowValues == null || rowValues.isEmpty) return '';

  fieldDelimiter ??= this.fieldDelimiter;
  // assign given textDelimiter to textEndDelimiter
  textEndDelimiter ??= textDelimiter;
  textDelimiter ??= this.textDelimiter;
  // if textDelimiter was null use the default textEndDelimiter
  textEndDelimiter ??= this.textEndDelimiter;
  eol ??= this.eol;
  delimitAllFields ??= this.delimitAllFields;
  convertNullTo ??= this.convertNullTo;

  if (fieldDelimiter == textDelimiter) {
    throw ArgumentError(
        'Field Delimiter ($fieldDelimiter) and Text Delimiter ($textDelimiter) must not be equal.');
  }

  String? fieldDel = '';

  // Comments assume field and text delimiter are default.
  // [val] _in the comments changes_ depending on the operation after the comment.
  rowValues.fold(sb, (StringBuffer sb, val) {
    // double => 4.2
    var valString = (convertNullTo != null && val == null)
        ? convertNullTo.toString()
        : val.toString();

    // 5,3 should become "5,3"

    if (delimitAllFields! ||
        _containsAny(valString,
            [fieldDelimiter, textDelimiter, textEndDelimiter, eol])) {
      // ab"cd => ab""cd
      if (_containsAny(valString, [textEndDelimiter])) {
        var newEndDelimiter = '$textEndDelimiter$textEndDelimiter';
        valString = valString.replaceAll(textEndDelimiter!, newEndDelimiter);
      }

      sb
        ..write(fieldDel) // ,
        ..write(textDelimiter) // "
        ..write(valString) // 5,3
        ..write(textEndDelimiter); // "
    } else {
      sb
        ..write(fieldDel)
        ..write(valString);
    }
    fieldDel = fieldDelimiter;
    return sb;
  });

  return returnString ? sb.toString() : null;
}