From 200b4e03b338b3b9aaed982f7abd07f6a385d10d Mon Sep 17 00:00:00 2001 From: James Abley Date: Fri, 11 Feb 2011 21:40:24 +0000 Subject: [PATCH] JRUBY-5455: StringIO 1.9 ungetc * 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 --- src/org/jruby/RubyStringIO.java | 43 ++++++++++++++++++++++----------- 1 file changed, 29 insertions(+), 14 deletions(-) diff --git a/src/org/jruby/RubyStringIO.java b/src/org/jruby/RubyStringIO.java index 5e03733d98b..150c5f6eac4 100644 --- a/src/org/jruby/RubyStringIO.java +++ b/src/org/jruby/RubyStringIO.java @@ -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; @@ -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); @@ -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(); } @@ -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));