private LogEntry tryDecodeFrame(Frame frame, Iterator<Log.Entry> entries) throws CodingException {
if (!isHeader(frame)) {
LOG.warning("Found a frame with no preceding header, skipping.");
return null;
}
FrameHeader header = frame.getHeader();
byte[][] chunks = new byte[header.getChunkCount()][];
Hasher hasher = hashFunction.newHasher();
for (int i = 0; i < header.getChunkCount(); i++) {
if (!entries.hasNext()) {
logBadFrame(header, i);
return null;
}
LogEntry logEntry = decodeLogEntry(entries.next());
if (!isFrame(logEntry)) {
logBadFrame(header, i);
return logEntry;
}
Frame chunkFrame = logEntry.getFrame();
if (!isChunk(chunkFrame)) {
logBadFrame(header, i);
return logEntry;
}
byte[] chunkData = chunkFrame.getChunk().getData();
hasher.putBytes(chunkData);
chunks[i] = chunkData;
}
if (!Arrays.equals(header.getChecksum(), hasher.hash().asBytes())) {
throw new CodingException("Read back a framed log entry that failed its checksum");
}
return Entries.thriftBinaryDecode(Bytes.concat(chunks));
}