summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Shumaker <lukeshu@lukeshu.com>2022-08-01 20:29:43 -0600
committerLuke Shumaker <lukeshu@lukeshu.com>2022-08-01 20:29:43 -0600
commit90c2f468869b0ef7e14955f63dca9c8dd8723b89 (patch)
treee9268f5a3f4148b0029b37c0feb923001f0f4623
parent14bb92b622d5cd56829d0d9f04a201c7260ff9f9 (diff)
wip
-rw-r--r--lib/lowmemjson/decode.go33
1 files changed, 28 insertions, 5 deletions
diff --git a/lib/lowmemjson/decode.go b/lib/lowmemjson/decode.go
index b2eaacf..1604e87 100644
--- a/lib/lowmemjson/decode.go
+++ b/lib/lowmemjson/decode.go
@@ -226,7 +226,26 @@ func decode(r io.RuneScanner, val reflect.Value) {
}
fVal = fVal.Field(idx)
}
- decode(r, fVal.Addr())
+ if field.Quote {
+ var buf bytes.Buffer
+ switch peekRune(r) {
+ case 'n':
+ decodeNull(r)
+ switch fVal.Kind() {
+ // I can't justify this list, other than that it's what encoding/json
+ // does. I don't understand their rationale.
+ case reflect.Interface, reflect.Pointer, reflect.Map, reflect.Slice:
+ fVal.Set(reflect.Zero(fVal.Type()))
+ }
+ case '"':
+ decodeString(r, &buf)
+ decode(&buf, fVal)
+ default:
+ panic(decodeError{fmt.Errorf("invalid character %q for ,string struct value", peekRune(r))})
+ }
+ } else {
+ decode(r, fVal)
+ }
})
case reflect.Map:
switch peekRune(r) {
@@ -269,7 +288,7 @@ func decode(r io.RuneScanner, val reflect.Value) {
}
fValPtr := reflect.New(typ.Elem())
- decode(r, fValPtr)
+ decode(r, fValPtr.Elem())
val.SetMapIndex(nameValPtr.Elem(), fValPtr.Elem())
})
@@ -294,7 +313,7 @@ func decode(r io.RuneScanner, val reflect.Value) {
}
decodeArray(r, func() {
mValPtr := reflect.New(typ.Elem())
- decode(r, mValPtr)
+ decode(r, mValPtr.Elem())
val.Set(reflect.Append(val, mValPtr.Elem()))
})
default:
@@ -305,7 +324,7 @@ func decode(r io.RuneScanner, val reflect.Value) {
i := 0
decodeArray(r, func() {
mValPtr := reflect.New(typ.Elem())
- decode(r, mValPtr)
+ decode(r, mValPtr.Elem())
val.Index(i).Set(mValPtr.Elem())
i++
})
@@ -350,18 +369,22 @@ func scan(r io.RuneScanner, out io.Writer) {
}
scanner.bailAfterCurrent = true
var err error
+ var eof bool
for err == nil {
c, ok := readRuneOrEOF(r)
if ok {
_, err = scanner.WriteRune(c)
} else {
+ eof = true
err = scanner.Flush()
break
}
}
if err != nil {
if err == errBailedAfterCurrent {
- unreadRune(r)
+ if !eof {
+ unreadRune(r)
+ }
} else {
panic(decodeError{err})
}