/// <summary> /// Decode messages from a payload and assign it a given kafka offset. /// </summary> /// <param name="offset">The offset represting the log entry from kafka of this message.</param> /// <param name="payload">The byte[] encode as a message from kafka.</param> /// <returns>Enumerable representing stream of messages decoded from byte[].</returns> /// <remarks>The return type is an Enumerable as the message could be a compressed message set.</remarks> public static IEnumerable <Message> DecodeMessage(long offset, byte[] payload) { var crc = payload.Take(4); var stream = new ReadByteStream(payload.Skip(4)); if (crc.SequenceEqual(Crc32.ComputeHash(stream.Payload)) == false) { throw new FailCrcCheckException("Payload did not match CRC validation."); } var message = new Message { Meta = new MessageMetadata { Offset = offset }, MagicNumber = stream.ReadByte(), Attribute = stream.ReadByte(), Key = stream.ReadIntString() }; var codec = (MessageCodec)(ProtocolConstants.AttributeCodeMask & message.Attribute); switch (codec) { case MessageCodec.CodecNone: message.Value = stream.ReadIntString(); yield return(message); break; case MessageCodec.CodecGzip: var gZipData = stream.ReadIntPrefixedBytes(); foreach (var m in DecodeMessageSet(Compression.Unzip(gZipData))) { yield return(m); } break; default: throw new NotSupportedException(string.Format("Codec type of {0} is not supported.", codec)); } }