parseHumanSize function

int parseHumanSize(
  1. String input
)

Parses a human-readable file size string (e.g., '1.5 GiB', '2 MB', '500 B') into bytes (int). Supports both SI (KB, MB, ...) and IEC (KiB, MiB, ...) units. Throws FormatException for invalid input.

Implementation

int parseHumanSize(String input) {
  final pattern = RegExp(r'([\d.,]+)\s*([a-zA-Z]+)', caseSensitive: false);
  final match = pattern.firstMatch(input.trim());
  if (match == null) {
    throw FormatException('Invalid file size format: $input');
  }

  final numStr = match.group(1)!.replaceAll(',', '.');
  final numValue = double.tryParse(numStr);
  if (numValue == null) {
    throw FormatException('Invalid number in file size: $numStr');
  }

  final unit = match.group(2)!.toUpperCase();
  const siUnits = {
    'B': 1,
    'KB': 1e3,
    'MB': 1e6,
    'GB': 1e9,
    'TB': 1e12,
    'PB': 1e15,
    'EB': 1e18,
    'ZB': 1e21,
    'YB': 1e24,
  };
  const iecUnits = {
    'B': 1,
    'KIB': 1024,
    'MIB': 1024 * 1024,
    'GIB': 1024 * 1024 * 1024,
    'TIB': 1024 * 1024 * 1024 * 1024,
    'PIB': 1024 * 1024 * 1024 * 1024 * 1024,
    'EIB': 1024 * 1024 * 1024 * 1024 * 1024 * 1024,
    'ZIB': 1024 * 1024 * 1024 * 1024 * 1024 * 1024 * 1024,
    'YIB': 1024 * 1024 * 1024 * 1024 * 1024 * 1024 * 1024 * 1024,
  };

  if (siUnits.containsKey(unit)) {
    return (numValue * siUnits[unit]!).round();
  } else if (iecUnits.containsKey(unit)) {
    return (numValue * iecUnits[unit]!).round();
  } else {
    throw FormatException('Unknown file size unit: $unit');
  }
}