![JAR search and dependency download from the Maven repository](/logo.png)
io.nem.symbol.catapult.builders.GeneratorUtils Maven / Gradle / Ivy
/**
*** Copyright (c) 2016-present,
*** Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. All rights reserved.
***
*** This file is part of Catapult.
***
*** Catapult is free software: you can redistribute it and/or modify
*** it under the terms of the GNU Lesser General Public License as published by
*** the Free Software Foundation, either version 3 of the License, or
*** (at your option) any later version.
***
*** Catapult 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 Lesser General Public License for more details.
***
*** You should have received a copy of the GNU Lesser General Public License
*** along with Catapult. If not, see .
**/
package io.nem.symbol.catapult.builders;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.Collection;
import java.util.EnumSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.function.Function;
/**
* Generator utility class.
*/
public final class GeneratorUtils {
/**
* Constructor.
*/
private GeneratorUtils() {
}
/**
* Throws if the object is null.
*
* @param object Object to to check.
* @param message Format string message.
* @param values Format values.
* @param Type of object.
*/
public static void notNull(T object, String message, Object... values) {
if (object == null) {
throw new NullPointerException(String.format(message, values));
}
}
/**
* Throws if the value is not true.
*
* @param expression Expression to check.
* @param message Format string message.
* @param values Format values.
*/
public static void isTrue(boolean expression, String message, Object... values) {
if (!expression) {
throw new IllegalArgumentException(String.format(message, values));
}
}
/**
* Throws if the value is not false.
*
* @param expression Expression to check.
* @param message Format string message.
* @param values Format values.
*/
public static void isFalse(boolean expression, String message, Object... values) {
isTrue(!expression, message, values);
}
/**
* Converts to an int by an unsigned conversion.
*
* @param value Signed byte.
* @return Positive integer.
*/
public static int toUnsignedInt(final byte value) {
return Byte.toUnsignedInt(value);
}
/**
* Converts to an int by an unsigned conversion.
*
* @param value Signed short.
* @return Positive integer.
*/
public static int toUnsignedInt(final short value) {
return Short.toUnsignedInt(value);
}
/**
* Creates a bitwise representation for an Set.
*
* @param enumClass Enum type.
* @param enumSet EnumSet to convert to bit representation.
* @param Type of enum.
* @return Long value of the EnumSet.
*/
public static & BitMaskable> long toLong(final Class enumClass,
final Set enumSet) {
final T[] enumValues = enumClass.getEnumConstants();
isFalse(enumValues.length > Long.SIZE,
"The number of enum constants is greater than " + Long.SIZE);
long result = 0;
for (final T value : enumValues) {
if (enumSet.contains(value)) {
result += value.getValueAsLong();
}
}
return result;
}
/**
* Creates a EnumSet from from a bit representation.
*
* @param enumClass Enum class.
* @param bitMaskValue Bitmask value.
* @param Enum type.
* @return EnumSet representing the long value.
*/
public static & BitMaskable> EnumSet toSet(final Class enumClass,
final long bitMaskValue) {
final EnumSet results = EnumSet.noneOf(enumClass);
for (final T constant : enumClass.getEnumConstants()) {
if (0 != (constant.getValueAsLong() & bitMaskValue)) {
results.add(constant);
}
}
return results;
}
/**
* Gets a runtime exception to propagates from an exception.
*
* @param exception Exception to propagate.
* @param wrap Function that wraps an exception in a runtime exception.
* @param Specific exception type.
* @return RuntimeException to throw.
*/
public static RuntimeException getExceptionToPropagate(
final Exception exception,
final Function wrap) {
if ((exception instanceof ExecutionException) && (RuntimeException.class
.isAssignableFrom(exception.getCause().getClass()))) {
return (RuntimeException) exception.getCause();
}
if (exception instanceof RuntimeException) {
return (RuntimeException) exception;
}
if (exception instanceof InterruptedException) {
Thread.currentThread().interrupt();
return new IllegalStateException(exception);
}
return wrap.apply(exception);
}
/**
* Gets a runtime exception to propagates from an exception.
*
* @param exception Exception to propagate.
* @param Specific exception type.
* @return RuntimeException to throw.
*/
public static RuntimeException getExceptionToPropagate(
final Exception exception) {
return getExceptionToPropagate(exception, RuntimeException::new);
}
/**
* Propagates checked exceptions as a specific runtime exception.
*
* @param callable Function to call.
* @param wrap Function that wraps an exception in a runtime exception.
* @param Return type.
* @param Specific exception type.
* @return Function result.
*/
public static T propagate(final Callable callable,
final Function wrap) {
try {
return callable.call();
} catch (final Exception e) {
throw getExceptionToPropagate(e, wrap);
}
}
/**
* Propagates checked exceptions as a runtime exception.
*
* @param callable Function to call.
* @param Function return type.
* @return Function result.
*/
public static T propagate(final Callable callable) {
return propagate(callable, RuntimeException::new);
}
/**
* Throwing consumer interface.
*
* @param Input type.
* @param Exception that is thrown.
*/
public interface ThrowingConsumer {
/**
* Performs operation on the given argument.
*
* @param t Input argument.
* @throws E Exception that is thrown.
*/
void accept(T t) throws E;
}
/**
* Serializes data using a helper function to write to the stream.
*
* @param consumer Helper function that writes data to DataOutputStream.
* @return Byte array of data written.
*/
public static byte[] serialize(ThrowingConsumer consumer) {
return propagate(() -> {
try (final ByteArrayOutputStream byteArrayStream = new ByteArrayOutputStream();
final DataOutputStream dataOutputStream = new DataOutputStream(byteArrayStream)) {
consumer.accept(dataOutputStream);
return byteArrayStream.toByteArray();
}
});
}
/**
* It moves the output stream pointer the padding size calculated from the payload size
*
* @param size the payload size used to calcualted the padding
* @param dataInputStream the input stream that will be moved the calcauted padding size
*/
public static void skipPadding(int size,
final DataInputStream dataInputStream) {
GeneratorUtils.propagate(() -> {
int padding = getPadding(size);
dataInputStream.skipBytes(padding);
return null;
});
}
/**
* This method writes 0 into the dataOutputStream. The amount of 0s is the calculated padding size from provided
* payload size.
*
* @param size the payload size used to calcualted the padding
* @param dataOutputStream used to write the 0s.
*/
public static void addPadding(int size, final DataOutputStream dataOutputStream) {
GeneratorUtils.propagate(() -> {
int padding = getPadding(size);
while (padding > 0) {
dataOutputStream.write(0);
padding--;
}
return null;
});
}
/**
* It calcualtes the padding that needs to be added/skipped when processing inner transactions.
*
* @param size the size of the payload using to calculate the padding
* @return the padding to be added/skipped.
*/
public static int getPadding(int size) {
int alignment = 8;
return 0 == size % alignment ? 0 : alignment - (size % alignment);
}
/**
* It reads count elements from the stream and creates a list using the builder
*
* @param builder the builder
* @param stream the stream
* @param count the elements to be read
* @param the the type to be returned
* @return a list of T.
*/
public static List loadFromBinaryArray(final Function builder,
final DataInputStream stream, final long count) {
List list = new java.util.ArrayList<>();
for (int i = 0; i < count; i++) {
list.add(builder.apply(stream));
}
return list;
}
/**
* It reads all the remaining entities using the total payload size.
*
* @param builder the entity builder
* @param stream the stream to read from
* @param payloadSize the payload size
* @param the type of the entity
* @return a list of entities
* @throws IOException when data cannot be loaded.
*/
public static List loadFromBinaryArrayRemaining(
final Function builder, DataInputStream stream, int payloadSize)
throws IOException {
final ByteBuffer byteCount = ByteBuffer.allocate(payloadSize);
stream.read(byteCount.array());
final DataInputStream dataInputStream = new DataInputStream(
new ByteArrayInputStream(byteCount.array()));
List entities = new java.util.ArrayList<>();
while (dataInputStream.available() > 0) {
T entity = builder.apply(dataInputStream);
entities.add(entity);
GeneratorUtils.skipPadding(entity.getSize(), dataInputStream);
}
return entities;
}
/**
* Write a list of catbuffer entities into the writer.
*
* @param dataOutputStream the stream to serialize into
* @param entities the entities to be serialized
* @throws IOException when data cannot be written.
*/
public static void writeList(final DataOutputStream dataOutputStream,
final List extends Serializer> entities) throws IOException {
for (Serializer entity : entities) {
final byte[] entityBytes = entity.serialize();
dataOutputStream.write(entityBytes, 0, entityBytes.length);
}
}
/**
* Write a serializer into the writer.
*
* @param dataOutputStream the stream to serialize into
* @param entity the entities to be serialized
* @throws IOException when data cannot be written.
*/
public static void writeEntity(final DataOutputStream dataOutputStream, final Serializer entity)
throws IOException {
final byte[] entityBytes = entity.serialize();
dataOutputStream.write(entityBytes, 0, entityBytes.length);
}
/**
* Read a {@link ByteBuffer} of the given size form the strem
*
* @param stream the stream
* @param size the size of the buffer to read
* @return the buffer
* @throws IOException when data cannot be read
*/
public static ByteBuffer readByteBuffer(final DataInputStream stream, final int size) throws IOException {
ByteBuffer buffer = ByteBuffer.allocate(size);
stream.readFully(buffer.array());
return buffer;
}
/**
* Returns the size of the buffer.
*
* @param buffer the buffer
* @return its size
*/
public static int getSize(final ByteBuffer buffer) {
return buffer.array().length;
}
/**
* Returns the size of the collection
* @param collection the collecion
* @return the size.
*/
public static int getSize(final Collection> collection) {
return collection.size();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy