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")
|
||||
}
|
||||
// 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 {
|
||||
return tagName, fmt.Errorf("nbt: %w", err)
|
||||
}
|
||||
|
@ -22,13 +22,22 @@ func Marshal(v any) ([]byte, error) {
|
||||
}
|
||||
|
||||
type Encoder struct {
|
||||
w io.Writer
|
||||
w io.Writer
|
||||
networkFormat bool
|
||||
}
|
||||
|
||||
func NewEncoder(w io.Writer) *Encoder {
|
||||
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.
|
||||
// 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
|
||||
@ -40,13 +49,13 @@ func NewEncoder(w io.Writer) *Encoder {
|
||||
// To force encode them as TagList, add a struct field tag.
|
||||
func (e *Encoder) Encode(v any, tagName string) error {
|
||||
t, val := getTagType(reflect.ValueOf(v))
|
||||
return e.marshal(val, t, tagName)
|
||||
}
|
||||
|
||||
func (e *Encoder) marshal(val reflect.Value, tagType byte, tagName string) error {
|
||||
if err := writeTag(e.w, tagType, tagName); err != nil {
|
||||
if err := writeTag(e.w, t, tagName); err != nil {
|
||||
return err
|
||||
}
|
||||
return e.marshal(val, t)
|
||||
}
|
||||
|
||||
func (e *Encoder) marshal(val reflect.Value, tagType byte) error {
|
||||
if val.CanInterface() {
|
||||
if encoder, ok := val.Interface().(Marshaler); ok {
|
||||
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
|
||||
}
|
||||
}
|
||||
@ -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())
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
@ -30,6 +30,7 @@ type DecoderReader = interface {
|
||||
type Decoder struct {
|
||||
r DecoderReader
|
||||
disallowUnknownFields bool
|
||||
networkFormat bool
|
||||
}
|
||||
|
||||
func NewDecoder(r io.Reader) *Decoder {
|
||||
@ -48,6 +49,14 @@ func (d *Decoder) DisallowUnknownFields() {
|
||||
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 {
|
||||
io.Reader
|
||||
}
|
||||
|
Reference in New Issue
Block a user