Skip to content

Commit 5522f39

Browse files
committed
Duplicate unget logic for buffer management from C
1 parent 8a19d64 commit 5522f39

File tree

1 file changed

+39
-22
lines changed

1 file changed

+39
-22
lines changed

ext/java/org/jruby/ext/stringio/StringIO.java

Lines changed: 39 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1431,7 +1431,6 @@ public IRubyObject ungetc(ThreadContext context, IRubyObject arg) {
14311431
if (len <= 0) EncodingUtils.encUintChr(context, cc, enc);
14321432
enc.codeToMbc(cc, buf, 0);
14331433
ungetbyteCommon(context, buf, 0, len);
1434-
return context.nil;
14351434
} else {
14361435
arg = arg.convertToString();
14371436
enc = getEncoding();
@@ -1440,10 +1439,10 @@ public IRubyObject ungetc(ThreadContext context, IRubyObject arg) {
14401439
if (enc != enc2 && enc != ASCIIEncoding.INSTANCE) {
14411440
argStr = EncodingUtils.strConvEnc(context, argStr, enc2, enc);
14421441
}
1443-
ByteList argBytes = argStr.getByteList();
1444-
ungetbyteCommon(context, argBytes.unsafeBytes(), argBytes.begin(), argBytes.realSize());
1445-
return context.nil;
1442+
ungetbyteCommon(context, argStr);
14461443
}
1444+
1445+
return context.nil;
14471446
}
14481447

14491448
private void ungetbyteCommon(ThreadContext context, int c) {
@@ -1475,32 +1474,50 @@ private void ungetbyteCommon(ThreadContext context, RubyString ungetBytes) {
14751474
ungetbyteCommon(context, ungetByteList.unsafeBytes(), ungetByteList.begin(), ungetByteList.realSize());
14761475
}
14771476

1478-
private void ungetbyteCommon(ThreadContext context, byte[] ungetBytes, int ungetBegin, int ungetLen) {
1479-
final int start; // = ptr.pos;
1480-
1481-
if (ungetLen == 0) return;
1477+
private void ungetbyteCommon(ThreadContext context, byte[] ungetBytes, int cp, int cl) {
1478+
if (cl == 0) return;
14821479

14831480
StringIOData ptr = this.ptr;
14841481

14851482
boolean locked = lock(context, ptr);
14861483
try {
1487-
RubyString string = ptr.string;
1488-
string.modify();
1484+
int pos = ptr.pos, len, rest;
1485+
RubyString str = ptr.string;
1486+
ByteList strBytelist;
1487+
byte[] strBytes;
1488+
int s;
14891489

1490-
int pos = ptr.pos;
1491-
if (ungetLen > pos) {
1492-
start = 0;
1490+
len = str.size();
1491+
rest = pos - len;
1492+
if (cl > pos) {
1493+
int ex = cl - (rest < 0 ? pos : len);
1494+
str.modifyExpand(len + ex);
1495+
strBytelist = str.getByteList();
1496+
strBytes = strBytelist.unsafeBytes();
1497+
s = strBytelist.begin();
1498+
strBytelist.setRealSize(len + ex);
1499+
if (rest < 0) System.arraycopy(strBytes, s + pos, strBytes, s + cl, -rest);
1500+
pos = 0;
1501+
}
1502+
else {
1503+
if (rest > 0) {
1504+
str.modifyExpand(len + rest);
1505+
strBytelist = str.getByteList();
1506+
strBytelist.setRealSize(len + rest);
1507+
} else {
1508+
strBytelist = str.getByteList();
1509+
}
1510+
strBytes = strBytelist.unsafeBytes();
1511+
s = strBytelist.begin();
1512+
if (rest > cl) Arrays.fill(strBytes, len, rest - cl, (byte) 0);
1513+
pos -= cl;
1514+
}
1515+
if (ungetBytes != null) {
1516+
System.arraycopy(ungetBytes, cp, strBytes, s + pos, cl);
14931517
} else {
1494-
start = pos - ungetLen;
1518+
System.arraycopy(strBytes, s, strBytes, s + pos, cl);
14951519
}
1496-
1497-
ByteList byteList = string.getByteList();
1498-
1499-
if (isEndOfString()) byteList.length(Math.max(pos, ungetLen));
1500-
1501-
byteList.replace(start, pos - start, ungetBytes, ungetBegin, ungetLen);
1502-
1503-
ptr.pos = start;
1520+
ptr.pos = pos;
15041521
} finally {
15051522
if (locked) unlock(ptr);
15061523
}

0 commit comments

Comments
 (0)