diff --git a/sslr-core/src/main/java/org/sonar/sslr/channel/CodeBuffer.java b/sslr-core/src/main/java/org/sonar/sslr/channel/CodeBuffer.java index fd958661d..f8631165c 100644 --- a/sslr-core/src/main/java/org/sonar/sslr/channel/CodeBuffer.java +++ b/sslr-core/src/main/java/org/sonar/sslr/channel/CodeBuffer.java @@ -27,6 +27,7 @@ import java.io.IOException; import java.io.Reader; import java.io.StringReader; +import java.nio.CharBuffer; /** * The CodeBuffer class provides all the basic features required to manipulate a source code character stream. Those features are : @@ -43,6 +44,7 @@ public class CodeBuffer implements CharSequence { private int lastChar = -1; private Cursor cursor; private char[] buffer; + private CharBuffer cb; private int bufferPosition = 0; private static final char LF = '\n'; private static final char CR = '\r'; @@ -73,6 +75,7 @@ protected CodeBuffer(Reader initialCodeReader, CodeReaderConfiguration configura } buffer = CharStreams.toString(reader).toCharArray(); + cb = CharBuffer.wrap(buffer); } catch (IOException e) { throw new ChannelException(e.getMessage(), e); } finally { @@ -203,7 +206,9 @@ public final int length() { @Override public final CharSequence subSequence(int start, int end) { - throw new UnsupportedOperationException(); + final int realStart = bufferPosition + start; + final int realEnd = bufferPosition + end; + return cb.subSequence(realStart, realEnd); } @Override diff --git a/sslr-core/src/test/java/org/sonar/sslr/channel/CodeBufferTest.java b/sslr-core/src/test/java/org/sonar/sslr/channel/CodeBufferTest.java index c04fc54e8..2d5067dbf 100644 --- a/sslr-core/src/test/java/org/sonar/sslr/channel/CodeBufferTest.java +++ b/sslr-core/src/test/java/org/sonar/sslr/channel/CodeBufferTest.java @@ -264,6 +264,29 @@ public void testChannelCodeReaderFilter() throws Exception { assertThat(code.pop(), is( -1)); } + @Test + public void testSubSequence() + { + final CodeReaderConfiguration cfg = new CodeReaderConfiguration(); + final String input = "some pretty short input\njust for kicks"; + final CodeBuffer code = new CodeBuffer(input, cfg); + + assertThat(code.subSequence(0, 4).toString(), is("some")); + assertThat(code.subSequence(24, 38).toString(), is("just for kicks")); + + // Shift by one; the subsequence should shift accordingly + code.pop(); + assertThat(code.subSequence(0, 4).toString(), is("ome ")); + + // Shift four more + code.pop(); + code.pop(); + code.pop(); + code.pop(); + assertThat(code.subSequence(0, 12).toString(), is("pretty short")); + assertThat(code.subSequence(13, 18).toString(), is("input")); + } + /** * Backward compatibility with a COBOL plugin: filter returns 0 instead of -1, when end of the stream has been reached. */