import io.netty.buffer.ByteBuf; //导入方法依赖的package包/类
@Override
public Iterable split(final ByteBuf buffer, final Charset charset, final boolean includeRemainingData) {
return () -> new AbstractIterator() {
// TODO Might throw an exception if multibyte charset is used and buffer is not complete.
// Use CharsetDecoder to create a CharBuffer and match on that!
private final String inputAsString = buffer.toString(charset);
final Matcher matcher = pattern.matcher(inputAsString);
private int positionInString = 0;
@Override
protected String computeNext() {
try {
if (!buffer.isReadable()) {
return endOfData();
}
if (matcher.find()) {
int firstByte = matcher.start();
if (firstByte == 0) {
// advance further, the buffer begins with our pattern.
if (matcher.find()) {
firstByte = matcher.start();
} else {
if (!includeRemainingData) {
// couldn't find the end of the entry (i.e. there wasn't a next line yet)
return endOfData();
} else {
// couldn't find another line, but we are asked to finish up, include everything that remains
return getRemainingContent();
}
}
}
if (firstByte == 0) {
// still haven't found a non-zero length string, keep waiting for more data.
return endOfData();
}
final String substring = inputAsString.substring(positionInString, firstByte);
positionInString = firstByte;
buffer.skipBytes(substring.getBytes(charset).length); // TODO performance
return substring;
} else {
if (includeRemainingData) {
return getRemainingContent();
}
return endOfData();
}
} catch (IllegalStateException e) {
// the cause contains the CharacterCodingException from the ChannelBuffer.toString() methods
// this usually means the buffer ended with an incomplete encoding of a unicode character.
// WHY U SO SUCK CHARACTER ENCODINGS?
// we need to wait until more data is available
return endOfData();
} finally {
buffer.discardReadBytes();
}
}
private String getRemainingContent() {
final ByteBuf channelBuffer = buffer.readBytes(buffer.readableBytes());
return channelBuffer.toString(charset);
}
};
}