decodeRetrieveResponse static method

RetrieveMessagesResponse decodeRetrieveResponse(
  1. Uint8List bytes
)

Decode retrieve messages response

Throws RetrieveRefusedException when the server answered with its JSON error envelope instead. The two cannot be confused: a compound response starts with a 4-byte length, and one starting with { would claim over 2 GB of metadata.

Implementation

static RetrieveMessagesResponse decodeRetrieveResponse(Uint8List bytes) {
  if (bytes.isNotEmpty && bytes[0] == 0x7B) {
    Map<String, dynamic>? envelope;
    try {
      envelope = jsonDecode(utf8.decode(bytes)) as Map<String, dynamic>;
    } catch (_) {}
    if (envelope != null) {
      throw RetrieveRefusedException(
        envelope['error'] as String? ?? 'retrieve refused',
        status: envelope['status'] as int?,
      );
    }
  }
  final data = ByteData.sublistView(bytes);
  int offset = 0;

  // Read metadata
  final metadataLength = data.getUint32(offset);
  offset += 4;

  final metadataBytes = bytes.sublist(offset, offset + metadataLength);
  final json = utf8.decode(metadataBytes);
  final metadata = jsonDecode(json) as Map<String, dynamic>;
  offset += metadataLength;

  final hasMore = metadata['hasMore'] as bool;
  final messageCount = metadata['messageCount'] as int;

  // Read message frames
  final messages = <SFMessage>[];
  for (int i = 0; i < messageCount; i++) {
    final msgLength = data.getUint32(offset);
    offset += 4;

    final msgBytes = bytes.sublist(offset, offset + msgLength);
    messages.add(_decodeMessage(msgBytes));
    offset += msgLength;
  }

  return RetrieveMessagesResponse(
    messages: messages,
    hasMore: hasMore,
  );
}