/// <summary> /// Decode a byte[] that represents a collection of messages. /// </summary> /// <param name="reader">The reader</param> /// <param name="partitionId">The partitionId messages are being read from.</param> /// <returns>Enumerable representing stream of messages decoded from byte[]</returns> public static IImmutableList <Message> ReadMessages(this IKafkaReader reader, int partitionId = 0) { var expectedLength = reader.ReadInt32(); if (!reader.Available(expectedLength)) { throw new BufferUnderRunException($"Message set size of {expectedLength} is not fully available."); } var messages = ImmutableList <Message> .Empty; var finalPosition = reader.Position + expectedLength; while (reader.Position < finalPosition) { // this checks that we have at least the minimum amount of data to retrieve a header if (reader.Available(MessageHeaderSize) == false) { break; } var offset = reader.ReadInt64(); var messageSize = reader.ReadInt32(); // if the stream does not have enough left in the payload, we got only a partial message if (reader.Available(messageSize) == false) { throw new BufferUnderRunException($"Message header size of {MessageHeaderSize} is not fully available."); } try { messages = messages.AddRange(reader.ReadMessage(messageSize, offset, partitionId)); } catch (EndOfStreamException ex) { throw new BufferUnderRunException($"Message size of {messageSize} is not available.", ex); } } return(messages); }