use netty buffer since java's ByteBuffer can't grow on its own

This commit is contained in:
mykola2312 2024-10-17 07:41:05 +03:00
parent 9345b50377
commit 679670b468
3 changed files with 38 additions and 14 deletions

View file

@ -40,6 +40,11 @@
<artifactId>junit-jupiter-params</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-buffer</artifactId>
<version>4.1.114.Final</version>
</dependency>
</dependencies>
<build>

View file

@ -1,6 +1,6 @@
package com.mykola2312.retracker.bencode;
import java.nio.ByteBuffer;
import static io.netty.buffer.Unpooled.buffer;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
@ -10,6 +10,8 @@ import com.mykola2312.retracker.bencode.error.BDecodeParseError;
import com.mykola2312.retracker.bencode.error.BErrorNoRoot;
import com.mykola2312.retracker.bencode.error.BErrorValueCast;
import io.netty.buffer.ByteBuf;
public class BTree {
private BValue root = null;
@ -17,6 +19,12 @@ public class BTree {
return root;
}
@SuppressWarnings("unchecked")
public <T extends BValue> T setRoot(T root) {
this.root = root;
return (T)this.root;
}
private static final byte BE_INTEGER = (byte)'i';
private static final byte BE_LIST = (byte)'l';
private static final byte BE_DICT = (byte)'d';
@ -143,7 +151,7 @@ public class BTree {
}
class BEncoder {
private ByteBuffer buffer = ByteBuffer.allocate(0);
private ByteBuf buffer = buffer();
private byte[] encodeInt(int value) {
return Integer.toString(value).getBytes(StandardCharsets.UTF_8);
@ -156,39 +164,39 @@ public class BTree {
public void encode(BValue node) {
switch (node.getType()) {
case INTEGER:
buffer.put(BE_INTEGER);
buffer.put(encodeLong(((BInteger)node).get()));
buffer.put(BE_END);
buffer.writeByte(BE_INTEGER);
buffer.writeBytes(encodeLong(((BInteger)node).get()));
buffer.writeByte(BE_END);
break;
case LIST:
buffer.put(BE_LIST);
buffer.writeByte(BE_LIST);
for (BValue item : node) {
encode(item);
}
buffer.put(BE_END);
buffer.writeByte(BE_END);
break;
case DICT:
buffer.put(BE_DICT);
buffer.writeByte(BE_DICT);
for (BValue key : node) {
encode(key);
encode(key.getChild());
}
buffer.put(BE_END);
buffer.writeByte(BE_END);
break;
case STRING:
byte[] bytes = ((BString)node).get();
buffer.put(encodeInt(bytes.length));
buffer.put(BE_STRING_SEP);
buffer.put(bytes);
buffer.writeBytes(encodeInt(bytes.length));
buffer.writeByte(BE_STRING_SEP);
buffer.writeBytes(bytes);
break;
}
}
public byte[] get() {
int length = buffer.position();
int length = buffer.writerIndex();
byte[] out = new byte[length];
buffer.get(out, 0, length);
buffer.getBytes(0, out);
return out;
}
}

View file

@ -1,5 +1,6 @@
package com.mykola2312.retracker.bencode;
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
@ -140,6 +141,16 @@ public class BTreeTest {
});
}
@Test
public void testEncode() {
assertDoesNotThrow(() -> {
BTree tree = new BTree();
tree.setRoot(new BInteger(1));
assertArrayEquals("i1e".getBytes(), tree.encode());
});
}
@Test
public void testTorrentFile() throws BError, IOException {
final byte[] data = Files.readAllBytes(Path.of("test", "test.torrent"));