1 /*
2 * Copyright 2015 The Netty Project
3 *
4 * The Netty Project licenses this file to you under the Apache License, version 2.0 (the
5 * "License"); you may not use this file except in compliance with the License. You may obtain a
6 * copy of the License at:
7 *
8 * https://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software distributed under the License
11 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
12 * or implied. See the License for the specific language governing permissions and limitations under
13 * the License.
14 */
15 package io.netty.util;
16
17 import static io.netty.util.ByteProcessorUtils.CARRIAGE_RETURN;
18 import static io.netty.util.ByteProcessorUtils.HTAB;
19 import static io.netty.util.ByteProcessorUtils.LINE_FEED;
20 import static io.netty.util.ByteProcessorUtils.SPACE;
21
22 /**
23 * Provides a mechanism to iterate over a collection of bytes.
24 */
25 public interface ByteProcessor {
26 /**
27 * A {@link ByteProcessor} which finds the first appearance of a specific byte.
28 */
29 class IndexOfProcessor implements ByteProcessor {
30 private final byte byteToFind;
31
32 public IndexOfProcessor(byte byteToFind) {
33 this.byteToFind = byteToFind;
34 }
35
36 @Override
37 public boolean process(byte value) {
38 return value != byteToFind;
39 }
40 }
41
42 /**
43 * A {@link ByteProcessor} which finds the first appearance which is not of a specific byte.
44 */
45 class IndexNotOfProcessor implements ByteProcessor {
46 private final byte byteToNotFind;
47
48 public IndexNotOfProcessor(byte byteToNotFind) {
49 this.byteToNotFind = byteToNotFind;
50 }
51
52 @Override
53 public boolean process(byte value) {
54 return value == byteToNotFind;
55 }
56 }
57
58 /**
59 * Aborts on a {@code NUL (0x00)}.
60 */
61 ByteProcessor FIND_NUL = new IndexOfProcessor((byte) 0);
62
63 /**
64 * Aborts on a non-{@code NUL (0x00)}.
65 */
66 ByteProcessor FIND_NON_NUL = new IndexNotOfProcessor((byte) 0);
67
68 /**
69 * Aborts on a {@code CR ('\r')}.
70 */
71 ByteProcessor FIND_CR = new IndexOfProcessor(CARRIAGE_RETURN);
72
73 /**
74 * Aborts on a non-{@code CR ('\r')}.
75 */
76 ByteProcessor FIND_NON_CR = new IndexNotOfProcessor(CARRIAGE_RETURN);
77
78 /**
79 * Aborts on a {@code LF ('\n')}.
80 */
81 ByteProcessor FIND_LF = new IndexOfProcessor(LINE_FEED);
82
83 /**
84 * Aborts on a non-{@code LF ('\n')}.
85 */
86 ByteProcessor FIND_NON_LF = new IndexNotOfProcessor(LINE_FEED);
87
88 /**
89 * Aborts on a semicolon {@code (';')}.
90 */
91 ByteProcessor FIND_SEMI_COLON = new IndexOfProcessor((byte) ';');
92
93 /**
94 * Aborts on a comma {@code (',')}.
95 */
96 ByteProcessor FIND_COMMA = new IndexOfProcessor((byte) ',');
97
98 /**
99 * Aborts on a ascii space character ({@code ' '}).
100 */
101 ByteProcessor FIND_ASCII_SPACE = new IndexOfProcessor(SPACE);
102
103 /**
104 * Aborts on a {@code CR ('\r')} or a {@code LF ('\n')}.
105 */
106 ByteProcessor FIND_CRLF = new ByteProcessor() {
107 @Override
108 public boolean process(byte value) {
109 return value != CARRIAGE_RETURN && value != LINE_FEED;
110 }
111 };
112
113 /**
114 * Aborts on a byte which is neither a {@code CR ('\r')} nor a {@code LF ('\n')}.
115 */
116 ByteProcessor FIND_NON_CRLF = new ByteProcessor() {
117 @Override
118 public boolean process(byte value) {
119 return value == CARRIAGE_RETURN || value == LINE_FEED;
120 }
121 };
122
123 /**
124 * Aborts on a linear whitespace (a ({@code ' '} or a {@code '\t'}).
125 */
126 ByteProcessor FIND_LINEAR_WHITESPACE = new ByteProcessor() {
127 @Override
128 public boolean process(byte value) {
129 return value != SPACE && value != HTAB;
130 }
131 };
132
133 /**
134 * Aborts on a byte which is not a linear whitespace (neither {@code ' '} nor {@code '\t'}).
135 */
136 ByteProcessor FIND_NON_LINEAR_WHITESPACE = new ByteProcessor() {
137 @Override
138 public boolean process(byte value) {
139 return value == SPACE || value == HTAB;
140 }
141 };
142
143 /**
144 * @return {@code true} if the processor wants to continue the loop and handle the next byte in the buffer.
145 * {@code false} if the processor wants to stop handling bytes and abort the loop.
146 */
147 boolean process(byte value) throws Exception;
148 }