in ratis-server/src/main/java/org/apache/ratis/server/raftlog/segmented/SegmentedRaftLogReader.java [283:333]
private LogEntryProto decodeEntry() throws IOException {
final int max = maxOpSize.getSizeInt();
limiter.setLimit(max);
in.mark(max);
byte nextByte;
try {
nextByte = in.readByte();
} catch (EOFException eof) {
// EOF at an opcode boundary is expected.
return null;
}
// Each log entry starts with a var-int. Thus a valid entry's first byte
// should not be 0. So if the terminate byte is 0, we should hit the end
// of the segment.
if (SegmentedRaftLogFormat.isTerminator(nextByte)) {
verifyTerminator();
return null;
}
// Here, we verify that the Op size makes sense and that the
// data matches its checksum before attempting to construct an Op.
int entryLength = CodedInputStream.readRawVarint32(nextByte, in);
if (entryLength > max) {
throw new IOException("Entry has size " + entryLength
+ ", but MAX_OP_SIZE = " + maxOpSize);
}
final int varintLength = CodedOutputStream.computeUInt32SizeNoTag(
entryLength);
final int totalLength = varintLength + entryLength;
checkBufferSize(totalLength, max);
in.reset();
in.mark(max);
IOUtils.readFully(in, temp, 0, totalLength);
// verify checksum
checksum.reset();
checksum.update(temp, 0, totalLength);
int expectedChecksum = in.readInt();
int calculatedChecksum = (int) checksum.getValue();
if (expectedChecksum != calculatedChecksum) {
final String s = StringUtils.format("Log entry corrupted: Calculated checksum is %08X but read checksum is %08X.",
calculatedChecksum, expectedChecksum);
throw new ChecksumException(s, limiter.markPos);
}
// parse the buffer
return LogEntryProto.parseFrom(
CodedInputStream.newInstance(temp, varintLength, entryLength));
}