Basic SNBT list support
This commit is contained in:
@ -1,6 +1,7 @@
|
|||||||
package nbt
|
package nbt
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"math"
|
"math"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
@ -31,7 +32,7 @@ func writeValue(e *Encoder, d *decodeState, tagName string) error {
|
|||||||
case scanBeginCompound:
|
case scanBeginCompound:
|
||||||
return writeCompound(e, d, tagName)
|
return writeCompound(e, d, tagName)
|
||||||
case scanBeginList:
|
case scanBeginList:
|
||||||
panic("not implemented")
|
return writeListOrArray(e, d, tagName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -105,6 +106,53 @@ func writeCompound(e *Encoder, d *decodeState, tagName string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func writeListOrArray(e *Encoder, d *decodeState, tagName string) error {
|
||||||
|
d.scanWhile(scanSkipSpace)
|
||||||
|
if d.opcode == scanEndValue { // ']', empty TAG_List
|
||||||
|
e.writeTag(TagList, tagName)
|
||||||
|
e.writeInt32(0)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
start := d.readIndex()
|
||||||
|
|
||||||
|
switch d.opcode {
|
||||||
|
case scanBeginLiteral:
|
||||||
|
d.scanWhile(scanContinue)
|
||||||
|
literal := d.data[start:d.readIndex()]
|
||||||
|
if d.opcode == scanListType { // TAG_X_Array
|
||||||
|
//listType := literal[0]
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if d.opcode != scanListValue { // TAG_List<TAG_String>
|
||||||
|
panic(phasePanicMsg)
|
||||||
|
}
|
||||||
|
// TODO
|
||||||
|
parseLiteral(literal)
|
||||||
|
fallthrough
|
||||||
|
case scanBeginList: // TAG_List<TAG_List>
|
||||||
|
// We don't know the length of the List,
|
||||||
|
// so we read them into a buffer and count.
|
||||||
|
var buf bytes.Buffer
|
||||||
|
e2 := NewEncoder(&buf)
|
||||||
|
var count int
|
||||||
|
for {
|
||||||
|
d.scanWhile(scanSkipSpace)
|
||||||
|
if d.opcode == scanEndValue {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if d.opcode == scanListValue {
|
||||||
|
// TODO
|
||||||
|
e2.writeInt32(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
e.writeListHeader(TagList, tagName, count)
|
||||||
|
e.w.Write(buf.Bytes())
|
||||||
|
case scanBeginCompound: // TAG_List<TAG_Compound>
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// readIndex returns the position of the last byte read.
|
// readIndex returns the position of the last byte read.
|
||||||
func (d *decodeState) readIndex() int {
|
func (d *decodeState) readIndex() int {
|
||||||
return d.off - 1
|
return d.off - 1
|
||||||
|
@ -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(`{ abc: 123F, def: {}}`); err != nil {
|
if err := e.WriteSNBT(`[1,2,3]`); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
t.Log(buf.Bytes())
|
t.Log(buf.Bytes())
|
||||||
|
@ -239,7 +239,7 @@ func (s *scanner) stateListOrArray(c byte) int {
|
|||||||
switch c {
|
switch c {
|
||||||
case 'B', 'I', 'L':
|
case 'B', 'I', 'L':
|
||||||
s.step = s.stateListOrArrayT
|
s.step = s.stateListOrArrayT
|
||||||
return scanContinue
|
return scanBeginLiteral
|
||||||
case ']':
|
case ']':
|
||||||
return s.stateEndValue(c)
|
return s.stateEndValue(c)
|
||||||
default:
|
default:
|
||||||
|
@ -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(`{ "a b\"c": {}, def: 12345, 'gh"i': 0.123f}`) {
|
for _, c := range []byte(`[I;1,2,3]`) {
|
||||||
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