From d829d3bccf376911aff1fae48315e7f2ee84f608 Mon Sep 17 00:00:00 2001 From: Tnze Date: Thu, 27 May 2021 10:45:36 +0800 Subject: [PATCH 1/3] support TAG_List --- nbt/encode.go | 10 ++++--- nbt/snbt_decode.go | 66 +++++++++++++++++++++++++++++++---------- nbt/snbt_decode_test.go | 6 ++-- 3 files changed, 60 insertions(+), 22 deletions(-) diff --git a/nbt/encode.go b/nbt/encode.go index fbc49b2..6f3836f 100644 --- a/nbt/encode.go +++ b/nbt/encode.go @@ -41,7 +41,7 @@ func (e *Encoder) marshal(val reflect.Value, tagType byte, tagName string) error func (e *Encoder) writeHeader(val reflect.Value, tagType byte, tagName string) (err error) { if tagType == TagList { eleType := getTagType(val.Type().Elem()) - err = e.writeListHeader(eleType, tagName, val.Len()) + err = e.writeListHeader(eleType, tagName, val.Len(), true) } else { err = e.writeTag(tagType, tagName) } @@ -224,9 +224,11 @@ func (e *Encoder) writeTag(tagType byte, tagName string) error { return err } -func (e *Encoder) writeListHeader(elementType byte, tagName string, n int) (err error) { - if err = e.writeTag(TagList, tagName); err != nil { - return +func (e *Encoder) writeListHeader(elementType byte, tagName string, n int, writeTag bool) (err error) { + if writeTag { + if err = e.writeTag(TagList, tagName); err != nil { + return + } } if _, err = e.w.Write([]byte{elementType}); err != nil { return diff --git a/nbt/snbt_decode.go b/nbt/snbt_decode.go index 0ffa2c8..21ee862 100644 --- a/nbt/snbt_decode.go +++ b/nbt/snbt_decode.go @@ -39,7 +39,8 @@ func writeValue(e *Encoder, d *decodeState, tagName string) error { e.writeTag(TagCompound, tagName) return writeCompoundPayload(e, d) case scanBeginList: - return writeListOrArray(e, d, tagName) + _, err := writeListOrArray(e, d, true, tagName) + return err } } @@ -102,11 +103,11 @@ func writeCompoundPayload(e *Encoder, d *decodeState) error { return nil } -func writeListOrArray(e *Encoder, d *decodeState, tagName string) error { +func writeListOrArray(e *Encoder, d *decodeState, writeTag bool, tagName string) (tagType byte, err error) { d.scanWhile(scanSkipSpace) if d.opcode == scanEndValue { // ']', empty TAG_List - e.writeListHeader(TagEnd, tagName, 0) - return nil + e.writeListHeader(TagEnd, tagName, 0, writeTag) + return TagList, nil } // We don't know the length of the List, @@ -124,14 +125,19 @@ func writeListOrArray(e *Encoder, d *decodeState, tagName string) error { var elemType byte switch literal[0] { case 'B': - e.writeTag(TagByteArray, tagName) + tagType = TagByteArray elemType = TagByte case 'I': - e.writeTag(TagIntArray, tagName) + tagType = TagIntArray elemType = TagInt case 'L': - e.writeTag(TagLongArray, tagName) + tagType = TagLongArray elemType = TagLong + default: + return TagList, errors.New("unknown Array type") + } + if writeTag { + e.writeTag(tagType, tagName) } for { d.scanNext() @@ -142,7 +148,7 @@ func writeListOrArray(e *Encoder, d *decodeState, tagName string) error { break } if d.opcode != scanBeginLiteral { - return errors.New("not literal in Array") + return tagType, errors.New("not literal in Array") } start := d.readIndex() @@ -150,7 +156,7 @@ func writeListOrArray(e *Encoder, d *decodeState, tagName string) error { literal := d.data[start:d.readIndex()] tagType, litVal := parseLiteral(literal) if tagType != elemType { - return errors.New("unexpected element type in TAG_Array") + return tagType, errors.New("unexpected element type in TAG_Array") } switch elemType { case TagByte: @@ -176,7 +182,7 @@ func writeListOrArray(e *Encoder, d *decodeState, tagName string) error { tagType = t } if t != tagType { - return errors.New("different TagType in List") + return TagList, errors.New("different TagType in List") } writeLiteralPayload(e2, v) count++ @@ -196,10 +202,40 @@ func writeListOrArray(e *Encoder, d *decodeState, tagName string) error { d.scanWhile(scanContinue) literal = d.data[start:d.readIndex()] } - e.writeListHeader(tagType, tagName, count) + e.writeListHeader(tagType, tagName, count, writeTag) e.w.Write(buf.Bytes()) case scanBeginList: // TAG_List - e.writeListHeader(TagList, tagName, count) + var elemType byte + for { + if d.opcode == scanSkipSpace { + d.scanWhile(scanSkipSpace) + } + if d.opcode != scanBeginList { + return TagList, errors.New("different TagType in List") + } + elemType, err = writeListOrArray(e2, d, false, "") + if err != nil { + return tagType, err + } + count++ + if d.opcode == scanSkipSpace { + d.scanWhile(scanSkipSpace) + } + // read ',' or ']' + d.scanNext() + if d.opcode == scanSkipSpace { + d.scanWhile(scanSkipSpace) + } + if d.opcode == scanEndValue { + break + } + if d.opcode != scanListValue { + panic(phasePanicMsg) + } + // read '[' + d.scanNext() + } + e.writeListHeader(elemType, tagName, count, writeTag) e.w.Write(buf.Bytes()) case scanBeginCompound: // TAG_List for { @@ -207,7 +243,7 @@ func writeListOrArray(e *Encoder, d *decodeState, tagName string) error { d.scanWhile(scanSkipSpace) } if d.opcode != scanBeginCompound { - return errors.New("different TagType in List") + return TagList, errors.New("different TagType in List") } writeCompoundPayload(e2, d) count++ @@ -228,10 +264,10 @@ func writeListOrArray(e *Encoder, d *decodeState, tagName string) error { // read '{' d.scanNext() } - e.writeListHeader(TagCompound, tagName, count) + e.writeListHeader(TagCompound, tagName, count, writeTag) e.w.Write(buf.Bytes()) } - return nil + return } // readIndex returns the position of the last byte read. diff --git a/nbt/snbt_decode_test.go b/nbt/snbt_decode_test.go index 57d187d..c9a873c 100644 --- a/nbt/snbt_decode_test.go +++ b/nbt/snbt_decode_test.go @@ -33,14 +33,14 @@ func TestEncoder_WriteSNBT(t *testing.T) { {`[a,"b",'c']`, []byte{9, 0, 0, 8, 0, 0, 0, 3, 0, 1, 'a', 0, 1, 'b', 0, 1, 'c'}}, {`[{},{a:1b},{}]`, []byte{9, 0, 0, 10, 0, 0, 0, 3, 0, 1, 0, 1, 'a', 1, 0, 0}}, {`[ { } , { a : 1b } , { } ] `, []byte{9, 0, 0, 10, 0, 0, 0, 3, 0, 1, 0, 1, 'a', 1, 0, 0}}, - {`[[],[]]`, []byte{9, 0, 0, 9, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0}}, + {`[[],[]]`, []byte{9, 0, 0, 9, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {`[B;]`, []byte{7, 0, 0, 0, 0, 0, 0}}, - {`[B;1,2,3]`, []byte{7, 0, 0, 0, 0, 0, 3, 1, 2, 3}}, + {`[B;1b,2B,3B]`, []byte{7, 0, 0, 0, 0, 0, 3, 1, 2, 3}}, {`[I;]`, []byte{11, 0, 0, 0, 0, 0, 0}}, {`[I;1,2,3]`, []byte{11, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3}}, {`[L;]`, []byte{12, 0, 0, 0, 0, 0, 0}}, - {`[L;1,2,3]`, []byte{12, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3}}, + {`[L;1L,2L,3L]`, []byte{12, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3}}, } for i := range testCases { buf.Reset() From 82a2efd6a0f4ce217886606f7897510b1104a239 Mon Sep 17 00:00:00 2001 From: Tnze Date: Thu, 27 May 2021 14:19:16 +0800 Subject: [PATCH 2/3] Pass bigTest --- nbt/snbt_decode.go | 48 +++++++++++++++++++++++++++++----------- nbt/snbt_decode_test.go | 28 ++++++++++++++++++----- nbt/snbt_scanner.go | 9 +++++--- nbt/snbt_scanner_test.go | 9 ++++---- 4 files changed, 68 insertions(+), 26 deletions(-) diff --git a/nbt/snbt_decode.go b/nbt/snbt_decode.go index 21ee862..9b8c542 100644 --- a/nbt/snbt_decode.go +++ b/nbt/snbt_decode.go @@ -67,6 +67,7 @@ func writeLiteralPayload(e *Encoder, v interface{}) error { } func writeCompoundPayload(e *Encoder, d *decodeState) error { + defer d.scanNext() for { d.scanWhile(scanSkipSpace) if d.opcode == scanEndValue { @@ -78,7 +79,12 @@ func writeCompoundPayload(e *Encoder, d *decodeState) error { // read tag name start := d.readIndex() d.scanWhile(scanContinue) - tagName := string(d.data[start:d.readIndex()]) + var tagName string + if tt, v := parseLiteral(d.data[start:d.readIndex()]); tt == TagString { + tagName = v.(string) + } else { + tagName = string(d.data[start:d.readIndex()]) + } // read value if d.opcode == scanSkipSpace { d.scanWhile(scanSkipSpace) @@ -107,6 +113,7 @@ func writeListOrArray(e *Encoder, d *decodeState, writeTag bool, tagName string) d.scanWhile(scanSkipSpace) if d.opcode == scanEndValue { // ']', empty TAG_List e.writeListHeader(TagEnd, tagName, 0, writeTag) + d.scanNext() return TagList, nil } @@ -121,6 +128,9 @@ func writeListOrArray(e *Encoder, d *decodeState, writeTag bool, tagName string) case scanBeginLiteral: d.scanWhile(scanContinue) literal := d.data[start:d.readIndex()] + if d.opcode == scanSkipSpace { + d.scanWhile(scanSkipSpace) + } if d.opcode == scanListType { // TAG_X_Array var elemType byte switch literal[0] { @@ -139,14 +149,19 @@ func writeListOrArray(e *Encoder, d *decodeState, writeTag bool, tagName string) if writeTag { e.writeTag(tagType, tagName) } + if d.opcode == scanSkipSpace { + d.scanWhile(scanSkipSpace) + } + d.scanWhile(scanSkipSpace) // ; + if d.opcode == scanEndValue { // ] + // empty array + e.writeInt32(0) + break + } for { - d.scanNext() if d.opcode == scanSkipSpace { d.scanWhile(scanSkipSpace) } - if d.opcode == scanEndValue { // ] - break - } if d.opcode != scanBeginLiteral { return tagType, errors.New("not literal in Array") } @@ -167,6 +182,17 @@ func writeListOrArray(e *Encoder, d *decodeState, writeTag bool, tagName string) e2.writeInt64(litVal.(int64)) } count++ + + if d.opcode == scanSkipSpace { + d.scanWhile(scanSkipSpace) + } + if d.opcode == scanEndValue { // ] + break + } + if d.opcode != scanListValue { + panic(phasePanicMsg) + } + d.scanWhile(scanSkipSpace) // , } e.writeInt32(int32(count)) e.w.Write(buf.Bytes()) @@ -197,7 +223,7 @@ func writeListOrArray(e *Encoder, d *decodeState, writeTag bool, tagName string) if d.opcode != scanListValue { panic(phasePanicMsg) } - d.scanNext() + d.scanWhile(scanSkipSpace) start = d.readIndex() d.scanWhile(scanContinue) literal = d.data[start:d.readIndex()] @@ -221,11 +247,7 @@ func writeListOrArray(e *Encoder, d *decodeState, writeTag bool, tagName string) if d.opcode == scanSkipSpace { d.scanWhile(scanSkipSpace) } - // read ',' or ']' - d.scanNext() - if d.opcode == scanSkipSpace { - d.scanWhile(scanSkipSpace) - } + // ',' or ']' if d.opcode == scanEndValue { break } @@ -251,7 +273,6 @@ func writeListOrArray(e *Encoder, d *decodeState, writeTag bool, tagName string) d.scanWhile(scanSkipSpace) } // read ',' or ']' - d.scanNext() if d.opcode == scanSkipSpace { d.scanWhile(scanSkipSpace) } @@ -267,6 +288,7 @@ func writeListOrArray(e *Encoder, d *decodeState, writeTag bool, tagName string) e.writeListHeader(TagCompound, tagName, count, writeTag) e.w.Write(buf.Bytes()) } + d.scanNext() return } @@ -334,7 +356,7 @@ func parseLiteral(literal []byte) (byte, interface{}) { if isNumber(c) { continue } else if integer { - if i == strlen-1 && isIntegerType(c) { + if i == strlen-1 && i != 0 && isIntegerType(c) { numberType = c strlen-- } else if i > 0 || i == 0 && c != '-' { diff --git a/nbt/snbt_decode_test.go b/nbt/snbt_decode_test.go index c9a873c..523c992 100644 --- a/nbt/snbt_decode_test.go +++ b/nbt/snbt_decode_test.go @@ -25,22 +25,28 @@ func TestEncoder_WriteSNBT(t *testing.T) { {`{}`, []byte{10, 0, 0, 0}}, {`{a:1b}`, []byte{10, 0, 0, 1, 0, 1, 'a', 1, 0}}, {`{ a : 1b }`, []byte{10, 0, 0, 1, 0, 1, 'a', 1, 0}}, - {`{a:1,2:c}`, []byte{10, 0, 0, 3, 0, 1, 'a', 0, 0, 0, 1, 8, 0, 1, '2', 0, 1, 'c', 0}}, - {`{a:{b:{}}}`, []byte{10, 0, 0, 10, 0, 1, 'a', 10, 0, 1, 'b', 0, 0, 0}}, + {`{b:1,2:c}`, []byte{10, 0, 0, 3, 0, 1, 'b', 0, 0, 0, 1, 8, 0, 1, '2', 0, 1, 'c', 0}}, + {`{c:{d:{}}}`, []byte{10, 0, 0, 10, 0, 1, 'c', 10, 0, 1, 'd', 0, 0, 0}}, + {`{h:{},"i":{}}`, []byte{10, 0, 0, 10, 0, 1, 'h', 0, 10, 0, 1, 'i', 0, 0}}, {`[]`, []byte{9, 0, 0, 0, 0, 0, 0, 0}}, {`[1b,2b,3b]`, []byte{9, 0, 0, 1, 0, 0, 0, 3, 1, 2, 3}}, + {`[ 1b , 2b , 3b ]`, []byte{9, 0, 0, 1, 0, 0, 0, 3, 1, 2, 3}}, {`[a,"b",'c']`, []byte{9, 0, 0, 8, 0, 0, 0, 3, 0, 1, 'a', 0, 1, 'b', 0, 1, 'c'}}, {`[{},{a:1b},{}]`, []byte{9, 0, 0, 10, 0, 0, 0, 3, 0, 1, 0, 1, 'a', 1, 0, 0}}, {`[ { } , { a : 1b } , { } ] `, []byte{9, 0, 0, 10, 0, 0, 0, 3, 0, 1, 0, 1, 'a', 1, 0, 0}}, {`[[],[]]`, []byte{9, 0, 0, 9, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, - {`[B;]`, []byte{7, 0, 0, 0, 0, 0, 0}}, - {`[B;1b,2B,3B]`, []byte{7, 0, 0, 0, 0, 0, 3, 1, 2, 3}}, + {`[B; ]`, []byte{7, 0, 0, 0, 0, 0, 0}}, + {`[B; 1b ,2B,3B]`, []byte{7, 0, 0, 0, 0, 0, 3, 1, 2, 3}}, {`[I;]`, []byte{11, 0, 0, 0, 0, 0, 0}}, - {`[I;1,2,3]`, []byte{11, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3}}, + {`[I; 1, 2 ,3]`, []byte{11, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3}}, {`[L;]`, []byte{12, 0, 0, 0, 0, 0, 0}}, - {`[L;1L,2L,3L]`, []byte{12, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3}}, + {`[ L; 1L,2L,3L]`, []byte{12, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3}}, + + {`{d:[]}`, []byte{10, 0, 0, 9, 0, 1, 'd', 0, 0, 0, 0, 0, 0}}, + {`{e:[]}`, []byte{10, 0, 0, 9, 0, 1, 'e', 0, 0, 0, 0, 0, 0}}, + {`{f:[], g:[]}`, []byte{10, 0, 0, 9, 0, 1, 'f', 0, 0, 0, 0, 0, 9, 0, 1, 'g', 0, 0, 0, 0, 0, 0}}, } for i := range testCases { buf.Reset() @@ -55,3 +61,13 @@ func TestEncoder_WriteSNBT(t *testing.T) { } } } + +func TestEncoder_WriteSNBT_bigTest(t *testing.T) { + var buf bytes.Buffer + e := NewEncoder(&buf) + + err := e.WriteSNBT(bigTestSNBT) + if err != nil { + t.Error(err) + } +} diff --git a/nbt/snbt_scanner.go b/nbt/snbt_scanner.go index 44c043f..27aa84d 100644 --- a/nbt/snbt_scanner.go +++ b/nbt/snbt_scanner.go @@ -10,10 +10,10 @@ const ( scanBeginLiteral // end implied by next result != scanContinue scanBeginCompound // begin TAG_Compound (after left-brace ) scanBeginList // begin TAG_List (after left-brack) - scanListValue // just finished read list value + scanListValue // just finished read list value (after comma) scanListType // just finished read list type (after "B;" or "L;") scanCompoundTagName // just finished read tag name (before colon) - scanCompoundValue // just finished read value (before comma or right-brace ) + scanCompoundValue // just finished read value (after comma) scanSkipSpace // space byte; can skip; known to be last "continue" result scanEndValue @@ -197,7 +197,7 @@ func (s *scanner) stateInSingleQuotedString(c byte) int { func (s *scanner) stateInSingleQuotedStringEsc(c byte) int { switch c { - case 'b', 'f', 'n', 'r', 't', '\\', '/', '\'': + case '\\', '\'': s.step = s.stateInSingleQuotedString return scanContinue } @@ -256,6 +256,9 @@ func (s *scanner) stateListOrArrayT(c byte) int { } func (s *scanner) stateArrayT(c byte) int { + if isSpace(c) { + return scanSkipSpace + } if c == ']' { // empty array return scanEndValue } diff --git a/nbt/snbt_scanner_test.go b/nbt/snbt_scanner_test.go index cf5de10..71eb119 100644 --- a/nbt/snbt_scanner_test.go +++ b/nbt/snbt_scanner_test.go @@ -9,7 +9,7 @@ func TestSNBT_checkScanCode(t *testing.T) { //t.SkipNow() var s scanner s.reset() - for _, c := range []byte(`[{},{a:1b},{}]`) { + for _, c := range []byte(`{ ghi: [B; 2B, 3B], klm: []}`) { t.Logf("[%c] - %d", c, s.step(c)) } t.Logf("[%c] - %d", ' ', s.eof()) @@ -41,13 +41,14 @@ func TestSNBT_number(t *testing.T) { } //go:embed bigTest_test.snbt -var bigTest string +var bigTestSNBT string func TestSNBT_compound(t *testing.T) { goods := []string{ `{}`, `{name:3.14f}`, `{ "name" : 12345 }`, `{ abc: { }}`, `{ "a b\"c": {}, def: 12345}`, - bigTest, + `{ ghi: [], klm: 1}`, + bigTestSNBT, } var s scanner for _, str := range goods { @@ -67,7 +68,7 @@ func TestSNBT_list(t *testing.T) { `[{}, {}, {"a\"b":520}]`, // List of Compound `[B,C,D]`, `[L, "abc"]`, // List of string (like array) `[B; 01B, 02B, 3B, 10B, 127B]`, // Array - `[I;]`, // Empty array + `[I;]`, `[B; ]`, // Empty array } var s scanner scan := func(str string) bool { From 69a8bad0258aea51223db42802e1480118b070f9 Mon Sep 17 00:00:00 2001 From: Tnze Date: Thu, 27 May 2021 14:58:40 +0800 Subject: [PATCH 3/3] fix scanner error of number like "100f" --- nbt/bigTest_test.snbt | 32 ++++++++++++++++---------------- nbt/snbt_scanner.go | 39 ++++----------------------------------- 2 files changed, 20 insertions(+), 51 deletions(-) diff --git a/nbt/bigTest_test.snbt b/nbt/bigTest_test.snbt index ec5e3b4..519aeb5 100644 --- a/nbt/bigTest_test.snbt +++ b/nbt/bigTest_test.snbt @@ -1,12 +1,21 @@ { - shortTest: 32767s, longTest: 9223372036854775807L, - byteTest: 127b, - "byteArrayTest (the first 1000 values of (n*n*255+n*7)%100, starting with n=0 (0, 62, 34, 16, 8, ...))": [B; 0B, 62B, 34B, 16B, 8B, 10B, 22B, 44B, 76B, 18B, 70B, 32B, 4B, 86B, 78B, 80B, 92B, 14B, 46B, 88B, 40B, 2B, 74B, 56B, 48B, 50B, 62B, 84B, 16B, 58B, 10B, 72B, 44B, 26B, 18B, 20B, 32B, 54B, 86B, 28B, 80B, 42B, 14B, 96B, 88B, 90B, 2B, 24B, 56B, 98B, 50B, 12B, 84B, 66B, 58B, 60B, 72B, 94B, 26B, 68B, 20B, 82B, 54B, 36B, 28B, 30B, 42B, 64B, 96B, 38B, 90B, 52B, 24B, 6B, 98B, 0B, 12B, 34B, 66B, 8B, 60B, 22B, 94B, 76B, 68B, 70B, 82B, 4B, 36B, 78B, 30B, 92B, 64B, 46B, 38B, 40B, 52B, 74B, 6B, 48B, 0B, 62B, 34B, 16B, 8B, 10B, 22B, 44B, 76B, 18B, 70B, 32B, 4B, 86B, 78B, 80B, 92B, 14B, 46B, 88B, 40B, 2B, 74B, 56B, 48B, 50B, 62B, 84B, 16B, 58B, 10B, 72B, 44B, 26B, 18B, 20B, 32B, 54B, 86B, 28B, 80B, 42B, 14B, 96B, 88B, 90B, 2B, 24B, 56B, 98B, 50B, 12B, 84B, 66B, 58B, 60B, 72B, 94B, 26B, 68B, 20B, 82B, 54B, 36B, 28B, 30B, 42B, 64B, 96B, 38B, 90B, 52B, 24B, 6B, 98B, 0B, 12B, 34B, 66B, 8B, 60B, 22B, 94B, 76B, 68B, 70B, 82B, 4B, 36B, 78B, 30B, 92B, 64B, 46B, 38B, 40B, 52B, 74B, 6B, 48B, 0B, 62B, 34B, 16B, 8B, 10B, 22B, 44B, 76B, 18B, 70B, 32B, 4B, 86B, 78B, 80B, 92B, 14B, 46B, 88B, 40B, 2B, 74B, 56B, 48B, 50B, 62B, 84B, 16B, 58B, 10B, 72B, 44B, 26B, 18B, 20B, 32B, 54B, 86B, 28B, 80B, 42B, 14B, 96B, 88B, 90B, 2B, 24B, 56B, 98B, 50B, 12B, 84B, 66B, 58B, 60B, 72B, 94B, 26B, 68B, 20B, 82B, 54B, 36B, 28B, 30B, 42B, 64B, 96B, 38B, 90B, 52B, 24B, 6B, 98B, 0B, 12B, 34B, 66B, 8B, 60B, 22B, 94B, 76B, 68B, 70B, 82B, 4B, 36B, 78B, 30B, 92B, 64B, 46B, 38B, 40B, 52B, 74B, 6B, 48B, 0B, 62B, 34B, 16B, 8B, 10B, 22B, 44B, 76B, 18B, 70B, 32B, 4B, 86B, 78B, 80B, 92B, 14B, 46B, 88B, 40B, 2B, 74B, 56B, 48B, 50B, 62B, 84B, 16B, 58B, 10B, 72B, 44B, 26B, 18B, 20B, 32B, 54B, 86B, 28B, 80B, 42B, 14B, 96B, 88B, 90B, 2B, 24B, 56B, 98B, 50B, 12B, 84B, 66B, 58B, 60B, 72B, 94B, 26B, 68B, 20B, 82B, 54B, 36B, 28B, 30B, 42B, 64B, 96B, 38B, 90B, 52B, 24B, 6B, 98B, 0B, 12B, 34B, 66B, 8B, 60B, 22B, 94B, 76B, 68B, 70B, 82B, 4B, 36B, 78B, 30B, 92B, 64B, 46B, 38B, 40B, 52B, 74B, 6B, 48B, 0B, 62B, 34B, 16B, 8B, 10B, 22B, 44B, 76B, 18B, 70B, 32B, 4B, 86B, 78B, 80B, 92B, 14B, 46B, 88B, 40B, 2B, 74B, 56B, 48B, 50B, 62B, 84B, 16B, 58B, 10B, 72B, 44B, 26B, 18B, 20B, 32B, 54B, 86B, 28B, 80B, 42B, 14B, 96B, 88B, 90B, 2B, 24B, 56B, 98B, 50B, 12B, 84B, 66B, 58B, 60B, 72B, 94B, 26B, 68B, 20B, 82B, 54B, 36B, 28B, 30B, 42B, 64B, 96B, 38B, 90B, 52B, 24B, 6B, 98B, 0B, 12B, 34B, 66B, 8B, 60B, 22B, 94B, 76B, 68B, 70B, 82B, 4B, 36B, 78B, 30B, 92B, 64B, 46B, 38B, 40B, 52B, 74B, 6B, 48B, 0B, 62B, 34B, 16B, 8B, 10B, 22B, 44B, 76B, 18B, 70B, 32B, 4B, 86B, 78B, 80B, 92B, 14B, 46B, 88B, 40B, 2B, 74B, 56B, 48B, 50B, 62B, 84B, 16B, 58B, 10B, 72B, 44B, 26B, 18B, 20B, 32B, 54B, 86B, 28B, 80B, 42B, 14B, 96B, 88B, 90B, 2B, 24B, 56B, 98B, 50B, 12B, 84B, 66B, 58B, 60B, 72B, 94B, 26B, 68B, 20B, 82B, 54B, 36B, 28B, 30B, 42B, 64B, 96B, 38B, 90B, 52B, 24B, 6B, 98B, 0B, 12B, 34B, 66B, 8B, 60B, 22B, 94B, 76B, 68B, 70B, 82B, 4B, 36B, 78B, 30B, 92B, 64B, 46B, 38B, 40B, 52B, 74B, 6B, 48B, 0B, 62B, 34B, 16B, 8B, 10B, 22B, 44B, 76B, 18B, 70B, 32B, 4B, 86B, 78B, 80B, 92B, 14B, 46B, 88B, 40B, 2B, 74B, 56B, 48B, 50B, 62B, 84B, 16B, 58B, 10B, 72B, 44B, 26B, 18B, 20B, 32B, 54B, 86B, 28B, 80B, 42B, 14B, 96B, 88B, 90B, 2B, 24B, 56B, 98B, 50B, 12B, 84B, 66B, 58B, 60B, 72B, 94B, 26B, 68B, 20B, 82B, 54B, 36B, 28B, 30B, 42B, 64B, 96B, 38B, 90B, 52B, 24B, 6B, 98B, 0B, 12B, 34B, 66B, 8B, 60B, 22B, 94B, 76B, 68B, 70B, 82B, 4B, 36B, 78B, 30B, 92B, 64B, 46B, 38B, 40B, 52B, 74B, 6B, 48B, 0B, 62B, 34B, 16B, 8B, 10B, 22B, 44B, 76B, 18B, 70B, 32B, 4B, 86B, 78B, 80B, 92B, 14B, 46B, 88B, 40B, 2B, 74B, 56B, 48B, 50B, 62B, 84B, 16B, 58B, 10B, 72B, 44B, 26B, 18B, 20B, 32B, 54B, 86B, 28B, 80B, 42B, 14B, 96B, 88B, 90B, 2B, 24B, 56B, 98B, 50B, 12B, 84B, 66B, 58B, 60B, 72B, 94B, 26B, 68B, 20B, 82B, 54B, 36B, 28B, 30B, 42B, 64B, 96B, 38B, 90B, 52B, 24B, 6B, 98B, 0B, 12B, 34B, 66B, 8B, 60B, 22B, 94B, 76B, 68B, 70B, 82B, 4B, 36B, 78B, 30B, 92B, 64B, 46B, 38B, 40B, 52B, 74B, 6B, 48B, 0B, 62B, 34B, 16B, 8B, 10B, 22B, 44B, 76B, 18B, 70B, 32B, 4B, 86B, 78B, 80B, 92B, 14B, 46B, 88B, 40B, 2B, 74B, 56B, 48B, 50B, 62B, 84B, 16B, 58B, 10B, 72B, 44B, 26B, 18B, 20B, 32B, 54B, 86B, 28B, 80B, 42B, 14B, 96B, 88B, 90B, 2B, 24B, 56B, 98B, 50B, 12B, 84B, 66B, 58B, 60B, 72B, 94B, 26B, 68B, 20B, 82B, 54B, 36B, 28B, 30B, 42B, 64B, 96B, 38B, 90B, 52B, 24B, 6B, 98B, 0B, 12B, 34B, 66B, 8B, 60B, 22B, 94B, 76B, 68B, 70B, 82B, 4B, 36B, 78B, 30B, 92B, 64B, 46B, 38B, 40B, 52B, 74B, 6B, 48B, 0B, 62B, 34B, 16B, 8B, 10B, 22B, 44B, 76B, 18B, 70B, 32B, 4B, 86B, 78B, 80B, 92B, 14B, 46B, 88B, 40B, 2B, 74B, 56B, 48B, 50B, 62B, 84B, 16B, 58B, 10B, 72B, 44B, 26B, 18B, 20B, 32B, 54B, 86B, 28B, 80B, 42B, 14B, 96B, 88B, 90B, 2B, 24B, 56B, 98B, 50B, 12B, 84B, 66B, 58B, 60B, 72B, 94B, 26B, 68B, 20B, 82B, 54B, 36B, 28B, 30B, 42B, 64B, 96B, 38B, 90B, 52B, 24B, 6B, 98B, 0B, 12B, 34B, 66B, 8B, 60B, 22B, 94B, 76B, 68B, 70B, 82B, 4B, 36B, 78B, 30B, 92B, 64B, 46B, 38B, 40B, 52B, 74B, 6B, 48B], - "listTest (long)": [11L, 12L, 13L, 14L, 15L], + shortTest: 32767s, + stringTest: "HELLO WORLD THIS IS A TEST STRING ÅÄÖ!", floatTest: 0.49823147f, - doubleTest: 0.4931287132182315d, + byteTest: 127b, intTest: 2147483647, + "nested compound test": { + ham: { + name: "Hampus", + value: 0.75f + }, + egg: { + name: "Eggbert", + value: 0.5f + } + }, + "listTest (long)": [11L, 12L, 13L, 14L, 15L], "listTest (compound)": [ { created-on: 1264099775885L, @@ -17,15 +26,6 @@ name: "Compound tag #1" } ], - "nested compound test": { - egg: { - name: "Eggbert", - value: 0.5f - }, - ham: { - name: "Hampus", - value: 0.75f - } - }, - stringTest: "HELLO WORLD THIS IS A TEST STRING ÅÄÖ!" + "byteArrayTest (the first 1000 values of (n*n*255+n*7)%100, starting with n=0 (0, 62, 34, 16, 8, ...))": [B; 0B, 62B, 34B, 16B, 8B, 10B, 22B, 44B, 76B, 18B, 70B, 32B, 4B, 86B, 78B, 80B, 92B, 14B, 46B, 88B, 40B, 2B, 74B, 56B, 48B, 50B, 62B, 84B, 16B, 58B, 10B, 72B, 44B, 26B, 18B, 20B, 32B, 54B, 86B, 28B, 80B, 42B, 14B, 96B, 88B, 90B, 2B, 24B, 56B, 98B, 50B, 12B, 84B, 66B, 58B, 60B, 72B, 94B, 26B, 68B, 20B, 82B, 54B, 36B, 28B, 30B, 42B, 64B, 96B, 38B, 90B, 52B, 24B, 6B, 98B, 0B, 12B, 34B, 66B, 8B, 60B, 22B, 94B, 76B, 68B, 70B, 82B, 4B, 36B, 78B, 30B, 92B, 64B, 46B, 38B, 40B, 52B, 74B, 6B, 48B, 0B, 62B, 34B, 16B, 8B, 10B, 22B, 44B, 76B, 18B, 70B, 32B, 4B, 86B, 78B, 80B, 92B, 14B, 46B, 88B, 40B, 2B, 74B, 56B, 48B, 50B, 62B, 84B, 16B, 58B, 10B, 72B, 44B, 26B, 18B, 20B, 32B, 54B, 86B, 28B, 80B, 42B, 14B, 96B, 88B, 90B, 2B, 24B, 56B, 98B, 50B, 12B, 84B, 66B, 58B, 60B, 72B, 94B, 26B, 68B, 20B, 82B, 54B, 36B, 28B, 30B, 42B, 64B, 96B, 38B, 90B, 52B, 24B, 6B, 98B, 0B, 12B, 34B, 66B, 8B, 60B, 22B, 94B, 76B, 68B, 70B, 82B, 4B, 36B, 78B, 30B, 92B, 64B, 46B, 38B, 40B, 52B, 74B, 6B, 48B, 0B, 62B, 34B, 16B, 8B, 10B, 22B, 44B, 76B, 18B, 70B, 32B, 4B, 86B, 78B, 80B, 92B, 14B, 46B, 88B, 40B, 2B, 74B, 56B, 48B, 50B, 62B, 84B, 16B, 58B, 10B, 72B, 44B, 26B, 18B, 20B, 32B, 54B, 86B, 28B, 80B, 42B, 14B, 96B, 88B, 90B, 2B, 24B, 56B, 98B, 50B, 12B, 84B, 66B, 58B, 60B, 72B, 94B, 26B, 68B, 20B, 82B, 54B, 36B, 28B, 30B, 42B, 64B, 96B, 38B, 90B, 52B, 24B, 6B, 98B, 0B, 12B, 34B, 66B, 8B, 60B, 22B, 94B, 76B, 68B, 70B, 82B, 4B, 36B, 78B, 30B, 92B, 64B, 46B, 38B, 40B, 52B, 74B, 6B, 48B, 0B, 62B, 34B, 16B, 8B, 10B, 22B, 44B, 76B, 18B, 70B, 32B, 4B, 86B, 78B, 80B, 92B, 14B, 46B, 88B, 40B, 2B, 74B, 56B, 48B, 50B, 62B, 84B, 16B, 58B, 10B, 72B, 44B, 26B, 18B, 20B, 32B, 54B, 86B, 28B, 80B, 42B, 14B, 96B, 88B, 90B, 2B, 24B, 56B, 98B, 50B, 12B, 84B, 66B, 58B, 60B, 72B, 94B, 26B, 68B, 20B, 82B, 54B, 36B, 28B, 30B, 42B, 64B, 96B, 38B, 90B, 52B, 24B, 6B, 98B, 0B, 12B, 34B, 66B, 8B, 60B, 22B, 94B, 76B, 68B, 70B, 82B, 4B, 36B, 78B, 30B, 92B, 64B, 46B, 38B, 40B, 52B, 74B, 6B, 48B, 0B, 62B, 34B, 16B, 8B, 10B, 22B, 44B, 76B, 18B, 70B, 32B, 4B, 86B, 78B, 80B, 92B, 14B, 46B, 88B, 40B, 2B, 74B, 56B, 48B, 50B, 62B, 84B, 16B, 58B, 10B, 72B, 44B, 26B, 18B, 20B, 32B, 54B, 86B, 28B, 80B, 42B, 14B, 96B, 88B, 90B, 2B, 24B, 56B, 98B, 50B, 12B, 84B, 66B, 58B, 60B, 72B, 94B, 26B, 68B, 20B, 82B, 54B, 36B, 28B, 30B, 42B, 64B, 96B, 38B, 90B, 52B, 24B, 6B, 98B, 0B, 12B, 34B, 66B, 8B, 60B, 22B, 94B, 76B, 68B, 70B, 82B, 4B, 36B, 78B, 30B, 92B, 64B, 46B, 38B, 40B, 52B, 74B, 6B, 48B, 0B, 62B, 34B, 16B, 8B, 10B, 22B, 44B, 76B, 18B, 70B, 32B, 4B, 86B, 78B, 80B, 92B, 14B, 46B, 88B, 40B, 2B, 74B, 56B, 48B, 50B, 62B, 84B, 16B, 58B, 10B, 72B, 44B, 26B, 18B, 20B, 32B, 54B, 86B, 28B, 80B, 42B, 14B, 96B, 88B, 90B, 2B, 24B, 56B, 98B, 50B, 12B, 84B, 66B, 58B, 60B, 72B, 94B, 26B, 68B, 20B, 82B, 54B, 36B, 28B, 30B, 42B, 64B, 96B, 38B, 90B, 52B, 24B, 6B, 98B, 0B, 12B, 34B, 66B, 8B, 60B, 22B, 94B, 76B, 68B, 70B, 82B, 4B, 36B, 78B, 30B, 92B, 64B, 46B, 38B, 40B, 52B, 74B, 6B, 48B, 0B, 62B, 34B, 16B, 8B, 10B, 22B, 44B, 76B, 18B, 70B, 32B, 4B, 86B, 78B, 80B, 92B, 14B, 46B, 88B, 40B, 2B, 74B, 56B, 48B, 50B, 62B, 84B, 16B, 58B, 10B, 72B, 44B, 26B, 18B, 20B, 32B, 54B, 86B, 28B, 80B, 42B, 14B, 96B, 88B, 90B, 2B, 24B, 56B, 98B, 50B, 12B, 84B, 66B, 58B, 60B, 72B, 94B, 26B, 68B, 20B, 82B, 54B, 36B, 28B, 30B, 42B, 64B, 96B, 38B, 90B, 52B, 24B, 6B, 98B, 0B, 12B, 34B, 66B, 8B, 60B, 22B, 94B, 76B, 68B, 70B, 82B, 4B, 36B, 78B, 30B, 92B, 64B, 46B, 38B, 40B, 52B, 74B, 6B, 48B, 0B, 62B, 34B, 16B, 8B, 10B, 22B, 44B, 76B, 18B, 70B, 32B, 4B, 86B, 78B, 80B, 92B, 14B, 46B, 88B, 40B, 2B, 74B, 56B, 48B, 50B, 62B, 84B, 16B, 58B, 10B, 72B, 44B, 26B, 18B, 20B, 32B, 54B, 86B, 28B, 80B, 42B, 14B, 96B, 88B, 90B, 2B, 24B, 56B, 98B, 50B, 12B, 84B, 66B, 58B, 60B, 72B, 94B, 26B, 68B, 20B, 82B, 54B, 36B, 28B, 30B, 42B, 64B, 96B, 38B, 90B, 52B, 24B, 6B, 98B, 0B, 12B, 34B, 66B, 8B, 60B, 22B, 94B, 76B, 68B, 70B, 82B, 4B, 36B, 78B, 30B, 92B, 64B, 46B, 38B, 40B, 52B, 74B, 6B, 48B, 0B, 62B, 34B, 16B, 8B, 10B, 22B, 44B, 76B, 18B, 70B, 32B, 4B, 86B, 78B, 80B, 92B, 14B, 46B, 88B, 40B, 2B, 74B, 56B, 48B, 50B, 62B, 84B, 16B, 58B, 10B, 72B, 44B, 26B, 18B, 20B, 32B, 54B, 86B, 28B, 80B, 42B, 14B, 96B, 88B, 90B, 2B, 24B, 56B, 98B, 50B, 12B, 84B, 66B, 58B, 60B, 72B, 94B, 26B, 68B, 20B, 82B, 54B, 36B, 28B, 30B, 42B, 64B, 96B, 38B, 90B, 52B, 24B, 6B, 98B, 0B, 12B, 34B, 66B, 8B, 60B, 22B, 94B, 76B, 68B, 70B, 82B, 4B, 36B, 78B, 30B, 92B, 64B, 46B, 38B, 40B, 52B, 74B, 6B, 48B, 0B, 62B, 34B, 16B, 8B, 10B, 22B, 44B, 76B, 18B, 70B, 32B, 4B, 86B, 78B, 80B, 92B, 14B, 46B, 88B, 40B, 2B, 74B, 56B, 48B, 50B, 62B, 84B, 16B, 58B, 10B, 72B, 44B, 26B, 18B, 20B, 32B, 54B, 86B, 28B, 80B, 42B, 14B, 96B, 88B, 90B, 2B, 24B, 56B, 98B, 50B, 12B, 84B, 66B, 58B, 60B, 72B, 94B, 26B, 68B, 20B, 82B, 54B, 36B, 28B, 30B, 42B, 64B, 96B, 38B, 90B, 52B, 24B, 6B, 98B, 0B, 12B, 34B, 66B, 8B, 60B, 22B, 94B, 76B, 68B, 70B, 82B, 4B, 36B, 78B, 30B, 92B, 64B, 46B, 38B, 40B, 52B, 74B, 6B, 48B], + doubleTest: 0.4931287132182315d } diff --git a/nbt/snbt_scanner.go b/nbt/snbt_scanner.go index 27aa84d..9aae51f 100644 --- a/nbt/snbt_scanner.go +++ b/nbt/snbt_scanner.go @@ -2,7 +2,6 @@ package nbt import ( "errors" - "sync" ) const ( @@ -47,28 +46,6 @@ func (s *scanner) reset() { s.parseState = s.parseState[0:0] } -var scannerPool = sync.Pool{ - New: func() interface{} { - return &scanner{} - }, -} - -func newScanner() *scanner { - scan := scannerPool.Get().(*scanner) - // scan.reset by design doesn't set bytes to zero - //scan.bytes = 0 - scan.reset() - return scan -} - -func freeScanner(scan *scanner) { - // Avoid hanging on to too much memory in extreme cases. - if len(scan.parseState) > 1024 { - scan.parseState = nil - } - scannerPool.Put(scan) -} - // pushParseState pushes a new parse state p onto the parse stack. // an error state is returned if maxNestingDepth was exceeded, otherwise successState is returned. func (s *scanner) pushParseState(c byte, newParseState int, successState int) int { @@ -282,10 +259,6 @@ func (s *scanner) stateNum0(c byte) int { s.step = s.stateNum1 return scanContinue } - if isAllowedInUnquotedString(c) { - s.step = s.stateInUnquotedString - return scanContinue - } return s.stateEndNumValue(c) } @@ -298,10 +271,6 @@ func (s *scanner) stateNum1(c byte) int { s.step = s.stateNumDot return scanContinue } - if isAllowedInUnquotedString(c) { - s.step = s.stateInUnquotedString - return scanContinue - } return s.stateEndNumValue(c) } @@ -326,10 +295,6 @@ func (s *scanner) stateNumDot0(c byte) int { s.step = s.stateNumDot0 return scanContinue } - if isAllowedInUnquotedString(c) { - s.step = s.stateInUnquotedString - return scanContinue - } return s.stateEndNumDotValue(c) } @@ -347,6 +312,10 @@ func (s *scanner) stateEndNumValue(c byte) int { case 'f', 'F', 'd', 'D': return s.stateEndNumDotValue(c) } + if isAllowedInUnquotedString(c) { + s.step = s.stateInUnquotedString + return scanContinue + } return s.stateEndValue(c) }