NBT Unmarshaler support

This commit is contained in:
Tnze
2019-07-31 21:00:30 +08:00
parent 4bd9c44f30
commit e385cb77cb
6 changed files with 29 additions and 50 deletions

9
nbt/interface.go Normal file
View File

@ -0,0 +1,9 @@
package nbt
type Unmarshaler interface {
Unmarshal(tagType byte, tagName string, r DecoderReader) error
}
//type Marshaler interface{
// Marshal()
//}

1
nbt/interface_test.go Normal file
View File

@ -0,0 +1 @@
package nbt

View File

@ -1,35 +0,0 @@
package nbt
import (
"bytes"
"reflect"
"testing"
)
func TestMarshal(t *testing.T) {
var (
want = []byte{
0x0A, 0, 0,
0x08, 0, 4, 0x4e, 0x61, 0x6d, 0x65, 0, 4, 0x54, 0x6e, 0x7a, 0x65,
0x01, 0x00, 0x08, 0x42, 0x79, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0xFF,
0,
}
value struct {
Name string
ByteTest byte
}
)
value.Name = "Tnze"
value.ByteTest = 0xFF
var buf bytes.Buffer
if err := Marshal(&buf, value); err != nil {
t.Fatal(err)
}
gets := buf.Bytes()
if !reflect.DeepEqual(gets, want) {
t.Errorf("marshal wrong: get [% 02x], want [% 02x]", gets, want)
}
}

View File

@ -24,19 +24,17 @@ const (
TagLongArray
)
type Decoder struct {
r interface {
type DecoderReader = interface {
io.ByteScanner
io.Reader
}
}
type Decoder struct {
r DecoderReader
}
func NewDecoder(r io.Reader) *Decoder {
d := new(Decoder)
if br, ok := r.(interface {
io.ByteScanner
io.Reader
}); ok {
if br, ok := r.(DecoderReader); ok {
d.r = br
} else {
d.r = bufio.NewReader(r)

View File

@ -53,7 +53,7 @@ func TestUnmarshal_simple(t *testing.T) {
t.Errorf("Unmarshal NBT fail: get %q, want %q", value.Name, "Bananrama")
}
//test skip
//test rawRead
var empty struct{}
if err := Unmarshal(data, &empty); err != nil {
t.Fatal(err)
@ -189,7 +189,7 @@ func TestUnmarshal_bitTest(t *testing.T) {
t.Errorf("parse fail, expect %v, get %v", want, value)
}
//test skip
//test rawRead
var empty struct{}
r, err = gzip.NewReader(bytes.NewReader(data))
if err != nil {

View File

@ -63,6 +63,12 @@ func (d *Decoder) checkCompressed() (compress string, err error) {
var ErrEND = errors.New("unexpected TAG_End")
func (d *Decoder) unmarshal(val reflect.Value, tagType byte, tagName string) error {
if val.CanInterface() {
if i, ok := val.Interface().(Unmarshaler); ok {
return i.Unmarshal(tagType, tagName, d.r)
}
}
switch tagType {
default:
return fmt.Errorf("unknown Tag 0x%02x", tagType)
@ -311,7 +317,7 @@ func (d *Decoder) unmarshal(val reflect.Value, tagType byte, tagName string) err
return err
}
} else {
if err := d.skip(tt); err != nil {
if err := d.rawRead(tt); err != nil {
return err
}
}
@ -344,10 +350,10 @@ func (d *Decoder) unmarshal(val reflect.Value, tagType byte, tagName string) err
return nil
}
func (d *Decoder) skip(tagType byte) error {
func (d *Decoder) rawRead(tagType byte) error {
switch tagType {
default:
return fmt.Errorf("unknown to skip 0x%02x", tagType)
return fmt.Errorf("unknown to read 0x%02x", tagType)
case TagByte:
_, err := d.r.ReadByte()
return err
@ -403,7 +409,7 @@ func (d *Decoder) skip(tagType byte) error {
return err
}
for i := 0; i < int(listLen); i++ {
if err := d.skip(listType); err != nil {
if err := d.rawRead(listType); err != nil {
return err
}
}
@ -416,7 +422,7 @@ func (d *Decoder) skip(tagType byte) error {
if tt == TagEnd {
break
}
err = d.skip(tt)
err = d.rawRead(tt)
if err != nil {
return err
}