Skip to content

Commit 200b4e0

Browse files
jableyheadius
authored andcommitted
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 <headius@headius.com>
1 parent 4e4bd02 commit 200b4e0

File tree

1 file changed

+29
-14
lines changed

1 file changed

+29
-14
lines changed

src/org/jruby/RubyStringIO.java

Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@
3434
import java.util.Arrays;
3535
import java.util.List;
3636

37-
import org.jcodings.Encoding;
3837
import org.jruby.anno.FrameField;
3938
import org.jruby.anno.JRubyClass;
4039
import org.jruby.anno.JRubyMethod;
@@ -744,6 +743,15 @@ public IRubyObject readchar() {
744743
return c;
745744
}
746745

746+
@JRubyMethod(name = "readchar", compat = CompatVersion.RUBY1_9)
747+
public IRubyObject readchar19(ThreadContext context) {
748+
IRubyObject c = getc19(context);
749+
750+
if (c.isNil()) throw getRuntime().newEOFError();
751+
752+
return c;
753+
}
754+
747755
@JRubyMethod(name = "readline", optional = 1, writes = FrameField.LASTLINE)
748756
public IRubyObject readline(ThreadContext context, IRubyObject[] args) {
749757
IRubyObject line = gets(context, args);
@@ -883,16 +891,7 @@ public IRubyObject ungetc(IRubyObject arg) {
883891

884892
int c = RubyNumeric.num2int(arg);
885893
if (data.pos == 0) return getRuntime().getNil();
886-
data.internal.modify();
887-
data.pos--;
888-
889-
ByteList bytes = data.internal.getByteList();
890-
891-
if (bytes.length() <= data.pos) {
892-
bytes.length((int)data.pos + 1);
893-
}
894-
895-
bytes.set((int) data.pos, c);
894+
ungetcCommon(c);
896895
return getRuntime().getNil();
897896
}
898897

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

903902
if (!arg.isNil()) {
903+
int c;
904904
if (arg instanceof RubyFixnum) {
905-
int codepoint = RubyNumeric.fix2int(arg);
906-
Encoding encoding = data.internal.getEncoding();
905+
c = RubyNumeric.fix2int(arg);
907906
} else {
908-
RubyString s = arg.convertToString();
907+
RubyString str = arg.convertToString();
908+
c = str.getEncoding().mbcToCode(str.getBytes(), 0, 1);
909909
}
910+
911+
ungetcCommon(c);
910912
}
911913

912914
return getRuntime().getNil();
913915
}
914916

917+
private void ungetcCommon(int c) {
918+
data.internal.modify();
919+
data.pos--;
920+
921+
ByteList bytes = data.internal.getByteList();
922+
923+
if (bytes.length() <= data.pos) {
924+
bytes.length((int)data.pos + 1);
925+
}
926+
927+
bytes.set((int) data.pos, c);
928+
}
929+
915930
@JRubyMethod(name = {"write", "syswrite"}, required = 1)
916931
public IRubyObject write(ThreadContext context, IRubyObject arg) {
917932
return context.getRuntime().newFixnum(writeInternal(context, arg));

0 commit comments

Comments
 (0)