All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.cp.elements.nio.BufferUtils Maven / Gradle / Ivy

/*
 * Copyright 2011-Present Author or Authors.
 *
 * 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 org.cp.elements.nio;

import java.nio.Buffer;
import java.nio.ByteBuffer;

import org.cp.elements.lang.Assert;
import org.cp.elements.lang.NumberUtils;
import org.cp.elements.lang.annotation.NotNull;
import org.cp.elements.lang.annotation.NullSafe;
import org.cp.elements.util.ArrayUtils;

/**
 * Abstract utility class for processing {@link Buffer Buffers}.
 *
 * @author John Blum
 * @see java.nio.Buffer
 * @since 1.0.0
 */
@SuppressWarnings("unused")
public abstract class BufferUtils {

  public static final int ONE_KILOBYTE_BUFFER_SIZE = 1024;
  public static final int TWO_KILOBYTE_BUFFER_SIZE = 2048;
  public static final int FOUR_KILOBYTE_BUFFER_SIZE = 4096;
  public static final int EIGHT_KILOBYTE_BUFFER_SIZE = 8192;
  public static final int SIXTEEN_KILOBYTE_BUFFER_SIZE = 8192;
  public static final int THIRTY_TWO_KILOBYTE_BUFFER_SIZE = 32768;
  public static final int SIXTY_FOUR_KILOBYTE_BUFFER_SIZE = 64536;

  public static final byte[] EMPTY_BYTE_ARRAY = new byte[0];

  /**
   * Computes the {@literal load factor} of the given, required {@link Buffer}.
   * 

* The {@literal load factor} is a function of the {@link Buffer Buffer's} {@link Buffer#position()} * and {@link Buffer#capacity()}, irrespective of the {@link Buffer Buffer's} {@link Buffer#limit()}, * if set. *

* Just because a {@link Buffer} has reached its {@link Buffer#limit()} does not mean it is at * or nearing {@link Buffer#capacity()}. This computation is often used in the determination * for whether to {@link #copy(ByteBuffer, int)} reallocate the {@link Buffer}. * * @param buffer {@link Buffer} used to compute the {@literal load factor}; must not be {@literal null}. * @return the computed {@literal load factor} of the given {@link Buffer}. * @throws IllegalArgumentException if the {@link Buffer} is {@literal null}. * @see java.nio.Buffer */ public static float computeLoadFactor(@NotNull Buffer buffer) { Assert.notNull(buffer, "A Buffer is required to compute load factor"); int bufferPosition = buffer.position(); return bufferPosition > 0 ? (float) bufferPosition / (float) buffer.capacity() : 0.0f; } /** * Copies the given, required {@link ByteBuffer} into a new {@link ByteBuffer} with * additional {@link ByteBuffer#capacity()}. *

* The {@link ByteBuffer#position()} will be set to immediately after the last byte copied from * the given {@link ByteBuffer}, which corresponds to either the given {@link ByteBuffer ByteBuffer's} * {@link ByteBuffer#limit()} or its {@link ByteBuffer#capacity()}, dependent on the existing data * in the {@link ByteBuffer}. *

* The {@link ByteBuffer#limit()} of the new {@link ByteBuffer} (copy) will match its {@link ByteBuffer#capacity()}. *

* The {@link ByteBuffer#capacity()} of the new {@link ByteBuffer} (copy) will be the {@link ByteBuffer#capacity()} * of the given {@link ByteBuffer} plus the {@code additionalCapacity}. * * @param buffer {@link ByteBuffer} to copy; must not be {@literal null}. * @param additionalCapacity {@link Integer} specifying the capacity to add to the new {@link ByteBuffer}; * must be greater than equal to {@literal 0}. * @return a new {@link ByteBuffer} with additional {@link ByteBuffer#capacity()} and the contents from the existing, * given {@link ByteBuffer}. * @throws IllegalArgumentException if the {@link ByteBuffer} is {@literal null} or {@code additionalCapacity} * is less than {@literal 0}. * @throws IllegalStateException if the given {@link ByteBuffer} to copy has no {@link ByteBuffer#capacity()} * or could not be {@link ByteBuffer#rewind() rewound} for the {@code copy} operation. * @see java.nio.ByteBuffer */ public static @NotNull ByteBuffer copy(@NotNull ByteBuffer buffer, int additionalCapacity) { Assert.notNull(buffer, "ByteBuffer to copy is required"); Assert.state(buffer.capacity() > 0, "ByteBuffer to copy has no capacity"); Assert.isTrue(additionalCapacity > -1, "Additional capacity [%d] must be greater than equal to 0", additionalCapacity); ByteBuffer bufferToCopy = prepareByteBufferToCopy(buffer); Assert.state(bufferToCopy.position() == 0, "Failed to rewind the given ByteBuffer"); Assert.state(bufferToCopy.remaining() > 0, "The given ByteBuffer has no remaining content to copy"); return bufferToCopy.isDirect() ? allocateDirect(bufferToCopy, additionalCapacity) : allocateNonDirect(bufferToCopy, additionalCapacity); } private static @NotNull ByteBuffer allocateDirect(@NotNull ByteBuffer existingBuffer, int additionalCapacity) { return ByteBuffer.allocateDirect(existingBuffer.capacity() + additionalCapacity).put(existingBuffer); } private static @NotNull ByteBuffer allocateNonDirect(@NotNull ByteBuffer existingBuffer, int additionalCapacity) { return ByteBuffer.allocate(existingBuffer.capacity() + additionalCapacity).put(existingBuffer); } private static @NotNull ByteBuffer prepareByteBufferToCopy(@NotNull ByteBuffer buffer) { return buffer.position() > 0 ? buffer.limit(buffer.position()).rewind() : buffer.limit(buffer.capacity()); } /** * Gets an array of bytes containing the contents of the given, required {@link ByteBuffer}. *

* This method handles {@link ByteBuffer#isReadOnly() read-only} {@link ByteBuffer ByteBuffers}. * * @param buffer {@link ByteBuffer} from which to extract an array of bytes * containing the entire contents of the buffer. * @return an array of bytes containing the contents of the given, required {@link ByteBuffer}. * @throws IllegalArgumentException if the {@link ByteBuffer} is {@literal null}. * @see java.nio.ByteBuffer */ public static byte[] getByteArray(@NotNull ByteBuffer buffer) { Assert.notNull(buffer, "ByteBuffer is required"); byte[] array = new byte[buffer.capacity()]; buffer.get(array); return array; } /** * Converts the primitive byte array into a big, wrapper {@link Byte} array. * * @param array primitive byte array to convert. * @return a big {@link Byte} array containing the elements of the primitive byte array. * @see #toPrimitiveByteArray(Byte[]) */ @NullSafe public static Byte[] toBigByteArray(byte[] array) { byte[] nullSafeArray = nullSafeArray(array); Byte[] bigByteArray = new Byte[nullSafeArray.length]; int index = 0; for (byte element : nullSafeArray) { bigByteArray[index++] = element; } return bigByteArray; } @NullSafe private static byte[] nullSafeArray(byte[] array) { return array != null ? array : EMPTY_BYTE_ARRAY; } /** * Converts the big, wrapper {@link Byte} array into a primitive byte array. * * @param array big, wrapper {@link Byte} array to convert. * @return a primitive byte array containing the element of the big {@link Byte} array. * @see #toBigByteArray(byte[]) */ @NullSafe public static byte[] toPrimitiveByteArray(Byte[] array) { Byte[] nullSafeArray = ArrayUtils.nullSafeArray(array, Byte.class); byte[] primitiveByteArray = new byte[nullSafeArray.length]; int index = 0; for (Byte element : nullSafeArray) { primitiveByteArray[index++] = NumberUtils.byteValue(element); } return primitiveByteArray; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy