/** * Calculates the safe shifts to use if searching backwards. A safe shift is either the length * of the sequence, if the byte does not appear in the {@link SequenceMatcher}, or the shortest * distance it appears from the beginning of the matcher, with zero being the value of the first * position in the sequence. */ @Override public SearchInfo create() { // Get info about the matcher: final SequenceMatcher sequence = getMatcher(); final int sequenceLength = sequence.length(); // Create the search info object fields final int lastPosition = sequenceLength - 1; final ByteMatcher byteMatcher = sequence.getMatcherForPosition(0); final SequenceMatcher verifier = (lastPosition == 0) ? null : sequence.subsequence(1, sequenceLength); // Set the default shift to the length of the sequence final int[] shifts = new int[256]; Arrays.fill(shifts, sequenceLength); // Now set specific byte shifts for the bytes actually in // the sequence itself. The shift is the position in the sequence, // but we do not create a shift for the first position 0. for (int sequencePos = lastPosition; sequencePos > 0; sequencePos--) { final ByteMatcher aMatcher = sequence.getMatcherForPosition(sequencePos); final byte[] matchingBytes = aMatcher.getMatchingBytes(); for (final byte b : matchingBytes) { shifts[b & 0xFF] = sequencePos; } } return new SearchInfo(shifts, byteMatcher, verifier); }
/** * Calculates the safe shifts to use if searching forwards. A safe shift is either the length of * the sequence, if the byte does not appear in the {@link SequenceMatcher}, or the shortest * distance it appears from the end of the matcher. */ @Override public SearchInfo create() { // Get info about the matcher: final SequenceMatcher sequence = getMatcher(); final int sequenceLength = sequence.length(); // Create the search info object fields: final int lastPosition = sequenceLength - 1; final ByteMatcher byteMatcher = sequence.getMatcherForPosition(lastPosition); final SequenceMatcher verifier = (lastPosition == 0) ? AnyByteMatcher.ANY_BYTE_MATCHER : sequence.subsequence(0, lastPosition); // Set the default shift to the length of the sequence for all possible byte values: final int[] shifts = new int[256]; Arrays.fill(shifts, sequenceLength); // Now set specific shifts for the bytes actually in // the sequence itself. The shift is the distance of a position // from the end of the sequence, but we do not create a shift for // the very last position. for (int sequencePos = 0; sequencePos < lastPosition; sequencePos++) { final ByteMatcher aMatcher = sequence.getMatcherForPosition(sequencePos); final byte[] matchingBytes = aMatcher.getMatchingBytes(); final int distanceFromEnd = sequenceLength - sequencePos - 1; for (final byte b : matchingBytes) { shifts[b & 0xFF] = distanceFromEnd; } } return new SearchInfo(shifts, byteMatcher, verifier); }