@@ -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