OnyxMessage.parse constructor

OnyxMessage.parse(
  1. String data,
  2. void handleLeftovers(
    1. String
    )
)

onyx runs on a Windows machine, so it uses Windows line endings All responses have a minimum of three lines. There are two kinds of responses; "info" responses look like this HTTPCODE-TEXTLINE 1 HTTPCODE-TEXTLINE 2 HTTPCODE command sent by user if there was one

for example, when a client first connects, we get:

200-Welcome to Onyx Manager v4.0.1010 build 0! 200-Type HELP for a list of available commands 200

after an invalid command, we get: 400-I never heard that command before... are you sure? 400-Type HELP for a list of commands 400 hello

"data" responses look like this HTTPCODE Ok response data .

after qlactive, we get this: 200 Ok No Active Qlist in List .

after qllist, we get this: 200 Ok 00002 - House Lights 00003 - SlimPar 00004 - LED Tape ... other items ... .

Implementation

/// There are two kinds of responses;
/// "info" responses look like this
/// HTTPCODE-TEXTLINE 1
/// HTTPCODE-TEXTLINE 2
/// HTTPCODE command sent by user if there was one
///
/// for example, when a client first connects, we get:
///
/// 200-*************Welcome to Onyx Manager v4.0.1010 build 0!*************
/// 200-Type HELP for a list of available commands
/// 200
///
/// after an invalid command, we get:
/// 400-I never heard that command before... are you sure?
/// 400-Type HELP for a list of commands
/// 400 hello
///
/// "data" responses look like this
/// HTTPCODE Ok
/// response data
/// .
///
/// after qlactive, we get this:
/// 200 Ok
/// No Active Qlist in List
/// .
///
/// after qllist, we get this:
/// 200 Ok
/// 00002 - House Lights
/// 00003 - SlimPar
/// 00004 - LED Tape
/// ... other items ...
/// .
OnyxMessage.parse(String data, void Function(String) handleLeftovers) {
  /// onyx messages have three lines terminated with \r\n
  var lines = data.split('\r\n');
  if (lines.length < 4) {
    handleLeftovers(data);
    throw const FormatException('incomplete onyx message');
  }

  // look for info packet
  if (lines.first.contains('-')) {
    type = OnyxMessageType.info;
    raw = lines.sublist(0, 3).join('\r\n');

    var lineData = lines[0].split('-');
    code = int.tryParse(lineData.first) ?? 400;
    message = lineData.sublist(1).join('-');

    lineData = lines[1].split('-');
    message += '\r\n' + lineData.sublist(1).join('-');

    // third line splits on a space
    lineData = lines[2].split(' ');
    message += '\r\n' + lineData.sublist(1).join(' ');

    handleLeftovers(lines.sublist(3).join('\r\n'));
  } else {
    // multiline messages must have a terminator
    if (!data.contains('\r\n.\r\n')) {
      handleLeftovers(data);
      throw const FormatException('incomplete onyx message');
    }

    type = OnyxMessageType.data;
    var responseData = lines.removeAt(0).split(' ');
    code = int.tryParse(responseData.first) ?? 200;
    message = responseData.sublist(1).join(' ');

    while (lines.isNotEmpty) {
      var line = lines.removeAt(0);
      if (line == '.') break;
      dataLines.add(line);
    }
    dataText = dataLines.join('\n'); // we prefer \n for newlines
    handleLeftovers(lines.join('\r\n'));
  }
}