int blen = slen + 30; /* len + margin */
ByteList dest = new ByteList(blen);
dest.setRealSize(blen);
int offset = 0, buf = 0, bp = 0, cp = begin;
Encoding enc = getEncodingForKCodeDefault(runtime, pattern, arg);
RubyMatchData match = null;
while (beg >= 0) {
final RubyString val;
final int begz = matcher.getBegin();
final int endz = matcher.getEnd();
if (repl == null) { // block given
match = RubyRegexp.updateBackRef(context, this, scope, matcher, pattern);
val = objAsString(context, block.yield(context, substr(runtime, begz, endz - begz)));
modifyCheck(bytes, slen);
if (bang) frozenCheck();
} else {
val = RubyRegexp.regsub(repl, this, matcher, enc);
}
tuFlags |= val.flags;
ByteList vbuf = val.value;
int len = (bp - buf) + (beg - offset) + vbuf.getRealSize() + 3;
if (blen < len) {
while (blen < len) blen <<= 1;
len = bp - buf;
dest.realloc(blen);
dest.setRealSize(blen);
bp = buf + len;
}
len = beg - offset; /* copy pre-match substr */
System.arraycopy(bytes, cp, dest.getUnsafeBytes(), bp, len);
bp += len;
System.arraycopy(vbuf.getUnsafeBytes(), vbuf.getBegin(), dest.getUnsafeBytes(), bp, vbuf.getRealSize());
bp += vbuf.getRealSize();
offset = endz;
if (begz == endz) {
if (slen <= endz) break;
len = enc.length(bytes, begin + endz, range);
System.arraycopy(bytes, begin + endz, dest.getUnsafeBytes(), bp, len);
bp += len;
offset = endz + len;
}
cp = begin + offset;