generate NBT TAG_Compound
This commit is contained in:
@ -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
|
||||
}
|
||||
|
||||
|
@ -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())
|
||||
|
@ -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)
|
||||
|
@ -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())
|
||||
|
Reference in New Issue
Block a user