public static long findFirstSyncPosition ( RcFileDataSource dataSource , long offset , long length , long syncFirst , long syncSecond ) throws IOException { requireNonNull ( dataSource , "dataSource is null" ) ; checkArgument ( offset >= 0 , "offset is negative" ) ; checkArgument ( length >= 1 , "length must be at least 1" ) ; checkArgument ( offset + length <= dataSource . getSize ( ) , "offset plus length is greater than data size" ) ; // The full sync sequence is "0xFFFFFFFF syncFirst syncSecond". If // this sequence begins the file range, the start position is returned // even if the sequence finishes after length. // NOTE: this decision must agree with RcFileReader.nextBlock Slice sync = Slices . allocate ( SIZE_OF_INT + SIZE_OF_LONG + SIZE_OF_LONG ) ; sync . setInt ( 0 , 0xFFFF_FFFF ) ; sync . setLong ( SIZE_OF_INT , syncFirst ) ; sync . setLong ( SIZE_OF_INT + SIZE_OF_LONG , syncSecond ) ; // read 4 MB chunks at a time, but only skip ahead 4 MB - SYNC_SEQUENCE_LENGTH bytes // this causes a re-read of SYNC_SEQUENCE_LENGTH bytes each time, but is much simpler code byte [ ] buffer = new byte [ toIntExact ( min ( 1 << 22 , length + ( SYNC_SEQUENCE_LENGTH - 1 ) ) ) ] ; Slice bufferSlice = Slices . wrappedBuffer ( buffer ) ; for ( long position = 0 ; position < length ; position += bufferSlice . length ( ) - ( SYNC_SEQUENCE_LENGTH - 1 ) ) { // either fill the buffer entirely, or read enough to allow all bytes in offset + length to be a start sequence int bufferSize = toIntExact ( min ( buffer . length , length + ( SYNC_SEQUENCE_LENGTH - 1 ) - position ) ) ; // don't read off the end of the file bufferSize = toIntExact ( min ( bufferSize , dataSource . getSize ( ) - offset - position ) ) ; dataSource . readFully ( offset + position , buffer , 0 , bufferSize ) ; // find the starting index position of the sync sequence int index = bufferSlice . indexOf ( sync ) ; if ( index >= 0 ) { // If the starting position is before the end of the search region, return the // absolute start position of the sequence. if ( position + index < length ) { long startOfSyncSequence = offset + position + index ; return startOfSyncSequence ; } else { // Otherwise, this is not a match for this region // Note: this case isn't strictly needed as the loop will exit, but it is // simpler to explicitly call it out. return - 1 ; } } } return - 1 ; }
Find the beginning of the first full sync sequence that starts within the specified range .