deserialize method

  1. @override
AbstractMessage? deserialize(
  1. Uint8List? msgPack
)
override

Converts a uint8 msgpack message into a WAMP message object

Implementation

@override
AbstractMessage? deserialize(Uint8List? msgPack) {
  if (msgPack == null) {
    return null;
  }
  if (_readMsgPackArrayHeader(msgPack, 0) == null) {
    _validateCompleteMsgPackValue(msgPack);
  }
  final fastPathMessage = _deserializeFastPathMessage(msgPack);
  if (fastPathMessage != null) {
    return fastPathMessage;
  }
  Object? message = msgpack_dart.deserialize(msgPack);
  if (message is List) {
    if (message.isEmpty) {
      throw const FormatException('WAMP message type must be an integer');
    }
    final rawMessageId = message[0];
    if (rawMessageId is! int) {
      throw const FormatException('WAMP message type must be an integer');
    }
    final messageId = rawMessageId;
    if (messageId == MessageTypes.codeHello) {
      validateKnownWampMessageMinimumFieldCount(message.length, 3);
      return Hello(
        message[1] as String?,
        _decodeDetailsMap(
          Map<dynamic, dynamic>.from(message[2] as Map<dynamic, dynamic>),
        ),
      );
    }
    if (messageId == MessageTypes.codeChallenge) {
      validateKnownWampMessageMinimumFieldCount(message.length, 3);
      return Challenge(
        message[1],
        _decodeChallengeExtraMap(
          Map<dynamic, dynamic>.from(message[2] as Map<dynamic, dynamic>),
        ),
      );
    }
    if (messageId == MessageTypes.codeAuthenticate) {
      validateKnownWampMessageMinimumFieldCount(message.length, 3);
      final extra = message[2];
      if (extra is! Map || extra.keys.any((key) => key is! String)) {
        throw const FormatException(
          'AUTHENTICATE.Extra must be a dictionary with string keys',
        );
      }
      return Authenticate(signature: message[1] as String?)
        ..extra = Map<String, Object?>.from(extra);
    }
    if (messageId == MessageTypes.codeWelcome) {
      validateKnownWampMessageMinimumFieldCount(message.length, 3);
      return Welcome(
        message[1],
        _decodeWelcomeDetailsMap(
          Map<dynamic, dynamic>.from(message[2] as Map<dynamic, dynamic>),
        ),
      );
    }
    if (messageId == MessageTypes.codeRegister) {
      validateKnownWampMessageMinimumFieldCount(message.length, 4);
      return Register(
        message[1],
        message[3],
        options: _decodeRegisterOptions(
          _decodeRequiredOptionsMap(message[2], 'REGISTER'),
        ),
      );
    }
    if (messageId == MessageTypes.codeUnregister) {
      validateKnownWampMessageMinimumFieldCount(message.length, 3);
      return Unregister(message[1], message[2]);
    }
    if (messageId == MessageTypes.codeCall) {
      validateKnownWampMessageMinimumFieldCount(message.length, 4);
      return _addPayload(
        Call(
          message[1],
          message[3],
          options: _decodeCallOptions(
            _decodeRequiredOptionsMap(message[2], 'CALL'),
          ),
        ),
        message,
        4,
      );
    }
    if (messageId == MessageTypes.codeYield) {
      validateKnownWampMessageMinimumFieldCount(message.length, 3);
      return _addPayload(
        Yield(
          message[1],
          options: _decodeYieldOptions(
            _decodeRequiredOptionsMap(message[2], 'YIELD'),
          ),
        ),
        message,
        3,
      );
    }
    if (messageId == MessageTypes.codePublish) {
      validateKnownWampMessageMinimumFieldCount(message.length, 4);
      return _addPayload(
        Publish(
          message[1],
          message[3],
          options: _decodePublishOptions(
            _decodeRequiredOptionsMap(message[2], 'PUBLISH'),
          ),
        ),
        message,
        4,
      );
    }
    if (messageId == MessageTypes.codeRegistered) {
      validateKnownWampMessageMinimumFieldCount(message.length, 3);
      return Registered(message[1], message[2]);
    }
    if (messageId == MessageTypes.codeUnregistered) {
      validateKnownWampMessageMinimumFieldCount(message.length, 2);
      return Unregistered(message[1]);
    }
    if (messageId == MessageTypes.codeInvocation) {
      validateKnownWampMessageMinimumFieldCount(message.length, 4);
      final detailsMap = message[3] as Map<dynamic, dynamic>;
      return _addPayload(
        Invocation(
          message[1],
          message[2],
          _decodeInvocationDetails(detailsMap),
        ),
        message,
        4,
      );
    }
    if (messageId == MessageTypes.codeInterrupt) {
      validateKnownWampMessageMinimumFieldCount(message.length, 3);
      final optionsMap = _validateRequiredOptionsMap(
        message[2],
        'INTERRUPT',
      );
      return interrupt_msg.Interrupt(
        message[1],
        options: (() {
          final options = interrupt_msg.InterruptOptions();
          options.mode = optionsMap['mode'] as String?;
          return options;
        })(),
      );
    }
    if (messageId == MessageTypes.codeCancel) {
      validateKnownWampMessageMinimumFieldCount(message.length, 3);
      final optionsMap = _validateRequiredOptionsMap(message[2], 'CANCEL');
      return cancel_msg.Cancel(
        message[1],
        options: (() {
          final options = cancel_msg.CancelOptions();
          options.mode = optionsMap['mode'] as String?;
          return options;
        })(),
      );
    }
    if (messageId == MessageTypes.codeResult) {
      validateKnownWampMessageMinimumFieldCount(message.length, 3);
      final detailsMap = message[2] as Map<dynamic, dynamic>;
      final progress = detailsMap['progress'];
      final pptScheme = detailsMap['ppt_scheme'];
      final pptSerializer = detailsMap['ppt_serializer'];
      final pptCipher = detailsMap['ppt_cipher'];
      final pptKeyId = detailsMap['ppt_keyid'];
      return _addPayload(
        Result(
          message[1],
          ResultDetails(
            progress: progress,
            pptScheme: pptScheme,
            pptSerializer: pptSerializer,
            pptCipher: pptCipher,
            pptKeyId: pptKeyId,
            custom: _extractCustomDetails(detailsMap, _resultDetailKeys),
          ),
        ),
        message,
        3,
      );
    }
    if (messageId == MessageTypes.codePublished) {
      validateKnownWampMessageMinimumFieldCount(message.length, 3);
      return Published(message[1], message[2]);
    }
    if (messageId == MessageTypes.codeSubscribe) {
      validateKnownWampMessageMinimumFieldCount(message.length, 4);
      return Subscribe(
        message[1],
        message[3],
        options: _decodeSubscribeOptions(
          _decodeRequiredOptionsMap(message[2], 'SUBSCRIBE'),
        ),
      );
    }
    if (messageId == MessageTypes.codeSubscribed) {
      validateKnownWampMessageMinimumFieldCount(message.length, 3);
      return Subscribed(message[1], message[2]);
    }
    if (messageId == MessageTypes.codeUnsubscribe) {
      validateKnownWampMessageMinimumFieldCount(message.length, 3);
      return Unsubscribe(message[1], message[2]);
    }
    if (messageId == MessageTypes.codeUnsubscribed) {
      validateKnownWampMessageMinimumFieldCount(message.length, 2);
      return Unsubscribed(
        message[1],
        message.length == 2
            ? null
            : _decodeUnsubscribedDetailsMap(
                Map<dynamic, dynamic>.from(
                  message[2] as Map<dynamic, dynamic>,
                ),
              ),
      );
    }
    if (messageId == MessageTypes.codeEvent) {
      validateKnownWampMessageMinimumFieldCount(message.length, 4);
      final detailsMap = message[3] as Map<dynamic, dynamic>;
      return _addPayload(
        Event(
          message[1],
          message[2],
          _decodeEventDetails(detailsMap),
        ),
        message,
        4,
      );
    }
    if (messageId == MessageTypes.codeError) {
      validateKnownWampMessageMinimumFieldCount(message.length, 5);
      return _addPayload(
        Error(
          message[1],
          message[2],
          Map<String, Object>.from(message[3]),
          message[4],
        ),
        message,
        5,
      );
    }
    if (messageId == MessageTypes.codeAbort) {
      validateKnownWampMessageMinimumFieldCount(message.length, 3);
      return Abort(
        message[2],
        message: _decodeAbortMessageMap(
          message[1] is Map
              ? Map<dynamic, dynamic>.from(
                  message[1] as Map<dynamic, dynamic>,
                )
              : null,
        ),
      );
    }
    if (messageId == MessageTypes.codeGoodbye) {
      validateKnownWampMessageMinimumFieldCount(message.length, 3);
      return Goodbye(
        _decodeGoodbyeMessageMap(
          message[1] is Map
              ? Map<dynamic, dynamic>.from(
                  message[1] as Map<dynamic, dynamic>,
                )
              : null,
        ),
        message[2],
      );
    }
  }
  _logger.shout(
    'Could not deserialize MessagePack WAMP message '
    '(${msgPack.length} bytes)',
  );
  // TODO respond with an error
  return null;
}