From 6a368ccd139d8e5f960ff3085f44322e7dbe6542 Mon Sep 17 00:00:00 2001 From: Robinson Date: Sat, 30 Jan 2021 16:17:04 +0100 Subject: [PATCH] Moved util subprojects into their own projects --- src/dorkbox/util/bytes/BigEndian.java | 772 ------- src/dorkbox/util/bytes/ByteArrayWrapper.java | 114 - src/dorkbox/util/bytes/ByteBuffer2.java | 1945 ----------------- src/dorkbox/util/bytes/LittleEndian.java | 769 ------- .../util/bytes/OptimizeUtilsByteArray.java | 477 ---- .../util/bytes/OptimizeUtilsByteBuf.java | 381 ---- src/dorkbox/util/bytes/UByte.java | 311 --- src/dorkbox/util/bytes/UInteger.java | 349 --- src/dorkbox/util/bytes/ULong.java | 273 --- src/dorkbox/util/bytes/UNumber.java | 44 - src/dorkbox/util/bytes/UShort.java | 195 -- src/dorkbox/util/bytes/Unsigned.java | 192 -- src/dorkbox/util/crypto/Crypto.java | 22 +- src/dorkbox/util/javaFx/JavaFX.java | 211 -- src/dorkbox/util/swt/Swt.java | 89 - src/dorkbox/util/swt/SwtAccess.java | 135 -- 16 files changed, 20 insertions(+), 6259 deletions(-) delete mode 100644 src/dorkbox/util/bytes/BigEndian.java delete mode 100644 src/dorkbox/util/bytes/ByteArrayWrapper.java delete mode 100644 src/dorkbox/util/bytes/ByteBuffer2.java delete mode 100644 src/dorkbox/util/bytes/LittleEndian.java delete mode 100644 src/dorkbox/util/bytes/OptimizeUtilsByteArray.java delete mode 100644 src/dorkbox/util/bytes/OptimizeUtilsByteBuf.java delete mode 100644 src/dorkbox/util/bytes/UByte.java delete mode 100644 src/dorkbox/util/bytes/UInteger.java delete mode 100644 src/dorkbox/util/bytes/ULong.java delete mode 100644 src/dorkbox/util/bytes/UNumber.java delete mode 100644 src/dorkbox/util/bytes/UShort.java delete mode 100644 src/dorkbox/util/bytes/Unsigned.java delete mode 100644 src/dorkbox/util/javaFx/JavaFX.java delete mode 100644 src/dorkbox/util/swt/Swt.java delete mode 100644 src/dorkbox/util/swt/SwtAccess.java diff --git a/src/dorkbox/util/bytes/BigEndian.java b/src/dorkbox/util/bytes/BigEndian.java deleted file mode 100644 index 1e22aa9..0000000 --- a/src/dorkbox/util/bytes/BigEndian.java +++ /dev/null @@ -1,772 +0,0 @@ -/* - * Copyright 2014 dorkbox, llc - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package dorkbox.util.bytes; - -import java.io.IOException; -import java.io.InputStream; -import java.math.BigInteger; -import java.nio.ByteBuffer; - -/** - * This is "motorola endian", or commonly as "network byte order". - *

- * This is also the default for Java. - *

- * arm is technically bi-endian - */ -@SuppressWarnings("ALL") -public -class BigEndian { - // the following are ALL in Bit-Endian (byte[0] is MOST significant) - - /** - * CHAR to and from bytes - */ - public static final - class Char_ { - @SuppressWarnings("fallthrough") - public static - char from(final byte[] bytes, final int offset, final int bytenum) { - char number = 0; - - switch (bytenum) { - case 2: - number |= (bytes[offset + 0] & 0xFF) << 8; - case 1: - number |= (bytes[offset + 1] & 0xFF) << 0; - } - - return number; - } - - @SuppressWarnings("fallthrough") - public static - char from(final byte[] bytes) { - char number = 0; - - switch (bytes.length) { - default: - case 2: - number |= (bytes[0] & 0xFF) << 8; - case 1: - number |= (bytes[1] & 0xFF) << 0; - } - - return number; - } - - public static - char from(final byte b0, final byte b1) { - return (char) ((b0 & 0xFF) << 8 | (b1 & 0xFF) << 0); - } - - public static - char from(final ByteBuffer buff) { - return from(buff.get(), buff.get()); - } - - public static - char from(final InputStream inputStream) throws IOException { - return from((byte) inputStream.read(), (byte) inputStream.read()); - } - - public static - byte[] toBytes(final char x) { - return new byte[] {(byte) (x >> 8), (byte) (x >> 0)}; - } - - public static - void toBytes(final char x, final byte[] bytes, final int offset) { - bytes[offset + 0] = (byte) (x >> 8); - bytes[offset + 1] = (byte) (x >> 0); - } - - public static - void toBytes(final char x, final byte[] bytes) { - bytes[0] = (byte) (x >> 8); - bytes[1] = (byte) (x >> 0); - } - - private - Char_() { - } - } - - - /** - * UNSIGNED CHAR to and from bytes - */ - public static final - class UChar_ { - @SuppressWarnings("fallthrough") - public static - UShort from(final byte[] bytes, final int offset, final int bytenum) { - char number = 0; - - switch (bytenum) { - case 2: - number |= (bytes[offset + 0] & 0xFF) << 8; - case 1: - number |= (bytes[offset + 1] & 0xFF) << 0; - } - - return UShort.valueOf(number); - } - - @SuppressWarnings("fallthrough") - public static - UShort from(final byte[] bytes) { - short number = 0; - - switch (bytes.length) { - default: - case 2: - number |= (bytes[0] & 0xFF) << 8; - case 1: - number |= (bytes[1] & 0xFF) << 0; - } - - return UShort.valueOf(number); - } - - public static - UShort from(final byte b0, final byte b1) { - return UShort.valueOf((short) ((b0 & 0xFF) << 8) | (b1 & 0xFF) << 0); - } - - public static - UShort from(final ByteBuffer buff) { - return from(buff.get(), buff.get()); - } - - public static - UShort from(final InputStream inputStream) throws IOException { - return from((byte) inputStream.read(), (byte) inputStream.read()); - } - - - public static - byte[] toBytes(final UShort x) { - int num = x.intValue(); - - return new byte[] {(byte) ((num & 0xFF00) >> 8), (byte) (num & 0x00FF >> 0)}; - } - - public static - void toBytes(final UShort x, final byte[] bytes, final int offset) { - int num = x.intValue(); - - bytes[offset + 0] = (byte) ((num & 0xFF00) >> 8); - bytes[offset + 1] = (byte) (num & 0x00FF >> 0); - } - - public static - void toBytes(final UShort x, final byte[] bytes) { - int num = x.intValue(); - - bytes[0] = (byte) ((num & 0xFF00) >> 8); - bytes[1] = (byte) (num & 0x00FF >> 0); - } - - - private - UChar_() { - } - } - - - /** - * SHORT to and from bytes - */ - public static final - class Short_ { - @SuppressWarnings("fallthrough") - public static - short from(final byte[] bytes, final int offset, final int bytenum) { - short number = 0; - - switch (bytenum) { - case 2: - number |= (bytes[offset + 0] & 0xFF) << 8; - case 1: - number |= (bytes[offset + 1] & 0xFF) << 0; - } - - return number; - } - - @SuppressWarnings("fallthrough") - public static - short from(final byte[] bytes) { - short number = 0; - - switch (bytes.length) { - default: - case 2: - number |= (bytes[0] & 0xFF) << 8; - case 1: - number |= (bytes[1] & 0xFF) << 0; - } - - return number; - } - - public static - short from(final byte b0, final byte b1) { - return (short) ((b0 & 0xFF) << 8 | (b1 & 0xFF) << 0); - } - - public static - short from(final ByteBuffer buff) { - return from(buff.get(), buff.get()); - } - - public static - short from(final InputStream inputStream) throws IOException { - return from((byte) inputStream.read(), (byte) inputStream.read()); - } - - public static - byte[] toBytes(final short x) { - return new byte[] {(byte) (x >> 8), (byte) (x >> 0)}; - } - - public static - void toBytes(final short x, final byte[] bytes, final int offset) { - bytes[offset + 0] = (byte) (x >> 8); - bytes[offset + 1] = (byte) (x >> 0); - } - - public static - void toBytes(final short x, final byte[] bytes) { - bytes[0] = (byte) (x >> 8); - bytes[1] = (byte) (x >> 0); - } - - private - Short_() { - } - } - - - /** - * UNSIGNED SHORT to and from bytes - */ - public static final - class UShort_ { - @SuppressWarnings("fallthrough") - public static - UShort from(final byte[] bytes, final int offset, final int bytenum) { - char number = 0; - - switch (bytenum) { - case 2: - number |= (bytes[offset + 0] & 0xFF) << 8; - case 1: - number |= (bytes[offset + 1] & 0xFF) << 0; - } - - return UShort.valueOf(number); - } - - @SuppressWarnings("fallthrough") - public static - UShort from(final byte[] bytes) { - short number = 0; - - switch (bytes.length) { - default: - case 2: - number |= (bytes[0] & 0xFF) << 8; - case 1: - number |= (bytes[1] & 0xFF) << 0; - } - - return UShort.valueOf(number); - } - - public static - UShort from(final byte b0, final byte b1) { - return UShort.valueOf((short) ((b0 & 0xFF) << 8) | (b1 & 0xFF) << 0); - } - - public static - UShort from(final ByteBuffer buff) { - return from(buff.get(), buff.get()); - } - - public static - UShort from(final InputStream inputStream) throws IOException { - return from((byte) inputStream.read(), (byte) inputStream.read()); - } - - public static - byte[] toBytes(final UShort x) { - final int num = x.intValue(); - - return new byte[] {(byte) ((num & 0xFF00) >> 8), (byte) (num & 0x00FF >> 0)}; - } - - public static - void toBytes(final UShort x, final byte[] bytes, final int offset) { - int num = x.intValue(); - - bytes[offset + 0] = (byte) ((num & 0xFF00) >> 8); - bytes[offset + 1] = (byte) (num & 0x00FF >> 0); - } - - public static - void toBytes(final UShort x, final byte[] bytes) { - int num = x.intValue(); - - bytes[0] = (byte) ((num & 0xFF00) >> 8); - bytes[1] = (byte) (num & 0x00FF >> 0); - } - - private - UShort_() { - } - } - - - /** - * INT to and from bytes - */ - public static final - class Int_ { - @SuppressWarnings("fallthrough") - public static - int from(final byte[] bytes, final int offset, final int bytenum) { - int number = 0; - - switch (bytenum) { - case 4: - number |= (bytes[offset + 0] & 0xFF) << 24; - case 3: - number |= (bytes[offset + 1] & 0xFF) << 16; - case 2: - number |= (bytes[offset + 2] & 0xFF) << 8; - case 1: - number |= (bytes[offset + 3] & 0xFF) << 0; - } - - return number; - } - - @SuppressWarnings("fallthrough") - public static - int from(final byte[] bytes) { - int number = 0; - - switch (bytes.length) { - default: - case 4: - number |= (bytes[0] & 0xFF) << 24; - case 3: - number |= (bytes[1] & 0xFF) << 16; - case 2: - number |= (bytes[2] & 0xFF) << 8; - case 1: - number |= (bytes[3] & 0xFF) << 0; - } - - return number; - } - - public static - int from(final byte b0, final byte b1, final byte b2, final byte b3) { - return (b0 & 0xFF) << 24 | - (b1 & 0xFF) << 16 | - (b2 & 0xFF) << 8 | - (b3 & 0xFF) << 0; - } - - public static - int from(final ByteBuffer buff) { - return from(buff.get(), buff.get(), buff.get(), buff.get()); - } - - public static - int from(InputStream inputStream) throws IOException { - return from((byte) inputStream.read(), (byte) inputStream.read(), (byte) inputStream.read(), (byte) inputStream.read()); - } - - public static - byte[] toBytes(final int x) { - return new byte[] {(byte) (x >> 24), (byte) (x >> 16), (byte) (x >> 8), (byte) (x >> 0)}; - } - - public static - void toBytes(final int x, final byte[] bytes, final int offset) { - bytes[offset + 0] = (byte) (x >> 24); - bytes[offset + 1] = (byte) (x >> 16); - bytes[offset + 2] = (byte) (x >> 8); - bytes[offset + 3] = (byte) (x >> 0); - } - - public static - void toBytes(final int x, final byte[] bytes) { - bytes[0] = (byte) (x >> 24); - bytes[1] = (byte) (x >> 16); - bytes[2] = (byte) (x >> 8); - bytes[3] = (byte) (x >> 0); - } - - private - Int_() { - } - } - - - /** - * UNSIGNED INT to and from bytes - */ - public static final - class UInt_ { - @SuppressWarnings("fallthrough") - public static - UInteger from(final byte[] bytes, final int offset, final int bytenum) { - int number = 0; - - switch (bytenum) { - case 4: - number |= (bytes[offset + 0] & 0xFF) << 24; - case 3: - number |= (bytes[offset + 1] & 0xFF) << 16; - case 2: - number |= (bytes[offset + 2] & 0xFF) << 8; - case 1: - number |= (bytes[offset + 3] & 0xFF) << 0; - } - - return UInteger.valueOf(number); - } - - @SuppressWarnings("fallthrough") - public static - UInteger from(final byte[] bytes) { - int number = 0; - - switch (bytes.length) { - default: - case 4: - number |= (bytes[0] & 0xFF) << 24; - case 3: - number |= (bytes[1] & 0xFF) << 16; - case 2: - number |= (bytes[2] & 0xFF) << 8; - case 1: - number |= (bytes[3] & 0xFF) << 0; - } - - return UInteger.valueOf(number); - } - - public static - UInteger from(final byte b0, final byte b1, final byte b2, final byte b3) { - int number = (b0 & 0xFF) << 24 | - (b1 & 0xFF) << 16 | - (b2 & 0xFF) << 8 | - (b3 & 0xFF) << 0; - - return UInteger.valueOf(number); - } - - public static - UInteger from(final ByteBuffer buff) { - return from(buff.get(), buff.get(), buff.get(), buff.get()); - } - - public static - UInteger from(final InputStream inputStream) throws IOException { - return from((byte) inputStream.read(), (byte) inputStream.read(), (byte) inputStream.read(), (byte) inputStream.read()); - } - - public static - byte[] toBytes(final UInteger x) { - long num = x.longValue(); - - return new byte[] {(byte) ((num & 0xFF000000L) >> 24), (byte) ((num & 0x00FF0000L) >> 16), (byte) ((num & 0x0000FF00L) >> 8), - (byte) (num & 0x000000FFL >> 0)}; - } - - public static - void toBytes(final UInteger x, final byte[] bytes, final int offset) { - long num = x.longValue(); - - bytes[offset + 0] = (byte) ((num & 0xFF000000L) >> 24); - bytes[offset + 1] = (byte) ((num & 0x00FF0000L) >> 16); - bytes[offset + 2] = (byte) ((num & 0x0000FF00L) >> 8); - bytes[offset + 3] = (byte) (num & 0x000000FFL >> 0); - } - - public static - void toBytes(final UInteger x, final byte[] bytes) { - long num = x.longValue(); - - bytes[0] = (byte) ((num & 0xFF000000L) >> 24); - bytes[1] = (byte) ((num & 0x00FF0000L) >> 16); - bytes[2] = (byte) ((num & 0x0000FF00L) >> 8); - bytes[3] = (byte) (num & 0x000000FFL >> 0); - } - - private - UInt_() { - } - } - - - /** - * LONG to and from bytes - */ - public static final - class Long_ { - @SuppressWarnings("fallthrough") - public static - long from(final byte[] bytes, final int offset, final int bytenum) { - long number = 0; - - switch (bytenum) { - case 8: - number |= (long) (bytes[offset + 0] & 0xFF) << 56; - case 7: - number |= (long) (bytes[offset + 1] & 0xFF) << 48; - case 6: - number |= (long) (bytes[offset + 2] & 0xFF) << 40; - case 5: - number |= (long) (bytes[offset + 3] & 0xFF) << 32; - case 4: - number |= (long) (bytes[offset + 4] & 0xFF) << 24; - case 3: - number |= (long) (bytes[offset + 5] & 0xFF) << 16; - case 2: - number |= (long) (bytes[offset + 6] & 0xFF) << 8; - case 1: - number |= (long) (bytes[offset + 7] & 0xFF) << 0; - } - - return number; - } - - @SuppressWarnings("fallthrough") - public static - long from(final byte[] bytes) { - long number = 0L; - - switch (bytes.length) { - default: - case 8: - number |= (long) (bytes[0] & 0xFF) << 56; - case 7: - number |= (long) (bytes[1] & 0xFF) << 48; - case 6: - number |= (long) (bytes[2] & 0xFF) << 40; - case 5: - number |= (long) (bytes[3] & 0xFF) << 32; - case 4: - number |= (long) (bytes[4] & 0xFF) << 24; - case 3: - number |= (long) (bytes[5] & 0xFF) << 16; - case 2: - number |= (long) (bytes[6] & 0xFF) << 8; - case 1: - number |= (long) (bytes[7] & 0xFF) << 0; - } - - return number; - } - - public static - long from(final byte b0, final byte b1, final byte b2, final byte b3, final byte b4, final byte b5, final byte b6, final byte b7) { - return (long) (b0 & 0xFF) << 56 | - (long) (b1 & 0xFF) << 48 | - (long) (b2 & 0xFF) << 40 | - (long) (b3 & 0xFF) << 32 | - (long) (b4 & 0xFF) << 24 | - (long) (b5 & 0xFF) << 16 | - (long) (b6 & 0xFF) << 8 | - (long) (b7 & 0xFF) << 0; - } - - public static - long from(final ByteBuffer buff) { - return from(buff.get(), buff.get(), buff.get(), buff.get(), buff.get(), buff.get(), buff.get(), buff.get()); - } - - public static - long from(final InputStream inputStream) throws IOException { - return from((byte) inputStream.read(), - (byte) inputStream.read(), - (byte) inputStream.read(), - (byte) inputStream.read(), - (byte) inputStream.read(), - (byte) inputStream.read(), - (byte) inputStream.read(), - (byte) inputStream.read()); - } - - public static - byte[] toBytes(final long x) { - return new byte[] {(byte) (x >> 56), (byte) (x >> 48), (byte) (x >> 40), (byte) (x >> 32), (byte) (x >> 24), (byte) (x >> 16), - (byte) (x >> 8), (byte) (x >> 0)}; - } - - public static - void toBytes(final long x, final byte[] bytes, final int offset) { - bytes[offset + 0] = (byte) (x >> 56); - bytes[offset + 1] = (byte) (x >> 48); - bytes[offset + 2] = (byte) (x >> 40); - bytes[offset + 3] = (byte) (x >> 32); - bytes[offset + 4] = (byte) (x >> 24); - bytes[offset + 5] = (byte) (x >> 16); - bytes[offset + 6] = (byte) (x >> 8); - bytes[offset + 7] = (byte) (x >> 0); - } - - public static - void toBytes(final long x, final byte[] bytes) { - bytes[0] = (byte) (x >> 56); - bytes[1] = (byte) (x >> 48); - bytes[2] = (byte) (x >> 40); - bytes[3] = (byte) (x >> 32); - bytes[4] = (byte) (x >> 24); - bytes[5] = (byte) (x >> 16); - bytes[6] = (byte) (x >> 8); - bytes[7] = (byte) (x >> 0); - } - - - private - Long_() { - } - } - - - /** - * UNSIGNED LONG to and from bytes - */ - public static final - class ULong_ { - @SuppressWarnings("fallthrough") - public static - ULong from(final byte[] bytes, final int offset, final int bytenum) { - long number = 0; - - switch (bytenum) { - case 8: - number |= (long) (bytes[offset + 0] & 0xFF) << 56; - case 7: - number |= (long) (bytes[offset + 1] & 0xFF) << 48; - case 6: - number |= (long) (bytes[offset + 2] & 0xFF) << 40; - case 5: - number |= (long) (bytes[offset + 3] & 0xFF) << 32; - case 4: - number |= (long) (bytes[offset + 4] & 0xFF) << 24; - case 3: - number |= (long) (bytes[offset + 5] & 0xFF) << 16; - case 2: - number |= (long) (bytes[offset + 6] & 0xFF) << 8; - case 1: - number |= (long) (bytes[offset + 7] & 0xFF) << 0; - } - - return ULong.valueOf(number); - } - - public static - ULong from(final byte[] bytes) { - BigInteger ulong = new BigInteger(1, bytes); - return ULong.valueOf(ulong); - } - - public static - ULong from(final byte b0, final byte b1, final byte b2, final byte b3, final byte b4, final byte b5, final byte b6, final byte b7) { - byte[] bytes = new byte[] {b0, b1, b2, b3, b4, b5, b6, b7}; - BigInteger ulong = new BigInteger(1, bytes); - return ULong.valueOf(ulong); - } - - public static - ULong from(final ByteBuffer buff) { - return from(buff.get(), buff.get(), buff.get(), buff.get(), buff.get(), buff.get(), buff.get(), buff.get()); - } - - public static - ULong from(final InputStream inputStream) throws IOException { - return from((byte) inputStream.read(), - (byte) inputStream.read(), - (byte) inputStream.read(), - (byte) inputStream.read(), - (byte) inputStream.read(), - (byte) inputStream.read(), - (byte) inputStream.read(), - (byte) inputStream.read()); - } - - public static - byte[] toBytes(final ULong x) { - // returns the shortest length byte array possible - byte[] bytes = x.toBigInteger() - .toByteArray(); - - if (bytes.length < 8) { - byte[] fixedBytes = new byte[8]; - int length = bytes.length; - - for (int i = 0; i < 8; i++) { - if (i < length) { - fixedBytes[i] = bytes[i]; - } - else { - fixedBytes[i] = 0; - } - } - bytes = fixedBytes; - } - - return bytes; - } - - public static - void toBytes(final ULong x, final byte[] bytes, final int offset) { - final byte[] bytes1 = toBytes(x); - int length = bytes.length; - int pos = 8; - - while (length > 0) { - bytes[pos--] = bytes1[offset + length--]; - } - } - - public static - void toBytes(final ULong x, final byte[] bytes) { - final byte[] bytes1 = toBytes(x); - int length = bytes.length; - int pos = 8; - - while (length > 0) { - bytes[pos--] = bytes1[length--]; - } - } - - - private - ULong_() { - } - } -} - diff --git a/src/dorkbox/util/bytes/ByteArrayWrapper.java b/src/dorkbox/util/bytes/ByteArrayWrapper.java deleted file mode 100644 index e48e04b..0000000 --- a/src/dorkbox/util/bytes/ByteArrayWrapper.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright 2014 dorkbox, llc - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package dorkbox.util.bytes; - -import java.util.Arrays; - -/** - * Necessary to provide equals and hashcode methods on a byte arrays, if they are to be used as keys in a map/set/etc - */ -public -class ByteArrayWrapper { - private byte[] data; - private Integer hashCode; - - private - ByteArrayWrapper() { - // this is necessary for kryo - } - - /** - * Permits the re-use of a byte array. - * - * @param copyBytes if TRUE, then the byteArray is copied. if FALSE, the byte array is used as-is. - * Using FALSE IS DANGEROUS!!!! If the underlying byte array is modified, this changes as well. - */ - public - ByteArrayWrapper(byte[] data, boolean copyBytes) { - if (data == null) { - throw new NullPointerException(); - } - int length = data.length; - - if (copyBytes) { - this.data = new byte[length]; - // copy so it's immutable as a key. - System.arraycopy(data, 0, this.data, 0, length); - } - else { - this.data = data; - } - } - - /** - * Makes a safe copy of the byte array, so that changes to the original do not affect the wrapper. - * Side affect is additional memory is used. - */ - public static - ByteArrayWrapper copy(byte[] data) { - if (data == null) { - return null; - } - - return new ByteArrayWrapper(data, true); - } - - /** - * Does not make a copy of the data, so changes to the original will also affect the wrapper. - * Side affect is no extra memory is needed. - */ - public static - ByteArrayWrapper wrap(byte[] data) { - if (data == null) { - return null; - } - return new ByteArrayWrapper(data, false); - } - - public - byte[] getBytes() { - return this.data; - } - - @Override - public - int hashCode() { - // might be null for a thread because it's stale. who cares, get the value again - Integer hashCode = this.hashCode; - if (hashCode == null) { - hashCode = Arrays.hashCode(this.data); - this.hashCode = hashCode; - } - return hashCode; - } - - @Override - public - boolean equals(Object other) { - if (!(other instanceof ByteArrayWrapper)) { - return false; - } - - // CANNOT be null, so we don't have to null check! - return Arrays.equals(this.data, ((ByteArrayWrapper) other).data); - } - - @Override - public - String toString() { - return "ByteArrayWrapper " + java.util.Arrays.toString(this.data); - } -} diff --git a/src/dorkbox/util/bytes/ByteBuffer2.java b/src/dorkbox/util/bytes/ByteBuffer2.java deleted file mode 100644 index ddb70d2..0000000 --- a/src/dorkbox/util/bytes/ByteBuffer2.java +++ /dev/null @@ -1,1945 +0,0 @@ -/* - * Copyright (c) 2008, Nathan Sweet - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - * * Neither the name of Esoteric Software nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Modified by dorkbox, llc - */ -package dorkbox.util.bytes; - -import java.nio.BufferUnderflowException; -import java.util.Arrays; - -/** - * A self-growing byte array wrapper. - * - * Utility methods are provided for efficiently writing primitive types and strings. - * - * Encoding of integers: BIG_ENDIAN is used for storing fixed native size integer values LITTLE_ENDIAN is used for a variable - * length encoding of integer values - * - * @author Nathan Sweet - */ -@SuppressWarnings({"unused", "DuplicatedCode", "ForLoopReplaceableByForEach"}) -public class ByteBuffer2 { - private int capacity; // exactly how many bytes have been allocated - private int maxCapacity; // how large we can grow - - - private int position; // current pointer to the point where data is read/written - - private byte[] bytes; // the backing buffer - private char[] chars = new char[32]; // small buffer for reading strings - - /** - * Creates an uninitialized object. {@link #setBuffer(byte[], int)} must be called before the object is used. - */ - public ByteBuffer2() { - } - - /** - * Creates a new object for writing to a byte array. - * - * @param bufferSize - * The initial and maximum size of the buffer. An exception is thrown if this size is exceeded. - */ - public ByteBuffer2(int bufferSize) { - this(bufferSize, bufferSize); - } - - /** - * Creates a new object for writing to a byte array. - * - * @param bufferSize - * The initial size of the buffer. - * @param maxBufferSize - * The buffer is doubled as needed until it exceeds maxBufferSize and an exception is thrown. Can be -1 - * for no maximum. - */ - public ByteBuffer2(int bufferSize, int maxBufferSize) { - if (maxBufferSize < -1) { - throw new IllegalArgumentException("maxBufferSize cannot be < -1: " + maxBufferSize); - } - - this.capacity = bufferSize; - this.maxCapacity = maxBufferSize == -1 ? Integer.MAX_VALUE : maxBufferSize; - this.bytes = new byte[bufferSize]; - } - - /** - * Creates a new object for writing to a byte array. - * - * @see #setBuffer(byte[]) - */ - public ByteBuffer2(byte[] buffer) { - this(buffer, buffer.length); - } - - /** - * Creates a new object for writing to a byte array. - * - * @see #setBuffer(byte[], int) - */ - public ByteBuffer2(byte[] buffer, int maxBufferSize) { - if (buffer == null) { - throw new IllegalArgumentException("buffer cannot be null."); - } - setBuffer(buffer, maxBufferSize); - } - - /** - * Sets the buffer that will be written to. {@link #setBuffer(byte[], int)} is called with the specified buffer's - * length as the maxBufferSize. - */ - public void setBuffer(byte[] buffer) { - setBuffer(buffer, buffer.length); - } - - /** - * Sets the buffer that will be written to. The position and total are reset, discarding any buffered bytes. - * - * @param maxBufferSize - * The buffer is doubled as needed until it exceeds maxBufferSize and an exception is thrown. - */ - public void setBuffer(byte[] buffer, int maxBufferSize) { - if (buffer == null) { - throw new IllegalArgumentException("buffer cannot be null."); - } - - if (maxBufferSize < -1) { - throw new IllegalArgumentException("maxBufferSize cannot be < -1: " + maxBufferSize); - } - - this.bytes = buffer; - this.maxCapacity = maxBufferSize == -1 ? Integer.MAX_VALUE : maxBufferSize; - this.capacity = buffer.length; - this.position = 0; - } - - /** - * Returns the buffer. The bytes between zero and {@link #position()} are the data that has been written. - */ - public byte[] getBuffer() { - return this.bytes; - } - - /** - * Returns a new byte array containing the bytes currently in the buffer between zero and {@link #position()}. - */ - public byte[] toBytes() { - int position2 = this.position; - byte[] newBuffer = new byte[position2]; - - if (position2 > 0) { - System.arraycopy(this.bytes, 0, newBuffer, 0, position2); - } - return newBuffer; - } - - /** - * Returns the remaining read/write bytes available before the end of the buffer - */ - public int remaining() { - return this.capacity - this.position; - } - - /** - * Returns the size of the backing byte buffer - */ - public int capacity() { - return this.capacity; - } - - /** - * Returns the current position in the buffer. This is the number of bytes that have not been flushed. - */ - public int position() { - return this.position; - } - - /** - * Sets the current position in the buffer. - */ - public void setPosition(int position) { - this.position = position; - } - - /** - * Sets the position to zero. - */ - public void clear() { - this.position = 0; - } - - /** - * Sets the position to zero. - */ - public void rewind() { - this.position = 0; - } - - /** - * Sets the position to zero, and write 0 to all bytes in the buffer - */ - public void clearSecure() { - this.position = 0; - byte[] buffer = this.bytes; - - for (int i=0;i= required) { - return false; - } - if (required > this.maxCapacity) { - throw new RuntimeException("Buffer overflow. Max capacity: " + this.maxCapacity + ", required: " + required); - } - - while (this.capacity - this.position < required) { - if (this.capacity == this.maxCapacity) { - throw new RuntimeException("Buffer overflow. Available: " + (this.capacity - this.position) - + ", required: " + required); - } - - // Grow buffer. - if (this.capacity == 0) { - this.capacity = 1; - } - this.capacity = Math.min((int)(this.capacity * 1.6D), this.maxCapacity); - if (this.capacity < 0) { - this.capacity = this.maxCapacity; - } - byte[] newBuffer = new byte[this.capacity]; - System.arraycopy(this.bytes, 0, newBuffer, 0, this.position); - this.bytes = newBuffer; - } - - return true; - } - - // byte - - /** - * Writes a byte. - */ - public void writeByte(byte value) { - if (this.position == this.capacity) { - require(1); - } - this.bytes[this.position++] = value; - } - - /** - * Writes a byte. - */ - public void writeByte(int value) { - if (this.position == this.capacity) { - require(1); - } - this.bytes[this.position++] = (byte) value; - } - - /** - * Writes the bytes. Note the byte[] length is not written. - */ - public void writeBytes(byte[] bytes) { - if (bytes == null) { - throw new IllegalArgumentException("bytes cannot be null."); - } - writeBytes(bytes, 0, bytes.length); - } - - /** - * Writes the bytes. Note the byte[] length is not written. - */ - public void writeBytes(byte[] bytes, int offset, int count) { - if (bytes == null) { - throw new IllegalArgumentException("bytes cannot be null."); - } - - int copyCount = Math.min(this.capacity - this.position, count); - while (true) { - System.arraycopy(bytes, offset, this.bytes, this.position, copyCount); - this.position += copyCount; - count -= copyCount; - if (count == 0) { - return; - } - offset += copyCount; - copyCount = Math.min(this.capacity, count); - require(copyCount); - } - } - - /** - * Reads a single byte. - */ - public byte readByte() { - return this.bytes[this.position++]; - } - - /** - * Reads a byte as an int from 0 to 255. - */ - public int readByteUnsigned() { - return this.bytes[this.position++] & 0xFF; - } - - /** - * Reads a single byte, does not advance the position - */ - public byte readByte(int position) { - return this.bytes[position]; - } - - /** - * Reads a byte as an int from 0 to 255, does not advance the position - */ - public int readByteUnsigned(int position) { - return this.bytes[position] & 0xFF; - } - - /** - * Reads the specified number of bytes into a new byte[]. - */ - public byte[] readBytes(int length) { - byte[] bytes = new byte[length]; - readBytes(bytes, 0, length); - return bytes; - } - - /** - * Reads bytes.length bytes and writes them to the specified byte[], starting at index 0. - */ - public void readBytes(byte[] bytes) { - readBytes(bytes, 0, bytes.length); - } - - /** - * Reads count bytes and writes them to the specified byte[], starting at offset in target byte array. - */ - public void readBytes(byte[] bytes, int offset, int count) { - if (bytes == null) { - throw new IllegalArgumentException("bytes cannot be null."); - } - - System.arraycopy(this.bytes, this.position, bytes, offset, count); - this.position += count; - } - - // int - - /** - * Writes a 4 byte int. Uses BIG_ENDIAN byte order. - */ - public void writeInt(int value) { - require(4); - - byte[] buffer = this.bytes; - buffer[this.position++] = (byte) (value >> 24); - buffer[this.position++] = (byte) (value >> 16); - buffer[this.position++] = (byte) (value >> 8); - buffer[this.position++] = (byte) value; - } - - /** - * Writes a 1-5 byte int. This stream may consider such a variable length encoding request as a hint. It is not - * guaranteed that a variable length encoding will be really used. The stream may decide to use native-sized integer - * representation for efficiency reasons. - * - * @param optimizePositive - * If true, small positive numbers will be more efficient (1 byte) and small negative numbers will be - * inefficient (5 bytes). - */ - public int writeInt(int value, boolean optimizePositive) { - return writeVarInt(value, optimizePositive); - } - - /** - * Writes a 1-5 byte int. It is guaranteed that a varible length encoding will be used. - * - * @param optimizePositive - * If true, small positive numbers will be more efficient (1 byte) and small negative numbers will be - * inefficient (5 bytes). - */ - public int writeVarInt(int value, boolean optimizePositive) { - if (!optimizePositive) { - value = value << 1 ^ value >> 31; - } - - if (value >>> 7 == 0) { - require(1); - this.bytes[this.position++] = (byte) value; - return 1; - } - if (value >>> 14 == 0) { - require(2); - byte[] buffer = this.bytes; - buffer[this.position++] = (byte) (value & 0x7F | 0x80); - buffer[this.position++] = (byte) (value >>> 7); - return 2; - } - if (value >>> 21 == 0) { - require(3); - byte[] buffer = this.bytes; - buffer[this.position++] = (byte) (value & 0x7F | 0x80); - buffer[this.position++] = (byte) (value >>> 7 | 0x80); - buffer[this.position++] = (byte) (value >>> 14); - return 3; - } - if (value >>> 28 == 0) { - require(4); - byte[] buffer = this.bytes; - buffer[this.position++] = (byte) (value & 0x7F | 0x80); - buffer[this.position++] = (byte) (value >>> 7 | 0x80); - buffer[this.position++] = (byte) (value >>> 14 | 0x80); - buffer[this.position++] = (byte) (value >>> 21); - return 4; - } - - require(5); - byte[] buffer = this.bytes; - buffer[this.position++] = (byte) (value & 0x7F | 0x80); - buffer[this.position++] = (byte) (value >>> 7 | 0x80); - buffer[this.position++] = (byte) (value >>> 14 | 0x80); - buffer[this.position++] = (byte) (value >>> 21 | 0x80); - buffer[this.position++] = (byte) (value >>> 28); - return 5; - } - - /** - * Reads a 4 byte int. - */ - public int readInt() { - byte[] buffer = this.bytes; - int position = this.position; - - int value = (buffer[position] & 0xFF) << 24 - | (buffer[position + 1] & 0xFF) << 16 - | (buffer[position + 2] & 0xFF) << 8 - | buffer[position + 3] & 0xFF; - - this.position = position + 4; - return value; - } - - /** - * Reads a 4 byte int, does not advance the position - */ - public int readInt(int position) { - byte[] buffer = this.bytes; - int value = (buffer[position] & 0xFF) << 24 - | (buffer[position + 1] & 0xFF) << 16 - | (buffer[position + 2] & 0xFF) << 8 - | buffer[position + 3] & 0xFF; - - this.position = position + 4; - return value; - } - - /** - * Reads a 1-5 byte int. This stream may consider such a variable length encoding request as a hint. It is not - * guaranteed that a variable length encoding will be really used. The stream may decide to use native-sized integer - * representation for efficiency reasons. - */ - public int readInt(boolean optimizePositive) { - return readVarInt(optimizePositive); - } - - /** - * Reads a 1-5 byte int. This stream may consider such a variable length encoding request as a hint. It is not - * guaranteed that a variable length encoding will be really used. The stream may decide to use native-sized integer - * representation for efficiency reasons. - *

- * does not advance the position - */ - public int readInt(int position, boolean optimizePositive) { - int pos = this.position; - this.position = position; - int value = readVarInt(optimizePositive); - this.position = pos; - return value; - } - - /** - * Reads a 1-5 byte int. It is guaranteed that a variable length encoding will be used. - */ - private int readVarInt(boolean optimizePositive) { - byte[] buffer = this.bytes; - - if (this.capacity - this.position < 5) { - return readInt_slow(optimizePositive); - } - - int b = buffer[this.position++]; - int result = b & 0x7F; - if ((b & 0x80) != 0) { - b = buffer[this.position++]; - result |= (b & 0x7F) << 7; - if ((b & 0x80) != 0) { - b = buffer[this.position++]; - result |= (b & 0x7F) << 14; - if ((b & 0x80) != 0) { - b = buffer[this.position++]; - result |= (b & 0x7F) << 21; - if ((b & 0x80) != 0) { - b = buffer[this.position++]; - result |= (b & 0x7F) << 28; - } - } - } - } - return optimizePositive ? result : result >>> 1 ^ -(result & 1); - } - - private int readInt_slow(boolean optimizePositive) { - byte[] buffer = this.bytes; - - // The buffer is guaranteed to have at least 1 byte. - int b = buffer[this.position++]; - int result = b & 0x7F; - if ((b & 0x80) != 0) { - b = buffer[this.position++]; - result |= (b & 0x7F) << 7; - if ((b & 0x80) != 0) { - b = buffer[this.position++]; - result |= (b & 0x7F) << 14; - if ((b & 0x80) != 0) { - b = buffer[this.position++]; - result |= (b & 0x7F) << 21; - if ((b & 0x80) != 0) { - b = buffer[this.position++]; - result |= (b & 0x7F) << 28; - } - } - } - } - return optimizePositive ? result : result >>> 1 ^ -(result & 1); - } - - /** - * Returns true if enough bytes are available to read an int with {@link #readInt(boolean)}. - */ - public boolean canReadInt() { - if (this.capacity - this.position >= 5) { - return true; - } - - if (this.position + 1 > this.capacity) { - return false; - } - - byte[] buffer = this.bytes; - - int p = this.position; - if ((buffer[p++] & 0x80) == 0) { - return true; - } - if (p == this.capacity) { - return false; - } - if ((buffer[p++] & 0x80) == 0) { - return true; - } - if (p == this.capacity) { - return false; - } - if ((buffer[p++] & 0x80) == 0) { - return true; - } - if (p == this.capacity) { - return false; - } - if ((buffer[p++] & 0x80) == 0) { - return true; - } - - return p != this.capacity; - } - - /** - * Returns true if enough bytes are available to read an int with {@link #readInt(boolean)}. - */ - public boolean canReadInt(int position) { - if (this.capacity - position >= 5) { - return true; - } - - if (position + 1 > this.capacity) { - return false; - } - - byte[] buffer = this.bytes; - - int p = position; - if ((buffer[p++] & 0x80) == 0) { - return true; - } - if (p == this.capacity) { - return false; - } - if ((buffer[p++] & 0x80) == 0) { - return true; - } - if (p == this.capacity) { - return false; - } - if ((buffer[p++] & 0x80) == 0) { - return true; - } - if (p == this.capacity) { - return false; - } - if ((buffer[p++] & 0x80) == 0) { - return true; - } - - return p != this.capacity; - } - - // string - - /** - * Writes the length and string, or null. Short strings are checked and if ASCII they are written more efficiently, - * else they are written as UTF8. If a string is known to be ASCII, {@link ByteBuffer2#writeAscii(String)} may be used. The - * string can be read using {@link ByteBuffer2#readString()} or {@link ByteBuffer2#readStringBuilder()}. - * - * @param value - * May be null. - */ - @SuppressWarnings("deprecation") - public void writeString(String value) { - if (value == null) { - writeByte(0x80); // 0 means null, bit 8 means UTF8. - return; - } - - int charCount = value.length(); - if (charCount == 0) { - writeByte(1 | 0x80); // 1 means empty string, bit 8 means UTF8. - return; - } - - // Detect ASCII. - boolean ascii = false; - if (charCount > 1 && charCount < 64) { - ascii = true; - for (int i = 0; i < charCount; i++) { - int c = value.charAt(i); - if (c > 127) { - ascii = false; - break; - } - } - } - - if (ascii) { - if (this.capacity - this.position < charCount) { - writeAscii_slow(value, charCount); - } else { - value.getBytes(0, charCount, this.bytes, this.position); - this.position += charCount; - } - this.bytes[this.position - 1] |= 0x80; - } else { - writeUtf8Length(charCount + 1); - int charIndex = 0; - if (this.capacity - this.position >= charCount) { - // Try to write 8 bit chars. - byte[] buffer = this.bytes; - int position = this.position; - for (; charIndex < charCount; charIndex++) { - int c = value.charAt(charIndex); - if (c > 127) { - break; - } - buffer[position++] = (byte) c; - } - this.position = position; - } - - if (charIndex < charCount) { - writeString_slow(value, charCount, charIndex); - } - } - } - - /** - * Writes the length and CharSequence as UTF8, or null. The string can be read using {@link ByteBuffer2#readString()} or - * {@link ByteBuffer2#readStringBuilder()}. - * - * @param value - * May be null. - */ - public void writeString(CharSequence value) { - if (value == null) { - writeByte(0x80); // 0 means null, bit 8 means UTF8. - return; - } - - int charCount = value.length(); - if (charCount == 0) { - writeByte(1 | 0x80); // 1 means empty string, bit 8 means UTF8. - return; - } - - writeUtf8Length(charCount + 1); - int charIndex = 0; - if (this.capacity - this.position >= charCount) { - // Try to write 8 bit chars. - byte[] buffer = this.bytes; - int position = this.position; - - for (; charIndex < charCount; charIndex++) { - int c = value.charAt(charIndex); - if (c > 127) { - break; - } - buffer[position++] = (byte) c; - } - this.position = position; - } - - if (charIndex < charCount) { - writeString_slow(value, charCount, charIndex); - } - } - - /** - * Writes a string that is known to contain only ASCII characters. Non-ASCII strings passed to this method will be - * corrupted. Each byte is a 7 bit character with the remaining byte denoting if another character is available. - * This is slightly more efficient than {@link ByteBuffer2#writeString(String)}. The string can be read using - * {@link ByteBuffer2#readString()} or {@link ByteBuffer2#readStringBuilder()}. - * - * @param value - * May be null. - */ - @SuppressWarnings("deprecation") - public void writeAscii(String value) { - if (value == null) { - writeByte(0x80); // 0 means null, bit 8 means UTF8. - return; - } - - int charCount = value.length(); - switch (charCount) { - case 0 : - writeByte(1 | 0x80); // 1 is string length + 1, bit 8 means UTF8. - return; - case 1 : - writeByte(2 | 0x80); // 2 is string length + 1, bit 8 means UTF8. - writeByte(value.charAt(0)); - return; - } - - if (this.capacity - this.position < charCount) { - writeAscii_slow(value, charCount); - } else { - value.getBytes(0, charCount, this.bytes, this.position); - this.position += charCount; - } - - this.bytes[this.position - 1] |= 0x80; // Bit 8 means end of ASCII. - } - - /** - * Writes the length of a string, which is a variable length encoded int except the first byte uses bit 8 to denote - * UTF8 and bit 7 to denote if another byte is present. - */ - private void writeUtf8Length(int value) { - - if (value >>> 6 == 0) { - require(1); - this.bytes[this.position++] = (byte) (value | 0x80); // Set bit 8. - } else if (value >>> 13 == 0) { - require(2); - byte[] buffer = this.bytes; - buffer[this.position++] = (byte) (value | 0x40 | 0x80); // Set bit 7 and 8. - buffer[this.position++] = (byte) (value >>> 6); - } else if (value >>> 20 == 0) { - require(3); - byte[] buffer = this.bytes; - buffer[this.position++] = (byte) (value | 0x40 | 0x80); // Set bit 7 and 8. - buffer[this.position++] = (byte) (value >>> 6 | 0x80); // Set bit 8. - buffer[this.position++] = (byte) (value >>> 13); - } else if (value >>> 27 == 0) { - require(4); - byte[] buffer = this.bytes; - buffer[this.position++] = (byte) (value | 0x40 | 0x80); // Set bit 7 and 8. - buffer[this.position++] = (byte) (value >>> 6 | 0x80); // Set bit 8. - buffer[this.position++] = (byte) (value >>> 13 | 0x80); // Set bit 8. - buffer[this.position++] = (byte) (value >>> 20); - } else { - require(5); - byte[] buffer = this.bytes; - buffer[this.position++] = (byte) (value | 0x40 | 0x80); // Set bit 7 and 8. - buffer[this.position++] = (byte) (value >>> 6 | 0x80); // Set bit 8. - buffer[this.position++] = (byte) (value >>> 13 | 0x80); // Set bit 8. - buffer[this.position++] = (byte) (value >>> 20 | 0x80); // Set bit 8. - buffer[this.position++] = (byte) (value >>> 27); - } - } - - private void writeString_slow(CharSequence value, int charCount, int charIndex) { - byte[] buffer = this.bytes; - for (; charIndex < charCount; charIndex++) { - if (this.position == this.capacity) { - require(Math.min(this.capacity, charCount - charIndex)); - buffer = this.bytes; - } - - int c = value.charAt(charIndex); - if (c <= 0x007F) { - this.bytes[this.position++] = (byte) c; - } else if (c > 0x07FF) { - buffer[this.position++] = (byte) (0xE0 | c >> 12 & 0x0F); - require(2); - - buffer = this.bytes; - buffer[this.position++] = (byte) (0x80 | c >> 6 & 0x3F); - buffer[this.position++] = (byte) (0x80 | c & 0x3F); - } else { - buffer[this.position++] = (byte) (0xC0 | c >> 6 & 0x1F); - require(1); - buffer = this.bytes; - buffer[this.position++] = (byte) (0x80 | c & 0x3F); - } - } - } - - @SuppressWarnings("deprecation") - private void writeAscii_slow(String value, int charCount) { - byte[] buffer = this.bytes; - int charIndex = 0; - int charsToWrite = Math.min(charCount, this.capacity - this.position); - - while (charIndex < charCount) { - value.getBytes(charIndex, charIndex + charsToWrite, buffer, this.position); - charIndex += charsToWrite; - this.position += charsToWrite; - charsToWrite = Math.min(charCount - charIndex, this.capacity); - if (require(charsToWrite)) { - buffer = this.bytes; - } - } - } - - /** - * Reads the length and string of UTF8 characters, or null. This can read strings written by - * {@link ByteBuffer2#writeString(String)} , {@link ByteBuffer2#writeString(CharSequence)}, and - * {@link ByteBuffer2#writeAscii(String)}. - * - * @return May be null. - */ - public String readString() { - int available = this.capacity - this.position; - - int b = this.bytes[this.position++]; - if ((b & 0x80) == 0) { - return readAscii(); // ASCII. - } - - // Null, empty, or UTF8. - int charCount = available >= 5 ? readUtf8Length(b) : readUtf8Length_slow(b); - switch (charCount) { - case 0 : - return null; - case 1 : - return ""; - } - charCount--; - - if (this.chars.length < charCount) { - this.chars = new char[charCount]; - } - - if (available < charCount) { - throw new BufferUnderflowException(); - } - - readUtf8(charCount); - return new String(this.chars, 0, charCount); - } - - private int readUtf8Length(int b) { - int result = b & 0x3F; // Mask all but first 6 bits. - if ((b & 0x40) != 0) { // Bit 7 means another byte, bit 8 means UTF8. - byte[] buffer = this.bytes; - - b = buffer[this.position++]; - result |= (b & 0x7F) << 6; - if ((b & 0x80) != 0) { - b = buffer[this.position++]; - result |= (b & 0x7F) << 13; - if ((b & 0x80) != 0) { - b = buffer[this.position++]; - result |= (b & 0x7F) << 20; - if ((b & 0x80) != 0) { - b = buffer[this.position++]; - result |= (b & 0x7F) << 27; - } - } - } - } - return result; - } - - private int readUtf8Length_slow(int b) { - int result = b & 0x3F; // Mask all but first 6 bits. - if ((b & 0x40) != 0) { // Bit 7 means another byte, bit 8 means UTF8. - byte[] buffer = this.bytes; - - b = buffer[this.position++]; - result |= (b & 0x7F) << 6; - if ((b & 0x80) != 0) { - b = buffer[this.position++]; - result |= (b & 0x7F) << 13; - if ((b & 0x80) != 0) { - b = buffer[this.position++]; - result |= (b & 0x7F) << 20; - if ((b & 0x80) != 0) { - b = buffer[this.position++]; - result |= (b & 0x7F) << 27; - } - } - } - } - return result; - } - - private void readUtf8(int charCount) { - byte[] buffer = this.bytes; - int position = this.position; - char[] chars = this.chars; - - // Try to read 7 bit ASCII chars. - int charIndex = 0; - int spaceAvailable = this.capacity - this.position; - int count = Math.min(spaceAvailable, charCount); - - int b; - while (charIndex < count) { - b = buffer[position++]; - if (b < 0) { - position--; - break; - } - chars[charIndex++] = (char) b; - } - this.position = position; - - // If buffer didn't hold all chars or any were not ASCII, use slow path for remainder. - if (charIndex < charCount) { - readUtf8_slow(charCount, charIndex); - } - } - - private void readUtf8_slow(int charCount, int charIndex) { - char[] chars = this.chars; - byte[] buffer = this.bytes; - - while (charIndex < charCount) { - int b = buffer[this.position++] & 0xFF; - switch (b >> 4) { - case 0 : - case 1 : - case 2 : - case 3 : - case 4 : - case 5 : - case 6 : - case 7 : - chars[charIndex] = (char) b; - break; - case 12 : - case 13 : - chars[charIndex] = (char) ((b & 0x1F) << 6 | buffer[this.position++] & 0x3F); - break; - case 14 : - chars[charIndex] = (char) ((b & 0x0F) << 12 | (buffer[this.position++] & 0x3F) << 6 | buffer[this.position++] & 0x3F); - break; - } - charIndex++; - } - } - - private String readAscii() { - byte[] buffer = this.bytes; - int end = this.position; - int start = end - 1; - int limit = this.capacity; - int b; - - do { - if (end == limit) { - return readAscii_slow(); - } - b = buffer[end++]; - } while ((b & 0x80) == 0); - - buffer[end - 1] &= 0x7F; // Mask end of ascii bit. - - @SuppressWarnings("deprecation") - String value = new String(buffer, 0, start, end - start); - buffer[end - 1] |= 0x80; - - this.position = end; - return value; - } - - private String readAscii_slow() { - this.position--; // Re-read the first byte. - - // Copy chars currently in buffer. - int charCount = this.capacity - this.position; - if (charCount > this.chars.length) { - this.chars = new char[charCount * 2]; - } - - char[] chars = this.chars; - byte[] buffer = this.bytes; - for (int i = this.position, ii = 0, n = this.capacity; i < n; i++, ii++) { - chars[ii] = (char) buffer[i]; - } - this.position = this.capacity; - - // Copy additional chars one by one. - while (true) { - int b = buffer[this.position++]; - if (charCount == chars.length) { - char[] newChars = new char[charCount * 2]; - System.arraycopy(chars, 0, newChars, 0, charCount); - chars = newChars; - this.chars = newChars; - } - if ((b & 0x80) == 0x80) { - chars[charCount++] = (char) (b & 0x7F); - break; - } - chars[charCount++] = (char) b; - } - - return new String(chars, 0, charCount); - } - - /** - * Reads the length and string of UTF8 characters, or null. This can read strings written by - * {@link ByteBuffer2#writeString(String)} , {@link ByteBuffer2#writeString(CharSequence)}, and - * {@link ByteBuffer2#writeAscii(String)}. - * - * @return May be null. - */ - public StringBuilder readStringBuilder() { - int available = this.capacity - this.position; - int b = this.bytes[this.position++]; - if ((b & 0x80) == 0) { - return new StringBuilder(readAscii()); // ASCII. - } - - // Null, empty, or UTF8. - int charCount = available >= 5 ? readUtf8Length(b) : readUtf8Length_slow(b); - switch (charCount) { - case 0 : - return null; - case 1 : - return new StringBuilder(); - } - charCount--; - if (this.chars.length < charCount) { - this.chars = new char[charCount]; - } - - readUtf8(charCount); - StringBuilder builder = new StringBuilder(charCount); - builder.append(this.chars, 0, charCount); - - return builder; - } - - - // float - - /** - * Writes a 4 byte float. - */ - public void writeFloat(float value) { - writeInt(Float.floatToIntBits(value)); - } - - /** - * Writes a 1-5 byte float with reduced precision. - * - * @param optimizePositive - * If true, small positive numbers will be more efficient (1 byte) and small negative numbers will be - * inefficient (5 bytes). - */ - public int writeFloat(float value, float precision, boolean optimizePositive) { - return writeInt((int) (value * precision), optimizePositive); - } - - /** - * Reads a 4 byte float. - */ - public float readFloat() { - return Float.intBitsToFloat(readInt()); - } - - /** - * Reads a 1-5 byte float with reduced precision. - */ - public float readFloat(float precision, boolean optimizePositive) { - return readInt(optimizePositive) / precision; - } - - /** - * Reads a 4 byte float, does not advance the position - */ - public float readFloat(int position) { - return Float.intBitsToFloat(readInt(position)); - } - - /** - * Reads a 1-5 byte float with reduced precision, does not advance the position - */ - public float readFloat(int position, float precision, boolean optimizePositive) { - return readInt(position, optimizePositive) / precision; - } - - // short - - /** - * Writes a 2 byte short. Uses BIG_ENDIAN byte order. - */ - public void writeShort(int value) { - require(2); - byte[] buffer = this.bytes; - buffer[this.position++] = (byte) (value >>> 8); - buffer[this.position++] = (byte) value; - } - - /** - * Reads a 2 byte short. - */ - public short readShort() { - byte[] buffer = this.bytes; - return (short) ((buffer[this.position++] & 0xFF) << 8 | buffer[this.position++] & 0xFF); - } - - /** - * Reads a 2 byte short as an int from 0 to 65535. - */ - public int readShortUnsigned() { - byte[] buffer = this.bytes; - return (buffer[this.position++] & 0xFF) << 8 | buffer[this.position++] & 0xFF; - } - - /** - * Reads a 2 byte short, does not advance the position - */ - public short readShort(int position) { - byte[] buffer = this.bytes; - return (short) ((buffer[position++] & 0xFF) << 8 | buffer[position] & 0xFF); - } - - /** - * Reads a 2 byte short as an int from 0 to 65535, does not advance the position - */ - public int readShortUnsigned(int position) { - byte[] buffer = this.bytes; - return (buffer[position++] & 0xFF) << 8 | buffer[position] & 0xFF; - } - - // long - - /** - * Writes an 8 byte long. Uses BIG_ENDIAN byte order. - */ - public void writeLong(long value) { - require(8); - - byte[] buffer = this.bytes; - buffer[this.position++] = (byte) (value >>> 56); - buffer[this.position++] = (byte) (value >>> 48); - buffer[this.position++] = (byte) (value >>> 40); - buffer[this.position++] = (byte) (value >>> 32); - buffer[this.position++] = (byte) (value >>> 24); - buffer[this.position++] = (byte) (value >>> 16); - buffer[this.position++] = (byte) (value >>> 8); - buffer[this.position++] = (byte) value; - } - - /** - * Writes a 1-9 byte long. This stream may consider such a variable length encoding request as a hint. It is not - * guaranteed that a variable length encoding will be really used. The stream may decide to use native-sized integer - * representation for efficiency reasons. - * - * @param optimizePositive - * If true, small positive numbers will be more efficient (1 byte) and small negative numbers will be - * inefficient (9 bytes). - */ - public int writeLong(long value, boolean optimizePositive) { - return writeVarLong(value, optimizePositive); - } - - /** - * Writes a 1-9 byte long. It is guaranteed that a varible length encoding will be used. - * - * @param optimizePositive - * If true, small positive numbers will be more efficient (1 byte) and small negative numbers will be - * inefficient (9 bytes). - */ - public int writeVarLong(long value, boolean optimizePositive) { - if (!optimizePositive) { - value = value << 1 ^ value >> 63; - } - if (value >>> 7 == 0) { - require(1); - this.bytes[this.position++] = (byte) value; - return 1; - } - if (value >>> 14 == 0) { - require(2); - byte[] buffer = this.bytes; - buffer[this.position++] = (byte) (value & 0x7F | 0x80); - buffer[this.position++] = (byte) (value >>> 7); - return 2; - } - if (value >>> 21 == 0) { - require(3); - byte[] buffer = this.bytes; - buffer[this.position++] = (byte) (value & 0x7F | 0x80); - buffer[this.position++] = (byte) (value >>> 7 | 0x80); - buffer[this.position++] = (byte) (value >>> 14); - return 3; - } - if (value >>> 28 == 0) { - require(4); - byte[] buffer = this.bytes; - buffer[this.position++] = (byte) (value & 0x7F | 0x80); - buffer[this.position++] = (byte) (value >>> 7 | 0x80); - buffer[this.position++] = (byte) (value >>> 14 | 0x80); - buffer[this.position++] = (byte) (value >>> 21); - return 4; - } - if (value >>> 35 == 0) { - require(5); - byte[] buffer = this.bytes; - buffer[this.position++] = (byte) (value & 0x7F | 0x80); - buffer[this.position++] = (byte) (value >>> 7 | 0x80); - buffer[this.position++] = (byte) (value >>> 14 | 0x80); - buffer[this.position++] = (byte) (value >>> 21 | 0x80); - buffer[this.position++] = (byte) (value >>> 28); - return 5; - } - if (value >>> 42 == 0) { - require(6); - byte[] buffer = this.bytes; - buffer[this.position++] = (byte) (value & 0x7F | 0x80); - buffer[this.position++] = (byte) (value >>> 7 | 0x80); - buffer[this.position++] = (byte) (value >>> 14 | 0x80); - buffer[this.position++] = (byte) (value >>> 21 | 0x80); - buffer[this.position++] = (byte) (value >>> 28 | 0x80); - buffer[this.position++] = (byte) (value >>> 35); - return 6; - } - if (value >>> 49 == 0) { - require(7); - byte[] buffer = this.bytes; - buffer[this.position++] = (byte) (value & 0x7F | 0x80); - buffer[this.position++] = (byte) (value >>> 7 | 0x80); - buffer[this.position++] = (byte) (value >>> 14 | 0x80); - buffer[this.position++] = (byte) (value >>> 21 | 0x80); - buffer[this.position++] = (byte) (value >>> 28 | 0x80); - buffer[this.position++] = (byte) (value >>> 35 | 0x80); - buffer[this.position++] = (byte) (value >>> 42); - return 7; - } - if (value >>> 56 == 0) { - require(8); - byte[] buffer = this.bytes; - buffer[this.position++] = (byte) (value & 0x7F | 0x80); - buffer[this.position++] = (byte) (value >>> 7 | 0x80); - buffer[this.position++] = (byte) (value >>> 14 | 0x80); - buffer[this.position++] = (byte) (value >>> 21 | 0x80); - buffer[this.position++] = (byte) (value >>> 28 | 0x80); - buffer[this.position++] = (byte) (value >>> 35 | 0x80); - buffer[this.position++] = (byte) (value >>> 42 | 0x80); - buffer[this.position++] = (byte) (value >>> 49); - return 8; - } - - require(9); - byte[] buffer = this.bytes; - buffer[this.position++] = (byte) (value & 0x7F | 0x80); - buffer[this.position++] = (byte) (value >>> 7 | 0x80); - buffer[this.position++] = (byte) (value >>> 14 | 0x80); - buffer[this.position++] = (byte) (value >>> 21 | 0x80); - buffer[this.position++] = (byte) (value >>> 28 | 0x80); - buffer[this.position++] = (byte) (value >>> 35 | 0x80); - buffer[this.position++] = (byte) (value >>> 42 | 0x80); - buffer[this.position++] = (byte) (value >>> 49 | 0x80); - buffer[this.position++] = (byte) (value >>> 56); - return 9; - } - - /** - * Returns true if enough bytes are available to read a long with {@link #readLong(boolean)}. - */ - public boolean canReadLong() { - if (this.capacity - this.position >= 9) { - return true; - } - - if (this.position + 1 > this.capacity) { - return false; - } - - byte[] buffer = this.bytes; - int p = this.position; - if ((buffer[p++] & 0x80) == 0) { - return true; - } - if (p == this.capacity) { - return false; - } - if ((buffer[p++] & 0x80) == 0) { - return true; - } - if (p == this.capacity) { - return false; - } - if ((buffer[p++] & 0x80) == 0) { - return true; - } - if (p == this.capacity) { - return false; - } - if ((buffer[p++] & 0x80) == 0) { - return true; - } - if (p == this.capacity) { - return false; - } - if ((buffer[p++] & 0x80) == 0) { - return true; - } - if (p == this.capacity) { - return false; - } - if ((buffer[p++] & 0x80) == 0) { - return true; - } - if (p == this.capacity) { - return false; - } - if ((buffer[p++] & 0x80) == 0) { - return true; - } - if (p == this.capacity) { - return false; - } - if ((buffer[p++] & 0x80) == 0) { - return true; - } - - return p != this.capacity; - } - - /** - * Returns true if enough bytes are available to read a long with {@link #readLong(boolean)}. - */ - public boolean canReadLong(int position) { - if (this.capacity - position >= 9) { - return true; - } - - if (position + 1 > this.capacity) { - return false; - } - - byte[] buffer = this.bytes; - int p = position; - if ((buffer[p++] & 0x80) == 0) { - return true; - } - if (p == this.capacity) { - return false; - } - if ((buffer[p++] & 0x80) == 0) { - return true; - } - if (p == this.capacity) { - return false; - } - if ((buffer[p++] & 0x80) == 0) { - return true; - } - if (p == this.capacity) { - return false; - } - if ((buffer[p++] & 0x80) == 0) { - return true; - } - if (p == this.capacity) { - return false; - } - if ((buffer[p++] & 0x80) == 0) { - return true; - } - if (p == this.capacity) { - return false; - } - if ((buffer[p++] & 0x80) == 0) { - return true; - } - if (p == this.capacity) { - return false; - } - if ((buffer[p++] & 0x80) == 0) { - return true; - } - if (p == this.capacity) { - return false; - } - if ((buffer[p++] & 0x80) == 0) { - return true; - } - - return p != this.capacity; - } - - /** - * Reads an 8 byte long. - */ - public long readLong() { - byte[] buffer = this.bytes; - - return (long) buffer[this.position++] << 56 - | (long) (buffer[this.position++] & 0xFF) << 48 - | (long) (buffer[this.position++] & 0xFF) << 40 - | (long) (buffer[this.position++] & 0xFF) << 32 - | (long) (buffer[this.position++] & 0xFF) << 24 - | (buffer[this.position++] & 0xFF) << 16 - | (buffer[this.position++] & 0xFF) << 8 - | buffer[this.position++] & 0xFF; - - } - - /** - * Reads a 1-9 byte long. This stream may consider such a variable length encoding request as a hint. It is not - * guaranteed that a variable length encoding will be really used. The stream may decide to use native-sized integer - * representation for efficiency reasons. - */ - public long readLong(boolean optimizePositive) { - return readVarLong(optimizePositive); - } - - /** - * Reads an 8 byte long, does not advance the position - */ - public long readLong(int position) { - byte[] buffer = this.bytes; - - return (long) buffer[position++] << 56 - | (long) (buffer[position++] & 0xFF) << 48 - | (long) (buffer[position++] & 0xFF) << 40 - | (long) (buffer[position++] & 0xFF) << 32 - | (long) (buffer[position++] & 0xFF) << 24 - | (buffer[position++] & 0xFF) << 16 - | (buffer[position++] & 0xFF) << 8 - | buffer[position] & 0xFF; - - } - - /** - * Reads a 1-9 byte long. This stream may consider such a variable length encoding request as a hint. It is not - * guaranteed that a variable length encoding will be really used. The stream may decide to use native-sized integer - * representation for efficiency reasons. - *

- * does not advance the position - */ - public long readLong(int position, boolean optimizePositive) { - int pos = this.position; - this.position = position; - long value = readVarLong(optimizePositive); - this.position = pos; - return value; - } - - /** - * Reads a 1-9 byte long. It is guaranteed that a varible length encoding will be used. - */ - private long readVarLong(boolean optimizePositive) { - if (this.capacity - this.position < 9) { - return readLong_slow(optimizePositive); - } - - int b = this.bytes[this.position++]; - long result = b & 0x7F; - if ((b & 0x80) != 0) { - byte[] buffer = this.bytes; - b = buffer[this.position++]; - result |= (b & 0x7F) << 7; - if ((b & 0x80) != 0) { - b = buffer[this.position++]; - result |= (b & 0x7F) << 14; - if ((b & 0x80) != 0) { - b = buffer[this.position++]; - result |= (b & 0x7F) << 21; - if ((b & 0x80) != 0) { - b = buffer[this.position++]; - result |= (long) (b & 0x7F) << 28; - if ((b & 0x80) != 0) { - b = buffer[this.position++]; - result |= (long) (b & 0x7F) << 35; - if ((b & 0x80) != 0) { - b = buffer[this.position++]; - result |= (long) (b & 0x7F) << 42; - if ((b & 0x80) != 0) { - b = buffer[this.position++]; - result |= (long) (b & 0x7F) << 49; - if ((b & 0x80) != 0) { - b = buffer[this.position++]; - result |= (long) b << 56; - } - } - } - } - } - } - } - } - - if (!optimizePositive) { - result = result >>> 1 ^ -(result & 1); - } - - return result; - } - - private long readLong_slow(boolean optimizePositive) { - // The buffer is guaranteed to have at least 1 byte. - byte[] buffer = this.bytes; - int b = buffer[this.position++]; - - long result = b & 0x7F; - if ((b & 0x80) != 0) { - b = buffer[this.position++]; - result |= (b & 0x7F) << 7; - if ((b & 0x80) != 0) { - b = buffer[this.position++]; - result |= (b & 0x7F) << 14; - if ((b & 0x80) != 0) { - b = buffer[this.position++]; - result |= (b & 0x7F) << 21; - if ((b & 0x80) != 0) { - b = buffer[this.position++]; - result |= (long) (b & 0x7F) << 28; - if ((b & 0x80) != 0) { - b = buffer[this.position++]; - result |= (long) (b & 0x7F) << 35; - if ((b & 0x80) != 0) { - b = buffer[this.position++]; - result |= (long) (b & 0x7F) << 42; - if ((b & 0x80) != 0) { - b = buffer[this.position++]; - result |= (long) (b & 0x7F) << 49; - if ((b & 0x80) != 0) { - b = buffer[this.position++]; - result |= (long) b << 56; - } - } - } - } - } - } - } - } - - if (!optimizePositive) { - result = result >>> 1 ^ -(result & 1); - } - return result; - } - - // boolean - - /** - * Writes a 1 byte boolean. - */ - public void writeBoolean(boolean value) { - require(1); - this.bytes[this.position++] = (byte) (value ? 1 : 0); - } - - /** - * Reads a 1 byte boolean. - */ - public boolean readBoolean () { - return this.bytes[this.position++] == 1; - } - - /** - * Reads a 1 byte boolean, does not advance the position - */ - public boolean readBoolean (int position) { - return this.bytes[position] == 1; - } - - // char - - /** - * Writes a 2 byte char. Uses BIG_ENDIAN byte order. - */ - public void writeChar(char value) { - require(2); - byte[] buffer = this.bytes; - buffer[this.position++] = (byte) (value >>> 8); - buffer[this.position++] = (byte) value; - } - - /** - * Reads a 2 byte char. - */ - public char readChar() { - byte[] buffer = this.bytes; - return (char) ((buffer[this.position++] & 0xFF) << 8 | buffer[this.position++] & 0xFF); - } - - /** - * Reads a 2 byte char, does not advance the position - */ - public char readChar(int position) { - byte[] buffer = this.bytes; - return (char) ((buffer[position++] & 0xFF) << 8 | buffer[position] & 0xFF); - } - - // double - - /** - * Writes an 8 byte double. - */ - public void writeDouble(double value) { - writeLong(Double.doubleToLongBits(value)); - } - - /** - * Writes a 1-9 byte double with reduced precision - * - * @param optimizePositive - * If true, small positive numbers will be more efficient (1 byte) and small negative numbers will be - * inefficient (9 bytes). - */ - public int writeDouble(double value, double precision, boolean optimizePositive) { - return writeLong((long) (value * precision), optimizePositive); - } - - - /** - * Reads an 8 bytes double. - */ - public double readDouble() { - return Double.longBitsToDouble(readLong()); - } - - /** - * Reads a 1-9 byte double with reduced precision. - */ - public double readDouble(double precision, boolean optimizePositive) { - return readLong(optimizePositive) / precision; - } - - /** - * Reads an 8 bytes double, does not advance the position - */ - public double readDouble(int position) { - return Double.longBitsToDouble(readLong(position)); - } - - /** - * Reads a 1-9 byte double with reduced precision, does not advance the position - */ - public double readDouble(int position, double precision, boolean optimizePositive) { - return readLong(position, optimizePositive) / precision; - } - - - - - - /** - * Returns the number of bytes that would be written with {@link #writeInt(int, boolean)}. - */ - public static int intLength(int value, boolean optimizePositive) { - if (!optimizePositive) { - value = value << 1 ^ value >> 31; - } - if (value >>> 7 == 0) { - return 1; - } - if (value >>> 14 == 0) { - return 2; - } - if (value >>> 21 == 0) { - return 3; - } - if (value >>> 28 == 0) { - return 4; - } - return 5; - } - - /** - * Returns the number of bytes that would be written with {@link #writeLong(long, boolean)}. - */ - public static int longLength(long value, boolean optimizePositive) { - if (!optimizePositive) { - value = value << 1 ^ value >> 63; - } - if (value >>> 7 == 0) { - return 1; - } - if (value >>> 14 == 0) { - return 2; - } - if (value >>> 21 == 0) { - return 3; - } - if (value >>> 28 == 0) { - return 4; - } - if (value >>> 35 == 0) { - return 5; - } - if (value >>> 42 == 0) { - return 6; - } - if (value >>> 49 == 0) { - return 7; - } - if (value >>> 56 == 0) { - return 8; - } - return 9; - } - - // Methods implementing bulk operations on arrays of primitive types - - /** - * Bulk output of an int array. - */ - public void writeInts(int[] object, boolean optimizePositive) { - for (int i = 0, n = object.length; i < n; i++) { - writeInt(object[i], optimizePositive); - } - } - - /** - * Bulk input of an int array. - */ - public int[] readInts(int length, boolean optimizePositive) { - int[] array = new int[length]; - for (int i = 0; i < length; i++) { - array[i] = readInt(optimizePositive); - } - return array; - } - - /** - * Bulk output of an long array. - */ - public void writeLongs(long[] object, boolean optimizePositive) { - for (int i = 0, n = object.length; i < n; i++) { - writeLong(object[i], optimizePositive); - } - } - - /** - * Bulk input of a long array. - */ - public long[] readLongs(int length, boolean optimizePositive) { - long[] array = new long[length]; - for (int i = 0; i < length; i++) { - array[i] = readLong(optimizePositive); - } - return array; - } - - /** - * Bulk output of an int array. - */ - public void writeInts(int[] object) { - for (int i = 0, n = object.length; i < n; i++) { - writeInt(object[i]); - } - } - - /** - * Bulk input of an int array. - */ - public int[] readInts(int length) { - int[] array = new int[length]; - for (int i = 0; i < length; i++) { - array[i] = readInt(); - } - return array; - } - - /** - * Bulk output of an long array. - */ - public void writeLongs(long[] object) { - for (int i = 0, n = object.length; i < n; i++) { - writeLong(object[i]); - } - } - - /** - * Bulk input of a long array. - */ - public long[] readLongs(int length) { - long[] array = new long[length]; - for (int i = 0; i < length; i++) { - array[i] = readLong(); - } - return array; - } - - /** - * Bulk output of a float array. - */ - public void writeFloats(float[] object) { - for (int i = 0, n = object.length; i < n; i++) { - writeFloat(object[i]); - } - } - - /** - * Bulk input of a float array. - */ - public float[] readFloats(int length) { - float[] array = new float[length]; - for (int i = 0; i < length; i++) { - array[i] = readFloat(); - } - return array; - } - - /** - * Bulk output of a short array. - */ - public void writeShorts(short[] object) { - for (int i = 0, n = object.length; i < n; i++) { - writeShort(object[i]); - } - } - - /** - * Bulk input of a short array. - */ - public short[] readShorts(int length) { - short[] array = new short[length]; - for (int i = 0; i < length; i++) { - array[i] = readShort(); - } - return array; - } - - /** - * Bulk output of a char array. - */ - public void writeChars(char[] object) { - for (int i = 0, n = object.length; i < n; i++) { - writeChar(object[i]); - } - } - - /** - * Bulk input of a char array. - */ - public char[] readChars(int length) { - char[] array = new char[length]; - for (int i = 0; i < length; i++) { - array[i] = readChar(); - } - return array; - } - - /** - * Bulk output of a double array. - */ - public void writeDoubles(double[] object) { - for (int i = 0, n = object.length; i < n; i++) { - writeDouble(object[i]); - } - } - - /** - * Bulk input of a double array - */ - public double[] readDoubles(int length) { - double[] array = new double[length]; - for (int i = 0; i < length; i++) { - array[i] = readDouble(); - } - return array; - } - - - @Override - public boolean equals(Object other) { - if (!(other instanceof ByteBuffer2)) { - return false; - } - - // CANNOT be null, so we don't have to null check! - return Arrays.equals(this.bytes, ((ByteBuffer2) other).bytes); - } - - @Override - public int hashCode() { - // might be null for a thread because it's stale. who cares, get the value again - return Arrays.hashCode(this.bytes); - } - - @Override - public String toString() { - return "ByteBuffer2 " + java.util.Arrays.toString(this.bytes); - } -} diff --git a/src/dorkbox/util/bytes/LittleEndian.java b/src/dorkbox/util/bytes/LittleEndian.java deleted file mode 100644 index 0efd247..0000000 --- a/src/dorkbox/util/bytes/LittleEndian.java +++ /dev/null @@ -1,769 +0,0 @@ -/* - * Copyright 2014 dorkbox, llc - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package dorkbox.util.bytes; - -import java.io.IOException; -import java.io.InputStream; -import java.math.BigInteger; -import java.nio.ByteBuffer; - -/** - * This is intel/amd/arm arch! - *

- * arm is technically bi-endian - *

- * Network byte order IS big endian, as is Java. - */ -@SuppressWarnings("ALL") -public -class LittleEndian { - // the following are ALL in Little-Endian (byte[0] is LEAST significant) - - /** - * CHAR to and from bytes - */ - public static final - class Char_ { - @SuppressWarnings("fallthrough") - public static - char from(final byte[] bytes, final int offset, final int byteNum) { - char number = 0; - - switch (byteNum) { - case 2: - number |= (bytes[offset + 1] & 0xFF) << 8; - case 1: - number |= (bytes[offset + 0] & 0xFF) << 0; - } - - return number; - } - - @SuppressWarnings("fallthrough") - public static - char from(final byte[] bytes) { - char number = 0; - - switch (bytes.length) { - default: - case 2: - number |= (bytes[1] & 0xFF) << 8; - case 1: - number |= (bytes[0] & 0xFF) << 0; - } - - return number; - } - - public static - char from(final byte b0, final byte b1) { - return (char) ((b1 & 0xFF) << 8 | (b0 & 0xFF) << 0); - } - - public static - char from(final ByteBuffer buff) { - return from(buff.get(), buff.get()); - } - - public static - char from(final InputStream inputStream) throws IOException { - return from((byte) inputStream.read(), (byte) inputStream.read()); - } - - public static - byte[] toBytes(final char x) { - return new byte[] {(byte) (x >> 0), (byte) (x >> 8)}; - } - - public static - void toBytes(final char x, final byte[] bytes, final int offset) { - bytes[offset + 1] = (byte) (x >> 8); - bytes[offset + 0] = (byte) (x >> 0); - } - - public static - void toBytes(final char x, final byte[] bytes) { - bytes[1] = (byte) (x >> 8); - bytes[0] = (byte) (x >> 0); - } - - - private - Char_() { - } - } - - - /** - * UNSIGNED CHAR to and from bytes - */ - public static final - class UChar_ { - @SuppressWarnings("fallthrough") - public static - UShort from(final byte[] bytes, final int offset, final int bytenum) { - char number = 0; - - switch (bytenum) { - case 2: - number |= (bytes[offset + 1] & 0xFF) << 8; - case 1: - number |= (bytes[offset + 0] & 0xFF) << 0; - } - - return UShort.valueOf(number); - } - - @SuppressWarnings("fallthrough") - public static - UShort from(final byte[] bytes) { - short number = 0; - - switch (bytes.length) { - default: - case 2: - number |= (bytes[1] & 0xFF) << 8; - case 1: - number |= (bytes[0] & 0xFF) << 0; - } - - return UShort.valueOf(number); - } - - public static - UShort from(final byte b0, final byte b1) { - return UShort.valueOf((short) ((b1 & 0xFF) << 8) | (b0 & 0xFF) << 0); - } - - public static - UShort from(final ByteBuffer buff) { - return from(buff.get(), buff.get()); - } - - public static - UShort from(final InputStream inputStream) throws IOException { - return from((byte) inputStream.read(), (byte) inputStream.read()); - } - - public static - byte[] toBytes(UShort x) { - int num = x.intValue(); - - return new byte[] {(byte) (num & 0x00FF >> 0), (byte) ((num & 0xFF00) >> 8)}; - } - - public static - void toBytes(final UShort x, final byte[] bytes, final int offset) { - int num = x.intValue(); - - bytes[offset + 1] = (byte) ((num & 0xFF00) >> 8); - bytes[offset + 0] = (byte) (num & 0x00FF >> 0); - } - - public static - void toBytes(final UShort x, final byte[] bytes) { - int num = x.intValue(); - - bytes[1] = (byte) ((num & 0xFF00) >> 8); - bytes[0] = (byte) (num & 0x00FF >> 0); - } - - private - UChar_() { - } - } - - - /** - * SHORT to and from bytes - */ - public static final - class Short_ { - @SuppressWarnings("fallthrough") - public static - short from(final byte[] bytes, final int offset, final int bytenum) { - short number = 0; - - switch (bytenum) { - case 2: - number |= (bytes[offset + 1] & 0xFF) << 8; - case 1: - number |= (bytes[offset + 0] & 0xFF) << 0; - } - - return number; - } - - @SuppressWarnings("fallthrough") - public static - short from(final byte[] bytes) { - short number = 0; - - switch (bytes.length) { - default: - case 2: - number |= (bytes[1] & 0xFF) << 8; - case 1: - number |= (bytes[0] & 0xFF) << 0; - } - - return number; - } - - public static - short from(final byte b0, final byte b1) { - return (short) ((b1 & 0xFF) << 8 | (b0 & 0xFF) << 0); - } - - public static - short from(final ByteBuffer buff) { - return from(buff.get(), buff.get()); - } - - public static - short from(final InputStream inputStream) throws IOException { - return from((byte) inputStream.read(), (byte) inputStream.read()); - } - - public static - byte[] toBytes(final short x) { - return new byte[] {(byte) (x >> 0), (byte) (x >> 8)}; - } - - public static - void toBytes(final short x, final byte[] bytes, final int offset) { - bytes[offset + 1] = (byte) (x >> 8); - bytes[offset + 0] = (byte) (x >> 0); - } - - public static - void toBytes(final short x, final byte[] bytes) { - bytes[1] = (byte) (x >> 8); - bytes[0] = (byte) (x >> 0); - } - - private - Short_() { - } - } - - - /** - * UNSIGNED SHORT to and from bytes - */ - public static final - class UShort_ { - @SuppressWarnings("fallthrough") - public static - UShort from(final byte[] bytes, final int offset, final int bytenum) { - short number = 0; - - switch (bytenum) { - case 2: - number |= (bytes[offset + 1] & 0xFF) << 8; - case 1: - number |= (bytes[offset + 0] & 0xFF) << 0; - } - - return UShort.valueOf(number); - } - - @SuppressWarnings("fallthrough") - public static - UShort from(final byte[] bytes) { - short number = 0; - - switch (bytes.length) { - default: - case 2: - number |= (bytes[1] & 0xFF) << 8; - case 1: - number |= (bytes[0] & 0xFF) << 0; - } - - return UShort.valueOf(number); - } - - public static - UShort from(final byte b0, final byte b1) { - return UShort.valueOf((short) ((b1 & 0xFF) << 8 | (b0 & 0xFF) << 0)); - } - - public static - UShort from(final ByteBuffer buff) { - return from(buff.get(), buff.get()); - } - - public static - UShort from(final InputStream inputStream) throws IOException { - return from((byte) inputStream.read(), (byte) inputStream.read()); - } - public static - byte[] toBytes(final UShort x) { - int num = x.intValue(); - - return new byte[] {(byte) (num & 0x00FF >> 0), (byte) ((num & 0xFF00) >> 8)}; - } - - public static - void toBytes(final UShort x, final byte[] bytes, final int offset) { - int num = x.intValue(); - - bytes[offset + 1] = (byte) ((num & 0xFF00) >> 8); - bytes[offset + 0] = (byte) (num & 0x00FF >> 0); - } - - public static - void toBytes(final UShort x, final byte[] bytes) { - int num = x.intValue(); - - bytes[1] = (byte) ((num & 0xFF00) >> 8); - bytes[0] = (byte) (num & 0x00FF >> 0); - } - - private - UShort_() { - } - } - - - /** - * INT to and from bytes - */ - public static final - class Int_ { - @SuppressWarnings("fallthrough") - public static - int from(final byte[] bytes, final int offset, final int bytenum) { - int number = 0; - - switch (bytenum) { - case 4: - number |= (bytes[offset + 3] & 0xFF) << 24; - case 3: - number |= (bytes[offset + 2] & 0xFF) << 16; - case 2: - number |= (bytes[offset + 1] & 0xFF) << 8; - case 1: - number |= (bytes[offset + 0] & 0xFF) << 0; - } - - return number; - } - - @SuppressWarnings("fallthrough") - public static - int from(final byte[] bytes) { - int number = 0; - - switch (bytes.length) { - default: - case 4: - number |= (bytes[3] & 0xFF) << 24; - case 3: - number |= (bytes[2] & 0xFF) << 16; - case 2: - number |= (bytes[1] & 0xFF) << 8; - case 1: - number |= (bytes[0] & 0xFF) << 0; - } - - return number; - } - - public static - int from(final byte b0, final byte b1, final byte b2, final byte b3) { - return (b3 & 0xFF) << 24 | - (b2 & 0xFF) << 16 | - (b1 & 0xFF) << 8 | - (b0 & 0xFF) << 0; - } - - public static - int from(final ByteBuffer buff) { - return from(buff.get(), buff.get(), buff.get(), buff.get()); - } - - public static - int from(final InputStream inputStream) throws IOException { - return from((byte) inputStream.read(), (byte) inputStream.read(), (byte) inputStream.read(), (byte) inputStream.read()); - } - - public static - byte[] toBytes(final int x) { - return new byte[] {(byte) (x >> 0), (byte) (x >> 8), (byte) (x >> 16), (byte) (x >> 24)}; - } - - public static - void toBytes(final int x, final byte[] bytes, final int offset) { - bytes[offset + 3] = (byte) (x >> 24); - bytes[offset + 2] = (byte) (x >> 16); - bytes[offset + 1] = (byte) (x >> 8); - bytes[offset + 0] = (byte) (x >> 0); - } - - public static - void toBytes(final int x, final byte[] bytes) { - bytes[3] = (byte) (x >> 24); - bytes[2] = (byte) (x >> 16); - bytes[1] = (byte) (x >> 8); - bytes[0] = (byte) (x >> 0); - } - - private - Int_() { - } - } - - - /** - * UNSIGNED INT to and from bytes - */ - public static final - class UInt_ { - @SuppressWarnings("fallthrough") - public static - UInteger from(final byte[] bytes, final int offset, final int bytenum) { - int number = 0; - - switch (bytenum) { - case 4: - number |= (bytes[offset + 3] & 0xFF) << 24; - case 3: - number |= (bytes[offset + 2] & 0xFF) << 16; - case 2: - number |= (bytes[offset + 1] & 0xFF) << 8; - case 1: - number |= (bytes[offset + 0] & 0xFF) << 0; - } - - return UInteger.valueOf(number); - } - - @SuppressWarnings("fallthrough") - public static - UInteger from(final byte[] bytes) { - int number = 0; - - switch (bytes.length) { - default: - case 4: - number |= (bytes[3] & 0xFF) << 24; - case 3: - number |= (bytes[2] & 0xFF) << 16; - case 2: - number |= (bytes[1] & 0xFF) << 8; - case 1: - number |= (bytes[0] & 0xFF) << 0; - } - - return UInteger.valueOf(number); - } - - public static - UInteger from(final byte b0, final byte b1, final byte b2, final byte b3) { - int number = (b3 & 0xFF) << 24 | - (b2 & 0xFF) << 16 | - (b1 & 0xFF) << 8 | - (b0 & 0xFF) << 0; - - return UInteger.valueOf(number); - } - - public static - UInteger from(final ByteBuffer buff) { - return from(buff.get(), buff.get(), buff.get(), buff.get()); - } - - public static - UInteger from(final InputStream inputStream) throws IOException { - return from((byte) inputStream.read(), (byte) inputStream.read(), (byte) inputStream.read(), (byte) inputStream.read()); - } - - public static - byte[] toBytes(final UInteger x) { - long num = x.longValue(); - - return new byte[] {(byte) (num & 0x000000FFL >> 0), (byte) ((num & 0x0000FF00L) >> 8), (byte) ((num & 0x00FF0000L) >> 16), - (byte) ((num & 0xFF000000L) >> 24)}; - } - - public static - void toBytes(final UInteger x, final byte[] bytes, final int offset) { - long num = x.longValue(); - - bytes[offset + 3] = (byte) ((num & 0xFF000000L) >> 24); - bytes[offset + 2] = (byte) ((num & 0x00FF0000L) >> 16); - bytes[offset + 1] = (byte) ((num & 0x0000FF00L) >> 8); - bytes[offset + 0] = (byte) (num & 0x000000FFL >> 0); - } - - - public static - void toBytes(final UInteger x, final byte[] bytes) { - long num = x.longValue(); - - bytes[3] = (byte) ((num & 0xFF000000L) >> 24); - bytes[2] = (byte) ((num & 0x00FF0000L) >> 16); - bytes[1] = (byte) ((num & 0x0000FF00L) >> 8); - bytes[0] = (byte) (num & 0x000000FFL >> 0); - } - - private - UInt_() { - } - } - - - /** - * LONG to and from bytes - */ - public static final - class Long_ { - @SuppressWarnings("fallthrough") - public static - long from(final byte[] bytes, final int offset, final int bytenum) { - long number = 0; - - switch (bytenum) { - case 8: - number |= (long) (bytes[offset + 7] & 0xFF) << 56; - case 7: - number |= (long) (bytes[offset + 6] & 0xFF) << 48; - case 6: - number |= (long) (bytes[offset + 5] & 0xFF) << 40; - case 5: - number |= (long) (bytes[offset + 4] & 0xFF) << 32; - case 4: - number |= (long) (bytes[offset + 3] & 0xFF) << 24; - case 3: - number |= (long) (bytes[offset + 2] & 0xFF) << 16; - case 2: - number |= (long) (bytes[offset + 1] & 0xFF) << 8; - case 1: - number |= (long) (bytes[offset + 0] & 0xFF) << 0; - } - - return number; - } - - @SuppressWarnings("fallthrough") - public static - long from(final byte[] bytes) { - long number = 0L; - - switch (bytes.length) { - default: - case 8: - number |= (long) (bytes[7] & 0xFF) << 56; - case 7: - number |= (long) (bytes[6] & 0xFF) << 48; - case 6: - number |= (long) (bytes[5] & 0xFF) << 40; - case 5: - number |= (long) (bytes[4] & 0xFF) << 32; - case 4: - number |= (long) (bytes[3] & 0xFF) << 24; - case 3: - number |= (long) (bytes[2] & 0xFF) << 16; - case 2: - number |= (long) (bytes[1] & 0xFF) << 8; - case 1: - number |= (long) (bytes[0] & 0xFF) << 0; - } - - return number; - } - - public static - long from(final byte b0, final byte b1, final byte b2, final byte b3, final byte b4, final byte b5, final byte b6, final byte b7) { - return (long) (b7 & 0xFF) << 56 | - (long) (b6 & 0xFF) << 48 | - (long) (b5 & 0xFF) << 40 | - (long) (b4 & 0xFF) << 32 | - (long) (b3 & 0xFF) << 24 | - (long) (b2 & 0xFF) << 16 | - (long) (b1 & 0xFF) << 8 | - (long) (b0 & 0xFF) << 0; - } - - public static - long from(final ByteBuffer buff) { - return from(buff.get(), buff.get(), buff.get(), buff.get(), buff.get(), buff.get(), buff.get(), buff.get()); - } - - public static - long from(final InputStream inputStream) throws IOException { - return from((byte) inputStream.read(), - (byte) inputStream.read(), - (byte) inputStream.read(), - (byte) inputStream.read(), - (byte) inputStream.read(), - (byte) inputStream.read(), - (byte) inputStream.read(), - (byte) inputStream.read()); - } - - public static - byte[] toBytes(final long x) { - return new byte[] {(byte) (x >> 0), (byte) (x >> 8), (byte) (x >> 16), (byte) (x >> 24), (byte) (x >> 32), (byte) (x >> 40), - (byte) (x >> 48), (byte) (x >> 56),}; - } - - public static - void toBytes(final long x, final byte[] bytes, final int offset) { - bytes[offset + 7] = (byte) (x >> 56); - bytes[offset + 6] = (byte) (x >> 48); - bytes[offset + 5] = (byte) (x >> 40); - bytes[offset + 4] = (byte) (x >> 32); - bytes[offset + 3] = (byte) (x >> 24); - bytes[offset + 2] = (byte) (x >> 16); - bytes[offset + 1] = (byte) (x >> 8); - bytes[offset + 0] = (byte) (x >> 0); - } - - public static - void toBytes(final long x, final byte[] bytes) { - bytes[7] = (byte) (x >> 56); - bytes[6] = (byte) (x >> 48); - bytes[5] = (byte) (x >> 40); - bytes[4] = (byte) (x >> 32); - bytes[3] = (byte) (x >> 24); - bytes[2] = (byte) (x >> 16); - bytes[1] = (byte) (x >> 8); - bytes[0] = (byte) (x >> 0); - } - - private - Long_() { - } - } - - - /** - * UNSIGNED LONG to and from bytes - */ - public static final - class ULong_ { - @SuppressWarnings("fallthrough") - public static - ULong from(final byte[] bytes, final int offset, final int bytenum) { - long number = 0; - - switch (bytenum) { - case 8: - number |= (long) (bytes[offset + 7] & 0xFF) << 56; - case 7: - number |= (long) (bytes[offset + 6] & 0xFF) << 48; - case 6: - number |= (long) (bytes[offset + 5] & 0xFF) << 40; - case 5: - number |= (long) (bytes[offset + 4] & 0xFF) << 32; - case 4: - number |= (long) (bytes[offset + 3] & 0xFF) << 24; - case 3: - number |= (long) (bytes[offset + 2] & 0xFF) << 16; - case 2: - number |= (long) (bytes[offset + 1] & 0xFF) << 8; - case 1: - number |= (long) (bytes[offset + 0] & 0xFF) << 0; - } - - return ULong.valueOf(number); - } - - public static - ULong from(final byte[] bytes) { - BigInteger ulong = new BigInteger(1, bytes); - return ULong.valueOf(ulong); - } - - public static - ULong from(final byte b0, final byte b1, final byte b2, final byte b3, final byte b4, final byte b5, final byte b6, final byte b7) { - byte[] bytes = new byte[] {b7, b6, b5, b4, b3, b2, b1, b0}; - BigInteger ulong = new BigInteger(1, bytes); - return ULong.valueOf(ulong); - } - - public static - ULong from(final ByteBuffer buff) { - return from(buff.get(), buff.get(), buff.get(), buff.get(), buff.get(), buff.get(), buff.get(), buff.get()); - } - - public static - ULong from(final InputStream inputStream) throws IOException { - return from((byte) inputStream.read(), - (byte) inputStream.read(), - (byte) inputStream.read(), - (byte) inputStream.read(), - (byte) inputStream.read(), - (byte) inputStream.read(), - (byte) inputStream.read(), - (byte) inputStream.read()); - } - - public static - byte[] toBytes(final ULong x) { - byte[] bytes = new byte[8]; - int offset = 0; - - byte temp_byte[] = x.toBigInteger() - .toByteArray(); - int array_count = temp_byte.length - 1; - - for (int i = 7; i >= 0; i--) { - if (array_count >= 0) { - bytes[offset] = temp_byte[array_count]; - } - else { - bytes[offset] = (byte) 00; - } - - offset++; - array_count--; - } - - return bytes; - } - - public static - void toBytes(final ULong x, final byte[] bytes, final int offset) { - final byte[] bytes1 = toBytes(x); - int length = bytes.length; - int pos = 8; - - while (length > 0) { - bytes[pos--] = bytes1[offset + length--]; - } - } - - public static - void toBytes(final ULong x, final byte[] bytes) { - final byte[] bytes1 = toBytes(x); - int length = bytes.length; - int pos = 8; - - while (length > 0) { - bytes[pos--] = bytes1[length--]; - } - } - - private - ULong_() { - } - } -} - diff --git a/src/dorkbox/util/bytes/OptimizeUtilsByteArray.java b/src/dorkbox/util/bytes/OptimizeUtilsByteArray.java deleted file mode 100644 index 7819d6e..0000000 --- a/src/dorkbox/util/bytes/OptimizeUtilsByteArray.java +++ /dev/null @@ -1,477 +0,0 @@ -/* - * Copyright 2014 dorkbox, llc - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Copyright (c) 2008, Nathan Sweet - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following - * conditions are met: - * - * - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the distribution. - * - Neither the name of Esoteric Software nor the names of its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package dorkbox.util.bytes; - -@SuppressWarnings({"Duplicates", "NumericCastThatLosesPrecision", "UnusedAssignment", "IntegerMultiplicationImplicitCastToLong", "unused"}) -public -class OptimizeUtilsByteArray { - - /** - * Returns the number of bytes that would be written with {@link #writeInt(byte[], int, boolean)}. - * - * @param optimizePositive - * true if you want to optimize the number of bytes needed to write the length value - */ - public static - int intLength(int value, boolean optimizePositive) { - return OptimizeUtilsByteBuf.intLength(value, optimizePositive); - } - - // int - - /** - * look at buffer, and see if we can read the length of the int off of it. (from the reader index) - * - * @return 0 if we could not read anything, >0 for the number of bytes for the int on the buffer - */ - @SuppressWarnings("SimplifiableIfStatement") - public static - boolean canReadInt(byte[] buffer) { - int position = 0; - return canReadInt(buffer, position); - } - - /** - * FROM KRYO - *

- * look at buffer, and see if we can read the length of the int off of it. (from the reader index) - * - * @param position where in the buffer to start reading - * @return 0 if we could not read anything, >0 for the number of bytes for the int on the buffer - */ - @SuppressWarnings("SimplifiableIfStatement") - public static - boolean canReadInt(final byte[] buffer, int position) { - int length = buffer.length; - - if (length >= 5) { - return true; - } - if ((buffer[position++] & 0x80) == 0) { - return true; - } - if (position == length) { - return false; - } - if ((buffer[position++] & 0x80) == 0) { - return true; - } - if (position == length) { - return false; - } - if ((buffer[position++] & 0x80) == 0) { - return true; - } - if (position == length) { - return false; - } - if ((buffer[position++] & 0x80) == 0) { - return true; - } - return position != length; - } - - /** - * Reads an int from the buffer that was optimized at position 0 - * - * @param optimizePositive - * If true, small positive numbers will be more efficient (1 byte) and small negative numbers will be inefficient (5 - * bytes). This ultimately means that it will use fewer bytes for positive numbers. - */ - public static - int readInt(byte[] buffer, boolean optimizePositive) { - int position = 0; - return readInt(buffer, optimizePositive, position); - } - - /** - * FROM KRYO - *

- * Reads an int from the buffer that was optimized. - * - * @param position where in the buffer to start reading - * @param optimizePositive - * If true, small positive numbers will be more efficient (1 byte) and small negative numbers will be inefficient (5 - * bytes). This ultimately means that it will use fewer bytes for positive numbers. - */ - public static - int readInt(final byte[] buffer, final boolean optimizePositive, int position) { - int b = buffer[position++]; - int result = b & 0x7F; - if ((b & 0x80) != 0) { - b = buffer[position++]; - result |= (b & 0x7F) << 7; - if ((b & 0x80) != 0) { - b = buffer[position++]; - result |= (b & 0x7F) << 14; - if ((b & 0x80) != 0) { - b = buffer[position++]; - result |= (b & 0x7F) << 21; - if ((b & 0x80) != 0) { - b = buffer[position++]; - result |= (b & 0x7F) << 28; - } - } - } - } - return optimizePositive ? result : result >>> 1 ^ -(result & 1); - } - - /** - * Writes the specified int to the buffer using 1 to 5 bytes, depending on the size of the number. - * - * @param optimizePositive - * If true, small positive numbers will be more efficient (1 byte) and small negative numbers will be inefficient (5 - * bytes). This ultimately means that it will use fewer bytes for positive numbers. - * - * @return the number of bytes written. - */ - public static - int writeInt(byte[] buffer, int value, boolean optimizePositive) { - int position = 0; - return writeInt(buffer, value, optimizePositive, position); - } - - /** - * FROM KRYO - *

- * Writes the specified int to the buffer using 1 to 5 bytes, depending on the size of the number. - * - * @param position where in the buffer to start writing - * @param optimizePositive - * If true, small positive numbers will be more efficient (1 byte) and small negative numbers will be inefficient (5 - * bytes). This ultimately means that it will use fewer bytes for positive numbers. - * - * @return the number of bytes written. - */ - public static - int writeInt(final byte[] buffer, int value, final boolean optimizePositive, int position) { - if (!optimizePositive) { - value = value << 1 ^ value >> 31; - } - if (value >>> 7 == 0) { - buffer[position++] = (byte) value; - return 1; - } - if (value >>> 14 == 0) { - buffer[position++] = (byte) (value & 0x7F | 0x80); - buffer[position++] = (byte) (value >>> 7); - return 2; - } - if (value >>> 21 == 0) { - buffer[position++] = (byte) (value & 0x7F | 0x80); - buffer[position++] = (byte) (value >>> 7 | 0x80); - buffer[position++] = (byte) (value >>> 14); - return 3; - } - if (value >>> 28 == 0) { - buffer[position++] = (byte) (value & 0x7F | 0x80); - buffer[position++] = (byte) (value >>> 7 | 0x80); - buffer[position++] = (byte) (value >>> 14 | 0x80); - buffer[position++] = (byte) (value >>> 21); - return 4; - } - buffer[position++] = (byte) (value & 0x7F | 0x80); - buffer[position++] = (byte) (value >>> 7 | 0x80); - buffer[position++] = (byte) (value >>> 14 | 0x80); - buffer[position++] = (byte) (value >>> 21 | 0x80); - buffer[position++] = (byte) (value >>> 28); - return 5; - } - - /** - * Returns 1-9 bytes that would be written with {@link #writeLong(byte[], long, boolean)}. - * - * @param optimizePositive - * If true, small positive numbers will be more efficient (1 byte) and small negative numbers will be inefficient (9 - * bytes). This ultimately means that it will use fewer bytes for positive numbers. - */ - public static - int longLength(long value, boolean optimizePositive) { - return OptimizeUtilsByteBuf.longLength(value, optimizePositive); - } - - - // long - - /** - * Reads a 1-9 byte long. - * - * @param optimizePositive - * If true, small positive numbers will be more efficient (1 byte) and small negative numbers will be inefficient (9 - * bytes). This ultimately means that it will use fewer bytes for positive numbers. - */ - public static - long readLong(byte[] buffer, boolean optimizePositive) { - int position = 0; - return readLong(buffer, optimizePositive, position); - } - - /** - * FROM KRYO - *

- * Reads a 1-9 byte long. - * - * @param position where in the buffer to start reading - * @param optimizePositive - * If true, small positive numbers will be more efficient (1 byte) and small negative numbers will be inefficient (9 - * bytes). This ultimately means that it will use fewer bytes for positive numbers. - */ - public static - long readLong(final byte[] buffer, final boolean optimizePositive, int position) { - int b = buffer[position++]; - long result = b & 0x7F; - if ((b & 0x80) != 0) { - b = buffer[position++]; - result |= (b & 0x7F) << 7; - if ((b & 0x80) != 0) { - b = buffer[position++]; - result |= (b & 0x7F) << 14; - if ((b & 0x80) != 0) { - b = buffer[position++]; - result |= (b & 0x7F) << 21; - if ((b & 0x80) != 0) { - b = buffer[position++]; - result |= (long) (b & 0x7F) << 28; - if ((b & 0x80) != 0) { - b = buffer[position++]; - result |= (long) (b & 0x7F) << 35; - if ((b & 0x80) != 0) { - b = buffer[position++]; - result |= (long) (b & 0x7F) << 42; - if ((b & 0x80) != 0) { - b = buffer[position++]; - result |= (long) (b & 0x7F) << 49; - if ((b & 0x80) != 0) { - b = buffer[position++]; - result |= (long) b << 56; - } - } - } - } - } - } - } - } - if (!optimizePositive) { - result = result >>> 1 ^ -(result & 1); - } - return result; - } - - /** - * Writes a 1-9 byte long. - * - * @param optimizePositive - * If true, small positive numbers will be more efficient (1 byte) and small negative numbers will be inefficient (9 - * bytes). - * - * @return the number of bytes written. - */ - public static - int writeLong(byte[] buffer, long value, boolean optimizePositive) { - int position = 0; - return writeLong(buffer, value, optimizePositive, position); - } - - /** - * FROM KRYO - *

- * Writes a 1-9 byte long. - * - * @param position where in the buffer to start writing - * @param optimizePositive - * If true, small positive numbers will be more efficient (1 byte) and small negative numbers will be inefficient (9 - * bytes). - * - * @return the number of bytes written. - */ - public static - int writeLong(final byte[] buffer, long value, final boolean optimizePositive, int position) { - if (!optimizePositive) { - value = value << 1 ^ value >> 63; - } - if (value >>> 7 == 0) { - buffer[position++] = (byte) value; - return 1; - } - if (value >>> 14 == 0) { - buffer[position++] = (byte) (value & 0x7F | 0x80); - buffer[position++] = (byte) (value >>> 7); - return 2; - } - if (value >>> 21 == 0) { - buffer[position++] = (byte) (value & 0x7F | 0x80); - buffer[position++] = (byte) (value >>> 7 | 0x80); - buffer[position++] = (byte) (value >>> 14); - return 3; - } - if (value >>> 28 == 0) { - buffer[position++] = (byte) (value & 0x7F | 0x80); - buffer[position++] = (byte) (value >>> 7 | 0x80); - buffer[position++] = (byte) (value >>> 14 | 0x80); - buffer[position++] = (byte) (value >>> 21); - return 4; - } - if (value >>> 35 == 0) { - buffer[position++] = (byte) (value & 0x7F | 0x80); - buffer[position++] = (byte) (value >>> 7 | 0x80); - buffer[position++] = (byte) (value >>> 14 | 0x80); - buffer[position++] = (byte) (value >>> 21 | 0x80); - buffer[position++] = (byte) (value >>> 28); - return 5; - } - if (value >>> 42 == 0) { - buffer[position++] = (byte) (value & 0x7F | 0x80); - buffer[position++] = (byte) (value >>> 7 | 0x80); - buffer[position++] = (byte) (value >>> 14 | 0x80); - buffer[position++] = (byte) (value >>> 21 | 0x80); - buffer[position++] = (byte) (value >>> 28 | 0x80); - buffer[position++] = (byte) (value >>> 35); - return 6; - } - if (value >>> 49 == 0) { - buffer[position++] = (byte) (value & 0x7F | 0x80); - buffer[position++] = (byte) (value >>> 7 | 0x80); - buffer[position++] = (byte) (value >>> 14 | 0x80); - buffer[position++] = (byte) (value >>> 21 | 0x80); - buffer[position++] = (byte) (value >>> 28 | 0x80); - buffer[position++] = (byte) (value >>> 35 | 0x80); - buffer[position++] = (byte) (value >>> 42); - return 7; - } - if (value >>> 56 == 0) { - buffer[position++] = (byte) (value & 0x7F | 0x80); - buffer[position++] = (byte) (value >>> 7 | 0x80); - buffer[position++] = (byte) (value >>> 14 | 0x80); - buffer[position++] = (byte) (value >>> 21 | 0x80); - buffer[position++] = (byte) (value >>> 28 | 0x80); - buffer[position++] = (byte) (value >>> 35 | 0x80); - buffer[position++] = (byte) (value >>> 42 | 0x80); - buffer[position++] = (byte) (value >>> 49); - return 8; - } - buffer[position++] = (byte) (value & 0x7F | 0x80); - buffer[position++] = (byte) (value >>> 7 | 0x80); - buffer[position++] = (byte) (value >>> 14 | 0x80); - buffer[position++] = (byte) (value >>> 21 | 0x80); - buffer[position++] = (byte) (value >>> 28 | 0x80); - buffer[position++] = (byte) (value >>> 35 | 0x80); - buffer[position++] = (byte) (value >>> 42 | 0x80); - buffer[position++] = (byte) (value >>> 49 | 0x80); - buffer[position++] = (byte) (value >>> 56); - return 9; - } - - /** - * look at buffer, and see if we can read the length of the long off of it (from the reader index). - * - * @return 0 if we could not read anything, >0 for the number of bytes for the long on the buffer - */ - public static - boolean canReadLong(byte[] buffer) { - int position = 0; - return canReadLong(buffer, position); - } - - /** - * FROM KRYO - *

- * look at buffer, and see if we can read the length of the long off of it (from the reader index). - * - * @param position where in the buffer to start reading - * @return 0 if we could not read anything, >0 for the number of bytes for the long on the buffer - */ - private static - boolean canReadLong(final byte[] buffer, int position) { - int limit = buffer.length; - - if (limit >= 9) { - return true; - } - if ((buffer[position++] & 0x80) == 0) { - return true; - } - if (position == limit) { - return false; - } - if ((buffer[position++] & 0x80) == 0) { - return true; - } - if (position == limit) { - return false; - } - if ((buffer[position++] & 0x80) == 0) { - return true; - } - if (position == limit) { - return false; - } - if ((buffer[position++] & 0x80) == 0) { - return true; - } - if (position == limit) { - return false; - } - if ((buffer[position++] & 0x80) == 0) { - return true; - } - if (position == limit) { - return false; - } - if ((buffer[position++] & 0x80) == 0) { - return true; - } - if (position == limit) { - return false; - } - if ((buffer[position++] & 0x80) == 0) { - return true; - } - if (position == limit) { - return false; - } - //noinspection SimplifiableIfStatement - if ((buffer[position++] & 0x80) == 0) { - return true; - } - - return position != limit; - } - - private - OptimizeUtilsByteArray() { - } -} diff --git a/src/dorkbox/util/bytes/OptimizeUtilsByteBuf.java b/src/dorkbox/util/bytes/OptimizeUtilsByteBuf.java deleted file mode 100644 index 32ca31e..0000000 --- a/src/dorkbox/util/bytes/OptimizeUtilsByteBuf.java +++ /dev/null @@ -1,381 +0,0 @@ -/* - * Copyright 2014 dorkbox, llc - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Copyright (c) 2008, Nathan Sweet - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following - * conditions are met: - * - * - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the distribution. - * - Neither the name of Esoteric Software nor the names of its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package dorkbox.util.bytes; - -import io.netty.buffer.ByteBuf; - -@SuppressWarnings({"Duplicates", "NumericCastThatLosesPrecision", "UnusedAssignment", "IntegerMultiplicationImplicitCastToLong", "unused"}) -public -class OptimizeUtilsByteBuf { - - // int - - /** - * FROM KRYO - *

- * Returns the number of bytes that would be written with {@link #writeInt(ByteBuf, int, boolean)}. - * - * @param optimizePositive - * If true, small positive numbers will be more efficient (1 byte) and small negative numbers will be inefficient (5 - * bytes). This ultimately means that it will use fewer bytes for positive numbers. - */ - public static - int intLength(int value, boolean optimizePositive) { - if (!optimizePositive) { - value = value << 1 ^ value >> 31; - } - if (value >>> 7 == 0) { - return 1; - } - if (value >>> 14 == 0) { - return 2; - } - if (value >>> 21 == 0) { - return 3; - } - if (value >>> 28 == 0) { - return 4; - } - return 5; - } - - /** - * FROM KRYO - *

- * look at buffer, and see if we can read the length of the int off of it. (from the reader index) - * - * @return 0 if we could not read anything, >0 for the number of bytes for the int on the buffer - */ - public static - int canReadInt(ByteBuf buffer) { - int startIndex = buffer.readerIndex(); - try { - int remaining = buffer.readableBytes(); - for (int offset = 0, count = 1; offset < 32 && remaining > 0; offset += 7, remaining--, count++) { - int b = buffer.readByte(); - if ((b & 0x80) == 0) { - return count; - } - } - return 0; - } finally { - buffer.readerIndex(startIndex); - } - } - - /** - * FROM KRYO - *

- * Reads an int from the buffer that was optimized. - * - * @param optimizePositive - * If true, small positive numbers will be more efficient (1 byte) and small negative numbers will be inefficient (5 - * bytes). This ultimately means that it will use fewer bytes for positive numbers. - * - * @return the number of bytes written. - */ - public static - int readInt(ByteBuf buffer, boolean optimizePositive) { - int b = buffer.readByte(); - int result = b & 0x7F; - if ((b & 0x80) != 0) { - b = buffer.readByte(); - result |= (b & 0x7F) << 7; - if ((b & 0x80) != 0) { - b = buffer.readByte(); - result |= (b & 0x7F) << 14; - if ((b & 0x80) != 0) { - b = buffer.readByte(); - result |= (b & 0x7F) << 21; - if ((b & 0x80) != 0) { - b = buffer.readByte(); - result |= (b & 0x7F) << 28; - } - } - } - } - return optimizePositive ? result : result >>> 1 ^ -(result & 1); - } - - /** - * FROM KRYO - *

- * Writes the specified int to the buffer using 1 to 5 bytes, depending on the size of the number. - * - * @param optimizePositive - * If true, small positive numbers will be more efficient (1 byte) and small negative numbers will be inefficient (5 - * bytes). This ultimately means that it will use fewer bytes for positive numbers. - * - * @return the number of bytes written. - */ - public static - int writeInt(ByteBuf buffer, int value, boolean optimizePositive) { - if (!optimizePositive) { - value = value << 1 ^ value >> 31; - } - if (value >>> 7 == 0) { - buffer.writeByte((byte) value); - return 1; - } - if (value >>> 14 == 0) { - buffer.writeByte((byte) (value & 0x7F | 0x80)); - buffer.writeByte((byte) (value >>> 7)); - return 2; - } - if (value >>> 21 == 0) { - buffer.writeByte((byte) (value & 0x7F | 0x80)); - buffer.writeByte((byte) (value >>> 7 | 0x80)); - buffer.writeByte((byte) (value >>> 14)); - return 3; - } - if (value >>> 28 == 0) { - buffer.writeByte((byte) (value & 0x7F | 0x80)); - buffer.writeByte((byte) (value >>> 7 | 0x80)); - buffer.writeByte((byte) (value >>> 14 | 0x80)); - buffer.writeByte((byte) (value >>> 21)); - return 4; - } - buffer.writeByte((byte) (value & 0x7F | 0x80)); - buffer.writeByte((byte) (value >>> 7 | 0x80)); - buffer.writeByte((byte) (value >>> 14 | 0x80)); - buffer.writeByte((byte) (value >>> 21 | 0x80)); - buffer.writeByte((byte) (value >>> 28)); - return 5; - } - - // long - - /** - * Returns the 1-9 bytes that would be written with {@link #writeLong(ByteBuf, long, boolean)}. - * - * @param optimizePositive - * If true, small positive numbers will be more efficient (1 byte) and small negative numbers will be inefficient (9 - * bytes). This ultimately means that it will use fewer bytes for positive numbers. - */ - public static - int longLength(long value, boolean optimizePositive) { - if (!optimizePositive) { - value = value << 1 ^ value >> 63; - } - if (value >>> 7 == 0) { - return 1; - } - if (value >>> 14 == 0) { - return 2; - } - if (value >>> 21 == 0) { - return 3; - } - if (value >>> 28 == 0) { - return 4; - } - if (value >>> 35 == 0) { - return 5; - } - if (value >>> 42 == 0) { - return 6; - } - if (value >>> 49 == 0) { - return 7; - } - if (value >>> 56 == 0) { - return 8; - } - return 9; - } - - /** - * FROM KRYO - *

- * Reads a 1-9 byte long. - * - * @param optimizePositive - * If true, small positive numbers will be more efficient (1 byte) and small negative numbers will be inefficient (9 - * bytes). This ultimately means that it will use fewer bytes for positive numbers. - */ - public static - long readLong(ByteBuf buffer, boolean optimizePositive) { - int b = buffer.readByte(); - long result = b & 0x7F; - if ((b & 0x80) != 0) { - b = buffer.readByte(); - result |= (b & 0x7F) << 7; - if ((b & 0x80) != 0) { - b = buffer.readByte(); - result |= (b & 0x7F) << 14; - if ((b & 0x80) != 0) { - b = buffer.readByte(); - result |= (b & 0x7F) << 21; - if ((b & 0x80) != 0) { - b = buffer.readByte(); - result |= (long) (b & 0x7F) << 28; - if ((b & 0x80) != 0) { - b = buffer.readByte(); - result |= (long) (b & 0x7F) << 35; - if ((b & 0x80) != 0) { - b = buffer.readByte(); - result |= (long) (b & 0x7F) << 42; - if ((b & 0x80) != 0) { - b = buffer.readByte(); - result |= (long) (b & 0x7F) << 49; - if ((b & 0x80) != 0) { - b = buffer.readByte(); - result |= (long) b << 56; - } - } - } - } - } - } - } - } - if (!optimizePositive) { - result = result >>> 1 ^ -(result & 1); - } - return result; - } - - /** - * FROM KRYO - *

- * Writes a 1-9 byte long. - * - * @param optimizePositive - * If true, small positive numbers will be more efficient (1 byte) and small negative numbers will be inefficient (9 - * bytes). This ultimately means that it will use fewer bytes for positive numbers. - * - * @return the number of bytes written. - */ - public static - int writeLong(ByteBuf buffer, long value, boolean optimizePositive) { - if (!optimizePositive) { - value = value << 1 ^ value >> 63; - } - if (value >>> 7 == 0) { - buffer.writeByte((byte) value); - return 1; - } - if (value >>> 14 == 0) { - buffer.writeByte((byte) (value & 0x7F | 0x80)); - buffer.writeByte((byte) (value >>> 7)); - return 2; - } - if (value >>> 21 == 0) { - buffer.writeByte((byte) (value & 0x7F | 0x80)); - buffer.writeByte((byte) (value >>> 7 | 0x80)); - buffer.writeByte((byte) (value >>> 14)); - return 3; - } - if (value >>> 28 == 0) { - buffer.writeByte((byte) (value & 0x7F | 0x80)); - buffer.writeByte((byte) (value >>> 7 | 0x80)); - buffer.writeByte((byte) (value >>> 14 | 0x80)); - buffer.writeByte((byte) (value >>> 21)); - return 4; - } - if (value >>> 35 == 0) { - buffer.writeByte((byte) (value & 0x7F | 0x80)); - buffer.writeByte((byte) (value >>> 7 | 0x80)); - buffer.writeByte((byte) (value >>> 14 | 0x80)); - buffer.writeByte((byte) (value >>> 21 | 0x80)); - buffer.writeByte((byte) (value >>> 28)); - return 5; - } - if (value >>> 42 == 0) { - buffer.writeByte((byte) (value & 0x7F | 0x80)); - buffer.writeByte((byte) (value >>> 7 | 0x80)); - buffer.writeByte((byte) (value >>> 14 | 0x80)); - buffer.writeByte((byte) (value >>> 21 | 0x80)); - buffer.writeByte((byte) (value >>> 28 | 0x80)); - buffer.writeByte((byte) (value >>> 35)); - return 6; - } - if (value >>> 49 == 0) { - buffer.writeByte((byte) (value & 0x7F | 0x80)); - buffer.writeByte((byte) (value >>> 7 | 0x80)); - buffer.writeByte((byte) (value >>> 14 | 0x80)); - buffer.writeByte((byte) (value >>> 21 | 0x80)); - buffer.writeByte((byte) (value >>> 28 | 0x80)); - buffer.writeByte((byte) (value >>> 35 | 0x80)); - buffer.writeByte((byte) (value >>> 42)); - return 7; - } - if (value >>> 56 == 0) { - buffer.writeByte((byte) (value & 0x7F | 0x80)); - buffer.writeByte((byte) (value >>> 7 | 0x80)); - buffer.writeByte((byte) (value >>> 14 | 0x80)); - buffer.writeByte((byte) (value >>> 21 | 0x80)); - buffer.writeByte((byte) (value >>> 28 | 0x80)); - buffer.writeByte((byte) (value >>> 35 | 0x80)); - buffer.writeByte((byte) (value >>> 42 | 0x80)); - buffer.writeByte((byte) (value >>> 49)); - return 8; - } - buffer.writeByte((byte) (value & 0x7F | 0x80)); - buffer.writeByte((byte) (value >>> 7 | 0x80)); - buffer.writeByte((byte) (value >>> 14 | 0x80)); - buffer.writeByte((byte) (value >>> 21 | 0x80)); - buffer.writeByte((byte) (value >>> 28 | 0x80)); - buffer.writeByte((byte) (value >>> 35 | 0x80)); - buffer.writeByte((byte) (value >>> 42 | 0x80)); - buffer.writeByte((byte) (value >>> 49 | 0x80)); - buffer.writeByte((byte) (value >>> 56)); - return 9; - } - - /** - * FROM KRYO - *

- * look at buffer, and see if we can read the length of the long off of it (from the reader index). - * - * @return 0 if we could not read anything, >0 for the number of bytes for the long on the buffer - */ - public static - int canReadLong(ByteBuf buffer) { - int position = buffer.readerIndex(); - try { - int remaining = buffer.readableBytes(); - for (int offset = 0, count = 1; offset < 64 && remaining > 0; offset += 7, remaining--, count++) { - int b = buffer.readByte(); - if ((b & 0x80) == 0) { - return count; - } - } - return 0; - } finally { - buffer.readerIndex(position); - } - } -} diff --git a/src/dorkbox/util/bytes/UByte.java b/src/dorkbox/util/bytes/UByte.java deleted file mode 100644 index b33a158..0000000 --- a/src/dorkbox/util/bytes/UByte.java +++ /dev/null @@ -1,311 +0,0 @@ -/* - * Copyright (c) 2011-2017, Data Geekery GmbH (http://www.datageekery.com) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package dorkbox.util.bytes; - -import java.io.ObjectStreamException; -import java.math.BigInteger; - -/** - * The unsigned byte type - * - * @author Lukas Eder - * @author Ed Schaller - * @author Jens Nerche - */ -public final class UByte extends UNumber implements Comparable { - - /** - * Generated UID - */ - private static final long serialVersionUID = -6821055240959745390L; - - /** - * Cached values - */ - private static final UByte[] VALUES = mkValues(); - - /** - * A constant holding the minimum value an unsigned byte can - * have, 0. - */ - public static final short MIN_VALUE = 0x00; - - /** - * A constant holding the maximum value an unsigned byte can - * have, 28-1. - */ - public static final short MAX_VALUE = 0xff; - - /** - * A constant holding the minimum value an unsigned byte can - * have as UByte, 0. - */ - public static final UByte MIN = valueOf(0x00); - - /** - * A constant holding the maximum value an unsigned byte can - * have as UByte, 28-1. - */ - public static final UByte MAX = valueOf(0xff); - - /** - * The value modelling the content of this unsigned byte - */ - private final short value; - - /** - * Generate a cached value for each byte value. - * - * @return Array of cached values for UByte. - */ - private static final UByte[] mkValues() { - UByte[] ret = new UByte[256]; - - for (int i = Byte.MIN_VALUE; i <= Byte.MAX_VALUE; i++) - ret[i & MAX_VALUE] = new UByte((byte) i); - - return ret; - } - - /** - * Get an instance of an unsigned byte - * - * @throws NumberFormatException If value does not contain a - * parsable unsigned byte. - */ - public static UByte valueOf(String value) throws NumberFormatException { - return valueOfUnchecked(rangeCheck(Short.parseShort(value))); - } - - /** - * Get an instance of an unsigned byte by masking it with - * 0xFF i.e. (byte) -1 becomes - * (ubyte) 255 - */ - public static UByte valueOf(byte value) { - return valueOfUnchecked((short) (value & MAX_VALUE)); - } - - /** - * Get the value of a short without checking the value. - */ - private static UByte valueOfUnchecked(short value) throws NumberFormatException { - return VALUES[value & MAX_VALUE]; - } - - /** - * Get an instance of an unsigned byte - * - * @throws NumberFormatException If value is not in the range - * of an unsigned byte - */ - public static UByte valueOf(short value) throws NumberFormatException { - return valueOfUnchecked(rangeCheck(value)); - } - - /** - * Get an instance of an unsigned byte - * - * @throws NumberFormatException If value is not in the range - * of an unsigned byte - */ - public static UByte valueOf(int value) throws NumberFormatException { - return valueOfUnchecked(rangeCheck(value)); - } - - /** - * Get an instance of an unsigned byte - * - * @throws NumberFormatException If value is not in the range - * of an unsigned byte - */ - public static UByte valueOf(long value) throws NumberFormatException { - return valueOfUnchecked(rangeCheck(value)); - } - - /** - * Create an unsigned byte - * - * @throws NumberFormatException If value is not in the range - * of an unsigned byte - */ - private UByte(long value) throws NumberFormatException { - this.value = rangeCheck(value); - } - - /** - * Create an unsigned byte - * - * @throws NumberFormatException If value is not in the range - * of an unsigned byte - */ - private UByte(int value) throws NumberFormatException { - this.value = rangeCheck(value); - } - - /** - * Create an unsigned byte - * - * @throws NumberFormatException If value is not in the range - * of an unsigned byte - */ - private UByte(short value) throws NumberFormatException { - this.value = rangeCheck(value); - } - - /** - * Create an unsigned byte by masking it with 0xFF - * i.e. (byte) -1 becomes (ubyte) 255 - */ - private UByte(byte value) { - this.value = (short) (value & MAX_VALUE); - } - - /** - * Create an unsigned byte - * - * @throws NumberFormatException If value does not contain a - * parsable unsigned byte. - */ - private UByte(String value) throws NumberFormatException { - this.value = rangeCheck(Short.parseShort(value)); - } - - /** - * Throw exception if value out of range (short version) - * - * @param value Value to check - * @return value if it is in range - * @throws NumberFormatException if value is out of range - */ - private static short rangeCheck(short value) throws NumberFormatException { - if (value < MIN_VALUE || value > MAX_VALUE) - throw new NumberFormatException("Value is out of range : " + value); - - return value; - } - - /** - * Throw exception if value out of range (int version) - * - * @param value Value to check - * @return value if it is in range - * @throws NumberFormatException if value is out of range - */ - private static short rangeCheck(int value) throws NumberFormatException { - if (value < MIN_VALUE || value > MAX_VALUE) - throw new NumberFormatException("Value is out of range : " + value); - - return (short) value; - } - - /** - * Throw exception if value out of range (long version) - * - * @param value Value to check - * @return value if it is in range - * @throws NumberFormatException if value is out of range - */ - private static short rangeCheck(long value) throws NumberFormatException { - if (value < MIN_VALUE || value > MAX_VALUE) - throw new NumberFormatException("Value is out of range : " + value); - - return (short) value; - } - - /** - * Replace version read through deserialization with cached version. Note - * that this does not use the {@link #valueOfUnchecked(short)} as we have no - * guarantee that the value from the stream is valid. - * - * @return cached instance of this object's value - * @throws ObjectStreamException - */ - private Object readResolve() throws ObjectStreamException { - return valueOf(value); - } - - @Override - public int intValue() { - return value; - } - - @Override - public long longValue() { - return value; - } - - @Override - public float floatValue() { - return value; - } - - @Override - public double doubleValue() { - return value; - } - - @Override - public int hashCode() { - return Short.valueOf(value).hashCode(); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj instanceof UByte) - return value == ((UByte) obj).value; - - return false; - } - - @Override - public String toString() { - return Short.valueOf(value).toString(); - } - - @Override - public String toHexString() { - return Integer.toHexString(this.value); - } - - @Override - public int compareTo(UByte o) { - return (value < o.value ? -1 : (value == o.value ? 0 : 1)); - } - - @Override - public BigInteger toBigInteger() { - return BigInteger.valueOf(value); - } - - public UByte add(UByte val) throws NumberFormatException { - return valueOf(value + val.value); - } - - public UByte add(int val) throws NumberFormatException { - return valueOf(value + val); - } - - public UByte subtract(final UByte val) { - return valueOf(value - val.value); - } - - public UByte subtract(final int val) { - return valueOf(value - val); - } -} diff --git a/src/dorkbox/util/bytes/UInteger.java b/src/dorkbox/util/bytes/UInteger.java deleted file mode 100644 index 3ddd8ab..0000000 --- a/src/dorkbox/util/bytes/UInteger.java +++ /dev/null @@ -1,349 +0,0 @@ -/* - * Copyright (c) 2011-2017, Data Geekery GmbH (http://www.datageekery.com) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package dorkbox.util.bytes; - -import java.io.ObjectStreamException; -import java.math.BigInteger; - -/** - * The unsigned int type - * - * @author Lukas Eder - * @author Ed Schaller - * @author Jens Nerche - */ -public final class UInteger extends UNumber implements Comparable { - - private static final Class CLASS = UInteger.class; - private static final String CLASS_NAME = CLASS.getName(); - - /** - * System property name for the property to set the size of the pre-cache. - */ - private static final String PRECACHE_PROPERTY = CLASS_NAME + ".precacheSize"; - - /** - * Default size for the value cache. - */ - private static final int DEFAULT_PRECACHE_SIZE = 256; - - /** - * Generated UID - */ - private static final long serialVersionUID = -6821055240959745390L; - - /** - * Cached values - */ - private static final UInteger[] VALUES = mkValues(); - - /** - * A constant holding the minimum value an unsigned int can - * have, 0. - */ - public static final long MIN_VALUE = 0x00000000; - - /** - * A constant holding the maximum value an unsigned int can - * have, 232-1. - */ - public static final long MAX_VALUE = 0xffffffffL; - - /** - * A constant holding the minimum value an unsigned int can - * have as UInteger, 0. - */ - public static final UInteger MIN = valueOf(MIN_VALUE); - - /** - * A constant holding the maximum value an unsigned int can - * have as UInteger, 232-1. - */ - public static final UInteger MAX = valueOf(MAX_VALUE); - - /** - * The value modelling the content of this unsigned int - */ - private final long value; - - /** - * Figure out the size of the precache. - * - * @return The parsed value of the system property - * {@link #PRECACHE_PROPERTY} or {@link #DEFAULT_PRECACHE_SIZE} if - * the property is not set, not a number or retrieving results in a - * {@link SecurityException}. If the parsed value is zero or - * negative no cache will be created. If the value is larger than - * {@link Integer#MAX_VALUE} then Integer#MAX_VALUE will be used. - */ - private static final int getPrecacheSize() { - String prop = null; - long propParsed; - - try { - prop = System.getProperty(PRECACHE_PROPERTY); - } - catch (SecurityException e) { - // security manager stopped us so use default - // FIXME: should we log this somewhere? - return DEFAULT_PRECACHE_SIZE; - } - if (prop == null) - return DEFAULT_PRECACHE_SIZE; - - // empty value - // FIXME: should we log this somewhere? - if (prop.length() <= 0) - return DEFAULT_PRECACHE_SIZE; - - try { - propParsed = Long.parseLong(prop); - } - catch (NumberFormatException e) { - // not a valid number - // FIXME: should we log this somewhere? - return DEFAULT_PRECACHE_SIZE; - } - - // treat negative value as no cache... - if (propParsed < 0) - return 0; - - // FIXME: should we log this somewhere? - if (propParsed > Integer.MAX_VALUE) - return Integer.MAX_VALUE; - - return (int) propParsed; - } - - /** - * Generate a cached value for initial unsigned integer values. - * - * @return Array of cached values for UInteger - */ - private static final UInteger[] mkValues() { - int precacheSize = getPrecacheSize(); - UInteger[] ret; - - if (precacheSize <= 0) - return null; - - ret = new UInteger[precacheSize]; - for (int i = 0; i < precacheSize; i++) - ret[i] = new UInteger(i); - - return ret; - } - - /** - * Unchecked internal constructor. This serves two purposes: first it allows - * {@link #UInteger(long)} to stay deprecated without warnings and second - * constructor without unnecessary value checks. - * - * @param value The value to wrap - * @param unused Unused parameter to distinguish between this and the - * deprecated public constructor. - */ - private UInteger(long value, boolean unused) { - this.value = value; - } - - /** - * Retrieve a cached value. - * - * @param value Cached value to retrieve - * @return Cached value if one exists. Null otherwise. - */ - private static UInteger getCached(long value) { - if (VALUES != null && value < VALUES.length) - return VALUES[(int) value]; - - return null; - } - - /** - * Get the value of a long without checking the value. - */ - private static UInteger valueOfUnchecked(long value) { - UInteger cached; - - if ((cached = getCached(value)) != null) - return cached; - - return new UInteger(value, true); - } - - /** - * Create an unsigned int - * - * @throws NumberFormatException If value does not contain a - * parsable unsigned int. - */ - public static UInteger valueOf(String value) throws NumberFormatException { - return valueOfUnchecked(rangeCheck(Long.parseLong(value))); - } - - /** - * Create an unsigned int by masking it with - * 0xFFFFFFFF i.e. (int) -1 becomes - * (uint) 4294967295 - */ - public static UInteger valueOf(int value) { - return valueOfUnchecked(value & MAX_VALUE); - } - - /** - * Create an unsigned int - * - * @throws NumberFormatException If value is not in the range - * of an unsigned byte - */ - public static UInteger valueOf(long value) throws NumberFormatException { - return valueOfUnchecked(rangeCheck(value)); - } - - /** - * Create an unsigned int - * - * @throws NumberFormatException If value is not in the range - * of an unsigned int - */ - private UInteger(long value) throws NumberFormatException { - this.value = rangeCheck(value); - } - - /** - * Create an unsigned int by masking it with - * 0xFFFFFFFF i.e. (int) -1 becomes - * (uint) 4294967295 - */ - private UInteger(int value) { - this.value = value & MAX_VALUE; - } - - /** - * Create an unsigned int - * - * @throws NumberFormatException If value does not contain a - * parsable unsigned int. - */ - private UInteger(String value) throws NumberFormatException { - this.value = rangeCheck(Long.parseLong(value)); - } - - /** - * Throw exception if value out of range (long version) - * - * @param value Value to check - * @return value if it is in range - * @throws NumberFormatException if value is out of range - */ - private static long rangeCheck(long value) throws NumberFormatException { - if (value < MIN_VALUE || value > MAX_VALUE) - throw new NumberFormatException("Value is out of range : " + value); - - return value; - } - - /** - * Replace version read through deserialization with cached version. - * - * @return cached instance of this object's value if one exists, otherwise - * this object - * @throws ObjectStreamException - */ - private Object readResolve() throws ObjectStreamException { - UInteger cached; - - // the value read could be invalid so check it - rangeCheck(value); - if ((cached = getCached(value)) != null) - return cached; - - return this; - } - - @Override - public int intValue() { - return (int) value; - } - - @Override - public long longValue() { - return value; - } - - @Override - public float floatValue() { - return value; - } - - @Override - public double doubleValue() { - return value; - } - - @Override - public BigInteger toBigInteger() { - return BigInteger.valueOf(value); - } - - @Override - public int hashCode() { - return Long.valueOf(value).hashCode(); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj instanceof UInteger) - return value == ((UInteger) obj).value; - - return false; - } - - @Override - public String toString() { - return Long.valueOf(value).toString(); - } - - @Override - public String toHexString() { - return Long.toHexString(this.value); - } - - @Override - public int compareTo(UInteger o) { - return (value < o.value ? -1 : (value == o.value ? 0 : 1)); - } - - public UInteger add(final UInteger val) { - return valueOf(value + val.value); - } - - public UInteger add(final int val) { - return valueOf(value + val); - } - - public UInteger subtract(final UInteger val) { - return valueOf(value - val.value); - } - - public UInteger subtract(final int val) { - return valueOf(value - val); - } -} diff --git a/src/dorkbox/util/bytes/ULong.java b/src/dorkbox/util/bytes/ULong.java deleted file mode 100644 index 8bf6449..0000000 --- a/src/dorkbox/util/bytes/ULong.java +++ /dev/null @@ -1,273 +0,0 @@ -/* - * Copyright (c) 2011-2017, Data Geekery GmbH (http://www.datageekery.com) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package dorkbox.util.bytes; - -import java.math.BigInteger; - -/** - * The unsigned long type - * - * @author Lukas Eder - * @author Jens Nerche - * @author Ivan Sokolov - */ -public final class ULong extends UNumber implements Comparable { - - /** - * Generated UID - */ - private static final long serialVersionUID = -6821055240959745390L; - - /** - * A constant holding the minimum value an unsigned long can - * have, 0. - */ - public static final BigInteger MIN_VALUE = BigInteger.ZERO; - - /** - * A constant holding the maximum value an unsigned long can - * have, 264-1. - */ - public static final BigInteger MAX_VALUE = new BigInteger("18446744073709551615"); - - /** - * A constant holding the maximum value + 1 an signed long can - * have, 263. - */ - public static final BigInteger MAX_VALUE_LONG = new BigInteger("9223372036854775808"); - - /** - * A constant holding the minimum value an unsigned long can - * have as ULong, 0. - */ - public static final ULong MIN = valueOf(MIN_VALUE.longValue()); - - /** - * A constant holding the maximum value + 1 an signed long can - * have as ULong, 263. - */ - public static final ULong MAX = valueOf(MAX_VALUE); - - /** - * The value modelling the content of this unsigned long - */ - private final long value; - - /** - * Create an unsigned long - * - * @throws NumberFormatException If value does not contain a - * parsable unsigned long. - */ - public static ULong valueOf(String value) throws NumberFormatException { - return new ULong(value); - } - - /** - * Create an unsigned long by masking it with - * 0xFFFFFFFFFFFFFFFF i.e. (long) -1 becomes - * (uint) 18446744073709551615 - */ - public static ULong valueOf(long value) { - return new ULong(value); - } - - /** - * Create an unsigned long - * - * @throws NumberFormatException If value is not in the range - * of an unsigned long - */ - public static ULong valueOf(BigInteger value) throws NumberFormatException { - return new ULong(value); - } - - public static int compare(long x, long y) { - x += Long.MIN_VALUE; - y += Long.MIN_VALUE; - return (x < y) ? -1 : ((x == y) ? 0 : 1); - } - - /** - * Create an unsigned long - * - * @throws NumberFormatException If value is not in the range - * of an unsigned long - */ - private ULong(BigInteger value) throws NumberFormatException { - if (value.compareTo(MIN_VALUE) < 0 || value.compareTo(MAX_VALUE) > 0) - throw new NumberFormatException(); - else - this.value = value.longValue(); - } - - /** - * Create an unsigned long by masking it with - * 0xFFFFFFFFFFFFFFFF i.e. (long) -1 becomes - * (uint) 18446744073709551615 - */ - private ULong(long value) { - this.value = value; - } - - /** - * Create an unsigned long - * - * @throws NumberFormatException If value does not contain a - * parsable unsigned long. - */ - private ULong(String value) throws NumberFormatException { - if (value == null) - throw new NumberFormatException("null"); - - int length = value.length(); - - if (length == 0) - throw new NumberFormatException("Empty input string"); - - if (value.charAt(0) == '-') - throw new NumberFormatException( - String.format("Illegal leading minus sign on unsigned string %s", value)); - - if (length <= 18) { - this.value = Long.parseLong(value, 10); - return; - } - - final long first = Long.parseLong(value.substring(0, length - 1), 10); - final int second = Character.digit(value.charAt(length - 1), 10); - if (second < 0) - throw new NumberFormatException("Bad digit at end of " + value); - - long result = first * 10 + second; - if (compare(result, first) < 0) - throw new NumberFormatException( - String.format("String value %s exceeds range of unsigned long", value)); - - this.value = result; - } - - @Override - public int intValue() { - return (int) value; - } - - @Override - public long longValue() { - return value; - } - - @Override - public float floatValue() { - if (value < 0) - return ((float) (value & Long.MAX_VALUE)) + Long.MAX_VALUE; - else - return value; - } - - @Override - public double doubleValue() { - if (value < 0) - return ((double) (value & Long.MAX_VALUE)) + Long.MAX_VALUE; - else - return value; - } - - @Override - public int hashCode() { - return Long.valueOf(value).hashCode(); - } - - @Override - public boolean equals(Object obj) { - if (obj instanceof ULong) - return value == ((ULong) obj).value; - - return false; - } - - @Override - public String toString() { - if (value >= 0) - return Long.toString(value); - else - return BigInteger.valueOf(value & Long.MAX_VALUE).add(MAX_VALUE_LONG).toString(); - } - @Override - public String toHexString() { - return Long.toHexString(this.value); - } - - @Override - public int compareTo(ULong o) { - return compare(value, o.value); - } - - public ULong add(ULong val) throws NumberFormatException { - if (value < 0 && val.value < 0) - throw new NumberFormatException(); - - final long result = value + val.value; - if ((value < 0 || val.value < 0) && result >= 0) - throw new NumberFormatException(); - - return valueOf(result); - } - - public ULong add(int val) throws NumberFormatException { - return add((long) val); - } - - public ULong add(long val) throws NumberFormatException { - if (val < 0) - return subtract(Math.abs(val)); - - final long result = value + val; - if (value < 0 && result >= 0) - throw new NumberFormatException(); - - return valueOf(result); - } - - public ULong subtract(final ULong val) { - if (this.compareTo(val) < 0) - throw new NumberFormatException(); - - final long result = value - val.value; - if (value < 0 && result >= 0) - throw new NumberFormatException(); - - return valueOf(result); - } - - public ULong subtract(final int val) { - return subtract((long) val); - } - - public ULong subtract(final long val) { - if (val < 0) - return add(-val); - - if (compare(value, val) < 0) - throw new NumberFormatException(); - - final long result = value - val; - if (value < 0 && result >= 0) - throw new NumberFormatException(); - - return valueOf(result); - } -} diff --git a/src/dorkbox/util/bytes/UNumber.java b/src/dorkbox/util/bytes/UNumber.java deleted file mode 100644 index 63f9004..0000000 --- a/src/dorkbox/util/bytes/UNumber.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2011-2017, Data Geekery GmbH (http://www.datageekery.com) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package dorkbox.util.bytes; - -import java.math.BigInteger; - -/** - * A base type for unsigned numbers. - * - * @author Lukas Eder - */ -public abstract class UNumber extends Number { - - /** - * Generated UID - */ - private static final long serialVersionUID = -7666221938815339843L; - - /** - * Get this number as a {@link BigInteger}. This is a convenience method for - * calling new BigInteger(toString()) - */ - public BigInteger toBigInteger() { - return new BigInteger(toString()); - } - - /** - * Converts this number to a hex string representation - */ - public abstract String toHexString(); -} diff --git a/src/dorkbox/util/bytes/UShort.java b/src/dorkbox/util/bytes/UShort.java deleted file mode 100644 index 8f011d0..0000000 --- a/src/dorkbox/util/bytes/UShort.java +++ /dev/null @@ -1,195 +0,0 @@ -/* - * Copyright (c) 2011-2017, Data Geekery GmbH (http://www.datageekery.com) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package dorkbox.util.bytes; - -import java.math.BigInteger; - -/** - * The unsigned short type - * - * @author Lukas Eder - * @author Jens Nerche - */ -public final class UShort extends UNumber implements Comparable { - - /** - * Generated UID - */ - private static final long serialVersionUID = -6821055240959745390L; - - /** - * A constant holding the minimum value an unsigned short can - * have, 0. - */ - public static final int MIN_VALUE = 0x0000; - - /** - * A constant holding the maximum value an unsigned short can - * have, 216-1. - */ - public static final int MAX_VALUE = 0xffff; - - /** - * A constant holding the minimum value an unsigned short can - * have as UShort, 0. - */ - public static final UShort MIN = valueOf(MIN_VALUE); - - /** - * A constant holding the maximum value an unsigned short can - * have as UShort, 216-1. - */ - public static final UShort MAX = valueOf(MAX_VALUE); - - /** - * The value modelling the content of this unsigned short - */ - private final int value; - - /** - * Create an unsigned short - * - * @throws NumberFormatException If value does not contain a - * parsable unsigned short. - */ - public static UShort valueOf(String value) throws NumberFormatException { - return new UShort(value); - } - - /** - * Create an unsigned short by masking it with - * 0xFFFF i.e. (short) -1 becomes - * (ushort) 65535 - */ - public static UShort valueOf(short value) { - return new UShort(value); - } - - /** - * Create an unsigned short - * - * @throws NumberFormatException If value is not in the range - * of an unsigned short - */ - public static UShort valueOf(int value) throws NumberFormatException { - return new UShort(value); - } - - /** - * Create an unsigned short - * - * @throws NumberFormatException If value is not in the range - * of an unsigned short - */ - private UShort(int value) throws NumberFormatException { - this.value = value; - rangeCheck(); - } - - /** - * Create an unsigned short by masking it with - * 0xFFFF i.e. (short) -1 becomes - * (ushort) 65535 - */ - private UShort(short value) { - this.value = value & MAX_VALUE; - } - - /** - * Create an unsigned short - * - * @throws NumberFormatException If value does not contain a - * parsable unsigned short. - */ - private UShort(String value) throws NumberFormatException { - this.value = Integer.parseInt(value); - rangeCheck(); - } - - private void rangeCheck() throws NumberFormatException { - if (value < MIN_VALUE || value > MAX_VALUE) - throw new NumberFormatException("Value is out of range : " + value); - } - - @Override - public int intValue() { - return value; - } - - @Override - public long longValue() { - return value; - } - - @Override - public float floatValue() { - return value; - } - - @Override - public double doubleValue() { - return value; - } - - @Override - public BigInteger toBigInteger() { - return BigInteger.valueOf(value); - } - - @Override - public int hashCode() { - return Integer.valueOf(value).hashCode(); - } - - @Override - public boolean equals(Object obj) { - if (obj instanceof UShort) - return value == ((UShort) obj).value; - - return false; - } - - @Override - public String toString() { - return Integer.valueOf(value).toString(); - } - - @Override - public String toHexString() { - return Integer.toHexString(this.value); - } - - @Override - public int compareTo(UShort o) { - return (value < o.value ? -1 : (value == o.value ? 0 : 1)); - } - - public UShort add(UShort val) throws NumberFormatException { - return valueOf(value + val.value); - } - - public UShort add(int val) throws NumberFormatException { - return valueOf(value + val); - } - - public UShort subtract(final UShort val) { - return valueOf(value - val.value); - } - - public UShort subtract(final int val) { - return valueOf(value - val); - } -} diff --git a/src/dorkbox/util/bytes/Unsigned.java b/src/dorkbox/util/bytes/Unsigned.java deleted file mode 100644 index 4ee2562..0000000 --- a/src/dorkbox/util/bytes/Unsigned.java +++ /dev/null @@ -1,192 +0,0 @@ -/* - * Copyright (c) 2011-2017, Data Geekery GmbH (http://www.datageekery.com) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package dorkbox.util.bytes; - -import java.math.BigInteger; - -/** - * A utility class for static access to unsigned number functionality. - *

- * It essentially contains factory methods for unsigned number wrappers. In - * future versions, it will also contain some arithmetic methods, handling - * regular arithmetic and bitwise operations - * - * @author Lukas Eder - */ -public final class Unsigned { - - /** - * Create an unsigned byte - * - * @throws NumberFormatException If value does not contain a - * parsable unsigned byte. - * @see UByte.valueOf(String) - */ - public static - UByte ubyte(String value) throws NumberFormatException { - return value == null ? null : UByte.valueOf(value); - } - - /** - * Create an unsigned byte by masking it with 0xFF - * i.e. (byte) -1 becomes (ubyte) 255 - * - * @see UByte#valueOf(byte) - */ - public static UByte ubyte(byte value) { - return UByte.valueOf(value); - } - - /** - * Create an unsigned byte - * - * @throws NumberFormatException If value is not in the range - * of an unsigned byte - * @see UByte#valueOf(short) - */ - public static UByte ubyte(short value) throws NumberFormatException { - return UByte.valueOf(value); - } - - /** - * Create an unsigned byte - * - * @throws NumberFormatException If value is not in the range - * of an unsigned byte - * @see UByte#valueOf(short) - */ - public static UByte ubyte(int value) throws NumberFormatException { - return UByte.valueOf(value); - } - - /** - * Create an unsigned byte - * - * @throws NumberFormatException If value is not in the range - * of an unsigned byte - * @see UByte#valueOf(short) - */ - public static UByte ubyte(long value) throws NumberFormatException { - return UByte.valueOf(value); - } - - /** - * Create an unsigned short - * - * @throws NumberFormatException If value does not contain a - * parsable unsigned short. - * @see UShort#valueOf(String) - */ - public static - UShort ushort(String value) throws NumberFormatException { - return value == null ? null : UShort.valueOf(value); - } - - /** - * Create an unsigned short by masking it with - * 0xFFFF i.e. (short) -1 becomes - * (ushort) 65535 - * - * @see UShort#valueOf(short) - */ - public static UShort ushort(short value) { - return UShort.valueOf(value); - } - - /** - * Create an unsigned short - * - * @throws NumberFormatException If value is not in the range - * of an unsigned short - * @see UShort#valueOf(int) - */ - public static UShort ushort(int value) throws NumberFormatException { - return UShort.valueOf(value); - } - - /** - * Create an unsigned int - * - * @throws NumberFormatException If value does not contain a - * parsable unsigned int. - * @see UInteger#valueOf(String) - */ - public static - UInteger uint(String value) throws NumberFormatException { - return value == null ? null : UInteger.valueOf(value); - } - - /** - * Create an unsigned int by masking it with - * 0xFFFFFFFF i.e. (int) -1 becomes - * (uint) 4294967295 - * - * @see UInteger#valueOf(int) - */ - public static UInteger uint(int value) { - return UInteger.valueOf(value); - } - - /** - * Create an unsigned int - * - * @throws NumberFormatException If value is not in the range - * of an unsigned int - * @see UInteger#valueOf(long) - */ - public static UInteger uint(long value) throws NumberFormatException { - return UInteger.valueOf(value); - } - - /** - * Create an unsigned long - * - * @throws NumberFormatException If value does not contain a - * parsable unsigned long. - * @see ULong#valueOf(String) - */ - public static - ULong ulong(String value) throws NumberFormatException { - return value == null ? null : ULong.valueOf(value); - } - - /** - * Create an unsigned long by masking it with - * 0xFFFFFFFFFFFFFFFF i.e. (long) -1 becomes - * (uint) 18446744073709551615 - * - * @see ULong#valueOf(long) - */ - public static ULong ulong(long value) { - return ULong.valueOf(value); - } - - /** - * Create an unsigned long - * - * @throws NumberFormatException If value is not in the range - * of an unsigned long - * @see ULong#valueOf(BigInteger) - */ - public static ULong ulong(BigInteger value) throws NumberFormatException { - return ULong.valueOf(value); - } - - /** - * No instances - */ - private Unsigned() {} -} diff --git a/src/dorkbox/util/crypto/Crypto.java b/src/dorkbox/util/crypto/Crypto.java index 04aff85..ac3c3d1 100644 --- a/src/dorkbox/util/crypto/Crypto.java +++ b/src/dorkbox/util/crypto/Crypto.java @@ -42,7 +42,6 @@ import org.lwjgl.util.xxhash.XXHash; import org.slf4j.Logger; import dorkbox.os.OS; -import dorkbox.util.bytes.LittleEndian; /** * http://en.wikipedia.org/wiki/NSA_Suite_B http://www.nsa.gov/ia/programs/suiteb_cryptography/ @@ -262,6 +261,25 @@ class Crypto { } } + static + int toInt(final byte[] bytes) { + int number = 0; + + switch (bytes.length) { + default: + case 4: + number |= (bytes[3] & 0xFF) << 24; + case 3: + number |= (bytes[2] & 0xFF) << 16; + case 2: + number |= (bytes[1] & 0xFF) << 8; + case 1: + number |= (bytes[0] & 0xFF) << 0; + } + + return number; + } + /** * Specifically, to return the hash of the ALL files/directories inside the jar, minus the action specified (LGPL) files. */ @@ -309,7 +327,7 @@ class Crypto { hasAction = true; // we have an ACTION describing how it was compressed, etc - int fileAction = LittleEndian.Int_.from(new byte[] {extraData[5], extraData[6], extraData[7], extraData[8]}); + int fileAction = toInt(new byte[] {extraData[5], extraData[6], extraData[7], extraData[8]}); if ((fileAction & action) != action) { okToHash = true; diff --git a/src/dorkbox/util/javaFx/JavaFX.java b/src/dorkbox/util/javaFx/JavaFX.java deleted file mode 100644 index 92da884..0000000 --- a/src/dorkbox/util/javaFx/JavaFX.java +++ /dev/null @@ -1,211 +0,0 @@ -/* - * Copyright 2016 dorkbox, llc - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package dorkbox.util.javaFx; - - -import java.lang.reflect.Method; -import java.security.AccessController; -import java.security.PrivilegedAction; - -import org.slf4j.LoggerFactory; - -import dorkbox.os.OS; -import dorkbox.util.swt.Swt; - -/** - * Utility methods for JavaFX. - *

- * We use reflection for these methods so that we can compile everything under a version of Java that might not have JavaFX. - */ -public -class JavaFX { - public final static boolean isLoaded; - public final static boolean isGtk3; - - - // Methods are cached for performance - private static final Method dispatchMethod; - private static final Method isEventThreadMethod; - private static final Object isEventThreadObject; - - - static { - // There is a silly amount of redirection, simply because we have to be able to access JavaFX, but only if it's in use. - // Since this class is the place other code interacts with, we can use JavaFX stuff if necessary without loading/linking - // the JavaFX classes by accident - - // We cannot use getToolkit(), because if JavaFX is not being used, calling getToolkit() will initialize it... - // see: https://bugs.openjdk.java.net/browse/JDK-8090933 - - Class javaFxLoggerClass = AccessController.doPrivileged(new PrivilegedAction>() { - @Override - public - Class run() { - try { - return Class.forName("com.sun.javafx.logging.PlatformLogger", true, ClassLoader.getSystemClassLoader()); - } catch (Exception ignored) { - } - try { - return Class.forName("com.sun.javafx.logging.PlatformLogger", true, Thread.currentThread().getContextClassLoader()); - } catch (Exception ignored) { - } - return null; - } - }); - - - boolean isJavaFxLoaded_ = false; - try { - if (javaFxLoggerClass != null) { - // this is important to use reflection, because if JavaFX is not being used, calling getToolkit() will initialize it... - java.lang.reflect.Method m = ClassLoader.class.getDeclaredMethod("findLoadedClass", String.class); - m.setAccessible(true); - ClassLoader cl = ClassLoader.getSystemClassLoader(); - - // JavaFX Java7,8 is GTK2 only. Java9 can have it be GTK3 if -Djdk.gtk.version=3 is specified - // see http://mail.openjdk.java.net/pipermail/openjfx-dev/2016-May/019100.html - isJavaFxLoaded_ = (null != m.invoke(cl, "com.sun.javafx.tk.Toolkit")) || (null != m.invoke(cl, "javafx.application.Application")); - } - } catch (Throwable e) { - LoggerFactory.getLogger(JavaFX.class).debug("Error detecting if JavaFX is loaded", e); - } - - boolean isJavaFxGtk3_ = false; - if (isJavaFxLoaded_) { - // JavaFX Java7,8 is GTK2 only. Java9 can MAYBE have it be GTK3 if `-Djdk.gtk.version=3` is specified - // see - // http://mail.openjdk.java.net/pipermail/openjfx-dev/2016-May/019100.html - // https://docs.oracle.com/javafx/2/system_requirements_2-2-3/jfxpub-system_requirements_2-2-3.htm - // from the page: JavaFX 2.2.3 for Linux requires gtk2 2.18+. - - - if (OS.javaVersion >= 9) { - // HILARIOUSLY enough, you can use JavaFX + SWT..... And the javaFX GTK version info SHOULD - // be based on what SWT has loaded - - // https://github.com/teamfx/openjfx-9-dev-rt/blob/master/modules/javafx.graphics/src/main/java/com/sun/glass/ui/gtk/GtkApplication.java - - if (Swt.isLoaded && !Swt.isGtk3) { - isJavaFxGtk3_ = AccessController.doPrivileged(new PrivilegedAction() { - @Override - public - Boolean run() { - String version = System.getProperty("jdk.gtk.version", "2"); - return "3".equals(version) || version.startsWith("3."); - } - }); - } - } - } - - - isLoaded = isJavaFxLoaded_; - isGtk3 = isJavaFxGtk3_; - - - Method _isEventThreadMethod = null; - Method _dispatchMethod = null; - Object _isEventThreadObject = null; - - if (isJavaFxLoaded_) { - try { - Class clazz = Class.forName("javafx.application.Platform"); - _dispatchMethod = clazz.getMethod("runLater", Runnable.class); - - // JAVA 7 - // javafx.application.Platform.isFxApplicationThread(); - - // JAVA 8 - // com.sun.javafx.tk.Toolkit.getToolkit().isFxUserThread(); - if (OS.javaVersion <= 7) { - clazz = Class.forName("javafx.application.Platform"); - _isEventThreadMethod = clazz.getMethod("isFxApplicationThread"); - _isEventThreadObject = null; - } else { - clazz = Class.forName("com.sun.javafx.tk.Toolkit"); - _isEventThreadMethod = clazz.getMethod("getToolkit"); - - _isEventThreadObject = _isEventThreadMethod.invoke(null); - _isEventThreadMethod = _isEventThreadObject.getClass() - .getMethod("isFxUserThread", (java.lang.Class[])null); - } - } catch (Throwable e) { - LoggerFactory.getLogger(JavaFX.class).error("Cannot initialize JavaFX", e); - } - } - - dispatchMethod = _dispatchMethod; - isEventThreadMethod = _isEventThreadMethod; - isEventThreadObject = _isEventThreadObject; - } - - public static - void dispatch(final Runnable runnable) { - // javafx.application.Platform.runLater(runnable); - - try { - dispatchMethod.invoke(null, runnable); - } catch (Throwable e) { - LoggerFactory.getLogger(JavaFX.class) - .error("Unable to execute JavaFX runLater(). Please create an issue with your OS and Java " + - "version so we may further investigate this issue."); - } - } - - public static - boolean isEventThread() { - // JAVA 7 - // javafx.application.Platform.isFxApplicationThread(); - - // JAVA 8 - // com.sun.javafx.tk.Toolkit.getToolkit().isFxUserThread(); - - try { - if (OS.javaVersion <= 7) { - return (Boolean) isEventThreadMethod.invoke(null); - } else { - Class[] args = null; - //noinspection ConstantConditions - return (Boolean) isEventThreadMethod.invoke(isEventThreadObject, (Object) args); - } - } catch (Throwable e) { - LoggerFactory.getLogger(JavaFX.class) - .error("Unable to check if JavaFX is in the event thread. Please create an issue with your OS and Java " + - "version so we may further investigate this issue."); - } - - return false; - } - - public static - void onShutdown(final Runnable runnable) { - // com.sun.javafx.tk.Toolkit.getToolkit() - // .addShutdownHook(runnable); - - try { - Class clazz = Class.forName("com.sun.javafx.tk.Toolkit"); - Method method = clazz.getMethod("getToolkit"); - Object o = method.invoke(null); - Method m = o.getClass() - .getMethod("addShutdownHook", Runnable.class); - m.invoke(o, runnable); - } catch (Throwable e) { - LoggerFactory.getLogger(JavaFX.class) - .error("Unable to insert shutdown hook into JavaFX. Please create an issue with your OS and Java " + - "version so we may further investigate this issue."); - } - } -} diff --git a/src/dorkbox/util/swt/Swt.java b/src/dorkbox/util/swt/Swt.java deleted file mode 100644 index 02b0aed..0000000 --- a/src/dorkbox/util/swt/Swt.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright 2016 dorkbox, llc - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package dorkbox.util.swt; - -import java.security.AccessController; -import java.security.PrivilegedAction; - -/** - * Utility methods for SWT. SWT is always available for compiling, so it is not necessary to use reflection to compile it. - *

- * SWT system tray types are GtkStatusIcon trays (so we don't want to use them) - */ -public -class Swt { - public final static boolean isLoaded; - public final static boolean isGtk3; - private static final int version; - - // NOTE: This class cannot have SWT **ANYTHING** in it - static { - // There is a silly amount of redirection, simply because we have to be able to access SWT, but only if it's in use. - - // Since this class is the place other code interacts with, we can use SWT stuff if necessary without loading/linking - // the SWT classes by accident - - Class swtErrorClass = AccessController.doPrivileged(new PrivilegedAction>() { - @Override - public - Class run() { - try { - return Class.forName("org.eclipse.swt.SWTError", true, ClassLoader.getSystemClassLoader()); - } catch (Exception ignored) { - } - try { - return Class.forName("org.eclipse.swt.SWTError", true, Thread.currentThread().getContextClassLoader()); - } catch (Exception ignored) { - } - return null; - } - }); - - if (swtErrorClass != null) { - // this means that SWT is available in the system at runtime. We use the error class because that DOES NOT intitialize anything - boolean isSwtLoadable_ = SwtAccess.isLoadable(); - version = SwtAccess.getVersion(); - isLoaded = isSwtLoadable_; - isGtk3 = isSwtLoadable_ && SwtAccess.isGtk3(); - - SwtAccess.init(); - } else { - version = 0; - isLoaded = false; - isGtk3 = false; - } - } - - public static - int getVersion() { - return version; - } - - public static - void dispatch(final Runnable runnable) { - SwtAccess.dispatch(runnable); - } - - public static - boolean isEventThread() { - return SwtAccess.isEventThread(); - } - - public static - void onShutdown(final Runnable runnable) { - SwtAccess.onShutdown(runnable); - } -} diff --git a/src/dorkbox/util/swt/SwtAccess.java b/src/dorkbox/util/swt/SwtAccess.java deleted file mode 100644 index 8d20bb1..0000000 --- a/src/dorkbox/util/swt/SwtAccess.java +++ /dev/null @@ -1,135 +0,0 @@ -package dorkbox.util.swt; - -import java.lang.reflect.Method; -import java.security.AccessController; -import java.security.PrivilegedAction; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.widgets.Display; - -import dorkbox.os.OS; - -public -class SwtAccess { - private static Display currentDisplay = null; - private static Thread currentDisplayThread = null; - - public static - void init() { - // we MUST save this on init, otherwise it is "null" when methods are run from the swing EDT. - currentDisplay = org.eclipse.swt.widgets.Display.getCurrent(); - currentDisplayThread = currentDisplay.getThread(); - } - - static - boolean isLoadable() { - return org.eclipse.swt.SWT.isLoadable(); - } - - static - void onShutdown(final org.eclipse.swt.widgets.Display currentDisplay, final Runnable runnable) { - // currentDisplay.getShells() must only be called inside the event thread! - - org.eclipse.swt.widgets.Shell shell = currentDisplay.getShells()[0]; - shell.addListener(org.eclipse.swt.SWT.Close, new org.eclipse.swt.widgets.Listener() { - @Override - public - void handleEvent(final org.eclipse.swt.widgets.Event event) { - runnable.run(); - } - }); - } - - static - int getVersion() { - return SWT.getVersion(); - } - - /** - * This is only necessary for linux. - * - * @return true if SWT is GTK3. False if SWT is GTK2. If for some reason we DO NOT KNOW, then we return false (GTK2). - */ - static boolean isGtk3() { - if (!OS.isLinux()) { - return false; - } - - // required to use reflection, because this is an internal class! - final String SWT_INTERNAL_CLASS = "org.eclipse.swt.internal.gtk.OS"; - Class osClass = AccessController.doPrivileged(new PrivilegedAction>() { - @Override - public - Class run() { - try { - return Class.forName(SWT_INTERNAL_CLASS, true, ClassLoader.getSystemClassLoader()); - } catch (Exception ignored) { - } - - try { - return Class.forName(SWT_INTERNAL_CLASS, true, Thread.currentThread().getContextClassLoader()); - } catch (Exception ignored) { - } - - return null; - } - }); - - - if (osClass == null) { - return false; - } - - final Class clazz = osClass; - Method method = AccessController.doPrivileged(new PrivilegedAction() { - @Override - public - Method run() { - try { - return clazz.getMethod("gtk_major_version"); - } catch (Exception e) { - return null; - } - } - }); - - if (method == null) { - return false; - } - - int version = 0; - try { - version = ((Number)method.invoke(osClass)).intValue(); - } catch (Exception ignored) { - // this method doesn't exist. - } - - return version == 3; - } - - static - void dispatch(final Runnable runnable) { - currentDisplay.syncExec(runnable); - } - - static - boolean isEventThread() { - return Thread.currentThread() == currentDisplayThread; - } - - static - void onShutdown(final Runnable runnable) { - // currentDisplay.getShells() must only be called inside the event thread! - if (isEventThread()) { - SwtAccess.onShutdown(currentDisplay, runnable); - } else { - dispatch(new Runnable() { - @Override - public - void run() { - SwtAccess.onShutdown(currentDisplay, runnable); - } - }); - } - } -}