Skip to content

Commit 286c7e6

Browse files
committed
Add v2 version for rlp project to accomodate new bytes API
Signed-off-by: Luis Pinto <[email protected]>
1 parent d5a3698 commit 286c7e6

File tree

12 files changed

+2288
-0
lines changed

12 files changed

+2288
-0
lines changed
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
// Copyright The Tuweni Authors
2+
// SPDX-License-Identifier: Apache-2.0
3+
package org.apache.tuweni.v2.rlp;
4+
5+
import static java.util.Objects.requireNonNull;
6+
import static org.apache.tuweni.v2.rlp.RLP.encodeByteArray;
7+
import static org.apache.tuweni.v2.rlp.RLP.encodeLength;
8+
import static org.apache.tuweni.v2.rlp.RLP.encodeNumber;
9+
10+
import org.apache.tuweni.v2.bytes.Bytes;
11+
12+
import java.util.ArrayDeque;
13+
import java.util.Deque;
14+
import java.util.function.Consumer;
15+
16+
final class AccumulatingRLPWriter implements RLPWriter {
17+
18+
private static final int COMBINE_THRESHOLD = 32;
19+
20+
private ArrayDeque<byte[]> values = new ArrayDeque<>();
21+
22+
Deque<byte[]> values() {
23+
return values;
24+
}
25+
26+
@Override
27+
public void writeRLP(Bytes value) {
28+
requireNonNull(value);
29+
appendBytes(value.toArrayUnsafe());
30+
}
31+
32+
@Override
33+
public void writeValue(Bytes value) {
34+
requireNonNull(value);
35+
writeByteArray(value.toArrayUnsafe());
36+
}
37+
38+
@Override
39+
public void writeByteArray(byte[] value) {
40+
encodeByteArray(value, this::appendBytes);
41+
}
42+
43+
@Override
44+
public void writeByte(byte value) {
45+
encodeByteArray(new byte[] {value}, this::appendBytes);
46+
}
47+
48+
@Override
49+
public void writeLong(long value) {
50+
appendBytes(encodeNumber(value));
51+
}
52+
53+
@Override
54+
public void writeList(Consumer<RLPWriter> fn) {
55+
requireNonNull(fn);
56+
AccumulatingRLPWriter listWriter = new AccumulatingRLPWriter();
57+
fn.accept(listWriter);
58+
int totalSize = 0;
59+
for (byte[] value : listWriter.values) {
60+
try {
61+
totalSize = Math.addExact(totalSize, value.length);
62+
} catch (ArithmeticException e) {
63+
throw new IllegalArgumentException(
64+
"Combined length of values is too long (> Integer.MAX_VALUE)");
65+
}
66+
}
67+
appendBytes(encodeLength(totalSize, 0xc0));
68+
this.values.addAll(listWriter.values);
69+
}
70+
71+
private void appendBytes(byte[] bytes) {
72+
if (bytes.length < COMBINE_THRESHOLD) {
73+
if (!values.isEmpty()) {
74+
byte[] last = values.getLast();
75+
if (last.length <= (COMBINE_THRESHOLD - bytes.length)) {
76+
byte[] combined = new byte[last.length + bytes.length];
77+
System.arraycopy(last, 0, combined, 0, last.length);
78+
System.arraycopy(bytes, 0, combined, last.length, bytes.length);
79+
values.pollLast();
80+
values.add(combined);
81+
return;
82+
}
83+
}
84+
}
85+
values.add(bytes);
86+
}
87+
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
// Copyright The Tuweni Authors
2+
// SPDX-License-Identifier: Apache-2.0
3+
package org.apache.tuweni.v2.rlp;
4+
5+
import static java.util.Objects.requireNonNull;
6+
import static org.apache.tuweni.v2.rlp.RLP.encodeByteArray;
7+
import static org.apache.tuweni.v2.rlp.RLP.encodeLength;
8+
import static org.apache.tuweni.v2.rlp.RLP.encodeNumber;
9+
10+
import org.apache.tuweni.v2.bytes.Bytes;
11+
12+
import java.nio.BufferOverflowException;
13+
import java.nio.ByteBuffer;
14+
import java.util.Deque;
15+
import java.util.function.Consumer;
16+
17+
final class ByteBufferRLPWriter implements RLPWriter {
18+
19+
private ByteBuffer buffer;
20+
21+
ByteBufferRLPWriter(ByteBuffer buffer) {
22+
this.buffer = buffer;
23+
}
24+
25+
@Override
26+
public void writeRLP(Bytes value) {
27+
buffer.put(value.toArrayUnsafe());
28+
}
29+
30+
@Override
31+
public void writeValue(Bytes value) {
32+
encodeByteArray(value.toArrayUnsafe(), buffer::put);
33+
}
34+
35+
@Override
36+
public void writeByteArray(byte[] value) {
37+
encodeByteArray(value, buffer::put);
38+
}
39+
40+
@Override
41+
public void writeByte(byte value) {
42+
encodeByteArray(new byte[] {value}, buffer::put);
43+
}
44+
45+
@Override
46+
public void writeLong(long value) {
47+
buffer.put(encodeNumber(value));
48+
}
49+
50+
@Override
51+
public void writeList(Consumer<RLPWriter> fn) {
52+
requireNonNull(fn);
53+
AccumulatingRLPWriter listWriter = new AccumulatingRLPWriter();
54+
fn.accept(listWriter);
55+
writeEncodedValuesAsList(listWriter.values());
56+
}
57+
58+
private void writeEncodedValuesAsList(Deque<byte[]> values) {
59+
int totalSize = 0;
60+
for (byte[] value : values) {
61+
try {
62+
totalSize = Math.addExact(totalSize, value.length);
63+
} catch (ArithmeticException e) {
64+
throw new BufferOverflowException();
65+
}
66+
}
67+
buffer.put(encodeLength(totalSize, 0xc0));
68+
values.forEach(bytes -> buffer.put(bytes));
69+
}
70+
}

0 commit comments

Comments
 (0)