From 90c2f468869b0ef7e14955f63dca9c8dd8723b89 Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Mon, 1 Aug 2022 20:29:43 -0600 Subject: wip --- lib/lowmemjson/decode.go | 33 ++++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) (limited to 'lib') 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}) } -- cgit v1.2.3-2-g168b