This interface provides methods to access an underlying byte array with a given length. The length of the byte region does not change over the lifetime of it.
This interface is similar to the ByteBuffer class, but defines less functionality and is designed to be RMI compatible.
Implementations of this interface may be immutable, in which case any attempt that tries to modify the contents of the underlying array should throw an UnsupportedOperationException.
A simple implementation of this interface is ByteArrayRegion.
Users are generally recommended not to implement this interface directly, but use the classes available in this library. (See ByteArrayRegion for wrapping preallocated arrays.)
When designing interfaces for RMI compatibility, and using ByteRegion instances, one should use the following guidelines:
- If you're reading from an array, use ByteArrayRegion as the parameter type. In this case the relevant part of the array will be transferred to your endpoint.
- If you're writing to a byte region, use ByteRegion as the parameter type and annotate it with
@RMIWrap(RMIByteRegionWrapper.class)
. In this case you'll call put(int, ByteArrayRegion) method on the argument accordingly, which calls will be forwarded over the RMI connection. Calling getLength() on the argument will result in no actual RMI calls, thanks to the annotated wrapper. - If you're reading and writing, see the writing use-case. You'll be reading the contents of the byte region by calling one of the copy methods.
- When writing to an array, you can use
instanceof ByteArrayRegion
to improve performance of your method call. Calling and putting the result of your method directly to the underlying array using ByteArrayRegion.getArray(), can be more efficient than allocating a temporary buffer for writing using the put methods. - When returning an array result of your method call consider using ByteArrayRegion as the result type, as that can allow reducing the number of array allocations. E.g. If you're reading some data into an internal buffer, then by returing ByteArrayRegion, you don't need to trim the length of the buffer for the return value.
Generally, when dealing with different types of ByteRegion and ByteArrayRegion in your code, you should prefer using the type ByteArrayRegion instead of upcasting it to ByteRegion. This provides extra information about where the array resides, and because ByteRegion was primarily designed to be used via RMI calls, they should only be used as parameters and maybe return types.
public static void | checkRange( Validation method for method arguments to check if a given region resides in the usage region specified by a
offset-length pair. |
public default byte[] | copy() Copies underlying contents of this byte region and returns it as a byte array. |
public byte[] | copyArrayRegion( Copies contents from a subregion of this byte region and returns it as an array. |
public byte | get( Gets the byte at the specified index. |
public int | Gets the length of this byte region. |
public default void | put( Puts a byte into the region at the given index. |
public void | put( Puts the given bytes into the byte region starting at the given offset. |
This method throws an exception if the specified region is not fully in the usage region.
regionindex < offset || regionindex + regionlength > offset + length
.Modifying the returned array will have no effect on the contents of this byte region.
Modifying the returned array will have no effect on the contents of this byte region.
offset < 0 || offset + length > this.length
.length < 0
.index < 0 || index >= length
.The length of a region doesn't change over the lifetime of an object.
index < 0 || index >= length
.
This method is the same as calling put(
index < 0 || index + bytes.length > length
.null
.