package org.jruby.lexer;
import org.jcodings.Encoding;
import org.jruby.RubyArray;
import org.jruby.RubyEncoding;
import org.jruby.RubyIO;
import org.jruby.RubyString;
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.util.ByteList;
import org.jruby.util.IOInputStream;
import org.jruby.util.io.ChannelHelper;
import java.nio.channels.Channel;
import java.nio.channels.Channels;
public class GetsLexerSource extends LexerSource {
private IRubyObject io;
private Encoding encoding;
private int offset;
public GetsLexerSource(String sourceName, int line, IRubyObject io, RubyArray scriptLines, Encoding encoding) {
super(sourceName, line, scriptLines);
this.io = io;
this.encoding = encoding;
}
public GetsLexerSource(String sourceName, int line, IRubyObject io, RubyArray scriptLines) {
this(sourceName, line, io, scriptLines, frobnicateEncoding(io));
}
public static final Encoding frobnicateEncoding(IRubyObject io) {
if (!io.respondsTo("encoding")) return io.getRuntime().getDefaultExternalEncoding();
IRubyObject encodingObject = io.callMethod(io.getRuntime().getCurrentContext(), "encoding");
return encodingObject instanceof RubyEncoding ?
((RubyEncoding) encodingObject).getEncoding() : io.getRuntime().getDefaultExternalEncoding();
}
@Override
public Encoding getEncoding() {
return encoding;
}
@Override
public void setEncoding(Encoding encoding) {
this.encoding = encoding;
encodeExistingScriptLines(encoding);
}
@Override
public ByteList gets() {
IRubyObject result = io.callMethod(io.getRuntime().getCurrentContext(), "gets");
if (result.isNil()) return null;
ByteList bytelist = result.convertToString().getByteList();
offset += bytelist.getRealSize();
bytelist.setEncoding(encoding);
if (scriptLines != null) scriptLines.append(RubyString.newString(scriptLines.getRuntime(), bytelist));
return bytelist;
}
@Override
public int getOffset() {
return offset;
}
@Override
public Channel getRemainingAsChannel() {
if (io instanceof RubyIO) return ((RubyIO) io).getChannel();
return ChannelHelper.readableChannel(new IOInputStream(io));
}
@Override
public IRubyObject getRemainingAsIO() {
return io;
}
}