Repository: activemq Updated Branches: refs/heads/activemq-5.14.x 6fe437a3d -> 32a4d7449
Add new implementations of the writeUTF8 and readUTF8 methods that are based on Apache Harmony code. This also avoid some code duplication that was occurring. (cherry picked from commit 45a1217228bc6fa9ccda49853156a5f71fe2c956) Project: http://git-wip-us.apache.org/repos/asf/activemq/repo Commit: http://git-wip-us.apache.org/repos/asf/activemq/commit/32a4d744 Tree: http://git-wip-us.apache.org/repos/asf/activemq/tree/32a4d744 Diff: http://git-wip-us.apache.org/repos/asf/activemq/diff/32a4d744 Branch: refs/heads/activemq-5.14.x Commit: 32a4d7449660f2495cc0f908af6d98a95c51787a Parents: 6fe437a Author: Hiram Chirino <[email protected]> Authored: Thu Apr 6 11:55:08 2017 -0400 Committer: Dejan Bosanac <[email protected]> Committed: Tue Apr 11 16:12:09 2017 +0200 ---------------------------------------------------------------------- .../activemq/util/DataByteArrayInputStream.java | 62 +------ .../util/DataByteArrayOutputStream.java | 45 +---- .../activemq/util/MarshallingSupport.java | 175 +++++++++---------- .../disk/util/DataByteArrayInputStream.java | 36 +--- .../disk/util/DataByteArrayOutputStream.java | 38 +--- 5 files changed, 110 insertions(+), 246 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/activemq/blob/32a4d744/activemq-client/src/main/java/org/apache/activemq/util/DataByteArrayInputStream.java ---------------------------------------------------------------------- diff --git a/activemq-client/src/main/java/org/apache/activemq/util/DataByteArrayInputStream.java b/activemq-client/src/main/java/org/apache/activemq/util/DataByteArrayInputStream.java index 0a13aa0..2fe92a1 100755 --- a/activemq-client/src/main/java/org/apache/activemq/util/DataByteArrayInputStream.java +++ b/activemq-client/src/main/java/org/apache/activemq/util/DataByteArrayInputStream.java @@ -259,62 +259,12 @@ public final class DataByteArrayInputStream extends InputStream implements DataI public String readUTF() throws IOException { int length = readUnsignedShort(); - char[] characters = new char[length]; - int c; - int c2; - int c3; - int count = 0; - int total = pos + length; - while (pos < total) { - c = (int)buf[pos] & 0xff; - if (c > 127) { - break; - } - pos++; - characters[count++] = (char)c; - } - while (pos < total) { - c = (int)buf[pos] & 0xff; - switch (c >> 4) { - case 0: - case 1: - case 2: - case 3: - case 4: - case 5: - case 6: - case 7: - pos++; - characters[count++] = (char)c; - break; - case 12: - case 13: - pos += 2; - if (pos > total) { - throw new UTFDataFormatException("bad string"); - } - c2 = (int)buf[pos - 1]; - if ((c2 & 0xC0) != 0x80) { - throw new UTFDataFormatException("bad string"); - } - characters[count++] = (char)(((c & 0x1F) << 6) | (c2 & 0x3F)); - break; - case 14: - pos += 3; - if (pos > total) { - throw new UTFDataFormatException("bad string"); - } - c2 = (int)buf[pos - 2]; - c3 = (int)buf[pos - 1]; - if (((c2 & 0xC0) != 0x80) || ((c3 & 0xC0) != 0x80)) { - throw new UTFDataFormatException("bad string"); - } - characters[count++] = (char)(((c & 0x0F) << 12) | ((c2 & 0x3F) << 6) | ((c3 & 0x3F) << 0)); - break; - default: - throw new UTFDataFormatException("bad string"); - } + if (pos + length > buf.length) { + throw new UTFDataFormatException("bad string"); } - return new String(characters, 0, count); + char chararr[] = new char[length]; + String result = MarshallingSupport.convertUTF8WithBuf(buf, chararr, pos, length); + pos += length; + return result; } } http://git-wip-us.apache.org/repos/asf/activemq/blob/32a4d744/activemq-client/src/main/java/org/apache/activemq/util/DataByteArrayOutputStream.java ---------------------------------------------------------------------- diff --git a/activemq-client/src/main/java/org/apache/activemq/util/DataByteArrayOutputStream.java b/activemq-client/src/main/java/org/apache/activemq/util/DataByteArrayOutputStream.java index e1035fc..692fb94 100755 --- a/activemq-client/src/main/java/org/apache/activemq/util/DataByteArrayOutputStream.java +++ b/activemq-client/src/main/java/org/apache/activemq/util/DataByteArrayOutputStream.java @@ -202,46 +202,17 @@ public final class DataByteArrayOutputStream extends OutputStream implements Dat } } - public void writeUTF(String str) throws IOException { - int strlen = str.length(); - int encodedsize = 0; - int c; - for (int i = 0; i < strlen; i++) { - c = str.charAt(i); - if ((c >= 0x0001) && (c <= 0x007F)) { - encodedsize++; - } else if (c > 0x07FF) { - encodedsize += 3; - } else { - encodedsize += 2; - } - } + public void writeUTF(String text) throws IOException { + long encodedsize = MarshallingSupport.countUTFBytes(text); if (encodedsize > 65535) { throw new UTFDataFormatException("encoded string too long: " + encodedsize + " bytes"); } - ensureEnoughBuffer(pos + encodedsize + 2); - writeShort(encodedsize); - int i = 0; - for (i = 0; i < strlen; i++) { - c = str.charAt(i); - if (!((c >= 0x0001) && (c <= 0x007F))) { - break; - } - buf[pos++] = (byte)c; - } - for (; i < strlen; i++) { - c = str.charAt(i); - if ((c >= 0x0001) && (c <= 0x007F)) { - buf[pos++] = (byte)c; - } else if (c > 0x07FF) { - buf[pos++] = (byte)(0xE0 | ((c >> 12) & 0x0F)); - buf[pos++] = (byte)(0x80 | ((c >> 6) & 0x3F)); - buf[pos++] = (byte)(0x80 | ((c >> 0) & 0x3F)); - } else { - buf[pos++] = (byte)(0xC0 | ((c >> 6) & 0x1F)); - buf[pos++] = (byte)(0x80 | ((c >> 0) & 0x3F)); - } - } + ensureEnoughBuffer((int)(pos + encodedsize + 2)); + writeShort((int)encodedsize); + + byte[] buffer = new byte[(int)encodedsize]; + MarshallingSupport.writeUTFBytesToBuffer(text, (int) encodedsize, buf, pos); + pos += encodedsize; } private void ensureEnoughBuffer(int newcount) { http://git-wip-us.apache.org/repos/asf/activemq/blob/32a4d744/activemq-client/src/main/java/org/apache/activemq/util/MarshallingSupport.java ---------------------------------------------------------------------- diff --git a/activemq-client/src/main/java/org/apache/activemq/util/MarshallingSupport.java b/activemq-client/src/main/java/org/apache/activemq/util/MarshallingSupport.java index 90ecb44..f290731 100755 --- a/activemq-client/src/main/java/org/apache/activemq/util/MarshallingSupport.java +++ b/activemq-client/src/main/java/org/apache/activemq/util/MarshallingSupport.java @@ -296,115 +296,100 @@ public final class MarshallingSupport { public static void writeUTF8(DataOutput dataOut, String text) throws IOException { if (text != null) { - int strlen = text.length(); - int utflen = 0; - char[] charr = new char[strlen]; - int c = 0; - int count = 0; - - text.getChars(0, strlen, charr, 0); - - for (int i = 0; i < strlen; i++) { - c = charr[i]; - if ((c >= 0x0001) && (c <= 0x007F)) { - utflen++; - } else if (c > 0x07FF) { - utflen += 3; - } else { - utflen += 2; - } - } - // TODO diff: Sun code - removed - byte[] bytearr = new byte[utflen + 4]; // TODO diff: Sun code - bytearr[count++] = (byte)((utflen >>> 24) & 0xFF); // TODO diff: - // Sun code - bytearr[count++] = (byte)((utflen >>> 16) & 0xFF); // TODO diff: - // Sun code - bytearr[count++] = (byte)((utflen >>> 8) & 0xFF); - bytearr[count++] = (byte)((utflen >>> 0) & 0xFF); - for (int i = 0; i < strlen; i++) { - c = charr[i]; - if ((c >= 0x0001) && (c <= 0x007F)) { - bytearr[count++] = (byte)c; - } else if (c > 0x07FF) { - bytearr[count++] = (byte)(0xE0 | ((c >> 12) & 0x0F)); - bytearr[count++] = (byte)(0x80 | ((c >> 6) & 0x3F)); - bytearr[count++] = (byte)(0x80 | ((c >> 0) & 0x3F)); - } else { - bytearr[count++] = (byte)(0xC0 | ((c >> 6) & 0x1F)); - bytearr[count++] = (byte)(0x80 | ((c >> 0) & 0x3F)); - } - } - dataOut.write(bytearr); + long utfCount = countUTFBytes(text); + dataOut.writeInt((int)utfCount); + byte[] buffer = new byte[(int)utfCount]; + int len = writeUTFBytesToBuffer(text, (int) utfCount, buffer, 0); + dataOut.write(buffer, 0, len); + + assert utfCount==len; } else { dataOut.writeInt(-1); } } + /** + * From: http://svn.apache.org/repos/asf/harmony/enhanced/java/trunk/classlib/modules/luni/src/main/java/java/io/DataOutputStream.java + */ + public static long countUTFBytes(String str) { + int utfCount = 0, length = str.length(); + for (int i = 0; i < length; i++) { + int charValue = str.charAt(i); + if (charValue > 0 && charValue <= 127) { + utfCount++; + } else if (charValue <= 2047) { + utfCount += 2; + } else { + utfCount += 3; + } + } + return utfCount; + } + + /** + * From: http://svn.apache.org/repos/asf/harmony/enhanced/java/trunk/classlib/modules/luni/src/main/java/java/io/DataOutputStream.java + */ + public static int writeUTFBytesToBuffer(String str, long count, + byte[] buffer, int offset) throws IOException { + int length = str.length(); + for (int i = 0; i < length; i++) { + int charValue = str.charAt(i); + if (charValue > 0 && charValue <= 127) { + buffer[offset++] = (byte) charValue; + } else if (charValue <= 2047) { + buffer[offset++] = (byte) (0xc0 | (0x1f & (charValue >> 6))); + buffer[offset++] = (byte) (0x80 | (0x3f & charValue)); + } else { + buffer[offset++] = (byte) (0xe0 | (0x0f & (charValue >> 12))); + buffer[offset++] = (byte) (0x80 | (0x3f & (charValue >> 6))); + buffer[offset++] = (byte) (0x80 | (0x3f & charValue)); + } + } + return offset; + } + public static String readUTF8(DataInput dataIn) throws IOException { - int utflen = dataIn.readInt(); // TODO diff: Sun code + int utflen = dataIn.readInt(); if (utflen > -1) { - StringBuffer str = new StringBuffer(utflen); byte bytearr[] = new byte[utflen]; - int c; - int char2; - int char3; - int count = 0; - + char chararr[] = new char[utflen]; dataIn.readFully(bytearr, 0, utflen); + return convertUTF8WithBuf(bytearr, chararr, 0, utflen); + } else { + return null; + } + } - while (count < utflen) { - c = bytearr[count] & 0xff; - switch (c >> 4) { - case 0: - case 1: - case 2: - case 3: - case 4: - case 5: - case 6: - case 7: - /* 0xxxxxxx */ - count++; - str.append((char)c); - break; - case 12: - case 13: - /* 110x xxxx 10xx xxxx */ - count += 2; - if (count > utflen) { - throw new UTFDataFormatException(); - } - char2 = bytearr[count - 1]; - if ((char2 & 0xC0) != 0x80) { - throw new UTFDataFormatException(); - } - str.append((char)(((c & 0x1F) << 6) | (char2 & 0x3F))); - break; - case 14: - /* 1110 xxxx 10xx xxxx 10xx xxxx */ - count += 3; - if (count > utflen) { - throw new UTFDataFormatException(); - } - char2 = bytearr[count - 2]; // TODO diff: Sun code - char3 = bytearr[count - 1]; // TODO diff: Sun code - if (((char2 & 0xC0) != 0x80) || ((char3 & 0xC0) != 0x80)) { - throw new UTFDataFormatException(); - } - str.append((char)(((c & 0x0F) << 12) | ((char2 & 0x3F) << 6) | ((char3 & 0x3F) << 0))); - break; - default: - /* 10xx xxxx, 1111 xxxx */ + /** + * From: http://svn.apache.org/repos/asf/harmony/enhanced/java/trunk/classlib/modules/luni/src/main/java/org/apache/harmony/luni/util/Util.java + */ + public static String convertUTF8WithBuf(byte[] buf, char[] out, int offset, + int utfSize) throws UTFDataFormatException { + int count = 0, s = 0, a; + while (count < utfSize) { + if ((out[s] = (char) buf[offset + count++]) < '\u0080') + s++; + else if (((a = out[s]) & 0xe0) == 0xc0) { + if (count >= utfSize) + throw new UTFDataFormatException(); + int b = buf[offset + count++]; + if ((b & 0xC0) != 0x80) + throw new UTFDataFormatException(); + out[s++] = (char) (((a & 0x1F) << 6) | (b & 0x3F)); + } else if ((a & 0xf0) == 0xe0) { + if (count + 1 >= utfSize) + throw new UTFDataFormatException(); + int b = buf[offset + count++]; + int c = buf[offset + count++]; + if (((b & 0xC0) != 0x80) || ((c & 0xC0) != 0x80)) throw new UTFDataFormatException(); - } + out[s++] = (char) (((a & 0x0F) << 12) | ((b & 0x3F) << 6) | (c & 0x3F)); + } else { + throw new UTFDataFormatException(); } - // The number of chars produced may be less than utflen - return new String(str); - } else { - return null; } + return new String(out, 0, s); } public static String propertiesToString(Properties props) throws IOException { http://git-wip-us.apache.org/repos/asf/activemq/blob/32a4d744/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/disk/util/DataByteArrayInputStream.java ---------------------------------------------------------------------- diff --git a/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/disk/util/DataByteArrayInputStream.java b/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/disk/util/DataByteArrayInputStream.java index 455a020..33ddd89 100755 --- a/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/disk/util/DataByteArrayInputStream.java +++ b/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/disk/util/DataByteArrayInputStream.java @@ -22,6 +22,7 @@ import java.io.InputStream; import java.io.UTFDataFormatException; import org.apache.activemq.util.ByteSequence; +import org.apache.activemq.util.MarshallingSupport; /** * Optimized ByteArrayInputStream that can be used more than once @@ -286,36 +287,13 @@ public final class DataByteArrayInputStream extends InputStream implements DataI @Override public String readUTF() throws IOException { int length = readUnsignedShort(); - int endPos = pos + length; - int count = 0, a; - char[] characters = new char[length]; - while (pos < endPos) { - if ((characters[count] = (char) buf[pos++]) < '\u0080') - count++; - else if (((a = characters[count]) & 0xE0) == 0xC0) { - if (pos >= endPos) { - throw new UTFDataFormatException("bad string"); - } - int b = buf[pos++]; - if ((b & 0xC0) != 0x80) { - throw new UTFDataFormatException("bad string"); - } - characters[count++] = (char) (((a & 0x1F) << 6) | (b & 0x3F)); - } else if ((a & 0xf0) == 0xe0) { - if (pos + 1 >= endPos) { - throw new UTFDataFormatException("bad string"); - } - int b = buf[pos++]; - int c = buf[pos++]; - if (((b & 0xC0) != 0x80) || ((c & 0xC0) != 0x80)) { - throw new UTFDataFormatException("bad string"); - } - characters[count++] = (char) (((a & 0x0F) << 12) | ((b & 0x3F) << 6) | (c & 0x3F)); - } else { - throw new UTFDataFormatException("bad string"); - } + if (pos + length > buf.length) { + throw new UTFDataFormatException("bad string"); } - return new String(characters, 0, count); + char chararr[] = new char[length]; + String result = MarshallingSupport.convertUTF8WithBuf(buf, chararr, pos, length); + pos += length; + return result; } public int getPos() { http://git-wip-us.apache.org/repos/asf/activemq/blob/32a4d744/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/disk/util/DataByteArrayOutputStream.java ---------------------------------------------------------------------- diff --git a/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/disk/util/DataByteArrayOutputStream.java b/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/disk/util/DataByteArrayOutputStream.java index d29b70f..5a3fba4 100755 --- a/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/disk/util/DataByteArrayOutputStream.java +++ b/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/disk/util/DataByteArrayOutputStream.java @@ -23,6 +23,7 @@ import java.io.UTFDataFormatException; import org.apache.activemq.store.kahadb.disk.page.PageFile; import org.apache.activemq.util.ByteSequence; +import org.apache.activemq.util.MarshallingSupport; /** * Optimized ByteArrayOutputStream @@ -228,38 +229,17 @@ public class DataByteArrayOutputStream extends OutputStream implements DataOutpu } @Override - public void writeUTF(String str) throws IOException { - int strlen = str.length(); - int encodedsize = 0; - int c; - for (int i = 0; i < strlen; i++) { - c = str.charAt(i); - if ((c >= 0x0001) && (c <= 0x007F)) { - encodedsize++; - } else if (c > 0x07FF) { - encodedsize += 3; - } else { - encodedsize += 2; - } - } + public void writeUTF(String text) throws IOException { + long encodedsize = MarshallingSupport.countUTFBytes(text); if (encodedsize > 65535) { throw new UTFDataFormatException("encoded string too long: " + encodedsize + " bytes"); } - ensureEnoughBuffer(pos + encodedsize + 2); - writeShort(encodedsize); - for (int i = 0; i < strlen; i++) { - int charValue = str.charAt(i); - if (charValue > 0 && charValue <= 127) { - buf[pos++] = (byte) charValue; - } else if (charValue <= 2047) { - buf[pos++] = (byte) (0xc0 | (0x1f & (charValue >> 6))); - buf[pos++] = (byte) (0x80 | (0x3f & charValue)); - } else { - buf[pos++] = (byte) (0xe0 | (0x0f & (charValue >> 12))); - buf[pos++] = (byte) (0x80 | (0x3f & (charValue >> 6))); - buf[pos++] = (byte) (0x80 | (0x3f & charValue)); - } - } + ensureEnoughBuffer((int)(pos + encodedsize + 2)); + writeShort((int)encodedsize); + + byte[] buffer = new byte[(int)encodedsize]; + MarshallingSupport.writeUTFBytesToBuffer(text, (int) encodedsize, buf, pos); + pos += encodedsize; onWrite(); }
