Skip to content

Commit fc01177

Browse files
committed
Refactor NBTReader and NBTWriter to use MinecraftEdition for byte order handling
1 parent 3be0047 commit fc01177

6 files changed

Lines changed: 74 additions & 33 deletions

File tree

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*
2+
* Copyright 2026 Glavo
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.glavo.nbt;
17+
18+
import java.nio.ByteOrder;
19+
20+
/// Represents the edition of Minecraft that the NBT data is used for.
21+
public enum MinecraftEdition {
22+
/// Stores the NBT data in big-endian byte order, and encodes strings in modified UTF-8.
23+
JAVA_EDITION(ByteOrder.BIG_ENDIAN),
24+
25+
/// Stores the NBT data in little-endian byte order, and encodes strings in UTF-8.
26+
BEDROCK_EDITION(ByteOrder.LITTLE_ENDIAN);
27+
28+
private final ByteOrder byteOrder;
29+
30+
MinecraftEdition(ByteOrder byteOrder) {
31+
this.byteOrder = byteOrder;
32+
}
33+
34+
public ByteOrder byteOrder() {
35+
return this.byteOrder;
36+
}
37+
}

src/main/java/org/glavo/nbt/internal/input/NBTReader.java

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616
package org.glavo.nbt.internal.input;
1717

18+
import org.glavo.nbt.MinecraftEdition;
1819
import org.glavo.nbt.internal.IOUtils;
1920
import org.glavo.nbt.internal.StringCache;
2021
import org.jetbrains.annotations.Nullable;
@@ -35,19 +36,19 @@ public final class NBTReader implements Closeable {
3536

3637
private final InputSource source;
3738
private final InputBuffer buffer;
38-
private final ByteOrder byteOrder;
39+
private final MinecraftEdition edition;
3940

4041
/// Used for reading UTF-8 strings
4142
private @Nullable StringBuilder charsBuffer;
4243

43-
public NBTReader(InputSource source, ByteOrder byteOrder) {
44+
public NBTReader(InputSource source, MinecraftEdition edition) {
4445
this.source = source;
45-
this.buffer = InputBuffer.allocate(IOUtils.DEFAULT_BUFFER_SIZE, source.supportDirectBuffer(), byteOrder);
46-
this.byteOrder = byteOrder;
46+
this.buffer = InputBuffer.allocate(IOUtils.DEFAULT_BUFFER_SIZE, source.supportDirectBuffer(), edition.byteOrder());
47+
this.edition = edition;
4748
}
4849

49-
public ByteOrder byteOrder() {
50-
return this.byteOrder;
50+
public MinecraftEdition getEdition() {
51+
return edition;
5152
}
5253

5354
@Override
@@ -175,7 +176,7 @@ public String readString() throws IOException {
175176
bytes.position(limit);
176177

177178
// For Minecraft Bedrock Edition, the string is encoded in standard UTF-8
178-
if (byteOrder == ByteOrder.LITTLE_ENDIAN) {
179+
if (edition == MinecraftEdition.BEDROCK_EDITION) {
179180
return getUTF8(bytes, offset, len);
180181
}
181182

src/main/java/org/glavo/nbt/internal/output/NBTWriter.java

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616
package org.glavo.nbt.internal.output;
1717

18+
import org.glavo.nbt.MinecraftEdition;
1819
import org.glavo.nbt.internal.IOUtils;
1920
import org.glavo.nbt.tag.*;
2021

@@ -28,13 +29,13 @@
2829
public final class NBTWriter implements Closeable, Flushable {
2930

3031
private final OutputStream outputStream;
31-
private final ByteOrder byteOrder;
3232
private ByteBuffer buffer;
33+
private final MinecraftEdition edition;
3334

34-
public NBTWriter(OutputStream outputStream, ByteOrder byteOrder) {
35+
public NBTWriter(OutputStream outputStream, MinecraftEdition edition) {
3536
this.outputStream = outputStream;
36-
this.byteOrder = byteOrder;
37-
this.buffer = ByteBuffer.allocate(8192).order(this.byteOrder);
37+
this.buffer = ByteBuffer.allocate(8192).order(edition.byteOrder());
38+
this.edition = edition;
3839
}
3940

4041
@Override
@@ -116,7 +117,7 @@ private void flushBuffer(int required) throws IOException {
116117
if (buffer.capacity() >= required) {
117118
buffer.clear();
118119
} else {
119-
buffer = ByteBuffer.allocate(Math.max(required, buffer.capacity() * 2)).order(byteOrder);
120+
buffer = ByteBuffer.allocate(Math.max(required, buffer.capacity() * 2)).order(buffer.order());
120121
}
121122
}
122123
}
@@ -243,7 +244,7 @@ private void writeString(String value) throws IOException {
243244
return;
244245
}
245246

246-
if (byteOrder == ByteOrder.LITTLE_ENDIAN) {
247+
if (edition == MinecraftEdition.BEDROCK_EDITION) {
247248
// Need Optimization
248249
byte[] bytes = value.getBytes(StandardCharsets.UTF_8);
249250
if (value.length() > 65535) {

src/main/java/org/glavo/nbt/tag/Tag.java

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616
package org.glavo.nbt.tag;
1717

18+
import org.glavo.nbt.MinecraftEdition;
1819
import org.glavo.nbt.NBTElement;
1920
import org.glavo.nbt.internal.input.InputSource;
2021
import org.glavo.nbt.internal.input.NBTReader;
@@ -51,11 +52,11 @@ public sealed abstract class Tag implements NBTElement
5152
}
5253

5354
public static Tag readTag(InputStream inputStream) throws IOException {
54-
return readTag(inputStream, ByteOrder.BIG_ENDIAN);
55+
return readTag(inputStream, MinecraftEdition.JAVA_EDITION);
5556
}
5657

57-
public static Tag readTag(InputStream inputStream, ByteOrder byteOrder) throws IOException {
58-
try (var reader = new NBTReader(new InputSource.OfInputStream(inputStream, false), byteOrder)) {
58+
public static Tag readTag(InputStream inputStream, MinecraftEdition edition) throws IOException {
59+
try (var reader = new NBTReader(new InputSource.OfInputStream(inputStream, false), edition)) {
5960
Tag tag = readTag(reader);
6061
if (tag == null) {
6162
throw new IOException("No tag found");
@@ -65,11 +66,11 @@ public static Tag readTag(InputStream inputStream, ByteOrder byteOrder) throws I
6566
}
6667

6768
public static CompoundTag<?> readCompoundTag(InputStream inputStream) throws IOException {
68-
return readCompoundTag(inputStream, ByteOrder.BIG_ENDIAN);
69+
return readCompoundTag(inputStream, MinecraftEdition.JAVA_EDITION);
6970
}
7071

71-
public static CompoundTag<?> readCompoundTag(InputStream inputStream, ByteOrder byteOrder) throws IOException {
72-
Tag rootTag = readTag(inputStream, byteOrder);
72+
public static CompoundTag<?> readCompoundTag(InputStream inputStream, MinecraftEdition edition) throws IOException {
73+
Tag rootTag = readTag(inputStream, edition);
7374
if (rootTag instanceof CompoundTag<?> compoundTag) {
7475
return compoundTag;
7576
} else {
@@ -124,11 +125,11 @@ public int getIndex() {
124125
}
125126

126127
public void writeTo(OutputStream outputStream) throws IOException {
127-
writeTo(outputStream, ByteOrder.BIG_ENDIAN);
128+
writeTo(outputStream, MinecraftEdition.JAVA_EDITION);
128129
}
129130

130-
public void writeTo(OutputStream outputStream, ByteOrder byteOrder) throws IOException {
131-
try (var writer = new NBTWriter(outputStream, byteOrder)) {
131+
public void writeTo(OutputStream outputStream, MinecraftEdition edition) throws IOException {
132+
try (var writer = new NBTWriter(outputStream, edition)) {
132133
writer.writeTag(this);
133134
}
134135
}

src/test/java/org/glavo/nbt/io/NBTReaderTest.java

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
package org.glavo.nbt.io;
1717

1818
import com.github.steveice10.opennbt.NBTIO;
19+
import org.glavo.nbt.MinecraftEdition;
1920
import org.glavo.nbt.tag.*;
2021
import org.junit.jupiter.api.Test;
2122

@@ -30,19 +31,19 @@ public final class NBTReaderTest {
3031

3132
private static Tag convert(
3233
com.github.steveice10.opennbt.tag.builtin.Tag tag,
33-
ByteOrder byteOrder)
34+
MinecraftEdition edition)
3435
throws IOException {
3536
var buffer = new ByteArrayOutputStream();
36-
NBTIO.writeTag(buffer, tag, byteOrder == ByteOrder.LITTLE_ENDIAN);
37+
NBTIO.writeTag(buffer, tag, edition == MinecraftEdition.BEDROCK_EDITION);
3738

38-
return Tag.readTag(new ByteArrayInputStream(buffer.toByteArray()), byteOrder);
39+
return Tag.readTag(new ByteArrayInputStream(buffer.toByteArray()), edition);
3940
}
4041

4142
private static void assertTagEquals(
4243
Tag expected,
4344
com.github.steveice10.opennbt.tag.builtin.Tag actual) throws IOException {
44-
assertEquals(expected, convert(actual, ByteOrder.BIG_ENDIAN));
45-
assertEquals(expected, convert(actual, ByteOrder.LITTLE_ENDIAN));
45+
assertEquals(expected, convert(actual, MinecraftEdition.JAVA_EDITION));
46+
assertEquals(expected, convert(actual, MinecraftEdition.BEDROCK_EDITION));
4647
}
4748

4849
@Test

src/test/java/org/glavo/nbt/io/NBTWriterTest.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,33 +16,33 @@
1616
package org.glavo.nbt.io;
1717

1818
import com.github.steveice10.opennbt.NBTIO;
19+
import org.glavo.nbt.MinecraftEdition;
1920
import org.glavo.nbt.tag.*;
2021
import org.junit.jupiter.api.Test;
2122

2223
import java.io.ByteArrayInputStream;
2324
import java.io.ByteArrayOutputStream;
2425
import java.io.IOException;
25-
import java.nio.ByteOrder;
2626

2727
import static org.junit.jupiter.api.Assertions.assertEquals;
2828

2929
public final class NBTWriterTest {
3030
private static com.github.steveice10.opennbt.tag.builtin.Tag convert(
3131
Tag tag,
32-
ByteOrder byteOrder)
32+
MinecraftEdition edition)
3333
throws IOException {
3434

3535
var buffer = new ByteArrayOutputStream();
36-
tag.writeTo(buffer, byteOrder);
36+
tag.writeTo(buffer, edition);
3737

38-
return NBTIO.readTag(new ByteArrayInputStream(buffer.toByteArray()), byteOrder == ByteOrder.LITTLE_ENDIAN);
38+
return NBTIO.readTag(new ByteArrayInputStream(buffer.toByteArray()), edition == MinecraftEdition.BEDROCK_EDITION);
3939
}
4040

4141
private static void assertTagEquals(
4242
com.github.steveice10.opennbt.tag.builtin.Tag expected,
4343
Tag actual) throws IOException {
44-
assertEquals(expected, convert(actual, ByteOrder.BIG_ENDIAN));
45-
assertEquals(expected, convert(actual, ByteOrder.LITTLE_ENDIAN));
44+
assertEquals(expected, convert(actual, MinecraftEdition.JAVA_EDITION));
45+
assertEquals(expected, convert(actual, MinecraftEdition.BEDROCK_EDITION));
4646
}
4747

4848
@Test

0 commit comments

Comments
 (0)