2025-11-24 22:52:51 +03:00

228 lines
8.2 KiB
Java

/*
* Decompiled with CFR 0.152.
*
* Could not load the following classes:
* com.google.common.annotations.VisibleForTesting
* org.jspecify.annotations.Nullable
*/
package net.minecraft.nbt;
import com.google.common.annotations.VisibleForTesting;
import java.io.BufferedOutputStream;
import java.io.DataInput;
import java.io.DataInputStream;
import java.io.DataOutput;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UTFDataFormatException;
import java.nio.file.Files;
import java.nio.file.LinkOption;
import java.nio.file.OpenOption;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
import net.minecraft.CrashReport;
import net.minecraft.CrashReportCategory;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.EndTag;
import net.minecraft.nbt.NbtAccounter;
import net.minecraft.nbt.ReportedNbtException;
import net.minecraft.nbt.StreamTagVisitor;
import net.minecraft.nbt.StringTag;
import net.minecraft.nbt.Tag;
import net.minecraft.nbt.TagType;
import net.minecraft.nbt.TagTypes;
import net.minecraft.util.DelegateDataOutput;
import net.minecraft.util.FastBufferedInputStream;
import net.minecraft.util.Util;
import org.jspecify.annotations.Nullable;
public class NbtIo {
private static final OpenOption[] SYNC_OUTPUT_OPTIONS = new OpenOption[]{StandardOpenOption.SYNC, StandardOpenOption.WRITE, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING};
public static CompoundTag readCompressed(Path file, NbtAccounter accounter) throws IOException {
try (InputStream rawInput = Files.newInputStream(file, new OpenOption[0]);){
CompoundTag compoundTag;
try (FastBufferedInputStream input = new FastBufferedInputStream(rawInput);){
compoundTag = NbtIo.readCompressed(input, accounter);
}
return compoundTag;
}
}
private static DataInputStream createDecompressorStream(InputStream in) throws IOException {
return new DataInputStream(new FastBufferedInputStream(new GZIPInputStream(in)));
}
private static DataOutputStream createCompressorStream(OutputStream out) throws IOException {
return new DataOutputStream(new BufferedOutputStream(new GZIPOutputStream(out)));
}
public static CompoundTag readCompressed(InputStream in, NbtAccounter accounter) throws IOException {
try (DataInputStream dis = NbtIo.createDecompressorStream(in);){
CompoundTag compoundTag = NbtIo.read(dis, accounter);
return compoundTag;
}
}
public static void parseCompressed(Path file, StreamTagVisitor output, NbtAccounter accounter) throws IOException {
try (InputStream rawInput = Files.newInputStream(file, new OpenOption[0]);
FastBufferedInputStream input = new FastBufferedInputStream(rawInput);){
NbtIo.parseCompressed(input, output, accounter);
}
}
public static void parseCompressed(InputStream in, StreamTagVisitor output, NbtAccounter accounter) throws IOException {
try (DataInputStream dis = NbtIo.createDecompressorStream(in);){
NbtIo.parse(dis, output, accounter);
}
}
public static void writeCompressed(CompoundTag tag, Path file) throws IOException {
try (OutputStream out = Files.newOutputStream(file, SYNC_OUTPUT_OPTIONS);
BufferedOutputStream bufferedOut = new BufferedOutputStream(out);){
NbtIo.writeCompressed(tag, bufferedOut);
}
}
public static void writeCompressed(CompoundTag tag, OutputStream out) throws IOException {
try (DataOutputStream dos = NbtIo.createCompressorStream(out);){
NbtIo.write(tag, dos);
}
}
public static void write(CompoundTag tag, Path file) throws IOException {
try (OutputStream out = Files.newOutputStream(file, SYNC_OUTPUT_OPTIONS);
BufferedOutputStream bufferedOut = new BufferedOutputStream(out);
DataOutputStream dos = new DataOutputStream(bufferedOut);){
NbtIo.write(tag, dos);
}
}
public static @Nullable CompoundTag read(Path file) throws IOException {
if (!Files.exists(file, new LinkOption[0])) {
return null;
}
try (InputStream in = Files.newInputStream(file, new OpenOption[0]);){
CompoundTag compoundTag;
try (DataInputStream dis = new DataInputStream(in);){
compoundTag = NbtIo.read(dis, NbtAccounter.unlimitedHeap());
}
return compoundTag;
}
}
public static CompoundTag read(DataInput input) throws IOException {
return NbtIo.read(input, NbtAccounter.unlimitedHeap());
}
public static CompoundTag read(DataInput input, NbtAccounter accounter) throws IOException {
Tag tag = NbtIo.readUnnamedTag(input, accounter);
if (tag instanceof CompoundTag) {
return (CompoundTag)tag;
}
throw new IOException("Root tag must be a named compound tag");
}
public static void write(CompoundTag tag, DataOutput output) throws IOException {
NbtIo.writeUnnamedTagWithFallback(tag, output);
}
public static void parse(DataInput input, StreamTagVisitor output, NbtAccounter accounter) throws IOException {
TagType<?> type = TagTypes.getType(input.readByte());
if (type == EndTag.TYPE) {
if (output.visitRootEntry(EndTag.TYPE) == StreamTagVisitor.ValueResult.CONTINUE) {
output.visitEnd();
}
return;
}
switch (output.visitRootEntry(type)) {
case HALT: {
break;
}
case BREAK: {
StringTag.skipString(input);
type.skip(input, accounter);
break;
}
case CONTINUE: {
StringTag.skipString(input);
type.parse(input, output, accounter);
}
}
}
public static Tag readAnyTag(DataInput input, NbtAccounter accounter) throws IOException {
byte type = input.readByte();
if (type == 0) {
return EndTag.INSTANCE;
}
return NbtIo.readTagSafe(input, accounter, type);
}
public static void writeAnyTag(Tag tag, DataOutput output) throws IOException {
output.writeByte(tag.getId());
if (tag.getId() == 0) {
return;
}
tag.write(output);
}
public static void writeUnnamedTag(Tag tag, DataOutput output) throws IOException {
output.writeByte(tag.getId());
if (tag.getId() == 0) {
return;
}
output.writeUTF("");
tag.write(output);
}
public static void writeUnnamedTagWithFallback(Tag tag, DataOutput output) throws IOException {
NbtIo.writeUnnamedTag(tag, new StringFallbackDataOutput(output));
}
@VisibleForTesting
public static Tag readUnnamedTag(DataInput input, NbtAccounter accounter) throws IOException {
byte type = input.readByte();
if (type == 0) {
return EndTag.INSTANCE;
}
StringTag.skipString(input);
return NbtIo.readTagSafe(input, accounter, type);
}
private static Tag readTagSafe(DataInput input, NbtAccounter accounter, byte type) {
try {
return TagTypes.getType(type).load(input, accounter);
}
catch (IOException e) {
CrashReport report = CrashReport.forThrowable(e, "Loading NBT data");
CrashReportCategory category = report.addCategory("NBT Tag");
category.setDetail("Tag type", type);
throw new ReportedNbtException(report);
}
}
public static class StringFallbackDataOutput
extends DelegateDataOutput {
public StringFallbackDataOutput(DataOutput parent) {
super(parent);
}
@Override
public void writeUTF(String s) throws IOException {
try {
super.writeUTF(s);
}
catch (UTFDataFormatException exception) {
Util.logAndPauseIfInIde("Failed to write NBT String", exception);
super.writeUTF("");
}
}
}
}