-
Notifications
You must be signed in to change notification settings - Fork 267
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge remote-tracking branch 'origin/ARROWHEAD-6.3.1-rc' into arrowhe…
…ad631-master-merge
- Loading branch information
Showing
66 changed files
with
1,282 additions
and
138 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
49 changes: 49 additions & 0 deletions
49
rskj-core/src/main/java/co/rsk/core/types/bytes/ByteSequence.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
/* | ||
* This file is part of RskJ | ||
* Copyright (C) 2024 RSK Labs Ltd. | ||
* | ||
* This program 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. | ||
* | ||
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>. | ||
*/ | ||
|
||
package co.rsk.core.types.bytes; | ||
|
||
/** | ||
* {@link ByteSequence} is the most basic interface that represents read-only sequence of <code>byte</code> values. | ||
*/ | ||
public interface ByteSequence { | ||
|
||
/** | ||
* Returns the length of this byte sequence. | ||
* | ||
* @return the length of the sequence of bytes represented by this | ||
* object. | ||
*/ | ||
int length(); | ||
|
||
/** | ||
* Returns the {@code byte} value at the | ||
* specified index. An index ranges from {@code 0} to | ||
* {@code length() - 1}. The first {@code byte} value of the sequence | ||
* is at index {@code 0}, the next at index {@code 1}, | ||
* and so on, as for array indexing. | ||
* | ||
* @param index the index of the {@code byte} value. | ||
* @return the {@code byte} value at the specified index of this array. | ||
* The first {@code byte} value is at index {@code 0}. | ||
* @exception IndexOutOfBoundsException if the {@code index} | ||
* argument is negative or not less than the length of this | ||
* array. | ||
*/ | ||
byte byteAt(int index); | ||
} |
167 changes: 167 additions & 0 deletions
167
rskj-core/src/main/java/co/rsk/core/types/bytes/Bytes.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,167 @@ | ||
/* | ||
* This file is part of RskJ | ||
* Copyright (C) 2024 RSK Labs Ltd. | ||
* | ||
* This program 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. | ||
* | ||
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>. | ||
*/ | ||
|
||
package co.rsk.core.types.bytes; | ||
|
||
import org.ethereum.util.ByteUtil; | ||
import org.ethereum.util.FastByteComparisons; | ||
|
||
import javax.annotation.Nonnull; | ||
import javax.annotation.Nullable; | ||
import java.util.Arrays; | ||
import java.util.Objects; | ||
|
||
/** | ||
* A {@link Bytes} is a readable sequence of <code>byte</code> values. This | ||
* interface provides uniform, read-only access to many different kinds of | ||
* <code>byte</code> sequences. | ||
* | ||
* <p> This interface does not refine the general contracts of the {@link | ||
* java.lang.Object#equals(java.lang.Object) equals} and {@link | ||
* java.lang.Object#hashCode() hashCode} methods. The result of comparing two | ||
* objects that implement <tt>Bytes</tt> is therefore, in general, | ||
* undefined. Each object may be implemented by a different class, and there | ||
* is no guarantee that each class will be capable of testing its instances | ||
* for equality with those of the other. It is therefore inappropriate to use | ||
* arbitrary <tt>Bytes</tt> instances as elements in a set or as keys in | ||
* a map. </p> | ||
*/ | ||
public interface Bytes extends BytesSlice { | ||
|
||
/** | ||
* Returns an instance of the {@link Bytes} interface, which represents {@code unsafeByteArray}. | ||
* | ||
* @return the instance of the {@link Bytes} interface that wraps a provided byte array. | ||
*/ | ||
static Bytes of(@Nullable byte[] unsafeByteArray) { | ||
if (unsafeByteArray == null) { | ||
return null; | ||
} | ||
return new BytesImpl(unsafeByteArray); | ||
} | ||
|
||
/** | ||
* A helper method for printing "nullable" byte arrays. | ||
* | ||
* @return {@code valueIfNull}, if {@code byteArray} is {@code null}. Otherwise - {@code Bytes.of(byteArray).toPrintableString()}. | ||
*/ | ||
static String toPrintableString(@Nullable byte[] byteArray, @Nullable String valueIfNull) { | ||
if (byteArray == null) { | ||
return valueIfNull; | ||
} | ||
return of(byteArray).toPrintableString(); | ||
} | ||
|
||
/** | ||
* A helper method for printing "nullable" byte arrays. | ||
* | ||
* @return {@code "<null>"}, if {@code byteArray} is {@code null}. Otherwise - {@code Bytes.of(byteArray).toPrintableString()}. | ||
*/ | ||
@Nonnull | ||
static String toPrintableString(@Nullable byte[] byteArray) { | ||
return toPrintableString(byteArray, "<null>"); | ||
} | ||
|
||
/** | ||
* A helper method for extracting "unsafe" underlying byte array from the {@code bytes} instance. | ||
* | ||
* @return {@code null}, if {@code bytes} is {@code null}. Otherwise - {@code bytes.asUnsafeByteArray()}. | ||
*/ | ||
@Nullable | ||
static byte[] asUnsafeByteArray(@Nullable Bytes bytes) { | ||
if (bytes == null) { | ||
return null; | ||
} | ||
return bytes.asUnsafeByteArray(); | ||
} | ||
|
||
static boolean equalBytes(Bytes b1, Bytes b2) { | ||
if (b1 == null && b2 == null) { | ||
return true; | ||
} | ||
if (b1 == null || b2 == null) { | ||
return false; | ||
} | ||
return FastByteComparisons.equalBytes(b1.asUnsafeByteArray(), b2.asUnsafeByteArray()); | ||
} | ||
|
||
/** | ||
* Returns an underlying byte array, which is backing this instance. Any mutations that are being done with the bytes | ||
* of returned array will have direct impact on the byte array that is being wrapped by this instance. | ||
* | ||
* @return the wrapped by this instance byte array. | ||
*/ | ||
byte[] asUnsafeByteArray(); | ||
} | ||
|
||
/** | ||
* The {@link BytesImpl} class represents a read-only sequence of <code>byte</code> values. | ||
* <p> | ||
* Instances of the {@link BytesImpl} class are constant; their values cannot be changed after they | ||
* are created via the methods that this class provides. But a {@code byteArray} instance itself provided in the constructor | ||
* is mutable and can be modified outside the class. It's generally a bad idea to mutate a byte array that's being wrapped | ||
* by an instance of this class, as the idea is to make a byte sequence immutable, which is not the case with the Java | ||
* built-in {@code byte[]} type. | ||
* <p> | ||
* Because {@link BytesImpl} objects are immutable they can be safely used by multiple Java threads, if the wrapped array | ||
* is not being referenced and modified outside. | ||
*/ | ||
class BytesImpl implements Bytes { | ||
|
||
private final byte[] byteArray; | ||
|
||
BytesImpl(@Nonnull byte[] unsafeByteArray) { | ||
this.byteArray = Objects.requireNonNull(unsafeByteArray); | ||
} | ||
|
||
@Override | ||
public int length() { | ||
return byteArray.length; | ||
} | ||
|
||
@Override | ||
public byte byteAt(int index) { | ||
return byteArray[index]; | ||
} | ||
|
||
@Override | ||
public byte[] copyArrayOfRange(int from, int to) { | ||
return Arrays.copyOfRange(byteArray, from, to); | ||
} | ||
|
||
@Override | ||
public String toHexString() { | ||
return ByteUtil.toHexString(byteArray); | ||
} | ||
|
||
@Override | ||
public String toHexString(int off, int length) { | ||
return ByteUtil.toHexString(byteArray, off, length); | ||
} | ||
|
||
@Nonnull | ||
@Override | ||
public byte[] asUnsafeByteArray() { | ||
return byteArray; | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
return toPrintableString(); | ||
} | ||
} |
131 changes: 131 additions & 0 deletions
131
rskj-core/src/main/java/co/rsk/core/types/bytes/BytesSlice.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
/* | ||
* This file is part of RskJ | ||
* Copyright (C) 2024 RSK Labs Ltd. | ||
* | ||
* This program 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. | ||
* | ||
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>. | ||
*/ | ||
|
||
package co.rsk.core.types.bytes; | ||
|
||
/** | ||
* A {@link BytesSlice} is a subsequence of bytes backed by another broader byte sequence. | ||
*/ | ||
public interface BytesSlice extends HexPrintableBytes { | ||
|
||
/** | ||
* Copies the specified range of the specified array into a new array. | ||
* The initial index of the range (<tt>from</tt>) must lie between zero | ||
* and <tt>original.length</tt>, inclusive. The value at | ||
* <tt>original[from]</tt> is placed into the initial element of the copy | ||
* (unless <tt>from == original.length</tt> or <tt>from == to</tt>). | ||
* Values from subsequent elements in the original array are placed into | ||
* subsequent elements in the copy. The final index of the range | ||
* (<tt>to</tt>), which must be greater than or equal to <tt>from</tt>, | ||
* may be greater than <tt>original.length</tt>, in which case | ||
* <tt>(byte)0</tt> is placed in all elements of the copy whose index is | ||
* greater than or equal to <tt>original.length - from</tt>. The length | ||
* of the returned array will be <tt>to - from</tt>. | ||
* | ||
* @param from the initial index of the range to be copied, inclusive | ||
* @param to the final index of the range to be copied, exclusive. | ||
* (This index may lie outside the array.) | ||
* @return a new array containing the specified range from the original array, | ||
* truncated or padded with zeros to obtain the required length | ||
* @throws ArrayIndexOutOfBoundsException if {@code from < 0} | ||
* or {@code from > original.length} | ||
* @throws IllegalArgumentException if <tt>from > to</tt> | ||
* @throws NullPointerException if <tt>original</tt> is null | ||
*/ | ||
byte[] copyArrayOfRange(int from, int to); | ||
|
||
default byte[] copyArray() { | ||
return copyArrayOfRange(0, length()); | ||
} | ||
|
||
default Bytes copyBytesOfRange(int from, int to) { | ||
return Bytes.of(copyArrayOfRange(from, to)); | ||
} | ||
|
||
default Bytes copyBytes() { | ||
return Bytes.of(copyArrayOfRange(0, length())); | ||
} | ||
|
||
default BytesSlice slice(int from, int to) { | ||
return new BytesSliceImpl(this, from, to); | ||
} | ||
} | ||
|
||
class BytesSliceImpl implements BytesSlice { | ||
|
||
private final BytesSlice originBytes; | ||
|
||
private final int from; | ||
private final int to; | ||
|
||
BytesSliceImpl(BytesSlice originBytes, int from, int to) { | ||
this.originBytes = originBytes; | ||
|
||
if (from < 0) { | ||
throw new IndexOutOfBoundsException(from + " < " + 0); | ||
} | ||
if (from > to) { | ||
throw new IndexOutOfBoundsException(from + " > " + to); | ||
} | ||
if (to > originBytes.length()) { | ||
throw new IndexOutOfBoundsException(to + " > " + "length"); | ||
} | ||
|
||
this.from = from; | ||
this.to = to; | ||
} | ||
|
||
@Override | ||
public int length() { | ||
return to - from; | ||
} | ||
|
||
@Override | ||
public byte byteAt(int index) { | ||
if (index < 0 || index >= length()) { | ||
throw new IndexOutOfBoundsException("invalid index: " + index); | ||
} | ||
return originBytes.byteAt(from + index); | ||
} | ||
|
||
@Override | ||
public byte[] copyArrayOfRange(int from, int to) { | ||
if (from < 0 || from > to || to > length()) { | ||
throw new IndexOutOfBoundsException("invalid 'from' and/or 'to': [" + from + ";" + to + ")"); | ||
} | ||
return originBytes.copyArrayOfRange(this.from + from, this.from + to); | ||
} | ||
|
||
@Override | ||
public String toHexString(int off, int length) { | ||
if (off < 0 || length < 0 || off + length > length()) { | ||
throw new IndexOutOfBoundsException("invalid 'off' and/or 'length': " + off + "; " + length); | ||
} | ||
return originBytes.toHexString(from + off, length); | ||
} | ||
|
||
@Override | ||
public String toHexString() { | ||
return toHexString(0, length()); | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
return toPrintableString(); | ||
} | ||
} |
Oops, something went wrong.