8300235: Use VarHandle access in Image(Input | Output)StreamImpl classes
Reviewed-by: rriggs
This commit is contained in:
parent
406021ad58
commit
b504c9411e
@ -0,0 +1,424 @@
|
||||
/*
|
||||
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package jdk.internal.util;
|
||||
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.invoke.VarHandle;
|
||||
import java.nio.ByteOrder;
|
||||
|
||||
/**
|
||||
* Utility methods for packing/unpacking primitive values in/out of byte arrays
|
||||
* using {@linkplain ByteOrder#LITTLE_ENDIAN little endian order}.
|
||||
* <p>
|
||||
* All methods in this class will throw an {@linkplain NullPointerException} if {@code null} is
|
||||
* passed in as a method parameter for a byte array.
|
||||
*/
|
||||
public final class ByteArrayLittleEndian {
|
||||
|
||||
private ByteArrayLittleEndian() {
|
||||
}
|
||||
|
||||
private static final VarHandle SHORT = createLittleEndian(short[].class);
|
||||
private static final VarHandle CHAR = createLittleEndian(char[].class);
|
||||
private static final VarHandle INT = createLittleEndian(int[].class);
|
||||
private static final VarHandle FLOAT = createLittleEndian(float[].class);
|
||||
private static final VarHandle LONG = createLittleEndian(long[].class);
|
||||
private static final VarHandle DOUBLE = createLittleEndian(double[].class);
|
||||
|
||||
/*
|
||||
* Methods for unpacking primitive values from byte arrays starting at
|
||||
* a given offset.
|
||||
*/
|
||||
|
||||
/**
|
||||
* {@return a {@code boolean} from the provided {@code array} at the given {@code offset}}.
|
||||
*
|
||||
* @param array to read a value from.
|
||||
* @param offset where extraction in the array should begin
|
||||
* @throws IndexOutOfBoundsException if the provided {@code offset} is outside
|
||||
* the range [0, array.length - 1]
|
||||
* @see #setBoolean(byte[], int, boolean)
|
||||
*/
|
||||
public static boolean getBoolean(byte[] array, int offset) {
|
||||
return array[offset] != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return a {@code char} from the provided {@code array} at the given {@code offset}
|
||||
* using little endian order}.
|
||||
* <p>
|
||||
* There are no access alignment requirements.
|
||||
*
|
||||
* @param array to get a value from.
|
||||
* @param offset where extraction in the array should begin
|
||||
* @throws IndexOutOfBoundsException if the provided {@code offset} is outside
|
||||
* the range [0, array.length - 2]
|
||||
* @see #setChar(byte[], int, char)
|
||||
*/
|
||||
public static char getChar(byte[] array, int offset) {
|
||||
return (char) CHAR.get(array, offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return a {@code short} from the provided {@code array} at the given {@code offset}
|
||||
* using little endian order}.
|
||||
* <p>
|
||||
* There are no access alignment requirements.
|
||||
*
|
||||
* @param array to get a value from.
|
||||
* @param offset where extraction in the array should begin
|
||||
* @return a {@code short} from the array
|
||||
* @throws IndexOutOfBoundsException if the provided {@code offset} is outside
|
||||
* the range [0, array.length - 2]
|
||||
* @see #setShort(byte[], int, short)
|
||||
*/
|
||||
public static short getShort(byte[] array, int offset) {
|
||||
return (short) SHORT.get(array, offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return an {@code unsigned short} from the provided {@code array} at the given {@code offset}
|
||||
* using little endian order}.
|
||||
* <p>
|
||||
* There are no access alignment requirements.
|
||||
*
|
||||
* @param array to get a value from.
|
||||
* @param offset where extraction in the array should begin
|
||||
* @return an {@code int} representing an unsigned short from the array
|
||||
* @throws IndexOutOfBoundsException if the provided {@code offset} is outside
|
||||
* the range [0, array.length - 2]
|
||||
* @see #setUnsignedShort(byte[], int, int)
|
||||
*/
|
||||
public static int getUnsignedShort(byte[] array, int offset) {
|
||||
return Short.toUnsignedInt((short) SHORT.get(array, offset));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return an {@code int} from the provided {@code array} at the given {@code offset}
|
||||
* using little endian order}.
|
||||
* <p>
|
||||
* There are no access alignment requirements.
|
||||
*
|
||||
* @param array to get a value from.
|
||||
* @param offset where extraction in the array should begin
|
||||
* @throws IndexOutOfBoundsException if the provided {@code offset} is outside
|
||||
* the range [0, array.length - 4]
|
||||
* @see #setInt(byte[], int, int)
|
||||
*/
|
||||
public static int getInt(byte[] array, int offset) {
|
||||
return (int) INT.get(array, offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return a {@code float} from the provided {@code array} at the given {@code offset}
|
||||
* using little endian order}.
|
||||
* <p>
|
||||
* Variants of {@linkplain Float#NaN } values are canonized to a single NaN value.
|
||||
* <p>
|
||||
* There are no access alignment requirements.
|
||||
*
|
||||
* @param array to get a value from.
|
||||
* @param offset where extraction in the array should begin
|
||||
* @throws IndexOutOfBoundsException if the provided {@code offset} is outside
|
||||
* the range [0, array.length - 4]
|
||||
* @see #setFloat(byte[], int, float)
|
||||
*/
|
||||
public static float getFloat(byte[] array, int offset) {
|
||||
// Using Float.intBitsToFloat collapses NaN values to a single
|
||||
// "canonical" NaN value
|
||||
return Float.intBitsToFloat((int) INT.get(array, offset));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return a {@code float} from the provided {@code array} at the given {@code offset}
|
||||
* using little endian order}.
|
||||
* <p>
|
||||
* Variants of {@linkplain Float#NaN } values are silently read according
|
||||
* to their bit patterns.
|
||||
* <p>
|
||||
* There are no access alignment requirements.
|
||||
*
|
||||
* @param array to get a value from.
|
||||
* @param offset where extraction in the array should begin
|
||||
* @throws IndexOutOfBoundsException if the provided {@code offset} is outside
|
||||
* the range [0, array.length - 4]
|
||||
* @see #setFloatRaw(byte[], int, float)
|
||||
*/
|
||||
public static float getFloatRaw(byte[] array, int offset) {
|
||||
// Just gets the bits as they are
|
||||
return (float) FLOAT.get(array, offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return a {@code long} from the provided {@code array} at the given {@code offset}
|
||||
* using little endian order}.
|
||||
* <p>
|
||||
* There are no access alignment requirements.
|
||||
*
|
||||
* @param array to get a value from.
|
||||
* @param offset where extraction in the array should begin
|
||||
* @throws IndexOutOfBoundsException if the provided {@code offset} is outside
|
||||
* the range [0, array.length - 8]
|
||||
* @see #setLong(byte[], int, long)
|
||||
*/
|
||||
public static long getLong(byte[] array, int offset) {
|
||||
return (long) LONG.get(array, offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return a {@code double} from the provided {@code array} at the given {@code offset}
|
||||
* using little endian order}.
|
||||
* <p>
|
||||
* Variants of {@linkplain Double#NaN } values are canonized to a single NaN value.
|
||||
* <p>
|
||||
* There are no access alignment requirements.
|
||||
*
|
||||
* @param array to get a value from.
|
||||
* @param offset where extraction in the array should begin
|
||||
* @throws IndexOutOfBoundsException if the provided {@code offset} is outside
|
||||
* the range [0, array.length - 8]
|
||||
* @see #setDouble(byte[], int, double)
|
||||
*/
|
||||
public static double getDouble(byte[] array, int offset) {
|
||||
// Using Double.longBitsToDouble collapses NaN values to a single
|
||||
// "canonical" NaN value
|
||||
return Double.longBitsToDouble((long) LONG.get(array, offset));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return a {@code double} from the provided {@code array} at the given {@code offset}
|
||||
* using little endian order}.
|
||||
* <p>
|
||||
* Variants of {@linkplain Double#NaN } values are silently read according to
|
||||
* their bit patterns.
|
||||
* <p>
|
||||
* There are no access alignment requirements.
|
||||
*
|
||||
* @param array to get a value from.
|
||||
* @param offset where extraction in the array should begin
|
||||
* @throws IndexOutOfBoundsException if the provided {@code offset} is outside
|
||||
* the range [0, array.length - 8]
|
||||
* @see #setDoubleRaw(byte[], int, double)
|
||||
*/
|
||||
public static double getDoubleRaw(byte[] array, int offset) {
|
||||
// Just gets the bits as they are
|
||||
return (double) DOUBLE.get(array, offset);
|
||||
}
|
||||
|
||||
/*
|
||||
* Methods for packing primitive values into byte arrays starting at a given
|
||||
* offset.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Sets (writes) the provided {@code value} into
|
||||
* the provided {@code array} beginning at the given {@code offset}.
|
||||
*
|
||||
* @param array to set (write) a value into
|
||||
* @param offset where setting (writing) in the array should begin
|
||||
* @param value value to set in the array
|
||||
* @throws IndexOutOfBoundsException if the provided {@code offset} is outside
|
||||
* the range [0, array.length]
|
||||
* @see #getBoolean(byte[], int)
|
||||
*/
|
||||
public static void setBoolean(byte[] array, int offset, boolean value) {
|
||||
array[offset] = (byte) (value ? 1 : 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets (writes) the provided {@code value} using little endian order into
|
||||
* the provided {@code array} beginning at the given {@code offset}.
|
||||
* <p>
|
||||
* There are no access alignment requirements.
|
||||
*
|
||||
* @param array to set (write) a value into
|
||||
* @param offset where setting (writing) in the array should begin
|
||||
* @param value value to set in the array
|
||||
* @throws IndexOutOfBoundsException if the provided {@code offset} is outside
|
||||
* the range [0, array.length - 2]
|
||||
* @see #getChar(byte[], int)
|
||||
*/
|
||||
public static void setChar(byte[] array, int offset, char value) {
|
||||
CHAR.set(array, offset, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets (writes) the provided {@code value} using little endian order into
|
||||
* the provided {@code array} beginning at the given {@code offset}.
|
||||
* <p>
|
||||
* There are no access alignment requirements.
|
||||
*
|
||||
* @param array to set (write) a value into
|
||||
* @param offset where setting (writing) in the array should begin
|
||||
* @param value value to set in the array
|
||||
* @throws IndexOutOfBoundsException if the provided {@code offset} is outside
|
||||
* the range [0, array.length - 2]
|
||||
* @see #getShort(byte[], int)
|
||||
*/
|
||||
public static void setShort(byte[] array, int offset, short value) {
|
||||
SHORT.set(array, offset, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets (writes) the provided {@code value} using little endian order into
|
||||
* the provided {@code array} beginning at the given {@code offset}.
|
||||
* <p>
|
||||
* There are no access alignment requirements.
|
||||
*
|
||||
* @param array to set (write) a value into
|
||||
* @param offset where setting (writing) in the array should begin
|
||||
* @param value value to set in the array
|
||||
* @throws IndexOutOfBoundsException if the provided {@code offset} is outside
|
||||
* the range [0, array.length - 2]
|
||||
* @see #getUnsignedShort(byte[], int)
|
||||
*/
|
||||
public static void setUnsignedShort(byte[] array, int offset, int value) {
|
||||
SHORT.set(array, offset, (short) (char) value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets (writes) the provided {@code value} using little endian order into
|
||||
* the provided {@code array} beginning at the given {@code offset}.
|
||||
* <p>
|
||||
* There are no access alignment requirements.
|
||||
*
|
||||
* @param array to set (write) a value into
|
||||
* @param offset where setting (writing) in the array should begin
|
||||
* @param value value to set in the array
|
||||
* @throws IndexOutOfBoundsException if the provided {@code offset} is outside
|
||||
* the range [0, array.length - 4]
|
||||
* @see #getInt(byte[], int)
|
||||
*/
|
||||
public static void setInt(byte[] array, int offset, int value) {
|
||||
INT.set(array, offset, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets (writes) the provided {@code value} using little endian order into
|
||||
* the provided {@code array} beginning at the given {@code offset}.
|
||||
* <p>
|
||||
* Variants of {@linkplain Float#NaN } values are canonized to a single NaN value.
|
||||
* <p>
|
||||
* There are no access alignment requirements.
|
||||
*
|
||||
* @param array to set (write) a value into
|
||||
* @param offset where setting (writing) in the array should begin
|
||||
* @param value value to set in the array
|
||||
* @throws IndexOutOfBoundsException if the provided {@code offset} is outside
|
||||
* the range [0, array.length - 2]
|
||||
* @see #getFloat(byte[], int)
|
||||
*/
|
||||
public static void setFloat(byte[] array, int offset, float value) {
|
||||
// Using Float.floatToIntBits collapses NaN values to a single
|
||||
// "canonical" NaN value
|
||||
INT.set(array, offset, Float.floatToIntBits(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets (writes) the provided {@code value} using little endian order into
|
||||
* the provided {@code array} beginning at the given {@code offset}.
|
||||
* <p>
|
||||
* Variants of {@linkplain Float#NaN } values are silently written according to
|
||||
* their bit patterns.
|
||||
* <p>
|
||||
* There are no access alignment requirements.
|
||||
*
|
||||
* @param array to set (write) a value into
|
||||
* @param offset where setting (writing) in the array should begin
|
||||
* @param value value to set in the array
|
||||
* @throws IndexOutOfBoundsException if the provided {@code offset} is outside
|
||||
* the range [0, array.length - 2]
|
||||
* @see #getFloatRaw(byte[], int)
|
||||
*/
|
||||
public static void setFloatRaw(byte[] array, int offset, float value) {
|
||||
// Just sets the bits as they are
|
||||
FLOAT.set(array, offset, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets (writes) the provided {@code value} using little endian order into
|
||||
* the provided {@code array} beginning at the given {@code offset}.
|
||||
* <p>
|
||||
* There are no access alignment requirements.
|
||||
*
|
||||
* @param array to set (write) a value into
|
||||
* @param offset where setting (writing) in the array should begin
|
||||
* @param value value to set in the array
|
||||
* @throws IndexOutOfBoundsException if the provided {@code offset} is outside
|
||||
* the range [0, array.length - 4]
|
||||
* @see #getLong(byte[], int)
|
||||
*/
|
||||
public static void setLong(byte[] array, int offset, long value) {
|
||||
LONG.set(array, offset, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets (writes) the provided {@code value} using little endian order into
|
||||
* the provided {@code array} beginning at the given {@code offset}.
|
||||
* <p>
|
||||
* Variants of {@linkplain Double#NaN } values are canonized to a single NaN value.
|
||||
* <p>
|
||||
* There are no access alignment requirements.
|
||||
*
|
||||
* @param array to set (write) a value into
|
||||
* @param offset where setting (writing) in the array should begin
|
||||
* @param value value to set in the array
|
||||
* @throws IndexOutOfBoundsException if the provided {@code offset} is outside
|
||||
* the range [0, array.length - 2]
|
||||
* @see #getDouble(byte[], int)
|
||||
*/
|
||||
public static void setDouble(byte[] array, int offset, double value) {
|
||||
// Using Double.doubleToLongBits collapses NaN values to a single
|
||||
// "canonical" NaN value
|
||||
LONG.set(array, offset, Double.doubleToLongBits(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets (writes) the provided {@code value} using little endian order into
|
||||
* the provided {@code array} beginning at the given {@code offset}.
|
||||
* <p>
|
||||
* Variants of {@linkplain Double#NaN } values are silently written according to
|
||||
* their bit patterns.
|
||||
* <p>
|
||||
* There are no access alignment requirements.
|
||||
*
|
||||
* @param array to set (write) a value into
|
||||
* @param offset where setting (writing) in the array should begin
|
||||
* @param value value to set in the array
|
||||
* @throws IndexOutOfBoundsException if the provided {@code offset} is outside
|
||||
* the range [0, array.length - 2]
|
||||
* @see #getDoubleRaw(byte[], int)
|
||||
*/
|
||||
public static void setDoubleRaw(byte[] array, int offset, double value) {
|
||||
// Just sets the bits as they are
|
||||
DOUBLE.set(array, offset, value);
|
||||
}
|
||||
|
||||
private static VarHandle createLittleEndian(Class<?> viewArrayClass) {
|
||||
return MethodHandles.byteArrayViewVarHandle(viewArrayClass, ByteOrder.LITTLE_ENDIAN);
|
||||
}
|
||||
|
||||
}
|
@ -272,6 +272,8 @@ module java.base {
|
||||
jdk.jfr;
|
||||
exports jdk.internal.util.random to
|
||||
jdk.random;
|
||||
exports jdk.internal.util to
|
||||
java.desktop;
|
||||
exports sun.net to
|
||||
java.net.http,
|
||||
jdk.naming.dns;
|
||||
|
@ -25,6 +25,9 @@
|
||||
|
||||
package javax.imageio.stream;
|
||||
|
||||
import jdk.internal.util.ByteArray;
|
||||
import jdk.internal.util.ByteArrayLittleEndian;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
@ -43,9 +46,9 @@ import javax.imageio.IIOException;
|
||||
*/
|
||||
public abstract class ImageInputStreamImpl implements ImageInputStream {
|
||||
|
||||
private Stack<Long> markByteStack = new Stack<>();
|
||||
private final Stack<Long> markByteStack = new Stack<>();
|
||||
|
||||
private Stack<Integer> markBitStack = new Stack<>();
|
||||
private final Stack<Integer> markBitStack = new Stack<>();
|
||||
|
||||
private boolean isClosed = false;
|
||||
|
||||
@ -240,14 +243,9 @@ public abstract class ImageInputStreamImpl implements ImageInputStream {
|
||||
if (read(byteBuf, 0, 2) != 2) {
|
||||
throw new EOFException();
|
||||
}
|
||||
|
||||
if (byteOrder == ByteOrder.BIG_ENDIAN) {
|
||||
return (short)
|
||||
(((byteBuf[0] & 0xff) << 8) | ((byteBuf[1] & 0xff) << 0));
|
||||
} else {
|
||||
return (short)
|
||||
(((byteBuf[1] & 0xff) << 8) | ((byteBuf[0] & 0xff) << 0));
|
||||
}
|
||||
return (byteOrder == ByteOrder.BIG_ENDIAN)
|
||||
? ByteArray.getShort(byteBuf, 0)
|
||||
: ByteArrayLittleEndian.getShort(byteBuf, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -272,15 +270,9 @@ public abstract class ImageInputStreamImpl implements ImageInputStream {
|
||||
throw new EOFException();
|
||||
}
|
||||
|
||||
if (byteOrder == ByteOrder.BIG_ENDIAN) {
|
||||
return
|
||||
(((byteBuf[0] & 0xff) << 24) | ((byteBuf[1] & 0xff) << 16) |
|
||||
((byteBuf[2] & 0xff) << 8) | ((byteBuf[3] & 0xff) << 0));
|
||||
} else {
|
||||
return
|
||||
(((byteBuf[3] & 0xff) << 24) | ((byteBuf[2] & 0xff) << 16) |
|
||||
((byteBuf[1] & 0xff) << 8) | ((byteBuf[0] & 0xff) << 0));
|
||||
}
|
||||
return (byteOrder == ByteOrder.BIG_ENDIAN)
|
||||
? ByteArray.getInt(byteBuf, 0)
|
||||
: ByteArrayLittleEndian.getInt(byteBuf, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -522,16 +514,12 @@ public abstract class ImageInputStreamImpl implements ImageInputStream {
|
||||
int boff = 0;
|
||||
if (byteOrder == ByteOrder.BIG_ENDIAN) {
|
||||
for (int j = 0; j < len; j++) {
|
||||
int b0 = b[boff];
|
||||
int b1 = b[boff + 1] & 0xff;
|
||||
s[off + j] = (short)((b0 << 8) | b1);
|
||||
s[off + j] = ByteArray.getShort(b, boff);
|
||||
boff += 2;
|
||||
}
|
||||
} else {
|
||||
for (int j = 0; j < len; j++) {
|
||||
int b0 = b[boff + 1];
|
||||
int b1 = b[boff] & 0xff;
|
||||
s[off + j] = (short)((b0 << 8) | b1);
|
||||
s[off + j] = ByteArrayLittleEndian.getShort(b, boff);
|
||||
boff += 2;
|
||||
}
|
||||
}
|
||||
@ -541,16 +529,12 @@ public abstract class ImageInputStreamImpl implements ImageInputStream {
|
||||
int boff = 0;
|
||||
if (byteOrder == ByteOrder.BIG_ENDIAN) {
|
||||
for (int j = 0; j < len; j++) {
|
||||
int b0 = b[boff];
|
||||
int b1 = b[boff + 1] & 0xff;
|
||||
c[off + j] = (char)((b0 << 8) | b1);
|
||||
c[off + j] = ByteArray.getChar(b, boff);
|
||||
boff += 2;
|
||||
}
|
||||
} else {
|
||||
for (int j = 0; j < len; j++) {
|
||||
int b0 = b[boff + 1];
|
||||
int b1 = b[boff] & 0xff;
|
||||
c[off + j] = (char)((b0 << 8) | b1);
|
||||
c[off + j] = ByteArrayLittleEndian.getChar(b, boff);
|
||||
boff += 2;
|
||||
}
|
||||
}
|
||||
@ -560,20 +544,12 @@ public abstract class ImageInputStreamImpl implements ImageInputStream {
|
||||
int boff = 0;
|
||||
if (byteOrder == ByteOrder.BIG_ENDIAN) {
|
||||
for (int j = 0; j < len; j++) {
|
||||
int b0 = b[boff];
|
||||
int b1 = b[boff + 1] & 0xff;
|
||||
int b2 = b[boff + 2] & 0xff;
|
||||
int b3 = b[boff + 3] & 0xff;
|
||||
i[off + j] = (b0 << 24) | (b1 << 16) | (b2 << 8) | b3;
|
||||
i[off + j] = ByteArray.getInt(b, boff);
|
||||
boff += 4;
|
||||
}
|
||||
} else {
|
||||
for (int j = 0; j < len; j++) {
|
||||
int b0 = b[boff + 3];
|
||||
int b1 = b[boff + 2] & 0xff;
|
||||
int b2 = b[boff + 1] & 0xff;
|
||||
int b3 = b[boff] & 0xff;
|
||||
i[off + j] = (b0 << 24) | (b1 << 16) | (b2 << 8) | b3;
|
||||
i[off + j] = ByteArrayLittleEndian.getInt(b, boff);
|
||||
boff += 4;
|
||||
}
|
||||
}
|
||||
@ -583,36 +559,12 @@ public abstract class ImageInputStreamImpl implements ImageInputStream {
|
||||
int boff = 0;
|
||||
if (byteOrder == ByteOrder.BIG_ENDIAN) {
|
||||
for (int j = 0; j < len; j++) {
|
||||
int b0 = b[boff];
|
||||
int b1 = b[boff + 1] & 0xff;
|
||||
int b2 = b[boff + 2] & 0xff;
|
||||
int b3 = b[boff + 3] & 0xff;
|
||||
int b4 = b[boff + 4];
|
||||
int b5 = b[boff + 5] & 0xff;
|
||||
int b6 = b[boff + 6] & 0xff;
|
||||
int b7 = b[boff + 7] & 0xff;
|
||||
|
||||
int i0 = (b0 << 24) | (b1 << 16) | (b2 << 8) | b3;
|
||||
int i1 = (b4 << 24) | (b5 << 16) | (b6 << 8) | b7;
|
||||
|
||||
l[off + j] = ((long)i0 << 32) | (i1 & 0xffffffffL);
|
||||
l[off + j] = ByteArray.getLong(b, boff);
|
||||
boff += 8;
|
||||
}
|
||||
} else {
|
||||
for (int j = 0; j < len; j++) {
|
||||
int b0 = b[boff + 7];
|
||||
int b1 = b[boff + 6] & 0xff;
|
||||
int b2 = b[boff + 5] & 0xff;
|
||||
int b3 = b[boff + 4] & 0xff;
|
||||
int b4 = b[boff + 3];
|
||||
int b5 = b[boff + 2] & 0xff;
|
||||
int b6 = b[boff + 1] & 0xff;
|
||||
int b7 = b[boff] & 0xff;
|
||||
|
||||
int i0 = (b0 << 24) | (b1 << 16) | (b2 << 8) | b3;
|
||||
int i1 = (b4 << 24) | (b5 << 16) | (b6 << 8) | b7;
|
||||
|
||||
l[off + j] = ((long)i0 << 32) | (i1 & 0xffffffffL);
|
||||
l[off + j] = ByteArrayLittleEndian.getLong(b, boff);
|
||||
boff += 8;
|
||||
}
|
||||
}
|
||||
@ -622,22 +574,12 @@ public abstract class ImageInputStreamImpl implements ImageInputStream {
|
||||
int boff = 0;
|
||||
if (byteOrder == ByteOrder.BIG_ENDIAN) {
|
||||
for (int j = 0; j < len; j++) {
|
||||
int b0 = b[boff];
|
||||
int b1 = b[boff + 1] & 0xff;
|
||||
int b2 = b[boff + 2] & 0xff;
|
||||
int b3 = b[boff + 3] & 0xff;
|
||||
int i = (b0 << 24) | (b1 << 16) | (b2 << 8) | b3;
|
||||
f[off + j] = Float.intBitsToFloat(i);
|
||||
f[off + j] = ByteArray.getFloat(b, boff);
|
||||
boff += 4;
|
||||
}
|
||||
} else {
|
||||
for (int j = 0; j < len; j++) {
|
||||
int b0 = b[boff + 3];
|
||||
int b1 = b[boff + 2] & 0xff;
|
||||
int b2 = b[boff + 1] & 0xff;
|
||||
int b3 = b[boff + 0] & 0xff;
|
||||
int i = (b0 << 24) | (b1 << 16) | (b2 << 8) | b3;
|
||||
f[off + j] = Float.intBitsToFloat(i);
|
||||
f[off + j] = ByteArrayLittleEndian.getFloat(b, boff);
|
||||
boff += 4;
|
||||
}
|
||||
}
|
||||
@ -647,38 +589,12 @@ public abstract class ImageInputStreamImpl implements ImageInputStream {
|
||||
int boff = 0;
|
||||
if (byteOrder == ByteOrder.BIG_ENDIAN) {
|
||||
for (int j = 0; j < len; j++) {
|
||||
int b0 = b[boff];
|
||||
int b1 = b[boff + 1] & 0xff;
|
||||
int b2 = b[boff + 2] & 0xff;
|
||||
int b3 = b[boff + 3] & 0xff;
|
||||
int b4 = b[boff + 4];
|
||||
int b5 = b[boff + 5] & 0xff;
|
||||
int b6 = b[boff + 6] & 0xff;
|
||||
int b7 = b[boff + 7] & 0xff;
|
||||
|
||||
int i0 = (b0 << 24) | (b1 << 16) | (b2 << 8) | b3;
|
||||
int i1 = (b4 << 24) | (b5 << 16) | (b6 << 8) | b7;
|
||||
long l = ((long)i0 << 32) | (i1 & 0xffffffffL);
|
||||
|
||||
d[off + j] = Double.longBitsToDouble(l);
|
||||
d[off + j] = ByteArray.getDouble(b, boff);
|
||||
boff += 8;
|
||||
}
|
||||
} else {
|
||||
for (int j = 0; j < len; j++) {
|
||||
int b0 = b[boff + 7];
|
||||
int b1 = b[boff + 6] & 0xff;
|
||||
int b2 = b[boff + 5] & 0xff;
|
||||
int b3 = b[boff + 4] & 0xff;
|
||||
int b4 = b[boff + 3];
|
||||
int b5 = b[boff + 2] & 0xff;
|
||||
int b6 = b[boff + 1] & 0xff;
|
||||
int b7 = b[boff] & 0xff;
|
||||
|
||||
int i0 = (b0 << 24) | (b1 << 16) | (b2 << 8) | b3;
|
||||
int i1 = (b4 << 24) | (b5 << 16) | (b6 << 8) | b7;
|
||||
long l = ((long)i0 << 32) | (i1 & 0xffffffffL);
|
||||
|
||||
d[off + j] = Double.longBitsToDouble(l);
|
||||
d[off + j] = ByteArrayLittleEndian.getDouble(b, boff);
|
||||
boff += 8;
|
||||
}
|
||||
}
|
||||
|
@ -25,6 +25,9 @@
|
||||
|
||||
package javax.imageio.stream;
|
||||
|
||||
import jdk.internal.util.ByteArray;
|
||||
import jdk.internal.util.ByteArrayLittleEndian;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UTFDataFormatException;
|
||||
import java.nio.ByteOrder;
|
||||
@ -63,11 +66,9 @@ public abstract class ImageOutputStreamImpl
|
||||
|
||||
public void writeShort(int v) throws IOException {
|
||||
if (byteOrder == ByteOrder.BIG_ENDIAN) {
|
||||
byteBuf[0] = (byte)(v >>> 8);
|
||||
byteBuf[1] = (byte)(v >>> 0);
|
||||
ByteArray.setUnsignedShort(byteBuf, 0, v);
|
||||
} else {
|
||||
byteBuf[0] = (byte)(v >>> 0);
|
||||
byteBuf[1] = (byte)(v >>> 8);
|
||||
ByteArrayLittleEndian.setUnsignedShort(byteBuf, 0, v);
|
||||
}
|
||||
write(byteBuf, 0, 2);
|
||||
}
|
||||
@ -78,38 +79,18 @@ public abstract class ImageOutputStreamImpl
|
||||
|
||||
public void writeInt(int v) throws IOException {
|
||||
if (byteOrder == ByteOrder.BIG_ENDIAN) {
|
||||
byteBuf[0] = (byte)(v >>> 24);
|
||||
byteBuf[1] = (byte)(v >>> 16);
|
||||
byteBuf[2] = (byte)(v >>> 8);
|
||||
byteBuf[3] = (byte)(v >>> 0);
|
||||
ByteArray.setInt(byteBuf, 0, v);
|
||||
} else {
|
||||
byteBuf[0] = (byte)(v >>> 0);
|
||||
byteBuf[1] = (byte)(v >>> 8);
|
||||
byteBuf[2] = (byte)(v >>> 16);
|
||||
byteBuf[3] = (byte)(v >>> 24);
|
||||
ByteArrayLittleEndian.setInt(byteBuf, 0, v);
|
||||
}
|
||||
write(byteBuf, 0, 4);
|
||||
}
|
||||
|
||||
public void writeLong(long v) throws IOException {
|
||||
if (byteOrder == ByteOrder.BIG_ENDIAN) {
|
||||
byteBuf[0] = (byte)(v >>> 56);
|
||||
byteBuf[1] = (byte)(v >>> 48);
|
||||
byteBuf[2] = (byte)(v >>> 40);
|
||||
byteBuf[3] = (byte)(v >>> 32);
|
||||
byteBuf[4] = (byte)(v >>> 24);
|
||||
byteBuf[5] = (byte)(v >>> 16);
|
||||
byteBuf[6] = (byte)(v >>> 8);
|
||||
byteBuf[7] = (byte)(v >>> 0);
|
||||
ByteArray.setLong(byteBuf, 0, v);
|
||||
} else {
|
||||
byteBuf[0] = (byte)(v >>> 0);
|
||||
byteBuf[1] = (byte)(v >>> 8);
|
||||
byteBuf[2] = (byte)(v >>> 16);
|
||||
byteBuf[3] = (byte)(v >>> 24);
|
||||
byteBuf[4] = (byte)(v >>> 32);
|
||||
byteBuf[5] = (byte)(v >>> 40);
|
||||
byteBuf[6] = (byte)(v >>> 48);
|
||||
byteBuf[7] = (byte)(v >>> 56);
|
||||
ByteArrayLittleEndian.setLong(byteBuf, 0, v);
|
||||
}
|
||||
// REMIND: Once 6277756 is fixed, we should do a bulk write of all 8
|
||||
// bytes here as we do in writeShort() and writeInt() for even better
|
||||
@ -141,15 +122,15 @@ public abstract class ImageOutputStreamImpl
|
||||
int boff = 0;
|
||||
if (byteOrder == ByteOrder.BIG_ENDIAN) {
|
||||
for (int i = 0; i < len ; i++) {
|
||||
int v = s.charAt(i);
|
||||
b[boff++] = (byte)(v >>> 8);
|
||||
b[boff++] = (byte)(v >>> 0);
|
||||
char v = s.charAt(i);
|
||||
ByteArray.setChar(b, boff, v);
|
||||
boff += 2;
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < len ; i++) {
|
||||
int v = s.charAt(i);
|
||||
b[boff++] = (byte)(v >>> 0);
|
||||
b[boff++] = (byte)(v >>> 8);
|
||||
char v = s.charAt(i);
|
||||
ByteArrayLittleEndian.setChar(b, boff, v);
|
||||
boff += 2;
|
||||
}
|
||||
}
|
||||
|
||||
@ -213,14 +194,14 @@ public abstract class ImageOutputStreamImpl
|
||||
if (byteOrder == ByteOrder.BIG_ENDIAN) {
|
||||
for (int i = 0; i < len; i++) {
|
||||
short v = s[off + i];
|
||||
b[boff++] = (byte)(v >>> 8);
|
||||
b[boff++] = (byte)(v >>> 0);
|
||||
ByteArray.setShort(b, boff, v);
|
||||
boff += 2;
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < len; i++) {
|
||||
short v = s[off + i];
|
||||
b[boff++] = (byte)(v >>> 0);
|
||||
b[boff++] = (byte)(v >>> 8);
|
||||
ByteArrayLittleEndian.setShort(b, boff, v);
|
||||
boff += 2;
|
||||
}
|
||||
}
|
||||
|
||||
@ -239,14 +220,14 @@ public abstract class ImageOutputStreamImpl
|
||||
if (byteOrder == ByteOrder.BIG_ENDIAN) {
|
||||
for (int i = 0; i < len; i++) {
|
||||
char v = c[off + i];
|
||||
b[boff++] = (byte)(v >>> 8);
|
||||
b[boff++] = (byte)(v >>> 0);
|
||||
ByteArray.setChar(b, boff, v);
|
||||
boff += 2;
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < len; i++) {
|
||||
char v = c[off + i];
|
||||
b[boff++] = (byte)(v >>> 0);
|
||||
b[boff++] = (byte)(v >>> 8);
|
||||
ByteArrayLittleEndian.setChar(b, boff, v);
|
||||
boff += 2;
|
||||
}
|
||||
}
|
||||
|
||||
@ -265,18 +246,14 @@ public abstract class ImageOutputStreamImpl
|
||||
if (byteOrder == ByteOrder.BIG_ENDIAN) {
|
||||
for (int j = 0; j < len; j++) {
|
||||
int v = i[off + j];
|
||||
b[boff++] = (byte)(v >>> 24);
|
||||
b[boff++] = (byte)(v >>> 16);
|
||||
b[boff++] = (byte)(v >>> 8);
|
||||
b[boff++] = (byte)(v >>> 0);
|
||||
ByteArray.setInt(b, boff, v);
|
||||
boff += 4;
|
||||
}
|
||||
} else {
|
||||
for (int j = 0; j < len; j++) {
|
||||
int v = i[off + j];
|
||||
b[boff++] = (byte)(v >>> 0);
|
||||
b[boff++] = (byte)(v >>> 8);
|
||||
b[boff++] = (byte)(v >>> 16);
|
||||
b[boff++] = (byte)(v >>> 24);
|
||||
ByteArrayLittleEndian.setInt(b, boff, v);
|
||||
boff += 4;
|
||||
}
|
||||
}
|
||||
|
||||
@ -295,26 +272,14 @@ public abstract class ImageOutputStreamImpl
|
||||
if (byteOrder == ByteOrder.BIG_ENDIAN) {
|
||||
for (int i = 0; i < len; i++) {
|
||||
long v = l[off + i];
|
||||
b[boff++] = (byte)(v >>> 56);
|
||||
b[boff++] = (byte)(v >>> 48);
|
||||
b[boff++] = (byte)(v >>> 40);
|
||||
b[boff++] = (byte)(v >>> 32);
|
||||
b[boff++] = (byte)(v >>> 24);
|
||||
b[boff++] = (byte)(v >>> 16);
|
||||
b[boff++] = (byte)(v >>> 8);
|
||||
b[boff++] = (byte)(v >>> 0);
|
||||
ByteArray.setLong(b, boff, v);
|
||||
boff += 8;
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < len; i++) {
|
||||
long v = l[off + i];
|
||||
b[boff++] = (byte)(v >>> 0);
|
||||
b[boff++] = (byte)(v >>> 8);
|
||||
b[boff++] = (byte)(v >>> 16);
|
||||
b[boff++] = (byte)(v >>> 24);
|
||||
b[boff++] = (byte)(v >>> 32);
|
||||
b[boff++] = (byte)(v >>> 40);
|
||||
b[boff++] = (byte)(v >>> 48);
|
||||
b[boff++] = (byte)(v >>> 56);
|
||||
ByteArrayLittleEndian.setLong(b, boff, v);
|
||||
boff += 8;
|
||||
}
|
||||
}
|
||||
|
||||
@ -332,19 +297,15 @@ public abstract class ImageOutputStreamImpl
|
||||
int boff = 0;
|
||||
if (byteOrder == ByteOrder.BIG_ENDIAN) {
|
||||
for (int i = 0; i < len; i++) {
|
||||
int v = Float.floatToIntBits(f[off + i]);
|
||||
b[boff++] = (byte)(v >>> 24);
|
||||
b[boff++] = (byte)(v >>> 16);
|
||||
b[boff++] = (byte)(v >>> 8);
|
||||
b[boff++] = (byte)(v >>> 0);
|
||||
float v = f[off + i];
|
||||
ByteArray.setFloat(b, boff, v);
|
||||
boff += 4;
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < len; i++) {
|
||||
int v = Float.floatToIntBits(f[off + i]);
|
||||
b[boff++] = (byte)(v >>> 0);
|
||||
b[boff++] = (byte)(v >>> 8);
|
||||
b[boff++] = (byte)(v >>> 16);
|
||||
b[boff++] = (byte)(v >>> 24);
|
||||
float v = f[off + i];
|
||||
ByteArrayLittleEndian.setFloat(b, boff, v);
|
||||
boff += 4;
|
||||
}
|
||||
}
|
||||
|
||||
@ -362,27 +323,15 @@ public abstract class ImageOutputStreamImpl
|
||||
int boff = 0;
|
||||
if (byteOrder == ByteOrder.BIG_ENDIAN) {
|
||||
for (int i = 0; i < len; i++) {
|
||||
long v = Double.doubleToLongBits(d[off + i]);
|
||||
b[boff++] = (byte)(v >>> 56);
|
||||
b[boff++] = (byte)(v >>> 48);
|
||||
b[boff++] = (byte)(v >>> 40);
|
||||
b[boff++] = (byte)(v >>> 32);
|
||||
b[boff++] = (byte)(v >>> 24);
|
||||
b[boff++] = (byte)(v >>> 16);
|
||||
b[boff++] = (byte)(v >>> 8);
|
||||
b[boff++] = (byte)(v >>> 0);
|
||||
double v = d[off + i];
|
||||
ByteArray.setDouble(b, boff, v);
|
||||
boff += 8;
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < len; i++) {
|
||||
long v = Double.doubleToLongBits(d[off + i]);
|
||||
b[boff++] = (byte)(v >>> 0);
|
||||
b[boff++] = (byte)(v >>> 8);
|
||||
b[boff++] = (byte)(v >>> 16);
|
||||
b[boff++] = (byte)(v >>> 24);
|
||||
b[boff++] = (byte)(v >>> 32);
|
||||
b[boff++] = (byte)(v >>> 40);
|
||||
b[boff++] = (byte)(v >>> 48);
|
||||
b[boff++] = (byte)(v >>> 56);
|
||||
double v = d[off + i];
|
||||
ByteArrayLittleEndian.setDouble(b, boff, v);
|
||||
boff += 8;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -37,12 +37,9 @@ import javax.imageio.stream.MemoryCacheImageInputStream;
|
||||
|
||||
public class ReadFullyTest {
|
||||
|
||||
static final ByteOrder bigEndian = ByteOrder.BIG_ENDIAN;
|
||||
static final ByteOrder littleEndian = ByteOrder.LITTLE_ENDIAN;
|
||||
|
||||
private static void expect(long e, long g) {
|
||||
if (e != g) {
|
||||
throw new RuntimeException("Expected " + e + ", got " + g);
|
||||
private static void assertEquals(long actual, long expected) {
|
||||
if (actual != expected) {
|
||||
throw new AssertionError("Expected 0x" + Long.toHexString(expected) + ", got 0x" + Long.toHexString(actual));
|
||||
}
|
||||
}
|
||||
|
||||
@ -65,82 +62,82 @@ public class ReadFullyTest {
|
||||
double[] d = new double[b.length/8];
|
||||
|
||||
iin.seek(0L);
|
||||
iin.setByteOrder(bigEndian);
|
||||
iin.setByteOrder(ByteOrder.BIG_ENDIAN);
|
||||
iin.readFully(s, 0, s.length);
|
||||
expect(s[0] & 0xffff, 0x1122);
|
||||
expect(s[1] & 0xffff, 0x4499);
|
||||
expect(s[2] & 0xffff, 0xAA33);
|
||||
expect(s[3] & 0xffff, 0xBBCC);
|
||||
assertEquals(s[0] & 0xffff, 0x1122);
|
||||
assertEquals(s[1] & 0xffff, 0x4499);
|
||||
assertEquals(s[2] & 0xffff, 0xAA33);
|
||||
assertEquals(s[3] & 0xffff, 0xBBCC);
|
||||
|
||||
iin.seek(0L);
|
||||
iin.setByteOrder(littleEndian);
|
||||
iin.setByteOrder(ByteOrder.LITTLE_ENDIAN);
|
||||
iin.readFully(s, 0, s.length);
|
||||
expect(s[0] & 0xffff, 0x2211);
|
||||
expect(s[1] & 0xffff, 0x9944);
|
||||
expect(s[2] & 0xffff, 0x33AA);
|
||||
expect(s[3] & 0xffff, 0xCCBB);
|
||||
assertEquals(s[0] & 0xffff, 0x2211);
|
||||
assertEquals(s[1] & 0xffff, 0x9944);
|
||||
assertEquals(s[2] & 0xffff, 0x33AA);
|
||||
assertEquals(s[3] & 0xffff, 0xCCBB);
|
||||
|
||||
iin.seek(0L);
|
||||
iin.setByteOrder(bigEndian);
|
||||
iin.setByteOrder(ByteOrder.BIG_ENDIAN);
|
||||
iin.readFully(c, 0, c.length);
|
||||
expect(c[0], 0x1122);
|
||||
expect(c[1], 0x4499);
|
||||
expect(c[2], 0xAA33);
|
||||
expect(c[3], 0xBBCC);
|
||||
assertEquals(c[0], 0x1122);
|
||||
assertEquals(c[1], 0x4499);
|
||||
assertEquals(c[2], 0xAA33);
|
||||
assertEquals(c[3], 0xBBCC);
|
||||
|
||||
iin.seek(0L);
|
||||
iin.setByteOrder(littleEndian);
|
||||
iin.setByteOrder(ByteOrder.LITTLE_ENDIAN);
|
||||
iin.readFully(c, 0, c.length);
|
||||
expect(c[0], 0x2211);
|
||||
expect(c[1], 0x9944);
|
||||
expect(c[2], 0x33AA);
|
||||
expect(c[3], 0xCCBB);
|
||||
assertEquals(c[0], 0x2211);
|
||||
assertEquals(c[1], 0x9944);
|
||||
assertEquals(c[2], 0x33AA);
|
||||
assertEquals(c[3], 0xCCBB);
|
||||
|
||||
iin.seek(0L);
|
||||
iin.setByteOrder(bigEndian);
|
||||
iin.setByteOrder(ByteOrder.BIG_ENDIAN);
|
||||
iin.readFully(i, 0, i.length);
|
||||
expect(i[0] & 0xffffffff, 0x11224499);
|
||||
expect(i[1] & 0xffffffff, 0xAA33BBCC);
|
||||
assertEquals(i[0] & 0xffffffff, 0x11224499);
|
||||
assertEquals(i[1] & 0xffffffff, 0xAA33BBCC);
|
||||
|
||||
iin.seek(0L);
|
||||
iin.setByteOrder(littleEndian);
|
||||
iin.setByteOrder(ByteOrder.LITTLE_ENDIAN);
|
||||
iin.readFully(i, 0, i.length);
|
||||
expect(i[0] & 0xffffffff, 0x99442211);
|
||||
expect(i[1] & 0xffffffff, 0xCCBB33AA);
|
||||
assertEquals(i[0] & 0xffffffff, 0x99442211);
|
||||
assertEquals(i[1] & 0xffffffff, 0xCCBB33AA);
|
||||
|
||||
iin.seek(0L);
|
||||
iin.setByteOrder(bigEndian);
|
||||
iin.setByteOrder(ByteOrder.BIG_ENDIAN);
|
||||
iin.readFully(f, 0, f.length);
|
||||
expect(Float.floatToIntBits(f[0]) & 0xffffffff, 0x11224499);
|
||||
expect(Float.floatToIntBits(f[1]) & 0xffffffff, 0xAA33BBCC);
|
||||
assertEquals(Float.floatToIntBits(f[0]) & 0xffffffff, 0x11224499);
|
||||
assertEquals(Float.floatToIntBits(f[1]) & 0xffffffff, 0xAA33BBCC);
|
||||
|
||||
iin.seek(0L);
|
||||
iin.setByteOrder(littleEndian);
|
||||
iin.setByteOrder(ByteOrder.LITTLE_ENDIAN);
|
||||
iin.readFully(f, 0, f.length);
|
||||
expect(Float.floatToIntBits(f[0]) & 0xffffffff, 0x99442211);
|
||||
expect(Float.floatToIntBits(f[1]) & 0xffffffff, 0xCCBB33AA);
|
||||
assertEquals(Float.floatToIntBits(f[0]) & 0xffffffff, 0x99442211);
|
||||
assertEquals(Float.floatToIntBits(f[1]) & 0xffffffff, 0xCCBB33AA);
|
||||
|
||||
iin.seek(0L);
|
||||
iin.setByteOrder(bigEndian);
|
||||
iin.setByteOrder(ByteOrder.BIG_ENDIAN);
|
||||
iin.readFully(l, 0, l.length);
|
||||
expect(l[0], 0x11224499AA33BBCCL);
|
||||
assertEquals(l[0], 0x11224499AA33BBCCL);
|
||||
|
||||
iin.seek(0L);
|
||||
iin.setByteOrder(littleEndian);
|
||||
iin.setByteOrder(ByteOrder.LITTLE_ENDIAN);
|
||||
iin.readFully(l, 0, l.length);
|
||||
expect(l[0], 0xCCBB33AA99442211L);
|
||||
assertEquals(l[0], 0xCCBB33AA99442211L);
|
||||
|
||||
iin.seek(0L);
|
||||
iin.setByteOrder(bigEndian);
|
||||
iin.setByteOrder(ByteOrder.BIG_ENDIAN);
|
||||
iin.readFully(d, 0, d.length);
|
||||
expect(Double.doubleToLongBits(d[0]), 0x11224499AA33BBCCL);
|
||||
assertEquals(Double.doubleToLongBits(d[0]), 0x11224499AA33BBCCL);
|
||||
|
||||
iin.seek(0L);
|
||||
iin.setByteOrder(littleEndian);
|
||||
iin.setByteOrder(ByteOrder.LITTLE_ENDIAN);
|
||||
iin.readFully(d, 0, d.length);
|
||||
expect(Double.doubleToLongBits(d[0]), 0xCCBB33AA99442211L);
|
||||
} catch (Exception ex) {
|
||||
throw new RuntimeException("Got exception " + ex);
|
||||
assertEquals(Double.doubleToLongBits(d[0]), 0xCCBB33AA99442211L);
|
||||
} catch (Throwable ex) {
|
||||
throw new RuntimeException("Got exception", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package org.openjdk.bench.javax.imageio.stream;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.openjdk.jmh.annotations.Benchmark;
|
||||
import org.openjdk.jmh.annotations.BenchmarkMode;
|
||||
import org.openjdk.jmh.annotations.Fork;
|
||||
import org.openjdk.jmh.annotations.Measurement;
|
||||
import org.openjdk.jmh.annotations.Mode;
|
||||
import org.openjdk.jmh.annotations.OutputTimeUnit;
|
||||
import org.openjdk.jmh.annotations.Param;
|
||||
import org.openjdk.jmh.annotations.Scope;
|
||||
import org.openjdk.jmh.annotations.Setup;
|
||||
import org.openjdk.jmh.annotations.State;
|
||||
import org.openjdk.jmh.annotations.Warmup;
|
||||
import org.openjdk.jmh.infra.Blackhole;
|
||||
|
||||
import javax.imageio.stream.ImageInputStreamImpl;
|
||||
import javax.imageio.stream.ImageOutputStreamImpl;
|
||||
|
||||
/**
|
||||
* Examine ImageInpuStream operations
|
||||
*/
|
||||
@BenchmarkMode(Mode.AverageTime)
|
||||
@OutputTimeUnit(TimeUnit.NANOSECONDS)
|
||||
@Warmup(iterations = 5, time = 1)
|
||||
@Measurement(iterations = 5, time = 1)
|
||||
@Fork(3)
|
||||
@State(Scope.Benchmark)
|
||||
public class ImageInputStreamBench {
|
||||
|
||||
// private static final byte[] ARRAY = new byte[8];
|
||||
private ImageInputStreamImpl imageInputStream;
|
||||
|
||||
@Setup
|
||||
public void createInstants() {
|
||||
// Various instants during the same day
|
||||
imageInputStream = new ImageInputStreamImpl() {
|
||||
@Override
|
||||
public int read() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read(byte[] b, int off, int len) throws IOException {
|
||||
//System.arraycopy(ARRAY, 0, b, off, len);
|
||||
return len;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void readInt(Blackhole bh) throws IOException {
|
||||
bh.consume(imageInputStream.readInt());
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void readLong(Blackhole bh) throws IOException {
|
||||
bh.consume(imageInputStream.readLong());
|
||||
}
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user