public static BlobAll deserializeBlobAll(InputStream stream, StoreKeyFactory storeKeyFactory)
      throws IOException, MessageFormatException {
    DataInputStream inputStream =
        stream instanceof DataInputStream ? (DataInputStream) stream : new DataInputStream(stream);
    short headerVersion = inputStream.readShort();
    ByteBuffer headerBuf;
    MessageHeader_Format header;
    switch (headerVersion) {
      case Message_Header_Version_V1:
        headerBuf = ByteBuffer.allocate(MessageFormatRecord.MessageHeader_Format_V1.getHeaderSize());
        headerBuf.putShort(headerVersion);
        inputStream.read(headerBuf.array(), Version_Field_Size_In_Bytes,
            MessageHeader_Format_V1.getHeaderSize() - Version_Field_Size_In_Bytes);
        headerBuf.rewind();
        header = new MessageHeader_Format_V1(headerBuf);
        break;
      case Message_Header_Version_V2:
        headerBuf = ByteBuffer.allocate(MessageFormatRecord.MessageHeader_Format_V2.getHeaderSize());
        headerBuf.putShort(headerVersion);
        inputStream.read(headerBuf.array(), Version_Field_Size_In_Bytes,
            MessageHeader_Format_V2.getHeaderSize() - Version_Field_Size_In_Bytes);
        headerBuf.rewind();
        header = new MessageHeader_Format_V2(headerBuf);
        break;
      case Message_Header_Version_V3:
        headerBuf = ByteBuffer.allocate(MessageFormatRecord.MessageHeader_Format_V3.getHeaderSize());
        headerBuf.putShort(headerVersion);
        inputStream.read(headerBuf.array(), Version_Field_Size_In_Bytes,
            MessageHeader_Format_V3.getHeaderSize() - Version_Field_Size_In_Bytes);
        headerBuf.rewind();
        header = new MessageHeader_Format_V3(headerBuf);
        break;
      default:
        throw new MessageFormatException("Message header version not supported",
            MessageFormatErrorCodes.UnknownFormatVersion);
    }
    header.verifyHeader();
    StoreKey storeKey = storeKeyFactory.getStoreKey(inputStream);
    ByteBuffer blobEncryptionKey = null;
    if (header.hasEncryptionKeyRecord()) {
      blobEncryptionKey = deserializeBlobEncryptionKey(stream);
    }
    BlobProperties blobProperties = deserializeBlobProperties(stream);
    byte[] userMetadata = deserializeUserMetadata(stream).array();
    BlobData blobData = deserializeBlob(stream);
    return new BlobAll(storeKey, blobEncryptionKey, new BlobInfo(blobProperties, userMetadata), blobData);
  }
Deserialize a complete blob record into a {@link BlobAll} object.
@param stream the {@link InputStream} from which to read the blob record.
@param storeKeyFactory the factory for parsing store keys.
@return a {@link BlobAll} object with the {@link BlobInfo} and {@link BlobData} for the blob.
@throws IOException
@throws MessageFormatException
ambry-messageformat/src/main/java/com/github/ambry/messageformat/MessageFormatRecord.java