ForeverZer0 / SharpNBT

A pure CLS-compliant C# implementation of the Named Binary Tag (NBT) format specification commonly used with Minecraft applications, allowing easy reading/writing streams and serialization to other formats.
MIT License
25 stars 9 forks source link

Split TagReader and TagWriter into separate sub-classes #22

Open ForeverZer0 opened 10 months ago

ForeverZer0 commented 10 months ago

Problem

There are currently three different ways that NBT can be serialized:

Format Endianness VarInt
Java Big None
Bedrock (file) Little None
Bedorck (network) Little Yes. Sometimes they are ZigZag encoded using the ProtoBuf style, other times not.

I will reserve disparaging Microsoft for needlessly complicating one of the most simple serialization formats in existence. It is par for the course, and not even unexpected anymore. I would be more surprised if they didn't mess it up.

Regardless, the TagReader and TagWriter class accounts for all scenarios using the format options passed to its constructor. While this works in practice, it means most methods have to do additional checks to see what the appropriate way to read the data is.

Proposal

Make TagReader and TagWriter abstract, with a factory method to create an instance. Internally these different ways of reading/writing can be split into separate classes that do not require any runtime checks.

Something akin to this psuedo-code:

public static TagReader Create(Stream stream, Format format)
{
    return format switch
    {
        Format.Java => new JavaReader(stream),
        Format.BedrockFile => new BedrockFileReader(stream),
        Format.BedrockNetwork => new BedrockNetworkReader(stream),
        _ => throw new ArgumentOutOfRangeException()
    };
}

The actual implementations can be completely transparent and need not even be part of the public API.