can parse TagCompound and TagString and TagFloat
This commit is contained in:
149
nbt/read.go
149
nbt/read.go
@ -4,6 +4,7 @@ import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
@ -16,59 +17,159 @@ func (d *Decoder) Decode(v interface{}) error {
|
||||
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()
|
||||
tagType, tagName, err := d.readTag()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return d.unmarshal(val.Elem(), tagType, tagName)
|
||||
}
|
||||
|
||||
var tagName string
|
||||
if !d.nameless { //Read Tag
|
||||
if tagName, err = d.readString(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
func (d *Decoder) unmarshal(val reflect.Value, tagType byte, tagName string) error {
|
||||
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())
|
||||
return fmt.Errorf("unknown Tag 0x%02x", tagType)
|
||||
case TagFloat:
|
||||
if vk := val.Kind(); vk != reflect.Float32 {
|
||||
return errors.New("cannot parse TagString as " + vk.String())
|
||||
}
|
||||
vInt, err := d.readInt32()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
val.Set(reflect.ValueOf(math.Float32frombits(uint32(vInt))))
|
||||
|
||||
case TagString:
|
||||
if vk := val.Kind(); vk != reflect.String {
|
||||
return errors.New("cannot parse TagString as " + vk.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())
|
||||
if vk := val.Kind(); vk != reflect.Struct {
|
||||
return errors.New("cannot parse TagCompound as " + vk.String())
|
||||
}
|
||||
fmt.Println("TagName:", tagName)
|
||||
tinfo := getTypeInfo(val.Type())
|
||||
for {
|
||||
tt, tn, err := d.readTag()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if tt == TagEnd {
|
||||
break
|
||||
}
|
||||
field := tinfo.findIndexByName(tn)
|
||||
if field != -1 {
|
||||
err = d.unmarshal(val.Field(field), tt, tn)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if err := d.skip(tt); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *Decoder) skip(tagType byte) error {
|
||||
switch tagType {
|
||||
default:
|
||||
return fmt.Errorf("unknown to skip 0x%02x", tagType)
|
||||
case TagByte:
|
||||
_, err := d.r.ReadByte()
|
||||
return err
|
||||
case TagString:
|
||||
_, err := d.readString()
|
||||
return err
|
||||
case TagShort:
|
||||
_, err := d.readNByte(2)
|
||||
return err
|
||||
case TagInt, TagFloat:
|
||||
_, err := d.readNByte(4)
|
||||
return err
|
||||
case TagLong, TagDouble:
|
||||
_, err := d.readNByte(8)
|
||||
return err
|
||||
case TagByteArray:
|
||||
aryLen, err := d.readInt32()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err = d.readNByte(int(aryLen)); err != nil {
|
||||
return err
|
||||
}
|
||||
case TagList:
|
||||
listType, err := d.r.ReadByte()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
listLen, err := d.readInt32()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for i := 0; i < int(listLen); i++ {
|
||||
if err := d.skip(listType); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
case TagCompound:
|
||||
for {
|
||||
tt, _, err := d.readTag()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if tt == TagEnd {
|
||||
break
|
||||
}
|
||||
err = d.skip(tt)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *Decoder) readTag() (tagType byte, tagName string, err error) {
|
||||
tagType, err = d.r.ReadByte()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if tagType != TagEnd && !d.nameless { //Read Tag
|
||||
tagName, err = d.readString()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
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) ?
|
||||
// for i := 0; i < n; i++ {
|
||||
// buf[i], err = d.r.ReadByte()
|
||||
// if err != nil {
|
||||
// return
|
||||
// }
|
||||
// }
|
||||
return
|
||||
}
|
||||
|
||||
func (d *Decoder) readInt16() (int16, error) {
|
||||
data, err := d.readNByte(2)
|
||||
return int16(data[0])<<4 | int16(data[1]), err
|
||||
return int16(data[0])<<8 | int16(data[1]), err
|
||||
}
|
||||
|
||||
func (d *Decoder) readInt32() (int32, error) {
|
||||
data, err := d.readNByte(4)
|
||||
return int32(data[0])<<24 | int32(data[1])<<16 |
|
||||
int32(data[2])<<8 | int32(data[3]), err
|
||||
}
|
||||
|
||||
func (d *Decoder) readString() (string, error) {
|
||||
|
Reference in New Issue
Block a user