package org.jruby.lexer;
import org.jcodings.Encoding;
import org.jruby.RubyArray;
import org.jruby.RubyIO;
import org.jruby.RubyString;
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.util.ByteList;
import org.jruby.util.io.ChannelHelper;
import java.io.ByteArrayInputStream;
import java.nio.channels.Channel;
public class ByteListLexerSource extends LexerSource {
private ByteList completeSource;
private int offset = 0;
public ByteListLexerSource(String sourceName, int line, ByteList in, RubyArray list) {
super(sourceName, line, list);
this.completeSource = in;
}
@Override
public Encoding getEncoding() {
return completeSource.getEncoding();
}
@Override
public void setEncoding(Encoding encoding) {
completeSource.setEncoding(encoding);
encodeExistingScriptLines(encoding);
}
@Override
public ByteList gets() {
int length = completeSource.length();
if (offset >= length) return null;
int end = completeSource.indexOf('\n', offset) + 1;
if (end == 0) end = length;
ByteList line = completeSource.makeShared(offset, end - offset);
offset = end;
if (scriptLines != null) scriptLines.append(RubyString.newString(scriptLines.getRuntime(), line));
return line;
}
@Override
public int getOffset() {
return offset;
}
@Override
public Channel getRemainingAsChannel() {
ByteArrayInputStream bais = new ByteArrayInputStream(completeSource.unsafeBytes(), completeSource.begin(), completeSource.realSize());
bais.skip(offset);
return ChannelHelper.readableChannel(bais);
}
@Override
public IRubyObject getRemainingAsIO() {
if (scriptLines == null) return null;
return new RubyIO(scriptLines.getRuntime(), getRemainingAsChannel());
}
}