blob: 7968cc7a09c7a7f35daf065d94358229d89ad433 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE
* file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file
* to You 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.apache.tuweni.ssz;
import org.apache.tuweni.bytes.Bytes;
import org.apache.tuweni.units.bigints.UInt256;
import org.apache.tuweni.units.bigints.UInt384;
import java.math.BigInteger;
import java.util.List;
/**
* A writer for encoding values to SSZ.
*/
public interface SSZWriter {
/**
* Append an already SSZ encoded value.
*
* Note that this method <b>may not</b> validate that {@code value} is a valid SSZ sequence. Appending an invalid SSZ
* sequence will cause the entire SSZ encoding produced by this writer to also be invalid.
*
* @param value the SSZ encoded bytes to append
*/
void writeSSZ(Bytes value);
/**
* Append an already SSZ encoded value.
*
* Note that this method <b>may not</b> validate that {@code value} is a valid SSZ sequence. Appending an invalid SSZ
* sequence will cause the entire SSZ encoding produced by this writer to also be invalid.
*
* @param value the SSZ encoded bytes to append
*/
default void writeSSZ(byte[] value) {
writeSSZ(Bytes.wrap(value));
}
/**
* Encode a {@link Bytes} value to SSZ.
*
* @param value the byte array to encode
*/
default void writeBytes(Bytes value) {
SSZ.encodeBytesTo(value, this::writeSSZ);
}
/**
* Encode a byte array to SSZ.
*
* @param value the byte array to encode
*/
default void writeBytes(byte[] value) {
SSZ.encodeByteArrayTo(value, this::writeSSZ);
}
/**
* Encode a known fixed-length {@link Bytes} value to SSZ without the length mixin.
*
* @param byteLength the number of byts to write
* @param value the byte array to encode
* @throws IllegalArgumentException if the byteLength is not the same size as value.
*/
default void writeFixedBytes(Bytes value) {
SSZ.encodeFixedBytesTo(value, this::writeSSZ);
}
/**
* Write a string to the output.
*
* @param str the string to write
*/
default void writeString(String str) {
SSZ.encodeStringTo(str, this::writeSSZ);
}
/**
* Write a two's-compliment integer to the output.
*
* @param value the integer to write
* @param bitLength the bit length of the integer value
* @throws IllegalArgumentException if the value is too large for the specified bit length
*/
default void writeInt(int value, int bitLength) {
writeSSZ(SSZ.encodeLongToByteArray(value, bitLength));
}
/**
* Write a two's-compliment long to the output.
*
* @param value the long value to write
* @param bitLength the bit length of the integer value
* @throws IllegalArgumentException if the value is too large for the specified bit length
*/
default void writeLong(long value, int bitLength) {
writeSSZ(SSZ.encodeLongToByteArray(value, bitLength));
}
/**
* Write a big integer to the output.
*
* @param value the integer to write
* @param bitLength the bit length of the integer value
* @throws IllegalArgumentException if the value is too large for the specified bit length
*/
default void writeBigInteger(BigInteger value, int bitLength) {
writeSSZ(SSZ.encodeBigIntegerToByteArray(value, bitLength));
}
/**
* Write an 8-bit two's-compliment integer to the output.
*
* @param value the integer to write
* @throws IllegalArgumentException if the value is too large to be represented in 8 bits
*/
default void writeInt8(int value) {
writeInt(value, 8);
}
/**
* Write a 16-bit two's-compliment integer to the output.
*
* @param value the integer to write
* @throws IllegalArgumentException If the value is too large to be represented in 16 bits
*/
default void writeInt16(int value) {
writeInt(value, 16);
}
/**
* Write a 32-bit two's-compliment integer to the output.
*
* @param value the integer to write
*/
default void writeInt32(int value) {
writeInt(value, 32);
}
/**
* Write a 64-bit two's-compliment integer to the output.
*
* @param value the long to write
*/
default void writeInt64(long value) {
writeLong(value, 64);
}
/**
* Write an unsigned integer to the output.
*
* Note that the argument {@code value} is a native signed int but will be interpreted as an unsigned value.
*
* @param value the integer to write
* @param bitLength the bit length of the integer value
* @throws IllegalArgumentException if the value is too large for the specified bit length
*/
default void writeUInt(int value, int bitLength) {
writeSSZ(SSZ.encodeULongToByteArray(value, bitLength));
}
/**
* Write an unsigned long to the output.
*
* Note that the argument {@code value} is a native signed long but will be interpreted as an unsigned value.
*
* @param value the long value to write
* @param bitLength the bit length of the integer value
* @throws IllegalArgumentException if the value is too large for the specified bit length
*/
default void writeULong(long value, int bitLength) {
writeSSZ(SSZ.encodeULongToByteArray(value, bitLength));
}
/**
* Write an unsigned big integer to the output.
*
* @param value the integer to write
* @param bitLength the bit length of the integer value
* @throws IllegalArgumentException if the value is too large for the specified bit length or the value is negative
*/
default void writeUBigInteger(BigInteger value, int bitLength) {
writeSSZ(SSZ.encodeUBigIntegerToByteArray(value, bitLength));
}
/**
* Write an 8-bit unsigned integer to the output.
*
* @param value the integer to write
* @throws IllegalArgumentException if the value is too large to be represented in 8 bits
*/
default void writeUInt8(int value) {
writeUInt(value, 8);
}
/**
* Write a 16-bit unsigned integer to the output.
*
* @param value the integer to write
* @throws IllegalArgumentException If the value is too large to be represented in 16 bits
*/
default void writeUInt16(int value) {
writeUInt(value, 16);
}
/**
* Write a 32-bit unsigned integer to the output.
*
* @param value the integer to write
*/
default void writeUInt32(long value) {
writeULong(value, 32);
}
/**
* Write a 64-bit unsigned integer to the output.
*
* Note that the argument {@code value} is a native signed long but will be interpreted as an unsigned value.
*
* @param value the long to write
*/
default void writeUInt64(long value) {
writeULong(value, 64);
}
/**
* Write a {@link UInt256} to the output.
*
* @param value the {@link UInt256} to write
*/
default void writeUInt256(UInt256 value) {
writeSSZ(SSZ.encodeUInt256(value));
}
/**
* Write a {@link UInt384} to the output.
*
* @param value the {@link UInt384} to write
*/
default void writeUInt384(UInt384 value) {
writeSSZ(SSZ.encodeUInt384(value));
}
/**
* Write a boolean to the output.
*
* @param value the boolean value
*/
default void writeBoolean(boolean value) {
writeSSZ(SSZ.encodeBoolean(value));
}
/**
* Write an address.
*
* @param address the address (must be exactly 20 bytes)
* @throws IllegalArgumentException if {@code address.size != 20}
*/
default void writeAddress(Bytes address) {
writeSSZ(SSZ.encodeAddress(address));
}
/**
* Write a hash.
*
* @param hash the hash
*/
default void writeHash(Bytes hash) {
writeSSZ(SSZ.encodeHash(hash));
}
/**
* Write a list of bytes.
*
* @param elements the bytes to write as a list
*/
default void writeBytesList(Bytes... elements) {
SSZ.encodeBytesListTo(elements, this::writeSSZ);
}
/**
* Write a list of bytes.
*
* @param elements the bytes to write as a list
*/
default void writeBytesList(List<? extends Bytes> elements) {
SSZ.encodeBytesListTo(elements, this::writeSSZ);
}
/**
* Write a vector of bytes.
*
* @param elements the bytes to write as a list
*/
default void writeVector(List<? extends Bytes> elements) {
SSZ.encodeBytesVectorTo(elements, this::writeSSZ);
}
/**
* Write a list of known-size homogenous bytes. The list itself WILL have a length mixin, but the elements WILL NOT.
*
* @param byteLength the number of bytes in each element
* @param elements the known-size bytes to write as a list
*/
default void writeFixedBytesList(List<? extends Bytes> elements) {
SSZ.encodeFixedBytesListTo(elements, this::writeSSZ);
}
/**
* Write a known-size fixed-length list of known-size homogenous bytes. Neither the list nor the elements in the list
* will have a length mixin.
*
* @param elements the bytes to write as a list
*/
default void writeFixedBytesVector(List<? extends Bytes> elements) {
SSZ.encodeFixedBytesVectorTo(elements, this::writeSSZ);
}
/**
* Write a list of strings, which must be of the same length
*
* @param elements the strings to write as a list
*/
default void writeStringList(String... elements) {
SSZ.encodeStringListTo(elements, this::writeSSZ);
}
/**
* Write a list of strings, which must be of the same length
*
* @param elements the strings to write as a list
*/
default void writeStringList(List<String> elements) {
SSZ.encodeStringListTo(elements, this::writeSSZ);
}
/**
* Write a list of two's compliment integers.
*
* @param bitLength the bit length of the encoded integers (must be a multiple of 8)
* @param elements the integers to write as a list
* @throws IllegalArgumentException if any values are too large for the specified bit length
*/
default void writeIntList(int bitLength, int... elements) {
SSZ.encodeIntListTo(bitLength, elements, this::writeSSZ);
}
/**
* Write a list of two's compliment integers.
*
* @param bitLength the bit length of the encoded integers (must be a multiple of 8)
* @param elements the integers to write as a list
* @throws IllegalArgumentException if any values are too large for the specified bit length
*/
default void writeIntList(int bitLength, List<Integer> elements) {
SSZ.encodeIntListTo(bitLength, elements, this::writeSSZ);
}
/**
* Write a list of two's compliment long integers.
*
* @param bitLength the bit length of the encoded integers (must be a multiple of 8)
* @param elements the long integers to write as a list
* @throws IllegalArgumentException if any values are too large for the specified bit length
*/
default void writeLongIntList(int bitLength, long... elements) {
SSZ.encodeLongIntListTo(bitLength, elements, this::writeSSZ);
}
/**
* Write a list of two's compliment long integers.
*
* @param bitLength the bit length of the encoded integers (must be a multiple of 8)
* @param elements the long integers to write as a list
* @throws IllegalArgumentException if any values are too large for the specified bit length
*/
default void writeLongIntList(int bitLength, List<Long> elements) {
SSZ.encodeLongIntListTo(bitLength, elements, this::writeSSZ);
}
/**
* Write a list of big integers.
*
* @param bitLength the bit length of each integer
* @param elements the integers to write as a list
* @throws IllegalArgumentException if an integer cannot be stored in the number of bytes provided
*/
default void writeBigIntegerList(int bitLength, BigInteger... elements) {
SSZ.encodeBigIntegerListTo(bitLength, elements, this::writeSSZ);
}
/**
* Write a list of big integers.
*
* @param bitLength the bit length of each integer
* @param elements the integers to write as a list
* @throws IllegalArgumentException if an integer cannot be stored in the number of bytes provided
*/
default void writeBigIntegerList(int bitLength, List<BigInteger> elements) {
SSZ.encodeBigIntegerListTo(bitLength, elements, this::writeSSZ);
}
/**
* Write a list of 8-bit two's compliment integers.
*
* @param elements the integers to write as a list
* @throws IllegalArgumentException if any values are too large to be represented in 8 bits
*/
default void writeInt8List(int... elements) {
writeIntList(8, elements);
}
/**
* Write a list of 8-bit two's compliment integers.
*
* @param elements the integers to write as a list.
* @throws IllegalArgumentException if any values are too large to be represented in 8 bits
*/
default void writeInt8List(List<Integer> elements) {
writeIntList(8, elements);
}
/**
* Write a list of 16-bit two's compliment integers.
*
* @param elements the integers to write as a list
* @throws IllegalArgumentException if any values are too large to be represented in 16 bits
*/
default void writeInt16List(int... elements) {
writeIntList(16, elements);
}
/**
* Write a list of 16-bit two's compliment integers.
*
* @param elements the integers to write as a list
* @throws IllegalArgumentException if any values are too large to be represented in 16 bits
*/
default void writeInt16List(List<Integer> elements) {
writeIntList(16, elements);
}
/**
* Write a list of 32-bit two's compliment integers.
*
* @param elements the integers to write as a list
*/
default void writeInt32List(int... elements) {
writeIntList(32, elements);
}
/**
* Write a list of 32-bit two's compliment integers.
*
* @param elements the integers to write as a list
*/
default void writeInt32List(List<Integer> elements) {
writeIntList(32, elements);
}
/**
* Write a list of 64-bit two's compliment integers.
*
* @param elements the integers to write as a list
*/
default void writeInt64List(long... elements) {
writeLongIntList(64, elements);
}
/**
* Write a list of 64-bit two's compliment integers.
*
* @param elements the integers to write as a list
*/
default void writeInt64List(List<Long> elements) {
writeLongIntList(64, elements);
}
/**
* Write a list of unsigned integers.
*
* Note that the {@code elements} are native signed ints, but will be interpreted as an unsigned values.
*
* @param bitLength the bit length of the encoded integers (must be a multiple of 8)
* @param elements the integers to write as a list
* @throws IllegalArgumentException if any values are too large for the specified bit length
*/
default void writeUIntList(int bitLength, int... elements) {
SSZ.encodeUIntListTo(bitLength, elements, this::writeSSZ);
}
/**
* Write a list of unsigned integers.
*
* Note that the {@code elements} are native signed ints, but will be interpreted as an unsigned values.
*
* @param bitLength the bit length of the encoded integers (must be a multiple of 8)
* @param elements the integers to write as a list
* @throws IllegalArgumentException if any values are too large for the specified bit length
*/
default void writeUIntList(int bitLength, List<Integer> elements) {
SSZ.encodeUIntListTo(bitLength, elements, this::writeSSZ);
}
/**
* Write a list of unsigned long integers.
*
* Note that the {@code elements} are native signed longs, but will be interpreted as an unsigned values.
*
* @param bitLength the bit length of the encoded integers (must be a multiple of 8)
* @param elements the long integers to write as a list
* @throws IllegalArgumentException if any values are too large for the specified bit length
*/
default void writeULongIntList(int bitLength, long... elements) {
SSZ.encodeULongIntListTo(bitLength, elements, this::writeSSZ);
}
/**
* Write a list of unsigned long integers.
*
* Note that the {@code elements} are native signed longs, but will be interpreted as an unsigned values.
*
* @param bitLength the bit length of the encoded integers (must be a multiple of 8)
* @param elements the long integers to write as a list
* @throws IllegalArgumentException if any values are too large for the specified bit length
*/
default void writeULongIntList(int bitLength, List<Long> elements) {
SSZ.encodeULongIntListTo(bitLength, elements, this::writeSSZ);
}
/**
* Write a list of 8-bit unsigned integers.
*
* @param elements the integers to write as a list
* @throws IllegalArgumentException if any values are too large to be represented in 8 bits
*/
default void writeUInt8List(int... elements) {
writeUIntList(8, elements);
}
/**
* Write a list of 8-bit unsigned integers.
*
* @param elements the integers to write as a list
* @throws IllegalArgumentException if any values are too large to be represented in 8 bits
*/
default void writeUInt8List(List<Integer> elements) {
writeUIntList(8, elements);
}
/**
* Write a list of 16-bit unsigned integers.
*
* @param elements the integers to write as a list
* @throws IllegalArgumentException if any values are too large to be represented in 16 bits
*/
default void writeUInt16List(int... elements) {
writeUIntList(16, elements);
}
/**
* Write a list of 16-bit unsigned integers.
*
* @param elements the integers to write as a list
* @throws IllegalArgumentException if any values are too large to be represented in 16 bits
*/
default void writeUInt16List(List<Integer> elements) {
writeUIntList(16, elements);
}
/**
* Write a list of 32-bit unsigned integers.
*
* @param elements the integers to write as a list
* @throws IllegalArgumentException if any values are too large to be represented in 32 bits
*/
default void writeUInt32List(long... elements) {
writeULongIntList(32, elements);
}
/**
* Write a list of 32-bit unsigned integers.
*
* @param elements the integers to write as a list
* @throws IllegalArgumentException if any values are too large to be represented in 32 bits
*/
default void writeUInt32List(List<Long> elements) {
writeULongIntList(32, elements);
}
/**
* Write a list of 64-bit unsigned integers.
*
* Note that the {@code elements} are native signed longs, but will be interpreted as an unsigned values.
*
* @param elements the integers to write as a list
*/
default void writeUInt64List(long... elements) {
writeULongIntList(64, elements);
}
/**
* Write a list of 64-bit unsigned integers.
*
* Note that the {@code elements} are native signed longs, but will be interpreted as an unsigned values.
*
* @param elements the integers to write as a list
*/
default void writeUInt64List(List<Long> elements) {
writeULongIntList(64, elements);
}
/**
* Write a list of unsigned 256-bit integers.
*
* @param elements the integers to write as a list
*/
default void writeUInt256List(UInt256... elements) {
SSZ.encodeUInt256ListTo(elements, this::writeSSZ);
}
/**
* Write a list of unsigned 256-bit integers.
*
* @param elements the integers to write as a list
*/
default void writeUInt256List(List<UInt256> elements) {
SSZ.encodeUInt256ListTo(elements, this::writeSSZ);
}
/**
* Write a list of unsigned 384-bit integers.
*
* @param elements the integers to write as a list
*/
default void writeUInt384List(List<UInt384> elements) {
SSZ.encodeUInt384ListTo(elements, this::writeSSZ);
}
/**
* Write a list of unsigned 384-bit integers.
*
* @param elements the integers to write as a list
*/
default void writeUInt384List(UInt384... elements) {
SSZ.encodeUInt384ListTo(elements, this::writeSSZ);
}
/**
* Write a list of hashes.
*
* @param elements the hashes to write as a list
*/
default void writeHashList(Bytes... elements) {
SSZ.encodeHashListTo(elements, this::writeSSZ);
}
/**
* Write a list of hashes.
*
* @param elements the hashes to write as a list
*/
default void writeHashList(List<? extends Bytes> elements) {
SSZ.encodeHashListTo(elements, this::writeSSZ);
}
/**
* Write a list of addresses.
*
* @param elements the addresses to write as a list
* @throws IllegalArgumentException if any {@code address.size != 20}
*/
default void writeAddressList(Bytes... elements) {
SSZ.encodeAddressListTo(elements, this::writeSSZ);
}
/**
* Write a list of addresses.
*
* @param elements the addresses to write as a list
* @throws IllegalArgumentException if any {@code address.size != 20}
*/
default void writeAddressList(List<? extends Bytes> elements) {
SSZ.encodeAddressListTo(elements, this::writeSSZ);
}
/**
* Write a list of booleans.
*
* @param elements the booleans to write as a list
*/
default void writeBooleanList(boolean... elements) {
SSZ.encodeBooleanListTo(elements, this::writeSSZ);
}
/**
* Write a list of booleans.
*
* @param elements the booleans to write as a list
*/
default void writeBooleanList(List<Boolean> elements) {
SSZ.encodeBooleanListTo(elements, this::writeSSZ);
}
}