vsprintf method

String vsprintf(
  1. String format,
  2. va_list arg
)

Writes formatted output to a string using a variable argument list.

Implementation

String vsprintf(String format, va_list arg) {
  final buffer = StringBuffer();
  for (int i = 0; i < format.length; i++) {
    if (format[i] == '%' && i + 1 < format.length) {
      i++;
      String specifier = format[i];
      if (specifier == '%') {
        buffer.write('%');
        continue;
      }

      // Check if there are arguments left without popping yet for the missing arg logic
      // But since va_list is opaque-ish, we should probably handle StateError or peek.
      // Actually, we can just peek internal _index.
      // But to be clean, let's catch StateError or just check.
      // Wait, Dart's standard library doesn't let us peek easily without breaking abstraction,
      // but since they are in the same package, it's fine, though va_arg handles it.
      dynamic argVal;
      try {
        argVal = va_arg<dynamic>(arg);
      } on StateError {
        buffer.write('%$specifier'); // Not enough arguments, just print literally
        continue;
      }

      switch (specifier) {
        case 'd':
        case 'i':
          buffer.write((argVal as num).toInt());
          break;
        case 'f':
          buffer.write((argVal as num).toDouble().toStringAsFixed(6));
          break;
        case 's':
          buffer.write(argVal.toString());
          break;
        case 'c':
          if (argVal is int) {
            buffer.writeCharCode(argVal);
          } else if (argVal is String && argVal.isNotEmpty) {
            buffer.write(argVal[0]);
          }
          break;
        case 'x':
          buffer.write((argVal as int).toRadixString(16).toLowerCase());
          break;
        case 'X':
          buffer.write((argVal as int).toRadixString(16).toUpperCase());
          break;
        default:
          buffer.write('%$specifier'); // Unsupported, print literal
          // We need to revert the arg index because we didn't consume it for a valid specifier.
          // Since we used va_arg, we advanced the index. We must decrement it.
          // In C, standard says behavior is undefined if format is invalid.
          // We'll just decrement it manually for our safe Dart implementation.
          arg.internalRevert();
      }
    } else {
      buffer.write(format[i]);
    }
  }
  return buffer.toString();
}