From 82a2efd6a0f4ce217886606f7897510b1104a239 Mon Sep 17 00:00:00 2001 From: Tnze Date: Thu, 27 May 2021 14:19:16 +0800 Subject: [PATCH] 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 {