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