support network format of nbt
This commit is contained in:
@ -35,7 +35,14 @@ func (d *Decoder) Decode(v any) (string, error) {
|
|||||||
return "", errors.New("nbt: non-pointer passed to Decode")
|
return "", errors.New("nbt: non-pointer passed to Decode")
|
||||||
}
|
}
|
||||||
// start read NBT
|
// start read NBT
|
||||||
tagType, tagName, err := d.readTag()
|
var tagType byte
|
||||||
|
var tagName string
|
||||||
|
var err error
|
||||||
|
if d.networkFormat {
|
||||||
|
tagType, err = d.r.ReadByte()
|
||||||
|
} else {
|
||||||
|
tagType, tagName, err = d.readTag()
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return tagName, fmt.Errorf("nbt: %w", err)
|
return tagName, fmt.Errorf("nbt: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -22,13 +22,22 @@ func Marshal(v any) ([]byte, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Encoder struct {
|
type Encoder struct {
|
||||||
w io.Writer
|
w io.Writer
|
||||||
|
networkFormat bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewEncoder(w io.Writer) *Encoder {
|
func NewEncoder(w io.Writer) *Encoder {
|
||||||
return &Encoder{w: w}
|
return &Encoder{w: w}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NetworkFormat controls wether encoder encoding nbt in "network format".
|
||||||
|
// Means it haven't a tag name for root tag.
|
||||||
|
//
|
||||||
|
// It is disabled by default.
|
||||||
|
func (e *Encoder) NetworkFormat(enable bool) {
|
||||||
|
e.networkFormat = enable
|
||||||
|
}
|
||||||
|
|
||||||
// Encode encodes v into the writer inside Encoder with the root tag named tagName.
|
// Encode encodes v into the writer inside Encoder with the root tag named tagName.
|
||||||
// In most cases, the root tag typed TagCompound and the tag name is empty string,
|
// In most cases, the root tag typed TagCompound and the tag name is empty string,
|
||||||
// but any other type is allowed just because there is valid technically. Once if
|
// but any other type is allowed just because there is valid technically. Once if
|
||||||
@ -40,13 +49,13 @@ func NewEncoder(w io.Writer) *Encoder {
|
|||||||
// To force encode them as TagList, add a struct field tag.
|
// To force encode them as TagList, add a struct field tag.
|
||||||
func (e *Encoder) Encode(v any, tagName string) error {
|
func (e *Encoder) Encode(v any, tagName string) error {
|
||||||
t, val := getTagType(reflect.ValueOf(v))
|
t, val := getTagType(reflect.ValueOf(v))
|
||||||
return e.marshal(val, t, tagName)
|
if err := writeTag(e.w, t, tagName); err != nil {
|
||||||
}
|
|
||||||
|
|
||||||
func (e *Encoder) marshal(val reflect.Value, tagType byte, tagName string) error {
|
|
||||||
if err := writeTag(e.w, tagType, tagName); err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
return e.marshal(val, t)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *Encoder) marshal(val reflect.Value, tagType byte) error {
|
||||||
if val.CanInterface() {
|
if val.CanInterface() {
|
||||||
if encoder, ok := val.Interface().(Marshaler); ok {
|
if encoder, ok := val.Interface().(Marshaler); ok {
|
||||||
return encoder.MarshalNBT(e.w)
|
return encoder.MarshalNBT(e.w)
|
||||||
@ -214,7 +223,10 @@ func (e *Encoder) writeValue(val reflect.Value, tagType byte) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := e.marshal(v, typ, t.name); err != nil {
|
if err := writeTag(e.w, typ, t.name); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := e.marshal(v, typ); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -232,7 +244,10 @@ func (e *Encoder) writeValue(val reflect.Value, tagType byte) error {
|
|||||||
return fmt.Errorf("encoding %q error: unsupport type %v", tagName, tagValue.Type())
|
return fmt.Errorf("encoding %q error: unsupport type %v", tagName, tagValue.Type())
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := e.marshal(tagValue, tagType, tagName); err != nil {
|
if err := writeTag(e.w, tagType, tagName); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := e.marshal(tagValue, tagType); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,6 +30,7 @@ type DecoderReader = interface {
|
|||||||
type Decoder struct {
|
type Decoder struct {
|
||||||
r DecoderReader
|
r DecoderReader
|
||||||
disallowUnknownFields bool
|
disallowUnknownFields bool
|
||||||
|
networkFormat bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewDecoder(r io.Reader) *Decoder {
|
func NewDecoder(r io.Reader) *Decoder {
|
||||||
@ -48,6 +49,14 @@ func (d *Decoder) DisallowUnknownFields() {
|
|||||||
d.disallowUnknownFields = true
|
d.disallowUnknownFields = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NetworkFormat controls wether the decoder parsing nbt in "network format".
|
||||||
|
// Means it haven't a tag name for root tag.
|
||||||
|
//
|
||||||
|
// It is disabled by default.
|
||||||
|
func (d *Decoder) NetworkFormat(enable bool) {
|
||||||
|
d.networkFormat = enable
|
||||||
|
}
|
||||||
|
|
||||||
type reader struct {
|
type reader struct {
|
||||||
io.Reader
|
io.Reader
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user