fixed lists

This commit is contained in:
Emery Hemingway 2013-12-06 02:29:22 -05:00
parent 9659acd38b
commit a1653e0f3a
2 changed files with 52 additions and 51 deletions

View File

@ -162,8 +162,6 @@ type decodeState struct {
data []byte
off int // read offset in data
scan scanner
tmpstr string // scratch space to avoid some allocations
op int
savedError error
}
@ -184,14 +182,6 @@ func (d *decodeState) error(err error) {
panic(err)
}
// saveError saves the first err it is called with,
// for reporting at the end of the unmarshal.
func (d *decodeState) saveError(err error) {
if d.savedError == nil {
d.savedError = err
}
}
// skip reads d.data until it hits the given op code
func (d *decodeState) skip() { //seekOp int) {
var skipScan scanner
@ -337,7 +327,7 @@ func (d *decodeState) integer(v reflect.Value) {
case reflect.Float32, reflect.Float64:
n, err := strconv.ParseFloat(s, v.Type().Bits())
if err != nil || v.OverflowFloat(n) {
d.saveError(&UnmarshalTypeError{"integer " + s, v.Type()})
d.error(&UnmarshalTypeError{"integer " + s, v.Type()})
}
v.SetFloat(n)
@ -411,7 +401,6 @@ func (d *decodeState) string(v reflect.Value) {
case reflect.Interface:
if v.NumMethod() != 0 {
d.error(&UnmarshalTypeError{"string", v.Type()})
return
}
x := d.readString()
v.Set(reflect.ValueOf(x))
@ -420,6 +409,7 @@ func (d *decodeState) string(v reflect.Value) {
// list consumes a list from d.data[d.off-1:], decoding into the value v.
func (d *decodeState) list(v reflect.Value) {
// Check type of target.
switch v.Kind() {
case reflect.Interface:
@ -432,37 +422,23 @@ func (d *decodeState) list(v reflect.Value) {
// Otherwilse it's invalid
fallthrough
default:
d.saveError(&UnmarshalTypeError{"list", v.Type()})
return
d.error(&UnmarshalTypeError{"list", v.Type()})
case reflect.Array:
case reflect.Slice:
break
}
var c, i int
var f func(reflect.Value)
var c, op int
i := v.Len()
Read:
for {
c = int(d.data[d.off])
d.off++
op = d.scan.step(&d.scan, c)
switch d.scan.step(&d.scan, c) {
case scanEndList, scanEndValue:
switch op {
case scanEndList:
break Read
case scanBeginStringLen:
f = d.string
case scanBeginInteger:
f = d.integer
case scanBeginList:
f = d.list
case scanBeginDict:
f = d.dict
case scanError:
d.error(d.scan.err)
default:
d.error(errPhase)
}
// Get element of array, growing if necessary.
@ -482,12 +458,39 @@ Read:
}
}
var subv reflect.Value
if i < v.Len() {
// Decode into element.
f(v.Index(i))
subv = v.Index(i)
} else {
// Ran out of fixed array: skip.
d.value(reflect.Value{})
subv = reflect.Value{}
}
for subv.Kind() == reflect.Ptr || v.Kind() == reflect.Interface {
if subv.IsNil() {
subv.Set(reflect.New(subv.Type().Elem()))
}
subv = subv.Elem()
}
switch op {
case scanBeginStringLen:
d.string(subv)
case scanBeginInteger:
d.integer(subv)
case scanBeginList:
d.list(subv)
case scanBeginDict:
d.dict(subv)
case scanError:
d.error(d.scan.err)
default:
d.error(errPhase)
}
i++
}
@ -520,7 +523,7 @@ Read:
c = int(d.data[d.off])
d.off++
switch d.scan.step(&d.scan, c) {
switch op := d.scan.step(&d.scan, c); op {
case scanEndList:
break Read
@ -557,17 +560,16 @@ func (d *decodeState) dict(v reflect.Value) {
// map must have string kind
t := v.Type()
if t.Key().Kind() != reflect.String {
d.saveError(&UnmarshalTypeError{"dictionary", v.Type()})
break
d.error(&UnmarshalTypeError{"dictionary", v.Type()})
}
if v.IsNil() {
v.Set(reflect.MakeMap(t))
}
case reflect.Struct:
default:
d.saveError(&UnmarshalTypeError{"dictionary", v.Type()})
return
d.error(&UnmarshalTypeError{"dictionary", v.Type()})
}
var mapElem reflect.Value

View File

@ -62,11 +62,6 @@ type scanner struct {
// Error that happened, if any.
err error
// 1-byte redo (see undo method)
redo bool
redoCode int
redoState func(*scanner, int) int
remain int
strLenB []byte
strLen int
@ -129,7 +124,6 @@ func (s *scanner) reset() {
s.step = stateBeginValue
s.parseState = s.parseState[0:0]
s.err = nil
s.redo = false
s.endTop = false
}
@ -174,7 +168,6 @@ func (s *scanner) pushParseState(p int) {
func (s *scanner) popParseState() {
n := len(s.parseState) - 1
s.parseState = s.parseState[0:n]
s.redo = false
if n == 0 {
s.step = stateEndTop
s.endTop = true
@ -191,16 +184,13 @@ func stateBeginValue(s *scanner, c int) int {
s.pushParseState(parseInteger)
return scanBeginInteger
case 'l':
s.step = stateBeginValue
s.step = stateBeginList
s.pushParseState(parseListValue)
return scanBeginList
case 'd':
s.step = stateBeginDictKey
s.pushParseState(parseDictKey)
return scanBeginDict
case 'e':
s.popParseState()
return scanEndValue
}
if c >= '0' && c <= '9' {
@ -235,11 +225,12 @@ func stateEndValue(s *scanner, c int) int {
return stateBeginDictKey(s, c)
case parseListValue:
s.step = stateBeginValue
if c == 'e' {
s.popParseState()
return scanEndList
}
s.step = stateBeginValue
//s.pushParseState(parseListValue)
return stateBeginValue(s, c)
}
return s.error(c, "")
@ -291,6 +282,14 @@ func stateParseString(s *scanner, c int) int {
return scanParseString
}
func stateBeginList(s *scanner, c int) int {
if c == 'e' {
s.popParseState()
return scanEndList
}
return stateBeginValue(s, c)
}
func stateParseKeyLen(s *scanner, c int) int {
if c == ':' {
var err error