mirror of
https://github.com/bitcoinj/bitcoinj.git
synced 2025-01-18 21:32:35 +01:00
Buffers: add write helpers writeLengthPrefixedBytes()
and writeLengthPrefixedString()
Includes a test.
This commit is contained in:
parent
fbc5185b5a
commit
06070eeaf2
@ -18,6 +18,7 @@ package org.bitcoinj.base.internal;
|
||||
|
||||
import org.bitcoinj.base.VarInt;
|
||||
|
||||
import java.nio.BufferOverflowException;
|
||||
import java.nio.BufferUnderflowException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
@ -59,6 +60,18 @@ public class Buffers {
|
||||
return readBytes(buf, length);
|
||||
}
|
||||
|
||||
/**
|
||||
* First write the length of the byte array as a {@link VarInt}. Then write the array contents.
|
||||
*
|
||||
* @param buf buffer to write to
|
||||
* @param bytes bytes to write
|
||||
* @return the buffer
|
||||
* @throws BufferOverflowException if the value doesn't fit the remaining buffer
|
||||
*/
|
||||
public static ByteBuffer writeLengthPrefixedBytes(ByteBuffer buf, byte[] bytes) throws BufferOverflowException {
|
||||
return buf.put(VarInt.of(bytes.length).serialize()).put(bytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* First read a {@link VarInt} from the buffer and use it to determine the number of bytes to read. Then read
|
||||
* that many bytes and interpret it as an UTF-8 encoded string to be returned. This construct is frequently used
|
||||
@ -72,6 +85,20 @@ public class Buffers {
|
||||
return new String(readLengthPrefixedBytes(buf), StandardCharsets.UTF_8);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode a given string using UTF-8. Then write the lnegth of the encoded bytes as a {@link VarInt}. Then write
|
||||
* the bytes themselves.
|
||||
*
|
||||
* @param buf buffer to write to
|
||||
* @param str string to write
|
||||
* @return the buffer
|
||||
* @throws BufferOverflowException if the value doesn't fit the remaining buffer
|
||||
*/
|
||||
public static ByteBuffer writeLengthPrefixedString(ByteBuffer buf, String str) throws BufferOverflowException {
|
||||
byte[] bytes = str.getBytes(StandardCharsets.UTF_8);
|
||||
return writeLengthPrefixedBytes(buf, bytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Advance buffer position by a given number of bytes.
|
||||
*
|
||||
|
58
core/src/test/java/org/bitcoinj/core/BuffersTest.java
Normal file
58
core/src/test/java/org/bitcoinj/core/BuffersTest.java
Normal file
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright by the original 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.bitcoinj.core;
|
||||
|
||||
import junitparams.JUnitParamsRunner;
|
||||
import junitparams.Parameters;
|
||||
import org.bitcoinj.base.VarInt;
|
||||
import org.bitcoinj.base.internal.Buffers;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import java.nio.Buffer;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Iterator;
|
||||
import java.util.Random;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static org.junit.Assert.assertArrayEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
|
||||
@RunWith(JUnitParamsRunner.class)
|
||||
public class BuffersTest {
|
||||
@Test
|
||||
@Parameters(method = "randomBytes")
|
||||
public void readAndWrite(byte[] bytes) {
|
||||
ByteBuffer buf = ByteBuffer.allocate(VarInt.sizeOf(bytes.length) + bytes.length);
|
||||
Buffers.writeLengthPrefixedBytes(buf, bytes);
|
||||
assertFalse(buf.hasRemaining());
|
||||
((Buffer) buf).rewind();
|
||||
byte[] copy = Buffers.readLengthPrefixedBytes(buf);
|
||||
assertFalse(buf.hasRemaining());
|
||||
assertArrayEquals(bytes, copy);
|
||||
}
|
||||
|
||||
private Iterator<byte[]> randomBytes() {
|
||||
Random random = new Random();
|
||||
return Stream.generate(() -> {
|
||||
int length = random.nextInt(10);
|
||||
byte[] bytes = new byte[length];
|
||||
random.nextBytes(bytes);
|
||||
return bytes;
|
||||
}).limit(10).iterator();
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user