deserialize method
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;
}