package org.jruby.util.io;
import org.jcodings.Encoding;
import org.jruby.Ruby;
import org.jruby.RubyHash;
import org.jruby.RubyString;
import org.jruby.ast.util.ArgsUtil;
import org.jruby.runtime.Block;
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.util.StringSupport;
import org.jruby.util.TypeConverter;
public class Getline {
public interface Callback<Self, Return extends IRubyObject> {
Return getline(ThreadContext context, Self self, IRubyObject rs, int limit, boolean chomp, Block block);
}
public static <Self, Return extends IRubyObject> Return getlineCall(ThreadContext context, Callback<Self, Return> getline, Self self, Encoding enc_io) {
return getlineCall(context, getline, self, enc_io, 0, null, null, null, Block.NULL_BLOCK);
}
public static <Self, Return extends IRubyObject> Return getlineCall(ThreadContext context, Callback<Self, Return> getline, Self self, Encoding enc_io, IRubyObject arg0) {
return getlineCall(context, getline, self, enc_io, 1, arg0, null, null, Block.NULL_BLOCK);
}
public static <Self, Return extends IRubyObject> Return getlineCall(ThreadContext context, Callback<Self, Return> getline, Self self, Encoding enc_io, IRubyObject arg0, IRubyObject arg1) {
return getlineCall(context, getline, self, enc_io, 2, arg0, arg1, null, Block.NULL_BLOCK);
}
public static <Self, Return extends IRubyObject> Return getlineCall(ThreadContext context, Callback<Self, Return> getline, Self self, Encoding enc_io, IRubyObject arg0, IRubyObject arg1, IRubyObject arg2) {
return getlineCall(context, getline, self, enc_io, 3, arg0, arg1, arg2, Block.NULL_BLOCK);
}
public static <Self, Return extends IRubyObject> Return getlineCall(ThreadContext context, Callback<Self, Return> getline, Self self, Encoding enc_io, Block block) {
return getlineCall(context, getline, self, enc_io, 0, null, null, null, block);
}
public static <Self, Return extends IRubyObject> Return getlineCall(ThreadContext context, Callback<Self, Return> getline, Self self, Encoding enc_io, IRubyObject arg0, Block block) {
return getlineCall(context, getline, self, enc_io, 1, arg0, null, null, block);
}
public static <Self, Return extends IRubyObject> Return getlineCall(ThreadContext context, Callback<Self, Return> getline, Self self, Encoding enc_io, IRubyObject arg0, IRubyObject arg1, Block block) {
return getlineCall(context, getline, self, enc_io, 2, arg0, arg1, null, block);
}
public static <Self, Return extends IRubyObject> Return getlineCall(ThreadContext context, Callback<Self, Return> getline, Self self, Encoding enc_io, IRubyObject arg0, IRubyObject arg1, IRubyObject arg2, Block block) {
return getlineCall(context, getline, self, enc_io, 3, arg0, arg1, arg2, block);
}
public static <Self, Return extends IRubyObject> Return getlineCall(ThreadContext context, Callback<Self, Return> getline, Self self, Encoding enc_io, int argc, IRubyObject arg0, IRubyObject arg1, IRubyObject arg2, Block block) {
final IRubyObject nil = context.nil;
boolean chomp = false;
long limit;
IRubyObject opt, optArg = nil, sepArg = null, limArg = null;
switch (argc) {
case 1:
optArg = arg0;
break;
case 2:
sepArg = arg0;
optArg = arg1;
break;
case 3:
sepArg = arg0;
limArg = arg1;
optArg = arg2;
break;
}
final Ruby runtime = context.runtime;
opt = ArgsUtil.getOptionsArg(runtime, optArg);
if (opt == nil) {
if (argc == 1) {
sepArg = arg0;
} else if (argc == 2) {
limArg = arg1;
}
} else {
IRubyObject chompKwarg = ArgsUtil.extractKeywordArg(context, "chomp", (RubyHash) opt);
if (chompKwarg != null) {
chomp = chompKwarg.isTrue();
}
}
IRubyObject rs = runtime.getRecordSeparatorVar().get();
IRubyObject lim = nil;
if (sepArg != null && limArg == null) {
IRubyObject tmp = nil;
if (sepArg == nil || (tmp = TypeConverter.checkStringType(runtime, sepArg)) != nil) {
rs = tmp;
} else {
lim = sepArg;
}
} else if (sepArg != null && limArg != null) {
rs = sepArg;
if (rs != nil) {
rs = rs.convertToString();
}
lim = limArg;
}
if (rs != nil) {
final RubyString rs_s = ((RubyString) rs);
final Encoding enc_rs = rs_s.getEncoding();
if (enc_io != enc_rs &&
(rs_s.scanForCodeRange() != StringSupport.CR_7BIT ||
(rs_s.size() > 0 && !enc_io.isAsciiCompatible()))) {
if (rs == runtime.getGlobalVariables().getDefaultSeparator()) {
rs = RubyString.newStringLight(runtime, 2, enc_io).cat('\n', enc_io);
}
else {
throw runtime.newArgumentError("encoding mismatch: " + enc_io + " IO with " + enc_rs + " RS");
}
}
}
limit = lim == nil ? -1 : lim.convertToInteger().getLongValue();
return getline.getline(context, self, rs, (int) limit, chomp, block);
}
}