blob: aba67c0c8caefdfd5021bf8f8163639c7c975e95 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
|
// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.io;
import java.nio.charset.Charset;
import java.nio.ByteBuffer;
/**
* Conventient utility for reading lines from ByteBuffers. Please
* read the method documentation for readLine() carefully. The NIO
* ByteBuffer abstraction is somewhat clumsy and thus usage of this
* code requires that you understand the semantics clearly.
*
* @author <a href="mailto:borud@yahoo-inc.com">Bjorn Borud</a>
*
*/
public class ReadLine {
static private Charset charset = Charset.forName("latin1");
/**
* Extract next line from a byte buffer. Looks for EOL characters
* between start and limit, and returns a string between start and
* the EOL charachers. It skips ahead past any remaining EOL
* characters and sets position to the first non-EOL character.
*
* If it doesn't find an EOL characher between start and limit
*/
public static String readLine(ByteBuffer buffer) {
int start = buffer.position();
for (int i = start; i < buffer.limit(); i++) {
if (isEolChar(buffer.get(i))) {
// detect and skip EOL at beginning. Also, update
// position so we compact the buffer if we exit the
// for loop without having found a proper string
if (i == start) {
for (; (i < buffer.limit()) && isEolChar(buffer.get(i)); i++) {
;
}
start = i;
buffer.position(i);
continue;
}
// extract string between start and i. limit() returns
// a buffer so we have to up-cast again
String line = charset.decode((ByteBuffer) buffer.slice().limit(i - start)).toString();
// skip remaining
for (; (i < buffer.limit()) && isEolChar(buffer.get(i)); i++) {
;
}
buffer.position(i);
return line;
}
}
// if we get here we didn't find any string. this may be
// because the buffer has no more content, ie. limit == position.
// if that is the case we clear the buffer.
//
// if we have content, but no more EOL characters we compact the
// buffer.
//
if (buffer.hasRemaining()) {
buffer.compact();
} else {
buffer.clear();
}
return null;
}
static boolean isEolChar(byte b) {
return ((10 == b) || (13 == b));
}
}
|