Merge remote-tracking branch 'origin/snbt_convertor' into snbt_convertor
# Conflicts: # nbt/snbt_scanner.go # nbt/snbt_scanner_test.go
This commit is contained in:
File diff suppressed because one or more lines are too long
@ -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) {
|
func (e *Encoder) writeHeader(val reflect.Value, tagType byte, tagName string) (err error) {
|
||||||
if tagType == TagList {
|
if tagType == TagList {
|
||||||
eleType := getTagType(val.Type().Elem())
|
eleType := getTagType(val.Type().Elem())
|
||||||
err = e.writeListHeader(eleType, tagName, val.Len())
|
err = e.writeListHeader(eleType, tagName, val.Len(), true)
|
||||||
} else {
|
} else {
|
||||||
err = e.writeTag(tagType, tagName)
|
err = e.writeTag(tagType, tagName)
|
||||||
}
|
}
|
||||||
@ -224,10 +224,12 @@ func (e *Encoder) writeTag(tagType byte, tagName string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Encoder) writeListHeader(elementType byte, tagName string, n int) (err error) {
|
func (e *Encoder) writeListHeader(elementType byte, tagName string, n int, writeTag bool) (err error) {
|
||||||
|
if writeTag {
|
||||||
if err = e.writeTag(TagList, tagName); err != nil {
|
if err = e.writeTag(TagList, tagName); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if _, err = e.w.Write([]byte{elementType}); err != nil {
|
if _, err = e.w.Write([]byte{elementType}); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -39,7 +39,8 @@ func writeValue(e *Encoder, d *decodeState, tagName string) error {
|
|||||||
e.writeTag(TagCompound, tagName)
|
e.writeTag(TagCompound, tagName)
|
||||||
return writeCompoundPayload(e, d)
|
return writeCompoundPayload(e, d)
|
||||||
case scanBeginList:
|
case scanBeginList:
|
||||||
return writeListOrArray(e, d, tagName)
|
_, err := writeListOrArray(e, d, true, tagName)
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,6 +67,7 @@ func writeLiteralPayload(e *Encoder, v interface{}) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func writeCompoundPayload(e *Encoder, d *decodeState) error {
|
func writeCompoundPayload(e *Encoder, d *decodeState) error {
|
||||||
|
defer d.scanNext()
|
||||||
for {
|
for {
|
||||||
d.scanWhile(scanSkipSpace)
|
d.scanWhile(scanSkipSpace)
|
||||||
if d.opcode == scanEndValue {
|
if d.opcode == scanEndValue {
|
||||||
@ -77,7 +79,12 @@ func writeCompoundPayload(e *Encoder, d *decodeState) error {
|
|||||||
// read tag name
|
// read tag name
|
||||||
start := d.readIndex()
|
start := d.readIndex()
|
||||||
d.scanWhile(scanContinue)
|
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
|
// read value
|
||||||
if d.opcode == scanSkipSpace {
|
if d.opcode == scanSkipSpace {
|
||||||
d.scanWhile(scanSkipSpace)
|
d.scanWhile(scanSkipSpace)
|
||||||
@ -102,11 +109,12 @@ func writeCompoundPayload(e *Encoder, d *decodeState) error {
|
|||||||
return nil
|
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)
|
d.scanWhile(scanSkipSpace)
|
||||||
if d.opcode == scanEndValue { // ']', empty TAG_List
|
if d.opcode == scanEndValue { // ']', empty TAG_List
|
||||||
e.writeListHeader(TagEnd, tagName, 0)
|
e.writeListHeader(TagEnd, tagName, 0, writeTag)
|
||||||
return nil
|
d.scanNext()
|
||||||
|
return TagList, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// We don't know the length of the List,
|
// We don't know the length of the List,
|
||||||
@ -120,29 +128,42 @@ func writeListOrArray(e *Encoder, d *decodeState, tagName string) error {
|
|||||||
case scanBeginLiteral:
|
case scanBeginLiteral:
|
||||||
d.scanWhile(scanContinue)
|
d.scanWhile(scanContinue)
|
||||||
literal := d.data[start:d.readIndex()]
|
literal := d.data[start:d.readIndex()]
|
||||||
|
if d.opcode == scanSkipSpace {
|
||||||
|
d.scanWhile(scanSkipSpace)
|
||||||
|
}
|
||||||
if d.opcode == scanListType { // TAG_X_Array
|
if d.opcode == scanListType { // TAG_X_Array
|
||||||
var elemType byte
|
var elemType byte
|
||||||
switch literal[0] {
|
switch literal[0] {
|
||||||
case 'B':
|
case 'B':
|
||||||
e.writeTag(TagByteArray, tagName)
|
tagType = TagByteArray
|
||||||
elemType = TagByte
|
elemType = TagByte
|
||||||
case 'I':
|
case 'I':
|
||||||
e.writeTag(TagIntArray, tagName)
|
tagType = TagIntArray
|
||||||
elemType = TagInt
|
elemType = TagInt
|
||||||
case 'L':
|
case 'L':
|
||||||
e.writeTag(TagLongArray, tagName)
|
tagType = TagLongArray
|
||||||
elemType = TagLong
|
elemType = TagLong
|
||||||
|
default:
|
||||||
|
return TagList, errors.New("unknown Array type")
|
||||||
|
}
|
||||||
|
if writeTag {
|
||||||
|
e.writeTag(tagType, tagName)
|
||||||
}
|
}
|
||||||
for {
|
|
||||||
d.scanNext()
|
|
||||||
if d.opcode == scanSkipSpace {
|
if d.opcode == scanSkipSpace {
|
||||||
d.scanWhile(scanSkipSpace)
|
d.scanWhile(scanSkipSpace)
|
||||||
}
|
}
|
||||||
|
d.scanWhile(scanSkipSpace) // ;
|
||||||
if d.opcode == scanEndValue { // ]
|
if d.opcode == scanEndValue { // ]
|
||||||
|
// empty array
|
||||||
|
e.writeInt32(0)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
for {
|
||||||
|
if d.opcode == scanSkipSpace {
|
||||||
|
d.scanWhile(scanSkipSpace)
|
||||||
|
}
|
||||||
if d.opcode != scanBeginLiteral {
|
if d.opcode != scanBeginLiteral {
|
||||||
return errors.New("not literal in Array")
|
return tagType, errors.New("not literal in Array")
|
||||||
}
|
}
|
||||||
start := d.readIndex()
|
start := d.readIndex()
|
||||||
|
|
||||||
@ -150,7 +171,7 @@ func writeListOrArray(e *Encoder, d *decodeState, tagName string) error {
|
|||||||
literal := d.data[start:d.readIndex()]
|
literal := d.data[start:d.readIndex()]
|
||||||
tagType, litVal := parseLiteral(literal)
|
tagType, litVal := parseLiteral(literal)
|
||||||
if tagType != elemType {
|
if tagType != elemType {
|
||||||
return errors.New("unexpected element type in TAG_Array")
|
return tagType, errors.New("unexpected element type in TAG_Array")
|
||||||
}
|
}
|
||||||
switch elemType {
|
switch elemType {
|
||||||
case TagByte:
|
case TagByte:
|
||||||
@ -161,6 +182,17 @@ func writeListOrArray(e *Encoder, d *decodeState, tagName string) error {
|
|||||||
e2.writeInt64(litVal.(int64))
|
e2.writeInt64(litVal.(int64))
|
||||||
}
|
}
|
||||||
count++
|
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.writeInt32(int32(count))
|
||||||
e.w.Write(buf.Bytes())
|
e.w.Write(buf.Bytes())
|
||||||
@ -176,7 +208,7 @@ func writeListOrArray(e *Encoder, d *decodeState, tagName string) error {
|
|||||||
tagType = t
|
tagType = t
|
||||||
}
|
}
|
||||||
if t != tagType {
|
if t != tagType {
|
||||||
return errors.New("different TagType in List")
|
return TagList, errors.New("different TagType in List")
|
||||||
}
|
}
|
||||||
writeLiteralPayload(e2, v)
|
writeLiteralPayload(e2, v)
|
||||||
count++
|
count++
|
||||||
@ -191,15 +223,41 @@ func writeListOrArray(e *Encoder, d *decodeState, tagName string) error {
|
|||||||
if d.opcode != scanListValue {
|
if d.opcode != scanListValue {
|
||||||
panic(phasePanicMsg)
|
panic(phasePanicMsg)
|
||||||
}
|
}
|
||||||
d.scanNext()
|
d.scanWhile(scanSkipSpace)
|
||||||
start = d.readIndex()
|
start = d.readIndex()
|
||||||
d.scanWhile(scanContinue)
|
d.scanWhile(scanContinue)
|
||||||
literal = d.data[start:d.readIndex()]
|
literal = d.data[start:d.readIndex()]
|
||||||
}
|
}
|
||||||
e.writeListHeader(tagType, tagName, count)
|
e.writeListHeader(tagType, tagName, count, writeTag)
|
||||||
e.w.Write(buf.Bytes())
|
e.w.Write(buf.Bytes())
|
||||||
case scanBeginList: // TAG_List<TAG_List>
|
case scanBeginList: // TAG_List<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)
|
||||||
|
}
|
||||||
|
// ',' or ']'
|
||||||
|
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())
|
e.w.Write(buf.Bytes())
|
||||||
case scanBeginCompound: // TAG_List<TAG_Compound>
|
case scanBeginCompound: // TAG_List<TAG_Compound>
|
||||||
for {
|
for {
|
||||||
@ -207,7 +265,7 @@ func writeListOrArray(e *Encoder, d *decodeState, tagName string) error {
|
|||||||
d.scanWhile(scanSkipSpace)
|
d.scanWhile(scanSkipSpace)
|
||||||
}
|
}
|
||||||
if d.opcode != scanBeginCompound {
|
if d.opcode != scanBeginCompound {
|
||||||
return errors.New("different TagType in List")
|
return TagList, errors.New("different TagType in List")
|
||||||
}
|
}
|
||||||
writeCompoundPayload(e2, d)
|
writeCompoundPayload(e2, d)
|
||||||
count++
|
count++
|
||||||
@ -215,7 +273,6 @@ func writeListOrArray(e *Encoder, d *decodeState, tagName string) error {
|
|||||||
d.scanWhile(scanSkipSpace)
|
d.scanWhile(scanSkipSpace)
|
||||||
}
|
}
|
||||||
// read ',' or ']'
|
// read ',' or ']'
|
||||||
d.scanNext()
|
|
||||||
if d.opcode == scanSkipSpace {
|
if d.opcode == scanSkipSpace {
|
||||||
d.scanWhile(scanSkipSpace)
|
d.scanWhile(scanSkipSpace)
|
||||||
}
|
}
|
||||||
@ -228,10 +285,11 @@ func writeListOrArray(e *Encoder, d *decodeState, tagName string) error {
|
|||||||
// read '{'
|
// read '{'
|
||||||
d.scanNext()
|
d.scanNext()
|
||||||
}
|
}
|
||||||
e.writeListHeader(TagCompound, tagName, count)
|
e.writeListHeader(TagCompound, tagName, count, writeTag)
|
||||||
e.w.Write(buf.Bytes())
|
e.w.Write(buf.Bytes())
|
||||||
}
|
}
|
||||||
return nil
|
d.scanNext()
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// readIndex returns the position of the last byte read.
|
// readIndex returns the position of the last byte read.
|
||||||
@ -298,7 +356,7 @@ func parseLiteral(literal []byte) (byte, interface{}) {
|
|||||||
if isNumber(c) {
|
if isNumber(c) {
|
||||||
continue
|
continue
|
||||||
} else if integer {
|
} else if integer {
|
||||||
if i == strlen-1 && isIntegerType(c) {
|
if i == strlen-1 && i != 0 && isIntegerType(c) {
|
||||||
numberType = c
|
numberType = c
|
||||||
strlen--
|
strlen--
|
||||||
} else if i > 0 || i == 0 && c != '-' {
|
} else if i > 0 || i == 0 && c != '-' {
|
||||||
|
@ -25,22 +25,28 @@ func TestEncoder_WriteSNBT(t *testing.T) {
|
|||||||
{`{}`, []byte{10, 0, 0, 0}},
|
{`{}`, []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 : 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}},
|
{`{b:1,2:c}`, []byte{10, 0, 0, 3, 0, 1, 'b', 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}},
|
{`{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}},
|
{`[]`, []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}},
|
||||||
|
{`[ 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,"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}},
|
||||||
{`[ { } , { 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; ]`, []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;]`, []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;]`, []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}},
|
||||||
|
|
||||||
|
{`{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 {
|
for i := range testCases {
|
||||||
buf.Reset()
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -9,10 +9,10 @@ const (
|
|||||||
scanBeginLiteral // end implied by next result != scanContinue
|
scanBeginLiteral // end implied by next result != scanContinue
|
||||||
scanBeginCompound // begin TAG_Compound (after left-brace )
|
scanBeginCompound // begin TAG_Compound (after left-brace )
|
||||||
scanBeginList // begin TAG_List (after left-brack)
|
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;")
|
scanListType // just finished read list type (after "B;" or "L;")
|
||||||
scanCompoundTagName // just finished read tag name (before colon)
|
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
|
scanSkipSpace // space byte; can skip; known to be last "continue" result
|
||||||
scanEndValue
|
scanEndValue
|
||||||
|
|
||||||
@ -176,7 +176,7 @@ func stateInSingleQuotedString(s *scanner, c byte) int {
|
|||||||
|
|
||||||
func stateInSingleQuotedStringEsc(s *scanner, c byte) int {
|
func stateInSingleQuotedStringEsc(s *scanner, c byte) int {
|
||||||
switch c {
|
switch c {
|
||||||
case 'b', 'f', 'n', 'r', 't', '\\', '/', '\'':
|
case '\\', '\'':
|
||||||
s.step = stateInSingleQuotedString
|
s.step = stateInSingleQuotedString
|
||||||
return scanContinue
|
return scanContinue
|
||||||
}
|
}
|
||||||
@ -235,6 +235,9 @@ func stateListOrArrayT(s *scanner, c byte) int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func stateArrayT(s *scanner, c byte) int {
|
func stateArrayT(s *scanner, c byte) int {
|
||||||
|
if isSpace(c) {
|
||||||
|
return scanSkipSpace
|
||||||
|
}
|
||||||
if c == ']' { // empty array
|
if c == ']' { // empty array
|
||||||
return scanEndValue
|
return scanEndValue
|
||||||
}
|
}
|
||||||
@ -258,10 +261,6 @@ func stateNum0(s *scanner, c byte) int {
|
|||||||
s.step = stateNum1
|
s.step = stateNum1
|
||||||
return scanContinue
|
return scanContinue
|
||||||
}
|
}
|
||||||
if isAllowedInUnquotedString(c) {
|
|
||||||
s.step = stateInUnquotedString
|
|
||||||
return scanContinue
|
|
||||||
}
|
|
||||||
return stateEndNumValue(s, c)
|
return stateEndNumValue(s, c)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -274,10 +273,6 @@ func stateNum1(s *scanner, c byte) int {
|
|||||||
s.step = stateNumDot
|
s.step = stateNumDot
|
||||||
return scanContinue
|
return scanContinue
|
||||||
}
|
}
|
||||||
if isAllowedInUnquotedString(c) {
|
|
||||||
s.step = stateInUnquotedString
|
|
||||||
return scanContinue
|
|
||||||
}
|
|
||||||
return stateEndNumValue(s, c)
|
return stateEndNumValue(s, c)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -302,10 +297,6 @@ func stateNumDot0(s *scanner, c byte) int {
|
|||||||
s.step = stateNumDot0
|
s.step = stateNumDot0
|
||||||
return scanContinue
|
return scanContinue
|
||||||
}
|
}
|
||||||
if isAllowedInUnquotedString(c) {
|
|
||||||
s.step = stateInUnquotedString
|
|
||||||
return scanContinue
|
|
||||||
}
|
|
||||||
return stateEndNumDotValue(s, c)
|
return stateEndNumDotValue(s, c)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -323,6 +314,10 @@ func stateEndNumValue(s *scanner, c byte) int {
|
|||||||
case 'f', 'F', 'd', 'D':
|
case 'f', 'F', 'd', 'D':
|
||||||
return stateEndNumDotValue(s, c)
|
return stateEndNumDotValue(s, c)
|
||||||
}
|
}
|
||||||
|
if isAllowedInUnquotedString(c) {
|
||||||
|
s.step = stateInUnquotedString
|
||||||
|
return scanContinue
|
||||||
|
}
|
||||||
return stateEndValue(s, c)
|
return stateEndValue(s, c)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,13 +41,14 @@ func TestSNBT_number(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//go:embed bigTest_test.snbt
|
//go:embed bigTest_test.snbt
|
||||||
var bigTest string
|
var bigTestSNBT string
|
||||||
|
|
||||||
func TestSNBT_compound(t *testing.T) {
|
func TestSNBT_compound(t *testing.T) {
|
||||||
goods := []string{
|
goods := []string{
|
||||||
`{}`, `{name:3.14f}`, `{ "name" : 12345 }`,
|
`{}`, `{name:3.14f}`, `{ "name" : 12345 }`,
|
||||||
`{ abc: { }}`, `{ "a b\"c": {}, def: 12345}`,
|
`{ abc: { }}`, `{ "a b\"c": {}, def: 12345}`,
|
||||||
bigTest,
|
`{ ghi: [], klm: 1}`,
|
||||||
|
bigTestSNBT,
|
||||||
}
|
}
|
||||||
var s scanner
|
var s scanner
|
||||||
for _, str := range goods {
|
for _, str := range goods {
|
||||||
@ -67,7 +68,7 @@ func TestSNBT_list(t *testing.T) {
|
|||||||
`[{}, {}, {"a\"b":520}]`, // List of Compound
|
`[{}, {}, {"a\"b":520}]`, // List of Compound
|
||||||
`[B,C,D]`, `[L, "abc"]`, // List of string (like array)
|
`[B,C,D]`, `[L, "abc"]`, // List of string (like array)
|
||||||
`[B; 01B, 02B, 3B, 10B, 127B]`, // Array
|
`[B; 01B, 02B, 3B, 10B, 127B]`, // Array
|
||||||
`[I;]`, // Empty array
|
`[I;]`, `[B; ]`, // Empty array
|
||||||
}
|
}
|
||||||
var s scanner
|
var s scanner
|
||||||
scan := func(str string) bool {
|
scan := func(str string) bool {
|
||||||
@ -91,10 +92,10 @@ func BenchmarkSNBT_bigTest(b *testing.B) {
|
|||||||
var s scanner
|
var s scanner
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
s.reset()
|
s.reset()
|
||||||
for _, c := range []byte(bigTest) {
|
for _, c := range []byte(bigTestSNBT) {
|
||||||
res := s.step(&s, c)
|
res := s.step(&s, c)
|
||||||
if res == scanError {
|
if res == scanError {
|
||||||
b.Errorf("scan valid data %q error: %v at [%d]", bigTest[:i], s.err, i)
|
b.Errorf("scan valid data %q error: %v at [%d]", bigTestSNBT[:i], s.err, i)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user