Skip to content

Commit

Permalink
Merge branch 'jruby-1_7'
Browse files Browse the repository at this point in the history
  • Loading branch information
headius committed Nov 26, 2013
2 parents 351790d + a6411a8 commit a97d736
Show file tree
Hide file tree
Showing 2 changed files with 126 additions and 90 deletions.
171 changes: 92 additions & 79 deletions core/src/main/java/org/jruby/RubyString.java
Expand Up @@ -1301,18 +1301,23 @@ public final RubyString cat(byte[] str, int beg, int len) {
return this;
}

// // rb_str_buf_append
public final RubyString cat19(RubyString str) {
ByteList other = str.value;
int otherCr = cat19(other, str.getCodeRange());
infectBy(str);
str.setCodeRange(otherCr);
// // rb_str_buf_append against VALUE
public final RubyString cat19(RubyString str2) {
ByteList ptr = str2.value;

int str2_cr = cat19(str2.getByteList(), str2.getCodeRange());

infectBy(str2);
str2.setCodeRange(str2_cr);

return this;
}

// rb_str_buf_append against ptr
public final int cat19(ByteList other, int codeRange) {
return cat(other.getUnsafeBytes(), other.getBegin(), other.getRealSize(),
other.getEncoding(), codeRange);
int[] ptr_cr_ret = {codeRange};
EncodingUtils.encCrStrBufCat(getRuntime(), this, other, other.getEncoding(), codeRange, ptr_cr_ret);
return ptr_cr_ret[0];
}

public final RubyString cat(RubyString str) {
Expand Down Expand Up @@ -1345,90 +1350,24 @@ public final RubyString cat(int code, Encoding enc) {
return this;
}

public final int cat(byte[]bytes, int p, int len, Encoding enc, int cr) {
modify(value.getRealSize() + len);
int toCr = getCodeRange();
Encoding toEnc = value.getEncoding();
int cr2 = cr;

if (toEnc == enc) {
if (toCr == CR_UNKNOWN) {
cr = CR_UNKNOWN;
} else if (cr == CR_UNKNOWN) {
cr = codeRangeScan(enc, bytes, p, len);
}
} else {
if (!toEnc.isAsciiCompatible() || !enc.isAsciiCompatible()) {
if (len == 0) return toCr;
if (value.getRealSize() == 0) {
System.arraycopy(bytes, p, value.getUnsafeBytes(), value.getBegin() + value.getRealSize(), len);
value.setRealSize(value.getRealSize() + len);
setEncodingAndCodeRange(enc, cr);
return cr;
}
throw getRuntime().newEncodingCompatibilityError("incompatible character encodings: " + toEnc + " and " + enc);
}
if (cr == CR_UNKNOWN) cr = codeRangeScan(enc, bytes, p, len);
if (toCr == CR_UNKNOWN) {
if (toEnc == ASCIIEncoding.INSTANCE || cr != CR_7BIT) toCr = scanForCodeRange();
}
}
if (cr2 != 0) cr2 = cr;

if (toEnc != enc && toCr != CR_7BIT && cr != CR_7BIT) {
throw getRuntime().newEncodingCompatibilityError("incompatible character encodings: " + toEnc + " and " + enc);
}

final int resCr;
final Encoding resEnc;
if (toCr == CR_UNKNOWN) {
resEnc = toEnc;
resCr = CR_UNKNOWN;
} else if (toCr == CR_7BIT) {
if (cr == CR_7BIT) {
resEnc = toEnc;
resCr = CR_7BIT;
} else {
resEnc = enc;
resCr = cr;
}
} else if (toCr == CR_VALID) {
resEnc = toEnc;
if (cr == CR_7BIT || cr == CR_VALID) {
resCr = toCr;
} else {
resCr = cr;
}
} else {
resEnc = toEnc;
resCr = len > 0 ? CR_UNKNOWN : toCr;
}

if (len < 0) throw getRuntime().newArgumentError("negative string size (or size too big)");

System.arraycopy(bytes, p, value.getUnsafeBytes(), value.getBegin() + value.getRealSize(), len);
value.setRealSize(value.getRealSize() + len);
setEncodingAndCodeRange(resEnc, resCr);

return cr2;
}

public final int cat(byte[]bytes, int p, int len, Encoding enc) {
return cat(bytes, p, len, enc, CR_UNKNOWN);
int[] ptr_cr_ret = {CR_UNKNOWN};
EncodingUtils.encCrStrBufCat(getRuntime(), this, new ByteList(bytes, p, len), enc, CR_UNKNOWN, ptr_cr_ret);
return ptr_cr_ret[0];
}

public final RubyString catAscii(byte[]bytes, int p, int len) {
Encoding enc = value.getEncoding();
if (enc.isAsciiCompatible()) {
cat(bytes, p, len, enc, CR_7BIT);
EncodingUtils.encCrStrBufCat(getRuntime(), this, new ByteList(bytes, p, len), enc, CR_7BIT, null);
} else {
byte buf[] = new byte[enc.maxLength()];
int end = p + len;
while (p < end) {
int c = bytes[p];
int cl = codeLength(getRuntime(), enc, c);
enc.codeToMbc(c, buf, 0);
cat(buf, 0, cl, enc, CR_VALID);
EncodingUtils.encCrStrBufCat(getRuntime(), this, new ByteList(bytes, p, len), enc, CR_7BIT, null);
p++;
}
}
Expand Down Expand Up @@ -6155,4 +6094,78 @@ public Object toJava(Class target) {
return super.toJava(target);
}
}

// old port of rb_enc_cr_str_buf_cat
@Deprecated
public final int cat(byte[]bytes, int p, int len, Encoding enc, int ptr_cr) {
Encoding str_enc = value.getEncoding();
Encoding res_enc;
int str_cr, res_cr;

modify(value.getRealSize() + len);
int toCr = getCodeRange();
Encoding toEnc = value.getEncoding();
int cr2 = ptr_cr;

if (toEnc == enc) {
if (toCr == CR_UNKNOWN) {
ptr_cr = CR_UNKNOWN;
} else if (ptr_cr == CR_UNKNOWN) {
ptr_cr = codeRangeScan(enc, bytes, p, len);
}
} else {
if (!toEnc.isAsciiCompatible() || !enc.isAsciiCompatible()) {
if (len == 0) return toCr;
if (value.getRealSize() == 0) {
System.arraycopy(bytes, p, value.getUnsafeBytes(), value.getBegin() + value.getRealSize(), len);
value.setRealSize(value.getRealSize() + len);
setEncodingAndCodeRange(enc, ptr_cr);
return ptr_cr;
}
throw getRuntime().newEncodingCompatibilityError("incompatible character encodings: " + toEnc + " and " + enc);
}
if (ptr_cr == CR_UNKNOWN) ptr_cr = codeRangeScan(enc, bytes, p, len);
if (toCr == CR_UNKNOWN) {
if (toEnc == ASCIIEncoding.INSTANCE || ptr_cr != CR_7BIT) toCr = scanForCodeRange();
}
}
if (cr2 != 0) cr2 = ptr_cr;

if (toEnc != enc && toCr != CR_7BIT && ptr_cr != CR_7BIT) {
throw getRuntime().newEncodingCompatibilityError("incompatible character encodings: " + toEnc + " and " + enc);
}

final int resCr;
final Encoding resEnc;
if (toCr == CR_UNKNOWN) {
resEnc = toEnc;
resCr = CR_UNKNOWN;
} else if (toCr == CR_7BIT) {
if (ptr_cr == CR_7BIT) {
resEnc = toEnc;
resCr = CR_7BIT;
} else {
resEnc = enc;
resCr = ptr_cr;
}
} else if (toCr == CR_VALID) {
resEnc = toEnc;
if (ptr_cr == CR_7BIT || ptr_cr == CR_VALID) {
resCr = toCr;
} else {
resCr = ptr_cr;
}
} else {
resEnc = toEnc;
resCr = len > 0 ? CR_UNKNOWN : toCr;
}

if (len < 0) throw getRuntime().newArgumentError("negative string size (or size too big)");

System.arraycopy(bytes, p, value.getUnsafeBytes(), value.getBegin() + value.getRealSize(), len);
value.setRealSize(value.getRealSize() + len);
setEncodingAndCodeRange(resEnc, resCr);

return cr2;
}
}
45 changes: 34 additions & 11 deletions core/src/main/java/org/jruby/util/io/EncodingUtils.java
Expand Up @@ -1018,14 +1018,39 @@ public static Encoding defaultExternalEncoding(Ruby runtime) {
return runtime.getEncodingService().getLocaleEncoding();
}

// rb_str_buf_cat
public static void rbStrBufCat(Ruby runtime, RubyString str, ByteList ptr) {
if (ptr.length() == 0) return;
// negative length check here, we shouldn't need
strBufCat(runtime, str, ptr);
}

// str_buf_cat
public static void strBufCat(Ruby runtime, RubyString str, ByteList ptr) {
int total, off = -1;

// termlen is not relevant since we have no termination sequence

// missing: if ptr string is inside str, off = ptr start minus str start

str.modify();
if (ptr.length() == 0) return;

// much logic is missing here, since we don't manually manage the ByteList buffer

total = str.size() + ptr.length();
str.getByteList().ensure(total);
str.getByteList().append(ptr);
}

// rb_enc_str_buf_cat
public static RubyString encStrBufCat(Ruby runtime, RubyString str, ByteList ptr, Encoding enc) {
return encCrStrBufCat(runtime, str, ptr,
public static void encStrBufCat(Ruby runtime, RubyString str, ByteList ptr, Encoding enc) {
encCrStrBufCat(runtime, str, ptr,
enc, StringSupport.CR_UNKNOWN, null);
}

// rb_enc_cr_str_buf_cat
public static RubyString encCrStrBufCat(Ruby runtime, RubyString str, ByteList ptr, Encoding ptrEnc, int ptr_cr, int[] ptr_cr_ret) {
public static void encCrStrBufCat(Ruby runtime, RubyString str, ByteList ptr, Encoding ptrEnc, int ptr_cr, int[] ptr_cr_ret) {
Encoding strEnc = str.getEncoding();
Encoding resEnc;
int str_cr, res_cr;
Expand All @@ -1042,12 +1067,12 @@ public static RubyString encCrStrBufCat(Ruby runtime, RubyString str, ByteList p
} else {
if (!strEnc.isAsciiCompatible() || !ptrEnc.isAsciiCompatible()) {
if (ptr.getRealSize() == 0) {
return str;
return;
}
if (str.size() == 0) {
str.cat19(ptr, ptr_cr);
str.setEncoding(ptrEnc);
return str;
rbStrBufCat(runtime, str, ptr);
str.setEncodingAndCodeRange(ptrEnc, ptr_cr);
return;
}
incompatible = true;
}
Expand Down Expand Up @@ -1099,9 +1124,7 @@ public static RubyString encCrStrBufCat(Ruby runtime, RubyString str, ByteList p

// MRI checks for len < 0 here, but I don't think that's possible for us

str.cat19(ptr, res_cr);
str.setEncoding(resEnc);

return str;
strBufCat(runtime, str, ptr);
str.setEncodingAndCodeRange(resEnc, res_cr);
}
}

0 comments on commit a97d736

Please sign in to comment.