1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package io.netty.buffer.search;
16
17 import io.netty.util.internal.PlatformDependent;
18
19
20
21
22
23
24
25
26
27
28
29 public class KmpSearchProcessorFactory extends AbstractSearchProcessorFactory {
30
31 private final int[] jumpTable;
32 private final byte[] needle;
33
34 public static class Processor implements SearchProcessor {
35
36 private final byte[] needle;
37 private final int[] jumpTable;
38 private long currentPosition;
39
40 Processor(byte[] needle, int[] jumpTable) {
41 this.needle = needle;
42 this.jumpTable = jumpTable;
43 }
44
45 @Override
46 public boolean process(byte value) {
47 while (currentPosition > 0 && PlatformDependent.getByte(needle, currentPosition) != value) {
48 currentPosition = PlatformDependent.getInt(jumpTable, currentPosition);
49 }
50 if (PlatformDependent.getByte(needle, currentPosition) == value) {
51 currentPosition++;
52 }
53 if (currentPosition == needle.length) {
54 currentPosition = PlatformDependent.getInt(jumpTable, currentPosition);
55 return false;
56 }
57
58 return true;
59 }
60
61 @Override
62 public void reset() {
63 currentPosition = 0;
64 }
65 }
66
67 KmpSearchProcessorFactory(byte[] needle) {
68 this.needle = needle.clone();
69 this.jumpTable = new int[needle.length + 1];
70
71 int j = 0;
72 for (int i = 1; i < needle.length; i++) {
73 while (j > 0 && needle[j] != needle[i]) {
74 j = jumpTable[j];
75 }
76 if (needle[j] == needle[i]) {
77 j++;
78 }
79 jumpTable[i + 1] = j;
80 }
81 }
82
83
84
85
86 @Override
87 public Processor newSearchProcessor() {
88 return new Processor(needle, jumpTable);
89 }
90
91 }