diff --git a/nbt/interface.go b/nbt/interface.go new file mode 100644 index 0000000..1821013 --- /dev/null +++ b/nbt/interface.go @@ -0,0 +1,9 @@ +package nbt + +type Unmarshaler interface { + Unmarshal(tagType byte, tagName string, r DecoderReader) error +} + +//type Marshaler interface{ +// Marshal() +//} diff --git a/nbt/interface_test.go b/nbt/interface_test.go new file mode 100644 index 0000000..41ad9a7 --- /dev/null +++ b/nbt/interface_test.go @@ -0,0 +1 @@ +package nbt diff --git a/nbt/marshal_test.go b/nbt/marshal_test.go deleted file mode 100644 index 0bc0bd8..0000000 --- a/nbt/marshal_test.go +++ /dev/null @@ -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) - } -} diff --git a/nbt/nbt.go b/nbt/nbt.go index 9c14996..794708e 100644 --- a/nbt/nbt.go +++ b/nbt/nbt.go @@ -24,19 +24,17 @@ const ( TagLongArray ) +type DecoderReader = interface { + io.ByteScanner + io.Reader +} type Decoder struct { - r interface { - io.ByteScanner - io.Reader - } + 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) diff --git a/nbt/nbt_test.go b/nbt/nbt_test.go index debe38d..4132892 100644 --- a/nbt/nbt_test.go +++ b/nbt/nbt_test.go @@ -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 { diff --git a/nbt/read.go b/nbt/read.go index a699605..9767168 100644 --- a/nbt/read.go +++ b/nbt/read.go @@ -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 }