Skip to content

Commit 66fe3ed

Browse files
committed
feat: compression, file utility functions and iterable ListTag
1 parent eae4bfd commit 66fe3ed

5 files changed

Lines changed: 110 additions & 26 deletions

File tree

build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ plugins {
44
}
55

66
group "dev.dewy"
7-
version "1.0.0"
7+
version "1.0.1"
88

99
task sourcesJar(type: Jar, dependsOn: classes) {
1010
classifier = "sources"

src/main/java/dev/dewy/nbt/tags/CompoundTag.java

Lines changed: 53 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,15 @@
22

33
import dev.dewy.nbt.Tag;
44
import dev.dewy.nbt.TagType;
5+
import dev.dewy.nbt.utils.CompressionType;
56
import dev.dewy.nbt.utils.Pair;
67
import dev.dewy.nbt.utils.ReadFunction;
78

8-
import java.io.DataInput;
9-
import java.io.DataOutput;
10-
import java.io.IOException;
9+
import java.io.*;
1110
import java.util.HashMap;
1211
import java.util.Map;
12+
import java.util.zip.GZIPInputStream;
13+
import java.util.zip.GZIPOutputStream;
1314

1415
/**
1516
* Implementation of the compound tag. A map in its raw form.
@@ -114,6 +115,24 @@ public void writeRoot(DataOutput output, String rootName) throws IOException {
114115
write(output);
115116
}
116117

118+
/**
119+
* Write the compound tag to a {@link File} with a name of its own, using a given compression scheme.
120+
*
121+
* @param rootName The root compound's name.
122+
* @param file The file to be written to.
123+
* @param compression The compression to be applied.
124+
* @throws IOException If any IO error occurs.
125+
*/
126+
public void writeRootToFile(String rootName, File file, CompressionType compression) throws IOException {
127+
DataOutputStream out = compression == CompressionType.GZIP
128+
? new DataOutputStream(new GZIPOutputStream(new BufferedOutputStream(new FileOutputStream(file))))
129+
: new DataOutputStream(new BufferedOutputStream(new FileOutputStream(file)));
130+
131+
writeRoot(out, rootName);
132+
133+
out.close();
134+
}
135+
117136
@Override
118137
public ReadFunction<DataInput, CompoundTag> getReader() {
119138
return read;
@@ -260,4 +279,35 @@ public static Pair<String, CompoundTag> readNamedRoot(DataInput input) throws IO
260279

261280
return new Pair<>(input.readUTF(), read.read(input));
262281
}
282+
283+
/**
284+
* Reads a root compound (full NBT structure) from a {@link File} with a given kind of compression.
285+
*
286+
* @param file The file to read from.
287+
* @param compression The compression of the file.
288+
* @throws IOException if any kind of IO error occurs.
289+
* @return The root compound read from the file.
290+
*/
291+
public static CompoundTag readRootFromFile(File file, CompressionType compression) throws IOException {
292+
return readNamedRootFromFile(file, compression).getRight();
293+
}
294+
295+
/**
296+
* Reads a root compound (full NBT structure) from a {@link File} with a given kind of compression, with its name attached.
297+
*
298+
* @param file The file to read from.
299+
* @param compression The compression of the file.
300+
* @throws IOException if any kind of IO error occurs.
301+
* @return A {@link Pair} with the name of the root tag on the left and the root tag object on the right.
302+
*/
303+
public static Pair<String, CompoundTag> readNamedRootFromFile(File file, CompressionType compression) throws IOException {
304+
DataInputStream in = compression == CompressionType.GZIP
305+
? new DataInputStream(new GZIPInputStream(new BufferedInputStream(new FileInputStream(file))))
306+
: new DataInputStream(new BufferedInputStream(new FileInputStream(file)));
307+
308+
Pair<String, CompoundTag> result = readNamedRoot(in);
309+
310+
in.close();
311+
return result;
312+
}
263313
}

src/main/java/dev/dewy/nbt/tags/ListTag.java

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,17 @@
88
import java.io.DataOutput;
99
import java.io.IOException;
1010
import java.util.ArrayList;
11+
import java.util.Iterator;
1112
import java.util.List;
13+
import java.util.Spliterator;
14+
import java.util.function.Consumer;
1215

1316
/**
1417
* Implementation of the list tag.
1518
*
1619
* @author dewy
1720
*/
18-
public class ListTag<T extends Tag> implements Tag {
21+
public class ListTag<T extends Tag> implements Tag, Iterable<T> {
1922
private List<T> value;
2023

2124
/**
@@ -199,6 +202,20 @@ public int indexOf(T tag) {
199202
return this.value.indexOf(tag);
200203
}
201204

205+
@Override
206+
public Iterator<T> iterator() {
207+
return this.value.iterator();
208+
}
209+
210+
@Override
211+
public void forEach(Consumer<? super T> action) {
212+
this.value.forEach(action);
213+
}
214+
215+
@Override
216+
public Spliterator<T> spliterator() {
217+
return this.value.spliterator();
218+
}
202219

203220
@Override
204221
public boolean equals(Object o) {
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package dev.dewy.nbt.utils;
2+
3+
/**
4+
* Defines the types of compression to be used for NBT data.
5+
*
6+
* @author dewy
7+
*/
8+
public enum CompressionType {
9+
/**
10+
* No compression.
11+
*/
12+
NONE,
13+
14+
/**
15+
* GZIP compression (adaptive Lempel-Ziv coding, deflate mode).
16+
*/
17+
GZIP
18+
}

src/test/java/dev/dewy/nbt/test/NBTTest.java

Lines changed: 20 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import dev.dewy.nbt.tags.StringTag;
66
import dev.dewy.nbt.tags.array.ByteArrayTag;
77
import dev.dewy.nbt.tags.number.ShortTag;
8-
import dev.dewy.nbt.utils.Pair;
8+
import dev.dewy.nbt.utils.CompressionType;
99

1010
import java.io.*;
1111
import java.util.Arrays;
@@ -40,37 +40,36 @@ private static void write() {
4040

4141
// Writing root compound to sample.nbt
4242

43-
try (DataOutputStream out = new DataOutputStream(new BufferedOutputStream(new FileOutputStream("sample.nbt")))) {
44-
root.writeRoot(out, "sample");
43+
try {
44+
root.writeRootToFile("sample", new File("sample.nbt"), CompressionType.GZIP);
4545
} catch (IOException e) {
4646
e.printStackTrace();
4747
}
4848
}
4949

5050
private static void read() {
51-
try (DataInputStream in = new DataInputStream(new BufferedInputStream(new FileInputStream("sample.nbt")))) {
52-
// Reading the root tag from sample.nbt
51+
CompoundTag root;
5352

54-
CompoundTag root = CompoundTag.readRoot(in);
55-
56-
// Decompiling root tag contents.
53+
try {
54+
root = CompoundTag.readRootFromFile(new File("sample.nbt"), CompressionType.GZIP);
55+
} catch (IOException e) {
56+
e.printStackTrace();
57+
return;
58+
}
5759

58-
ShortTag number = (ShortTag) root.get("number");
59-
ByteArrayTag array = (ByteArrayTag) root.get("array");
60-
StringTag string = (StringTag) root.get("string");
61-
ListTag<StringTag> cheeses = (ListTag<StringTag>) root.get("cheeses");
60+
ShortTag number = (ShortTag) root.get("number");
61+
ByteArrayTag array = (ByteArrayTag) root.get("array");
62+
StringTag string = (StringTag) root.get("string");
63+
ListTag<StringTag> cheeses = (ListTag<StringTag>) root.get("cheeses");
6264

63-
// Printing them out.
65+
// Printing them out.
6466

65-
System.out.println(number.getValue());
66-
System.out.println(Arrays.toString(array.getValue()));
67-
System.out.println(string.getValue());
67+
System.out.println(number.getValue());
68+
System.out.println(Arrays.toString(array.getValue()));
69+
System.out.println(string.getValue());
6870

69-
for (StringTag s : cheeses.getValue()) {
70-
System.out.println(s.getValue());
71-
}
72-
} catch (IOException e) {
73-
e.printStackTrace();
71+
for (StringTag s : cheeses) {
72+
System.out.println(s.getValue());
7473
}
7574
}
7675
}

0 commit comments

Comments
 (0)