private LogChunkType readNextChunk ( ) { // clear the current chunk currentChunk = Slices . EMPTY_SLICE ; // read the next block if necessary if ( currentBlock . available ( ) < HEADER_SIZE ) { if ( ! readNextBlock ( ) ) { if ( eof ) { return EOF ; } } } // parse header int expectedChecksum = currentBlock . readInt ( ) ; int length = currentBlock . readUnsignedByte ( ) ; length = length | currentBlock . readUnsignedByte ( ) << 8 ; byte chunkTypeId = currentBlock . readByte ( ) ; LogChunkType chunkType = getLogChunkTypeByPersistentId ( chunkTypeId ) ; // verify length if ( length > currentBlock . available ( ) ) { int dropSize = currentBlock . available ( ) + HEADER_SIZE ; reportCorruption ( dropSize , "Invalid chunk length" ) ; currentBlock = Slices . EMPTY_SLICE . input ( ) ; return BAD_CHUNK ; } // skip zero length records if ( chunkType == ZERO_TYPE && length == 0 ) { // Skip zero length record without reporting any drops since // such records are produced by the writing code. currentBlock = Slices . EMPTY_SLICE . input ( ) ; return BAD_CHUNK ; } // Skip physical record that started before initialOffset if ( endOfBufferOffset - HEADER_SIZE - length < initialOffset ) { currentBlock . skipBytes ( length ) ; return BAD_CHUNK ; } // read the chunk currentChunk = currentBlock . readBytes ( length ) ; if ( verifyChecksums ) { int actualChecksum = getChunkChecksum ( chunkTypeId , currentChunk ) ; if ( actualChecksum != expectedChecksum ) { // Drop the rest of the buffer since "length" itself may have // been corrupted and if we trust it, we could find some // fragment of a real log record that just happens to look // like a valid log record. int dropSize = currentBlock . available ( ) + HEADER_SIZE ; currentBlock = Slices . EMPTY_SLICE . input ( ) ; reportCorruption ( dropSize , "Invalid chunk checksum" ) ; return BAD_CHUNK ; } } // Skip unknown chunk types // Since this comes last so we the, know it is a valid chunk, and is just a type we don't understand if ( chunkType == UNKNOWN ) { reportCorruption ( length , String . format ( "Unknown chunk type %d" , chunkType . getPersistentId ( ) ) ) ; return BAD_CHUNK ; } return chunkType ; }
Return type or one of the preceding special values