diff options
Diffstat (limited to 'vespajlib/src/main/java/com/yahoo/io/ReadLine.java')
-rw-r--r-- | vespajlib/src/main/java/com/yahoo/io/ReadLine.java | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/vespajlib/src/main/java/com/yahoo/io/ReadLine.java b/vespajlib/src/main/java/com/yahoo/io/ReadLine.java new file mode 100644 index 00000000000..aba67c0c8ca --- /dev/null +++ b/vespajlib/src/main/java/com/yahoo/io/ReadLine.java @@ -0,0 +1,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)); + } +} |