fromPackets static method

List<Command> fromPackets(
  1. String raw
)

fromPackets creates a List<Command> from a raw message following this structure: commandId;commandName;args;crc16

Implementation

static List<Command> fromPackets(String raw) {
  final parts = raw.split(';');
  if (parts.isEmpty) return [];

  if (parts.length == 1) return [];
  // The parts should be divisible by 4, can be multiple groups

  if (parts.length % 4 != 0) {
    throw ParseException('Invalid command definition');
  }

  // Separate each group
  final List<Command> commands = [];

  for (int i = 0; i < parts.length; i += 4) {
    final commandId = parts[i];
    final commandName = parts[i + 1];
    final rawArgs = parts[i + 2];
    final receivedCrc = int.tryParse(parts[i + 3], radix: 16) ?? 0;
    final calculatedCrc = calculateCrc("$commandId;$commandName;$rawArgs;".codeUnits);
    if (receivedCrc != calculatedCrc) {
      throw CrcException(
        'Invalid CRC, expected ${receivedCrc.toRadixString(16)}, '
        'got ${calculatedCrc.toRadixString(16)}',
      );
    }

    Map<String, dynamic> args = {};

    if (rawArgs.isNotEmpty) {
      // Split each raw args by ','
      final argParts = rawArgs.split(',');
      for (var arg in argParts) {
        final parts = arg.split(':');
        final key = parts[0];
        final value = parts[1];

        final intRegex = RegExp(r'^\d+$');
        final doubleRegex = RegExp(r'^\d+\.\d+$');
        if (intRegex.hasMatch(value)) {
          args[key] = int.parse(value);
        } else if (doubleRegex.hasMatch(value)) {
          args[key] = double.parse(value);
        } else if (value == 'true' || value == 'false') {
          args[key] = value == 'true';
        } else {
          args[key] = value;
        }
      }
    }

    commands.add(Command(commandId: commandId, commandName: commandName, args: args));
  }

  return commands;
}