generate NBT TAG_Compound

This commit is contained in:
Tnze
2021-05-26 01:35:58 +08:00
parent 1f7d07b279
commit 00fcdb4b14
4 changed files with 47 additions and 17 deletions

View File

@ -1,9 +1,5 @@
package nbt
import (
"fmt"
)
type decodeState struct {
data []byte
off int // next read offset in data
@ -16,28 +12,27 @@ const phasePanicMsg = "SNBT decoder out of sync - data changing underfoot?"
func (e *Encoder) WriteSNBT(snbt string) error {
d := decodeState{data: []byte(snbt)}
d.scan.reset()
return writeValue(e, &d, "")
}
func writeValue(e *Encoder, d *decodeState, tagName string) error {
d.scanWhile(scanSkipSpace)
switch d.opcode {
default:
panic(phasePanicMsg)
case scanBeginLiteral:
return writeLiteral(e, &d)
return writeLiteral(e, d, tagName)
case scanBeginCompound:
panic("not implemented")
return writeCompound(e, d, tagName)
case scanBeginList:
panic("not implemented")
}
return nil
}
func writeLiteral(e *Encoder, d *decodeState) error {
func writeLiteral(e *Encoder, d *decodeState, tagName string) error {
start := d.readIndex()
d.scanNext()
d.scanWhile(scanContinue)
literal := d.data[start:d.readIndex()]
fmt.Printf("%d %d [%d]- %q\n", start, d.off, d.opcode, literal)
switch literal[0] {
case '"', '\'': // TAG_String
@ -52,8 +47,42 @@ func writeLiteral(e *Encoder, d *decodeState) error {
return nil
}
func writeCompound(e *Encoder, d *decodeState) error {
e.writeTag(TagCompound, "")
func writeCompound(e *Encoder, d *decodeState, tagName string) error {
e.writeTag(TagCompound, tagName)
for {
d.scanWhile(scanSkipSpace)
if d.opcode == scanEndValue {
break
}
if d.opcode != scanBeginLiteral {
panic(phasePanicMsg)
}
// read tag name
start := d.readIndex()
d.scanWhile(scanContinue)
tagName := string(d.data[start:d.readIndex()])
// read value
if d.opcode == scanSkipSpace {
d.scanWhile(scanSkipSpace)
}
if d.opcode != scanCompoundTagName {
panic(phasePanicMsg)
}
d.scanWhile(scanSkipSpace)
writeLiteral(e, d, tagName)
// Next token must be , or }.
if d.opcode == scanSkipSpace {
d.scanWhile(scanSkipSpace)
}
if d.opcode == scanEndValue {
break
}
if d.opcode != scanCompoundValue {
panic(phasePanicMsg)
}
}
e.w.Write([]byte{TagEnd})
return nil
}

View File

@ -8,7 +8,7 @@ import (
func TestEncoder_WriteSNBT(t *testing.T) {
var buf bytes.Buffer
e := NewEncoder(&buf)
if err := e.WriteSNBT(`"12345"`); err != nil {
if err := e.WriteSNBT(`{ abc: a123}`); err != nil {
t.Fatal(err)
}
t.Log(buf.Bytes())

View File

@ -397,6 +397,7 @@ func (s *scanner) stateEndValue(c byte) int {
}
return s.error(c, "")
}
func (s *scanner) error(c byte, context string) int {
s.step = s.stateError
s.err = errors.New(context)

View File

@ -6,10 +6,10 @@ import (
)
func TestSNBT_checkScanCode(t *testing.T) {
//t.SkipNow()
t.SkipNow()
var s scanner
s.reset()
for _, c := range []byte(`1234`) {
for _, c := range []byte(`{ "a b\"c": {}, def: 12345, 'gh"i': 0.123f}`) {
t.Logf("[%c] - %d", c, s.step(c))
}
t.Logf("[%c] - %d", ' ', s.eof())