public static List < Long > locate ( List < byte [ ] > targets , List < POSITION > locations , InputStream is , long maxOffset ) throws IOException { if ( targets . isEmpty ( ) ) { throw new IllegalArgumentException ( "Targets argument can't be empty" ) ; } if ( locations . size ( ) != targets . size ( ) ) { throw new IllegalArgumentException ( "Targets and Locations arguments must be of equal length" ) ; } for ( byte [ ] target : targets ) { if ( target . length == 0 ) { throw new IllegalArgumentException ( "Input Targets must be non-zero length" ) ; } } if ( maxOffset <= 0 ) { maxOffset = Long . MAX_VALUE ; } long posSource = - 1 ; int iRead ; byte bRead ; List < Long > result = new ArrayList <> ( targets . size ( ) ) ; for ( int i = 0 ; i < targets . size ( ) ; i ++ ) { byte [ ] target = targets . get ( i ) ; int posTarget = 0 ; byte bTarget = target [ posTarget ] ; while ( ( iRead = is . read ( ) ) >= 0 ) { posSource ++ ; if ( posSource > maxOffset ) { // reached max allowed offset, returning what we have so far return result ; } bRead = ( byte ) iRead ; if ( bRead != bTarget ) { if ( posTarget > 0 ) { posTarget = 0 ; bTarget = target [ posTarget ] ; } continue ; } else { posTarget ++ ; if ( posTarget == target . length ) { // the end of target has been reached, add it to result switch ( locations . get ( i ) ) { case START : result . add ( posSource - target . length + 1 ) ; break ; case END : result . add ( posSource ) ; break ; default : throw new IllegalArgumentException ( "Unsupported ELEMENT_LOCATION" ) ; } // move to next target break ; // break out of while(is.read()) } bTarget = target [ posTarget ] ; continue ; } } if ( iRead < 0 && result . size ( ) != targets . size ( ) ) { // reached EOF without finding all the targets in the input stream return Collections . emptyList ( ) ; } } return result ; }
Locates specific sequences of bytes in the input stream .