Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: jruby/jruby
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 6ee71037eb08^
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: fe821dea6171
Choose a head ref
  • 3 commits
  • 3 files changed
  • 1 contributor

Commits on Mar 19, 2015

  1. Unverified

    This commit is not signed, but one or more authors requires that any commit attributed to them is signed.
    Copy the full SHA
    6ee7103 View commit details
  2. Fix error type.

    headius committed Mar 19, 2015
    Copy the full SHA
    6120fca View commit details
  3. Re-port tr logic from MRI.

    headius committed Mar 19, 2015
    Copy the full SHA
    fe821de View commit details
Showing with 241 additions and 141 deletions.
  1. +1 −1 core/pom.xml
  2. +99 −51 core/src/main/java/org/jruby/RubyString.java
  3. +141 −89 core/src/main/java/org/jruby/util/StringSupport.java
2 changes: 1 addition & 1 deletion core/pom.xml
Original file line number Diff line number Diff line change
@@ -137,7 +137,7 @@
<dependency>
<groupId>org.jruby.extras</groupId>
<artifactId>bytelist</artifactId>
<version>1.0.12</version>
<version>1.0.13-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.jruby.jcodings</groupId>
150 changes: 99 additions & 51 deletions core/src/main/java/org/jruby/RubyString.java
Original file line number Diff line number Diff line change
@@ -73,6 +73,7 @@
import org.jruby.util.io.EncodingUtils;

import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.Locale;

import static org.jruby.RubyComparable.invcmp;
@@ -91,6 +92,7 @@
import static org.jruby.util.StringSupport.MBCLEN_CHARFOUND_P;
import static org.jruby.util.StringSupport.MBCLEN_INVALID_P;
import static org.jruby.util.StringSupport.MBCLEN_NEEDMORE_P;
import static org.jruby.util.StringSupport.TRANS_SIZE;
import static org.jruby.util.StringSupport.codeLength;
import static org.jruby.util.StringSupport.codePoint;
import static org.jruby.util.StringSupport.codeRangeScan;
@@ -2468,7 +2470,7 @@ private Encoding subBangVerifyEncoding(ThreadContext context, RubyString repl, i
Encoding strEnc = value.getEncoding();
if (codeRangeScan(strEnc, bytes, p, beg) != CR_7BIT ||
codeRangeScan(strEnc, bytes, p + end, len - end) != CR_7BIT) {
throw context.runtime.newArgumentError(
throw context.runtime.newEncodingCompatibilityError(
"incompatible character encodings " + strEnc + " and " + repl.value.getEncoding());
}
return repl.value.getEncoding();
@@ -2735,7 +2737,18 @@ private IRubyObject rindexCommon19(Ruby runtime, ThreadContext context, final IR
pos = subLength(pos);
}
} else if (sub instanceof RubyString) {
pos = StringSupport.rindex(value, StringSupport.strLengthFromRubyString(this, this.checkEncoding((RubyString) sub)), StringSupport.strLengthFromRubyString(((RubyString) sub), this.checkEncoding((RubyString) sub)), pos, (RubyString) sub, this.checkEncoding((RubyString) sub));
Encoding enc = this.checkEncoding((RubyString) sub);
pos = StringSupport.rindex(
value,
StringSupport.strLengthFromRubyString(
this,
enc),
StringSupport.strLengthFromRubyString(
((RubyString) sub),
enc),
pos,
(RubyString) sub,
this.checkEncoding((RubyString) sub));
} else {
IRubyObject tmp = sub.checkStringType();
if (tmp.isNil()) throw runtime.newTypeError("type mismatch: " + sub.getMetaClass().getName() + " given");
@@ -4773,65 +4786,64 @@ public IRubyObject tr_bang19(ThreadContext context, IRubyObject src, IRubyObject

private IRubyObject trTrans19(ThreadContext context, IRubyObject src, IRubyObject repl, boolean sflag) {
Ruby runtime = context.runtime;
if (value.getRealSize() == 0) return runtime.getNil();

RubyString replStr = repl.convertToString();
ByteList replList = replStr.value;
if (replList.getRealSize() == 0) return delete_bang19(context, src);

RubyString srcStr = src.convertToString();
ByteList srcList = srcStr.value;

if (value.getRealSize() == 0) return runtime.getNil();
if (replList.getRealSize() == 0) return delete_bang19(context, src);

int cr = getCodeRange();
Encoding e1 = checkEncoding(srcStr);
Encoding e2 = checkEncoding(replStr);
Encoding enc = e1 == e2 ? e1 : srcStr.checkEncoding(replStr);

int cr = getCodeRange();

final StringSupport.TR trSrc = new StringSupport.TR(srcList);
boolean cflag = false;
if (value.getRealSize() > 0) {
if (enc.isAsciiCompatible()) {
if (trSrc.buf.length > 0 && (trSrc.buf[trSrc.p] & 0xff) == '^' && trSrc.p + 1 < trSrc.pend) {
cflag = true;
trSrc.p++;
}
} else {
int cl = StringSupport.preciseLength(enc, trSrc.buf, trSrc.p, trSrc.pend);
if (enc.mbcToCode(trSrc.buf, trSrc.p, trSrc.pend) == '^' && trSrc.p + cl < trSrc.pend) {
cflag = true;
trSrc.p += cl;
}
}
}
int[] l = {0};

boolean singlebyte = singleByteOptimizable();
if (value.getRealSize() > 1 &&
EncodingUtils.encAscget(trSrc.buf, trSrc.p, trSrc.pend, l, enc) == '^' &&
trSrc.p + 1 < trSrc.pend){
cflag = true;
trSrc.p++;
}

int c;
int c, c0, last = 0;
final int[]trans = new int[StringSupport.TRANS_SIZE];
IntHash<Integer> hash = null;
final StringSupport.TR trRepl = new StringSupport.TR(replList);
boolean modify = false;
IntHash<Integer> hash = null;
boolean singlebyte = singleByteOptimizable();

int last = 0;
if (cflag) {
for (int i=0; i< StringSupport.TRANS_SIZE; i++) trans[i] = 1;
for (int i=0; i< StringSupport.TRANS_SIZE; i++) {
trans[i] = 1;
}

while ((c = StringSupport.trNext(trSrc, runtime, enc)) >= 0) {
while ((c = StringSupport.trNext(trSrc, runtime, enc)) != -1) {
if (c < StringSupport.TRANS_SIZE) {
trans[c & 0xff] = -1;
trans[c] = -1;
} else {
if (hash == null) hash = new IntHash<Integer>();
hash.put(c, 1); // QTRUE
}
}
while ((c = StringSupport.trNext(trRepl, runtime, enc)) >= 0) {} /* retrieve last replacer */
while ((c = StringSupport.trNext(trRepl, runtime, enc)) != -1) {} /* retrieve last replacer */
last = trRepl.now;
for (int i=0; i< StringSupport.TRANS_SIZE; i++) {
if (trans[i] >= 0) trans[i] = last;
if (trans[i] != -1) {
trans[i] = last;
}
}
} else {
for (int i=0; i< StringSupport.TRANS_SIZE; i++) trans[i] = -1;
for (int i=0; i< StringSupport.TRANS_SIZE; i++) {
trans[i] = -1;
}

while ((c = StringSupport.trNext(trSrc, runtime, enc)) >= 0) {
while ((c = StringSupport.trNext(trSrc, runtime, enc)) != -1) {
int r = StringSupport.trNext(trRepl, runtime, enc);
if (r == -1) r = trRepl.now;
if (c < StringSupport.TRANS_SIZE) {
@@ -4844,19 +4856,19 @@ private IRubyObject trTrans19(ThreadContext context, IRubyObject src, IRubyObjec
}
}

if (cr == CR_VALID) cr = CR_7BIT;
if (cr == CR_VALID) {
cr = CR_7BIT;
}
modifyAndKeepCodeRange();
int s = value.getBegin();
int send = s + value.getRealSize();
byte sbytes[] = value.getUnsafeBytes();
int max = value.getRealSize();
boolean modify = false;

int clen, tlen, c0;

if (sflag) {
int clen, tlen;
int max = value.getRealSize();
int save = -1;
byte[]buf = new byte[max];
byte[] buf = new byte[max];
int t = 0;
while (s < send) {
boolean mayModify = false;
@@ -4865,7 +4877,25 @@ private IRubyObject trTrans19(ThreadContext context, IRubyObject src, IRubyObjec
tlen = enc == e1 ? clen : codeLength(runtime, enc, c);
s += clen;

c = trCode(c, trans, hash, cflag, last, false);
if (c < TRANS_SIZE) {
c = trCode(c, trans, hash, cflag, last, false);
} else if (hash != null) {
Integer tmp = hash.get(c);
if (tmp == null) {
if (cflag) {
c = last;
} else {
c = -1;
}
} else if (cflag) {
c = -1;
} else {
c = tmp;
}
} else {
c = -1;
}

if (c != -1) {
if (save == c) {
if (cr == CR_7BIT && !Encoding.isAscii(c)) cr = CR_VALID;
@@ -4881,13 +4911,11 @@ private IRubyObject trTrans19(ThreadContext context, IRubyObject src, IRubyObjec
}

while (t + tlen >= max) {
max <<= 1;
byte[]tbuf = new byte[max];
System.arraycopy(buf, 0, tbuf, 0, buf.length);
buf = tbuf;
max *= 2;
buf = Arrays.copyOf(buf, max);
}
enc.codeToMbc(c, buf, t);
if (mayModify && (tlen == 1 ? sbytes[s] != buf[t] : ByteList.memcmp(sbytes, s, buf, t, tlen) != 0)) modify = true;
if (mayModify && ByteList.memcmp(sbytes, s, buf, t, tlen) != 0) modify = true;
if (cr == CR_7BIT && !Encoding.isAscii(c)) cr = CR_VALID;
t += tlen;
}
@@ -4909,7 +4937,7 @@ private IRubyObject trTrans19(ThreadContext context, IRubyObject src, IRubyObjec
s++;
}
} else {
max += max >> 1;
int clen, tlen, max = (int)(value.realSize() * 1.2);
byte[]buf = new byte[max];
int t = 0;

@@ -4920,7 +4948,25 @@ private IRubyObject trTrans19(ThreadContext context, IRubyObject src, IRubyObjec
tlen = enc == e1 ? clen : codeLength(runtime, enc, c);

c = trCode(c, trans, hash, cflag, last, true);

if (c < TRANS_SIZE) {
c = trans[c];
} else if (hash != null) {
Integer tmp = hash.get(c);
if (tmp == null) {
if (cflag) {
c = last;
} else {
c = -1;
}
} else if (cflag) {
c = -1;
} else {
c = tmp;
}
}
else {
c = cflag ? last : -1;
}
if (c != -1) {
tlen = codeLength(runtime, enc, c);
modify = true;
@@ -4930,12 +4976,14 @@ private IRubyObject trTrans19(ThreadContext context, IRubyObject src, IRubyObjec
}
while (t + tlen >= max) {
max <<= 1;
byte[]tbuf = new byte[max];
System.arraycopy(buf, 0, tbuf, 0, buf.length);
buf = tbuf;
buf = Arrays.copyOf(buf, max);
}
if (s != t) {
enc.codeToMbc(c, buf, t);
if (mayModify && ByteList.memcmp(sbytes, s, buf, t, tlen) != 0) {
modify = true;
}
}
enc.codeToMbc(c, buf, t);
if (mayModify && (tlen == 1 ? sbytes[s] != buf[t] : ByteList.memcmp(sbytes, s, buf, t, tlen) != 0)) modify = true;

if (cr == CR_7BIT && !Encoding.isAscii(c)) cr = CR_VALID;
s += clen;
Loading