Merge branch '1.5.x'

pull/7211/merge
Andy Wilkinson 8 years ago
commit 3f655d998d

@ -23,6 +23,7 @@ import java.nio.charset.Charset;
* reasons to save constructing Strings for ZIP data. * reasons to save constructing Strings for ZIP data.
* *
* @author Phillip Webb * @author Phillip Webb
* @author Andy Wilkinson
*/ */
final class AsciiBytes { final class AsciiBytes {
@ -156,21 +157,35 @@ final class AsciiBytes {
int hash = this.hash; int hash = this.hash;
if (hash == 0 && this.bytes.length > 0) { if (hash == 0 && this.bytes.length > 0) {
for (int i = this.offset; i < this.offset + this.length; i++) { for (int i = this.offset; i < this.offset + this.length; i++) {
int b = this.bytes[i] & 0xff; int b = this.bytes[i];
if (b > 0x7F) { if (b < 0) {
// Decode multi-byte UTF b = b & 0x7F;
for (int size = 0; size < 3; size++) { int limit;
if ((b & (0x40 >> size)) == 0) { int excess = 0x80;
b = b & (0x1F >> size); if (b < 96) {
for (int j = 0; j < size; j++) { limit = 1;
b <<= 6; excess += 0x40 << 6;
b |= this.bytes[++i] & 0x3F;
}
break;
}
} }
else if (b < 112) {
limit = 2;
excess += (0x60 << 12) + (0x80 << 6);
}
else {
limit = 3;
excess += (0x70 << 18) + (0x80 << 12) + (0x80 << 6);
}
for (int j = 0; j < limit; j++) {
b = (b << 6) + (this.bytes[++i] & 0xFF);
}
b -= excess;
}
if (b <= 0xFFFF) {
hash = 31 * hash + b;
}
else {
hash = 31 * hash + ((b >> 0xA) + 0xD7C0);
hash = 31 * hash + ((b & 0x3FF) + 0xDC00);
} }
hash = 31 * hash + b;
} }
this.hash = hash; this.hash = hash;
} }

@ -26,6 +26,7 @@ import static org.assertj.core.api.Assertions.assertThat;
* Tests for {@link AsciiBytes}. * Tests for {@link AsciiBytes}.
* *
* @author Phillip Webb * @author Phillip Webb
* @author Andy Wilkinson
*/ */
public class AsciiBytesTests { public class AsciiBytesTests {
@ -140,16 +141,26 @@ public class AsciiBytesTests {
@Test @Test
public void hashCodeSameAsString() throws Exception { public void hashCodeSameAsString() throws Exception {
String s = "abcABC123xyz!"; hashCodeSameAsString("abcABC123xyz!");
AsciiBytes a = new AsciiBytes(s);
assertThat(s.hashCode()).isEqualTo(a.hashCode());
} }
@Test @Test
public void hashCodeSameAsStringWithSpecial() throws Exception { public void hashCodeSameAsStringWithSpecial() throws Exception {
String s = "special/\u00EB.dat"; hashCodeSameAsString("special/\u00EB.dat");
AsciiBytes a = new AsciiBytes(s); }
assertThat(s.hashCode()).isEqualTo(a.hashCode());
@Test
public void hashCodeSameAsStringWithCyrillicCharacters() throws Exception {
hashCodeSameAsString("\u0432\u0435\u0441\u043D\u0430");
}
@Test
public void hashCodeSameAsStringWithEmoji() throws Exception {
hashCodeSameAsString("\ud83d\udca9");
}
private void hashCodeSameAsString(String input) {
assertThat(new AsciiBytes(input).hashCode()).isEqualTo(input.hashCode());
} }
} }

Loading…
Cancel
Save