nbt

package module
v0.0.4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 23, 2022 License: MIT Imports: 9 Imported by: 4

README

nbt

This module provides a simple NBT encoder and decoder. Compression is to be handled outside of this module.

Installation

Go get it with

go get github.com/tsatke/nbt

Documentation

Overview

Package nbt provides encoding and decoding functionality for minecraft's NBT format. This package implements support for both BigEndian and SmallEndian, i.e. for every binary.ByteOrder.

To marshal a struct, use the marshal function as follows.

type myStruct struct {
	X int `nbt:"x"`
}
...
_ = nbt.MarshalWriter(myWriter, binary.BigEndian, myStruct{5})

The above example will write the following as NBT.

TagCompound(''): 1 entries
{
	TagInt('x'): 5
}

You can also manually encode a tag, as follows.

enc := nbt.NewEncoder(myWriter, binary.BigEndian)
	_ = enc.WriteTag(nbt.NewCompoundTag("", []Tag{
		nbt.NewIntTag("x", 5),
	}),
)

This will result in the same output on the writer as in the example above. To read this written NBT tag, there are a few options, the easiest one being unmarshalling.

var v myStruct
_ = nbt.UnmarshalReader(myReader, binary.BigEndian, &v)
// v == 5

For (un-)marshalling, there is a struct tag, which supports naming, '-' (ignore while marshalling and unmarshalling) and 'omitempty', which ignores zero values while marshalling. For reading tags one by one from a reader, the process is similar to encoding.

dec := NewDecoder(myReader, binary.BigEndian)
tag, err := dec.ReadTag()
fmt.Println(nbt.ToString(tag))

This will print whatever one tag was on the reader. nbt.ToString will print an NBT tag in the above used representation.

Another way of decoding is using the nbt.Mapper. It is designed to unmarshal larger structures, for which unmarshalling is not flexible enough. It is more work than unmarshalling, but provides a clean and simple API for decoding. The idea is based on XPath, and a simple version of that is currently implemented.

TagCompound(''): 1 entries
{
	TagCompound('first'): 1 entries
	{
		TagInt('x'): 5
	}
}

Using this NBT structure, the following code will extract the value 5 and finally print it.

var myInt int
mapper := nbt.NewSimpleMapper(myTag)
_ = mapper.MapInt("first.x", &myInt)
fmt.Println(myInt)

This works for all NBT data types, including arrays and lists. For lists, the mapping function takes a function that is called before any mapping is done with the size of the list, which allows the user to preallocate a slice or similar. The following code decodes a list of int tags into an int array.

var myInts []int
_ = mapper.MapList("path.to.intlist", func(size int) {
	myInts = make([]int, size)
}, func(i int, mapper Mapper) error {
	return mapper.MapInt(&myInts[i])
})

Any error returned will contain a detailed message, what caused the error. Examples are, that the root tag or any tag in the query path except the last element is not a compound, the query path does not exist, or a type didn't match.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func MarshalWriter

func MarshalWriter(w io.Writer, order binary.ByteOrder, val interface{}) error

MarshalWriter marshals the given val onto the given writer as an NBT tag. The given byte order is respected.

func ToString

func ToString(tag Tag) string

ToString converts the given tag to a human readable string representation. This is expensive.

func UnmarshalReader

func UnmarshalReader(rd io.Reader, order binary.ByteOrder, v interface{}) error

UnmarshalReader unmarshals NBT data from the given reader into the given interface.

Types

type Byte

type Byte struct {
	Value int8
	// contains filtered or unexported fields
}

Byte is a tag for a byte

func NewByteTag

func NewByteTag(name string, val int8) *Byte

NewByteTag returns a new Byte tag

func (*Byte) ID

func (t *Byte) ID() ID

ID returns this tag's id.

func (Byte) Name

func (t Byte) Name() string

func (*Byte) ReadFrom

func (t *Byte) ReadFrom(reader io.Reader, bo binary.ByteOrder) error

ReadFrom reads a byte from the given reader.

func (Byte) SetName

func (t Byte) SetName(name string)

func (*Byte) WriteTo

func (t *Byte) WriteTo(writer io.Writer, bo binary.ByteOrder) error

WriteTo writes this byte to the given writer.

type ByteArray

type ByteArray struct {
	Value []int8
	// contains filtered or unexported fields
}

ByteArray is a tag for []byte

func NewByteArrayTag

func NewByteArrayTag(name string, val []int8) *ByteArray

NewByteArrayTag returns a new ByteArray tag

func (*ByteArray) ID

func (t *ByteArray) ID() ID

ID returns tag id

func (ByteArray) Name

func (t ByteArray) Name() string

func (*ByteArray) ReadFrom

func (t *ByteArray) ReadFrom(reader io.Reader, order binary.ByteOrder) error

ReadFrom reads a byte array from the reader.

func (ByteArray) SetName

func (t ByteArray) SetName(name string)

func (*ByteArray) WriteTo

func (t *ByteArray) WriteTo(writer io.Writer, order binary.ByteOrder) error

WriteTo writes this byte array to the given writer.

type Compound

type Compound struct {
	Value map[string]Tag
	// contains filtered or unexported fields
}

Compound is a list of named tags.

func NewCompoundTag

func NewCompoundTag(name string, val []Tag) *Compound

NewCompoundTag returns a new Compound tag.

func (*Compound) Get

func (t *Compound) Get(name string) (Tag, bool)

Get returns the named tag with the given name in this compound, or false if no such tag exists.

func (*Compound) ID

func (t *Compound) ID() ID

ID returns this tag's id.

func (Compound) Name

func (t Compound) Name() string

func (*Compound) Put

func (t *Compound) Put(tag Tag)

Put puts the given named tag into this compound.

func (*Compound) ReadFrom

func (t *Compound) ReadFrom(reader io.Reader, order binary.ByteOrder) error

ReadFrom reads a compound tag from the given reader.

func (Compound) SetName

func (t Compound) SetName(name string)

func (*Compound) WriteTo

func (t *Compound) WriteTo(writer io.Writer, order binary.ByteOrder) error

WriteTo writes this tag to the given writer.

type Decoder

type Decoder interface {
	ReadTag() (Tag, error)
}

Decoder describes a component that is capable of reading NBT tags from some source.

func NewDecoder

func NewDecoder(source io.Reader, byteOrder binary.ByteOrder) Decoder

NewDecoder creates a new Decoder that will decode from the given reader and respect the given byte order. The byte order has to be compliant with the byte order of the NBT data in the source.

type Double

type Double struct {
	Value float64
	// contains filtered or unexported fields
}

Double is a double tag, which contains a float64 value.

func NewDoubleTag

func NewDoubleTag(name string, val float64) *Double

NewDoubleTag returns a new Double tag.

func (*Double) ID

func (t *Double) ID() ID

ID returns this tag's id.

func (Double) Name

func (t Double) Name() string

func (*Double) ReadFrom

func (t *Double) ReadFrom(reader io.Reader, order binary.ByteOrder) error

ReadFrom reads a double from the given reader.

func (Double) SetName

func (t Double) SetName(name string)

func (*Double) WriteTo

func (t *Double) WriteTo(writer io.Writer, order binary.ByteOrder) error

WriteTo writes this double to the writer.

type Encoder

type Encoder interface {
	WriteTag(Tag) error
}

Encoder describes a component that is capable of writing NBT tags to some sink.

func NewEncoder

func NewEncoder(target io.Writer, byteOrder binary.ByteOrder) Encoder

NewEncoder creates a new Encoder that will encode NBT tags with the given byte order and write them on the given writer.

type End

type End struct {
	// contains filtered or unexported fields
}

End is an end tag. This has no data.

func NewEndTag

func NewEndTag() *End

NewEndTag creates a new End tag.

func (*End) ID

func (t *End) ID() ID

ID returns tag id

func (End) Name

func (t End) Name() string

func (*End) ReadFrom

func (t *End) ReadFrom(_ io.Reader, _ binary.ByteOrder) error

ReadFrom is an effective noop.

func (End) SetName

func (t End) SetName(name string)

func (*End) WriteTo

func (t *End) WriteTo(w io.Writer, order binary.ByteOrder) error

WriteTo writes this tag onto the given writer, i.e. writes the end tag id byte.

type Float

type Float struct {
	Value float32
	// contains filtered or unexported fields
}

Float is a float tag.

func NewFloatTag

func NewFloatTag(name string, val float32) *Float

NewFloatTag returns a new Float tag.

func (*Float) ID

func (t *Float) ID() ID

ID returns this tag's id.

func (Float) Name

func (t Float) Name() string

func (*Float) ReadFrom

func (t *Float) ReadFrom(reader io.Reader, order binary.ByteOrder) error

ReadFrom reads a float from the given reader.

func (Float) SetName

func (t Float) SetName(name string)

func (*Float) WriteTo

func (t *Float) WriteTo(writer io.Writer, order binary.ByteOrder) error

WriteTo writes a float to the given writer.

type ID

type ID byte

ID is a tag id, such as IDTagEnd or IDTagLongArray.

const (
	// IDTagEnd indicates the end for a compound tag.
	IDTagEnd ID = iota // TagEnd

	// IDTagByte is a signed byte (-128 to 127).
	IDTagByte // TagByte

	// IDTagShort is a signed short (-32768 to 32767).
	IDTagShort // TagShort

	// IDTagInt is a signed int (-2147483648 to 2147483647).
	IDTagInt // TagInt

	// IDTagLong is a signed long (-9223372036854775808 to 9223372036854775807).
	IDTagLong // TagLong

	// IDTagFloat is a signed float32 (IEEE-754).
	IDTagFloat // TagFloat

	// IDTagDouble is a signed float64 (IEEE-754).
	IDTagDouble // TagDouble

	// IDTagByteArray is a array of signed bytes.
	IDTagByteArray // TagByteArray

	// IDTagString is a UTF-8 string.
	IDTagString // TagString

	// IDTagList is a list of nameless tags, all tags are of the same type.
	IDTagList // TagList

	// IDTagCompound is a list of named tags.
	IDTagCompound // TagCompound

	// IDTagIntArray is a array for int(4bytes).
	IDTagIntArray // TagIntArray

	// IDTagLongArray is a array for long(8bytes).
	IDTagLongArray // TagLongArray

	// NumIDTags is the amount of ID tags that are known.
	NumIDTags // amount of ID tags
)

func (ID) String

func (i ID) String() string

type Identifier

type Identifier interface {
	ID() ID
}

Identifier is something with an ID.

type Int

type Int struct {
	Value int32
	// contains filtered or unexported fields
}

Int is an int tag.

func NewIntTag

func NewIntTag(name string, val int32) *Int

NewIntTag returns a new Int tag.

func (*Int) ID

func (t *Int) ID() ID

ID returns this tag's id.

func (Int) Name

func (t Int) Name() string

func (*Int) ReadFrom

func (t *Int) ReadFrom(reader io.Reader, order binary.ByteOrder) error

ReadFrom reads an int from the given reader.

func (Int) SetName

func (t Int) SetName(name string)

func (*Int) WriteTo

func (t *Int) WriteTo(writer io.Writer, order binary.ByteOrder) error

WriteTo writes this int to the given writer.

type IntArray

type IntArray struct {
	Value []int32
	// contains filtered or unexported fields
}

IntArray is a tag for a int array

func NewIntArrayTag

func NewIntArrayTag(name string, val []int32) *IntArray

NewIntArrayTag returns a new IntArray tag

func (*IntArray) ID

func (t *IntArray) ID() ID

ID returns tag id

func (IntArray) Name

func (t IntArray) Name() string

func (*IntArray) ReadFrom

func (t *IntArray) ReadFrom(reader io.Reader, order binary.ByteOrder) error

ReadFrom reads an int array from the given reader.

func (IntArray) SetName

func (t IntArray) SetName(name string)

func (*IntArray) WriteTo

func (t *IntArray) WriteTo(writer io.Writer, order binary.ByteOrder) error

WriteTo writes this int array to the given writer.

type List

type List struct {
	Value []Tag

	ListType ID
	// contains filtered or unexported fields
}

List is a list of unnamed tags.

func NewListTag

func NewListTag(name string, val []Tag, typ ID) *List

NewListTag returns a new List tag.

func (*List) ID

func (t *List) ID() ID

ID returns this tag's id.

func (List) Name

func (t List) Name() string

func (*List) ReadFrom

func (t *List) ReadFrom(reader io.Reader, order binary.ByteOrder) error

ReadFrom reads a list from the given reader.

func (List) SetName

func (t List) SetName(name string)

func (*List) WriteTo

func (t *List) WriteTo(writer io.Writer, order binary.ByteOrder) error

WriteTo writes this tag to the given writer.

type Long

type Long struct {
	Value int64
	// contains filtered or unexported fields
}

Long is a tag for an int64

func NewLongTag

func NewLongTag(name string, val int64) *Long

NewLongTag returns a new Long tag

func (*Long) ID

func (t *Long) ID() ID

ID returns this tag's id.

func (Long) Name

func (t Long) Name() string

func (*Long) ReadFrom

func (t *Long) ReadFrom(reader io.Reader, order binary.ByteOrder) error

ReadFrom reads a long from the given reader.

func (Long) SetName

func (t Long) SetName(name string)

func (*Long) WriteTo

func (t *Long) WriteTo(writer io.Writer, order binary.ByteOrder) error

WriteTo writes this long to the given reader.

type LongArray

type LongArray struct {
	Value []int64
	// contains filtered or unexported fields
}

LongArray is a tag for a array of longs

func NewLongArrayTag

func NewLongArrayTag(name string, val []int64) *LongArray

NewLongArrayTag returns a new LongArray tag

func (*LongArray) ID

func (t *LongArray) ID() ID

ID returns the tag id.

func (LongArray) Name

func (t LongArray) Name() string

func (*LongArray) ReadFrom

func (t *LongArray) ReadFrom(reader io.Reader, order binary.ByteOrder) error

ReadFrom reads a long array from the given reader.

func (LongArray) SetName

func (t LongArray) SetName(name string)

func (*LongArray) WriteTo

func (t *LongArray) WriteTo(writer io.Writer, order binary.ByteOrder) error

WriteTo writes this long array to the given writer.

type Mapper

type Mapper interface {
	// Query will execute the given query string on the tag in this mapper.
	// The interpretation of the query is implementation specific.
	Query(string) (Tag, error)
	// MapByte will interpret the tag under the given query path as byte and
	// store it under the given *int8, or return an error if the tag under the
	// path is not a byte tag.
	MapByte(string, *int8) error
	// MapShort will interpret the tag under the given query path as short and
	// store it under the given *int16, or return an error if the tag under the
	// path is not a short tag.
	MapShort(string, *int16) error
	// MapInt will interpret the tag under the given query path as int and
	// store it under the given *int, or return an error if the tag under the
	// path is not an int tag.
	MapInt(string, *int) error
	// MapInt32 works just as MapInt, but converts the given int to an int32.
	// This can be useful if you have a lot of ints (which are 4-byte in NBT),
	// but want to save the extra 4 bytes if you're on a 64bit arch.
	MapInt32(string, *int32) error
	// MapLong will interpret the tag under the given query path as int64 and
	// store it under the given *int64, or return an error if the tag under the
	// path is not a long tag.
	MapLong(string, *int64) error
	// MapFloat will interpret the tag under the given query path as float32 and
	// store it under the given *float32, or return an error if the tag under the
	// path is not a long tag.
	MapFloat(string, *float32) error
	// MapDouble will interpret the tag under the given query path as float64 and
	// store it under the given *float64, or return an error if the tag under the
	// path is not a long tag.
	MapDouble(string, *float64) error
	// MapString will interpret the tag under the given query path as string and
	// store it under the given *string, or return an error if the tag under the
	// path is not a string tag.
	MapString(string, *string) error
	// MapByteArray will interpret the tag under the given query path as bytearray and
	// store it under the given *[]int8, or return an error if the tag under the
	// path is not a bytearray tag.
	MapByteArray(string, *[]int8) error
	// MapIntArray will interpret the tag under the given query path as intarray and
	// store it under the given *[]int, or return an error if the tag under the
	// path is not a intarray tag.
	MapIntArray(string, *[]int) error
	// MapInt32Array is the array equivalent to MapInt32.
	MapInt32Array(string, *[]int32) error
	// MapLongArray will interpret the tag under the given query path as longarray and
	// store it under the given *[]int64, or return an error if the tag under the
	// path is not a longarray tag.
	MapLongArray(string, *[]int64) error
	// MapList will interpret the tag under the given query path as list. It will return
	// an error if that tag is not a list (also returns an error if the path points to
	// an array). Before calling the mapping function, it will call the initializer function
	// once with the size of the list, allowing for preallocation. After that, it will call
	// the mapping function for every element in the list, with the mapper containing only
	// the list element at index i. i is the zero-based index of an element in the list.
	MapList(query string, initializer func(int), mapping func(i int, mapper Mapper) error) error
	// MapCustom is equivalent to calling Query, and then calling the given function with the tag
	// udner the query, or return an error if any.
	MapCustom(string, func(Tag) error) error
}

Mapper describes a component that can be used to support more complex mappings of known structures than marshalling could support.

func NewSimpleMapper

func NewSimpleMapper(source Tag) Mapper

NewSimpleMapper creates a new mapper on the given source tag. It doesn't do any kind of caching or other performance improvements.

type Namer

type Namer interface {
	Name() string
	SetName(string)
}

Namer is something that has a name. The name is mutable.

type ReaderFrom

type ReaderFrom interface {
	ReadFrom(io.Reader, binary.ByteOrder) error
}

ReaderFrom is something that can read from a reader respecting a byte order.

type Short

type Short struct {
	Value int16
	// contains filtered or unexported fields
}

Short is a tag for a short

func NewShortTag

func NewShortTag(name string, val int16) *Short

NewShortTag returns a new Short tag

func (*Short) ID

func (t *Short) ID() ID

ID returns this tag's id.

func (Short) Name

func (t Short) Name() string

func (*Short) ReadFrom

func (t *Short) ReadFrom(reader io.Reader, order binary.ByteOrder) error

ReadFrom reads a short from the given reader.

func (Short) SetName

func (t Short) SetName(name string)

func (*Short) WriteTo

func (t *Short) WriteTo(writer io.Writer, order binary.ByteOrder) error

WriteTo writes this short to the given writer.

type String

type String struct {
	Value string
	// contains filtered or unexported fields
}

String is a tag for string

func NewStringTag

func NewStringTag(name string, val string) *String

NewStringTag returns a new String tag

func (*String) ID

func (t *String) ID() ID

ID returns this tag's id.

func (String) Name

func (t String) Name() string

func (*String) ReadFrom

func (t *String) ReadFrom(reader io.Reader, order binary.ByteOrder) error

ReadFrom reads a string from the given reader.

func (String) SetName

func (t String) SetName(name string)

func (*String) WriteTo

func (t *String) WriteTo(writer io.Writer, order binary.ByteOrder) error

WriteTo writes this string to the given reader.

type Tag

type Tag interface {
	Identifier
	Namer
	ReaderFrom
	WriterTo
}

Tag is an NBT tag.

type WriterTo

type WriterTo interface {
	WriteTo(io.Writer, binary.ByteOrder) error
}

WriterTo is something that can write to a writer respecting a byte order.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL