From 1ee452ff5f39a8c70b91fae4c1b7b9fdc9961250 Mon Sep 17 00:00:00 2001 From: Tnze Date: Thu, 19 May 2022 16:28:04 +0800 Subject: [PATCH] nbt supports encode int8 as TagByte and []int8 as TagByteArray --- nbt/encode.go | 17 ++++++++++++++--- nbt/encode_test.go | 14 ++++++++++++++ 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/nbt/encode.go b/nbt/encode.go index c230335..18e65a7 100644 --- a/nbt/encode.go +++ b/nbt/encode.go @@ -10,6 +10,7 @@ import ( "reflect" "strconv" "strings" + "unsafe" ) // Marshal is the shortcut of NewEncoder().Encode() with empty tag name. @@ -62,7 +63,13 @@ func (e *Encoder) writeValue(val reflect.Value, tagType byte) error { default: return errors.New("unsupported type 0x" + strconv.FormatUint(uint64(tagType), 16)) case TagByte: - _, err := e.w.Write([]byte{byte(val.Uint())}) + var err error + switch val.Kind() { + case reflect.Int8: + _, err = e.w.Write([]byte{byte(val.Int())}) + case reflect.Uint8: + _, err = e.w.Write([]byte{byte(val.Uint())}) + } return err case TagShort: return e.writeInt16(int16(val.Int())) @@ -81,7 +88,11 @@ func (e *Encoder) writeValue(val reflect.Value, tagType byte) error { } if tagType == TagByteArray { - _, err := e.w.Write(val.Bytes()) + _, err := e.w.Write(*(*[]byte)((unsafe.Pointer)(&reflect.SliceHeader{ + Data: val.Pointer(), + Len: val.Len(), + Cap: val.Cap(), + }))) return err } else { for i := 0; i < n; i++ { @@ -264,7 +275,7 @@ func getTagType(v reflect.Value) (byte, reflect.Value) { func getTagTypeByType(vk reflect.Type) byte { switch vk.Kind() { - case reflect.Uint8: + case reflect.Int8, reflect.Uint8: return TagByte case reflect.Int16, reflect.Uint16: return TagShort diff --git a/nbt/encode_test.go b/nbt/encode_test.go index fd488b8..96d882e 100644 --- a/nbt/encode_test.go +++ b/nbt/encode_test.go @@ -41,6 +41,20 @@ func TestEncoder_Encode_intArray(t *testing.T) { } } +func TestENcoder_encodeInt8(t *testing.T) { + // Test marshal pure Int array + v := []int8{0, -10, 3} + out := []byte{ + TagByteArray, 0x00, 0x00, 0, 0, 0, 3, + 0x00, 0xf6, 0x03, + } + if data, err := Marshal(v); err != nil { + t.Error(err) + } else if !bytes.Equal(data, out) { + t.Errorf("output binary not right: get % 02x, want % 02x ", data, out) + } +} + func TestEncoder_Encode_floatArray(t *testing.T) { // Test marshal pure Int array v := []float32{0.3, -100, float32(math.NaN())}