NBT Unmarshaler support
This commit is contained in:
9
nbt/interface.go
Normal file
9
nbt/interface.go
Normal 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
1
nbt/interface_test.go
Normal file
@ -0,0 +1 @@
|
|||||||
|
package nbt
|
@ -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)
|
|
||||||
}
|
|
||||||
}
|
|
14
nbt/nbt.go
14
nbt/nbt.go
@ -24,19 +24,17 @@ const (
|
|||||||
TagLongArray
|
TagLongArray
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type DecoderReader = interface {
|
||||||
|
io.ByteScanner
|
||||||
|
io.Reader
|
||||||
|
}
|
||||||
type Decoder struct {
|
type Decoder struct {
|
||||||
r interface {
|
r DecoderReader
|
||||||
io.ByteScanner
|
|
||||||
io.Reader
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewDecoder(r io.Reader) *Decoder {
|
func NewDecoder(r io.Reader) *Decoder {
|
||||||
d := new(Decoder)
|
d := new(Decoder)
|
||||||
if br, ok := r.(interface {
|
if br, ok := r.(DecoderReader); ok {
|
||||||
io.ByteScanner
|
|
||||||
io.Reader
|
|
||||||
}); ok {
|
|
||||||
d.r = br
|
d.r = br
|
||||||
} else {
|
} else {
|
||||||
d.r = bufio.NewReader(r)
|
d.r = bufio.NewReader(r)
|
||||||
|
@ -53,7 +53,7 @@ func TestUnmarshal_simple(t *testing.T) {
|
|||||||
t.Errorf("Unmarshal NBT fail: get %q, want %q", value.Name, "Bananrama")
|
t.Errorf("Unmarshal NBT fail: get %q, want %q", value.Name, "Bananrama")
|
||||||
}
|
}
|
||||||
|
|
||||||
//test skip
|
//test rawRead
|
||||||
var empty struct{}
|
var empty struct{}
|
||||||
if err := Unmarshal(data, &empty); err != nil {
|
if err := Unmarshal(data, &empty); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
@ -189,7 +189,7 @@ func TestUnmarshal_bitTest(t *testing.T) {
|
|||||||
t.Errorf("parse fail, expect %v, get %v", want, value)
|
t.Errorf("parse fail, expect %v, get %v", want, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
//test skip
|
//test rawRead
|
||||||
var empty struct{}
|
var empty struct{}
|
||||||
r, err = gzip.NewReader(bytes.NewReader(data))
|
r, err = gzip.NewReader(bytes.NewReader(data))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
16
nbt/read.go
16
nbt/read.go
@ -63,6 +63,12 @@ func (d *Decoder) checkCompressed() (compress string, err error) {
|
|||||||
var ErrEND = errors.New("unexpected TAG_End")
|
var ErrEND = errors.New("unexpected TAG_End")
|
||||||
|
|
||||||
func (d *Decoder) unmarshal(val reflect.Value, tagType byte, tagName string) error {
|
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 {
|
switch tagType {
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("unknown Tag 0x%02x", tagType)
|
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
|
return err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if err := d.skip(tt); err != nil {
|
if err := d.rawRead(tt); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -344,10 +350,10 @@ func (d *Decoder) unmarshal(val reflect.Value, tagType byte, tagName string) err
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Decoder) skip(tagType byte) error {
|
func (d *Decoder) rawRead(tagType byte) error {
|
||||||
switch tagType {
|
switch tagType {
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("unknown to skip 0x%02x", tagType)
|
return fmt.Errorf("unknown to read 0x%02x", tagType)
|
||||||
case TagByte:
|
case TagByte:
|
||||||
_, err := d.r.ReadByte()
|
_, err := d.r.ReadByte()
|
||||||
return err
|
return err
|
||||||
@ -403,7 +409,7 @@ func (d *Decoder) skip(tagType byte) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
for i := 0; i < int(listLen); i++ {
|
for i := 0; i < int(listLen); i++ {
|
||||||
if err := d.skip(listType); err != nil {
|
if err := d.rawRead(listType); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -416,7 +422,7 @@ func (d *Decoder) skip(tagType byte) error {
|
|||||||
if tt == TagEnd {
|
if tt == TagEnd {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
err = d.skip(tt)
|
err = d.rawRead(tt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user