Skip to content

Commit

Permalink
JRUBY-5455: StringIO 1.9 ungetc
Browse files Browse the repository at this point in the history
* Could probably do with more specs for ungetc around codepoints
  outside the BMP.
* getc passes.
* readchar passes.
* Extract common 1.8 / 1.9 behaviour for ungetc.

Signed-off-by: Charles Oliver Nutter <headius@headius.com>
  • Loading branch information
jabley authored and headius committed Feb 16, 2011
1 parent 4e4bd02 commit 200b4e0
Showing 1 changed file with 29 additions and 14 deletions.
43 changes: 29 additions & 14 deletions src/org/jruby/RubyStringIO.java
Expand Up @@ -34,7 +34,6 @@
import java.util.Arrays;
import java.util.List;

import org.jcodings.Encoding;
import org.jruby.anno.FrameField;
import org.jruby.anno.JRubyClass;
import org.jruby.anno.JRubyMethod;
Expand Down Expand Up @@ -744,6 +743,15 @@ public IRubyObject readchar() {
return c;
}

@JRubyMethod(name = "readchar", compat = CompatVersion.RUBY1_9)
public IRubyObject readchar19(ThreadContext context) {
IRubyObject c = getc19(context);

if (c.isNil()) throw getRuntime().newEOFError();

return c;
}

@JRubyMethod(name = "readline", optional = 1, writes = FrameField.LASTLINE)
public IRubyObject readline(ThreadContext context, IRubyObject[] args) {
IRubyObject line = gets(context, args);
Expand Down Expand Up @@ -883,16 +891,7 @@ public IRubyObject ungetc(IRubyObject arg) {

int c = RubyNumeric.num2int(arg);
if (data.pos == 0) return getRuntime().getNil();
data.internal.modify();
data.pos--;

ByteList bytes = data.internal.getByteList();

if (bytes.length() <= data.pos) {
bytes.length((int)data.pos + 1);
}

bytes.set((int) data.pos, c);
ungetcCommon(c);
return getRuntime().getNil();
}

Expand All @@ -901,17 +900,33 @@ public IRubyObject ungetc19(ThreadContext context, IRubyObject arg) {
checkReadable();

if (!arg.isNil()) {
int c;
if (arg instanceof RubyFixnum) {
int codepoint = RubyNumeric.fix2int(arg);
Encoding encoding = data.internal.getEncoding();
c = RubyNumeric.fix2int(arg);
} else {
RubyString s = arg.convertToString();
RubyString str = arg.convertToString();
c = str.getEncoding().mbcToCode(str.getBytes(), 0, 1);
}

ungetcCommon(c);
}

return getRuntime().getNil();
}

private void ungetcCommon(int c) {
data.internal.modify();
data.pos--;

ByteList bytes = data.internal.getByteList();

if (bytes.length() <= data.pos) {
bytes.length((int)data.pos + 1);
}

bytes.set((int) data.pos, c);
}

@JRubyMethod(name = {"write", "syswrite"}, required = 1)
public IRubyObject write(ThreadContext context, IRubyObject arg) {
return context.getRuntime().newFixnum(writeInternal(context, arg));
Expand Down

0 comments on commit 200b4e0

Please sign in to comment.