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 package nbt
import (
"fmt"
)
type decodeState struct { type decodeState struct {
data []byte data []byte
off int // next read offset in data 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 { func (e *Encoder) WriteSNBT(snbt string) error {
d := decodeState{data: []byte(snbt)} d := decodeState{data: []byte(snbt)}
d.scan.reset() d.scan.reset()
return writeValue(e, &d, "")
}
func writeValue(e *Encoder, d *decodeState, tagName string) error {
d.scanWhile(scanSkipSpace) d.scanWhile(scanSkipSpace)
switch d.opcode { switch d.opcode {
default: default:
panic(phasePanicMsg) panic(phasePanicMsg)
case scanBeginLiteral: case scanBeginLiteral:
return writeLiteral(e, &d) return writeLiteral(e, d, tagName)
case scanBeginCompound: case scanBeginCompound:
panic("not implemented") return writeCompound(e, d, tagName)
case scanBeginList: case scanBeginList:
panic("not implemented") panic("not implemented")
} }
return nil
} }
func writeLiteral(e *Encoder, d *decodeState) error { func writeLiteral(e *Encoder, d *decodeState, tagName string) error {
start := d.readIndex() start := d.readIndex()
d.scanNext()
d.scanWhile(scanContinue) d.scanWhile(scanContinue)
literal := d.data[start:d.readIndex()] literal := d.data[start:d.readIndex()]
fmt.Printf("%d %d [%d]- %q\n", start, d.off, d.opcode, literal)
switch literal[0] { switch literal[0] {
case '"', '\'': // TAG_String case '"', '\'': // TAG_String
@ -52,8 +47,42 @@ func writeLiteral(e *Encoder, d *decodeState) error {
return nil return nil
} }
func writeCompound(e *Encoder, d *decodeState) error { func writeCompound(e *Encoder, d *decodeState, tagName string) error {
e.writeTag(TagCompound, "") 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 return nil
} }

View File

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

View File

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

View File

@ -6,10 +6,10 @@ import (
) )
func TestSNBT_checkScanCode(t *testing.T) { func TestSNBT_checkScanCode(t *testing.T) {
//t.SkipNow() t.SkipNow()
var s scanner var s scanner
s.reset() 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", c, s.step(c))
} }
t.Logf("[%c] - %d", ' ', s.eof()) t.Logf("[%c] - %d", ' ', s.eof())