can parse TAG_String
This commit is contained in:
44
nbt/nbt.go
Normal file
44
nbt/nbt.go
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
package nbt
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"io"
|
||||||
|
)
|
||||||
|
|
||||||
|
//Tag type IDs
|
||||||
|
const (
|
||||||
|
TagEnd byte = iota
|
||||||
|
TagByte
|
||||||
|
TagShort
|
||||||
|
TagInt
|
||||||
|
TagLong
|
||||||
|
TagFloat
|
||||||
|
TagDouble
|
||||||
|
TagByteArray
|
||||||
|
TagString
|
||||||
|
TagList
|
||||||
|
TagCompound
|
||||||
|
TagIntArray
|
||||||
|
TagLongArray
|
||||||
|
)
|
||||||
|
|
||||||
|
type Decoder struct {
|
||||||
|
r interface {
|
||||||
|
io.ByteReader
|
||||||
|
io.Reader
|
||||||
|
}
|
||||||
|
nameless bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewDecoder(r io.Reader) *Decoder {
|
||||||
|
d := new(Decoder)
|
||||||
|
if br, ok := r.(interface {
|
||||||
|
io.ByteReader
|
||||||
|
io.Reader
|
||||||
|
}); ok {
|
||||||
|
d.r = br
|
||||||
|
} else {
|
||||||
|
d.r = bufio.NewReader(r)
|
||||||
|
}
|
||||||
|
return d
|
||||||
|
}
|
42
nbt/nbt_test.go
Normal file
42
nbt/nbt_test.go
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
package nbt
|
||||||
|
|
||||||
|
import "testing"
|
||||||
|
|
||||||
|
func TestUnmarshal_simple(t *testing.T) {
|
||||||
|
var data = []byte{
|
||||||
|
0x0a, 0x00, 0x0b, 0x68, 0x65, 0x6c, 0x6c, 0x6f,
|
||||||
|
0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x08, 0x00,
|
||||||
|
0x04, 0x6e, 0x61, 0x6d, 0x65, 0x00, 0x09, 0x42,
|
||||||
|
0x61, 0x6e, 0x61, 0x6e, 0x72, 0x61, 0x6d, 0x61,
|
||||||
|
0x00,
|
||||||
|
}
|
||||||
|
|
||||||
|
var value struct {
|
||||||
|
Name string `nbt:"name"`
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := Unmarshal(data, &value); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if value.Name != "Bananrama" {
|
||||||
|
t.Errorf("Unmarshal NBT fail: get %q, want %q", value.Name, "Bananrama")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUnmarshal_string(t *testing.T) {
|
||||||
|
var data = []byte{
|
||||||
|
0x08, 0x00, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x00, 0x09,
|
||||||
|
0x42, 0x61, 0x6e, 0x61, 0x6e, 0x72, 0x61, 0x6d, 0x61,
|
||||||
|
}
|
||||||
|
|
||||||
|
var Name string
|
||||||
|
|
||||||
|
if err := Unmarshal(data, &Name); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if Name != "Bananrama" {
|
||||||
|
t.Errorf("Unmarshal NBT fail: get %q, want %q", Name, "Bananrama")
|
||||||
|
}
|
||||||
|
}
|
81
nbt/read.go
Normal file
81
nbt/read.go
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
package nbt
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"reflect"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Unmarshal(data []byte, v interface{}) error {
|
||||||
|
return NewDecoder(bytes.NewReader(data)).Decode(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Decoder) Decode(v interface{}) error {
|
||||||
|
val := reflect.ValueOf(v)
|
||||||
|
if val.Kind() != reflect.Ptr {
|
||||||
|
return errors.New("non-pointer passed to Unmarshal")
|
||||||
|
}
|
||||||
|
return d.unmarshal(val.Elem())
|
||||||
|
}
|
||||||
|
|
||||||
|
// func (d *Decoder) unmarshalInt(val reflect.Value) error {
|
||||||
|
|
||||||
|
// }
|
||||||
|
|
||||||
|
func (d *Decoder) unmarshal(val reflect.Value) error {
|
||||||
|
tagType, err := d.r.ReadByte()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var tagName string
|
||||||
|
if !d.nameless { //Read Tag
|
||||||
|
if tagName, err = d.readString(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch tagType {
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("unknown tag 0x%2x", tagType)
|
||||||
|
case TagString:
|
||||||
|
if val.Kind() != reflect.String {
|
||||||
|
return errors.New("cannot unmarshal TAG_String into " + val.Kind().String())
|
||||||
|
}
|
||||||
|
|
||||||
|
s, err := d.readString()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
val.SetString(s)
|
||||||
|
case TagCompound:
|
||||||
|
if val.Kind() != reflect.Struct {
|
||||||
|
return errors.New("cannot unmarshal TAG_Compound into " + val.Kind().String())
|
||||||
|
}
|
||||||
|
fmt.Println("TagName:", tagName)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Decoder) readNByte(n int) (buf []byte, err error) {
|
||||||
|
buf = make([]byte, n)
|
||||||
|
_, err = d.r.Read(buf) //what happend if (returned n) != (argument n) ?
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Decoder) readInt16() (int16, error) {
|
||||||
|
data, err := d.readNByte(2)
|
||||||
|
return int16(data[0])<<4 | int16(data[1]), err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Decoder) readString() (string, error) {
|
||||||
|
length, err := d.readInt16()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
buf, err := d.readNByte(int(length))
|
||||||
|
return string(buf), err
|
||||||
|
}
|
22
nbt/typeinfo.go
Normal file
22
nbt/typeinfo.go
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
package nbt
|
||||||
|
|
||||||
|
import (
|
||||||
|
"reflect"
|
||||||
|
)
|
||||||
|
|
||||||
|
type typeInfo struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func getTypeInfo(typ reflect.Type) (*typeInfo, error) {
|
||||||
|
tinfo := new(typeInfo)
|
||||||
|
if typ.Kind() == reflect.Struct {
|
||||||
|
n := typ.NumField()
|
||||||
|
for i := 0; i < n; i++ {
|
||||||
|
f := typ.Field(i)
|
||||||
|
if (f.PkgPath != "" && !f.Anonymous) || f.Tag.Get("nbt") == "-" {
|
||||||
|
continue // Private field
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return tinfo, nil
|
||||||
|
}
|
Reference in New Issue
Block a user