diff options
Diffstat (limited to 'decode.go')
-rw-r--r-- | decode.go | 183 |
1 files changed, 90 insertions, 93 deletions
@@ -23,7 +23,10 @@ import ( "unicode/utf16" "unicode/utf8" - "git.lukeshu.com/go/lowmemjson/internal" + "git.lukeshu.com/go/lowmemjson/internal/base64dec" + "git.lukeshu.com/go/lowmemjson/internal/fastio" + "git.lukeshu.com/go/lowmemjson/internal/jsonparse" + "git.lukeshu.com/go/lowmemjson/internal/jsonstruct" ) // Decodable is the interface implemented by types that can decode a @@ -90,7 +93,6 @@ type Decoder struct { useNumber bool // state - err error posStack []int64 structStack []decodeStackItem } @@ -106,7 +108,7 @@ func NewDecoder(r io.RuneScanner) *Decoder { return &Decoder{ io: runeTypeScanner{ inner: r, - parser: internal.Parser{ + parser: jsonparse.Parser{ MaxDepth: maxNestingDepth, }, }, @@ -146,7 +148,7 @@ func (dec *Decoder) More() bool { dec.io.Reset() _, _, t, e := dec.io.ReadRuneType() _ = dec.io.UnreadRune() // best effort - return e == nil && t != internal.RuneTypeEOF + return e == nil && t != jsonparse.RuneTypeEOF } func (dec *Decoder) posStackPush() { @@ -207,7 +209,7 @@ func (dec *Decoder) DecodeThenEOF(ptr any) (err error) { return err } c, s, t, _ := dec.io.ReadRuneType() - if t != internal.RuneTypeEOF { + if t != jsonparse.RuneTypeEOF { panic("should not happen") } if s > 0 { @@ -240,18 +242,13 @@ func (dec *Decoder) Decode(ptr any) (err error) { } } - if dec.err != nil { - return dec.err - } - dec.io.Reset() dec.io.PushReadBarrier() defer func() { if r := recover(); r != nil { if de, ok := r.(decodeError); ok { pub := DecodeError(de) - dec.err = &pub - err = dec.err + err = &pub } else { panic(r) } @@ -280,7 +277,7 @@ func (dec *Decoder) panicType(jTyp string, gTyp reflect.Type, err error) { }) } -func (dec *Decoder) readRune() (rune, internal.RuneType) { +func (dec *Decoder) readRune() (rune, jsonparse.RuneType) { c, _, t, e := dec.io.ReadRuneType() if e != nil { panic(decodeError{ @@ -301,20 +298,20 @@ func (dec *Decoder) unreadRune() { } } -func (dec *Decoder) peekRuneType() internal.RuneType { +func (dec *Decoder) peekRuneType() jsonparse.RuneType { _, t := dec.readRune() dec.unreadRune() return t } -func (dec *Decoder) expectRune(ec rune, et internal.RuneType) { +func (dec *Decoder) expectRune(ec rune, et jsonparse.RuneType) { ac, at := dec.readRune() if ac != ec || at != et { panic("should not happen") } } -func (dec *Decoder) expectRuneType(ec rune, et internal.RuneType, gt reflect.Type) { +func (dec *Decoder) expectRuneType(ec rune, et jsonparse.RuneType, gt reflect.Type) { ac, at := dec.readRune() if ac != ec || at != et { dec.panicType(at.JSONType(), gt, nil) @@ -331,7 +328,7 @@ func (sc *decRuneScanner) ReadRune() (rune, int, error) { return 0, 0, io.EOF } c, s, t, e := sc.dec.io.ReadRuneType() - if t == internal.RuneTypeEOF { + if t == jsonparse.RuneTypeEOF { sc.eof = true sc.dec.io.PopReadBarrier() return 0, 0, io.EOF @@ -418,7 +415,7 @@ func (dec *Decoder) decode(val reflect.Value, nullOK bool) { dec.panicType(t.JSONType(), reflect.PointerTo(typ), err) } case val.CanAddr() && reflect.PointerTo(typ).Implements(textUnmarshalerType): - if nullOK && dec.peekRuneType() == internal.RuneTypeNullN { + if nullOK && dec.peekRuneType() == jsonparse.RuneTypeNullN { dec.decodeNull() return } @@ -431,13 +428,13 @@ func (dec *Decoder) decode(val reflect.Value, nullOK bool) { default: switch kind := typ.Kind(); kind { case reflect.Bool: - if nullOK && dec.peekRuneType() == internal.RuneTypeNullN { + if nullOK && dec.peekRuneType() == jsonparse.RuneTypeNullN { dec.decodeNull() return } val.SetBool(dec.decodeBool(typ)) case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - if nullOK && dec.peekRuneType() == internal.RuneTypeNullN { + if nullOK && dec.peekRuneType() == jsonparse.RuneTypeNullN { dec.decodeNull() return } @@ -449,7 +446,7 @@ func (dec *Decoder) decode(val reflect.Value, nullOK bool) { } val.SetInt(n) case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: - if nullOK && dec.peekRuneType() == internal.RuneTypeNullN { + if nullOK && dec.peekRuneType() == jsonparse.RuneTypeNullN { dec.decodeNull() return } @@ -461,7 +458,7 @@ func (dec *Decoder) decode(val reflect.Value, nullOK bool) { } val.SetUint(n) case reflect.Float32, reflect.Float64: - if nullOK && dec.peekRuneType() == internal.RuneTypeNullN { + if nullOK && dec.peekRuneType() == jsonparse.RuneTypeNullN { dec.decodeNull() return } @@ -473,7 +470,7 @@ func (dec *Decoder) decode(val reflect.Value, nullOK bool) { } val.SetFloat(n) case reflect.String: - if nullOK && dec.peekRuneType() == internal.RuneTypeNullN { + if nullOK && dec.peekRuneType() == jsonparse.RuneTypeNullN { dec.decodeNull() return } @@ -514,29 +511,29 @@ func (dec *Decoder) decode(val reflect.Value, nullOK bool) { // in the loop) because the only way it's possible is if there's // an interface in there, which'd break from the loop on its own. // - // ptr.CanSet() || dec.peekRuneType() != internal.RuneTypeNullN + // ptr.CanSet() || dec.peekRuneType() != jsonparse.RuneTypeNullN // // We only need the pointer itself to be settable if we're // decoding null. - if ptr.Elem() != val && (ptr.CanSet() || dec.peekRuneType() != internal.RuneTypeNullN) { + if ptr.Elem() != val && (ptr.CanSet() || dec.peekRuneType() != jsonparse.RuneTypeNullN) { dec.decode(ptr, false) break } } // Couldn't get type information from a pointer; fall back to untyped mode. switch dec.peekRuneType() { - case internal.RuneTypeNullN: + case jsonparse.RuneTypeNullN: dec.decodeNull() val.Set(reflect.Zero(typ)) default: val.Set(reflect.ValueOf(dec.decodeAny())) } case reflect.Struct: - if nullOK && dec.peekRuneType() == internal.RuneTypeNullN { + if nullOK && dec.peekRuneType() == jsonparse.RuneTypeNullN { dec.decodeNull() return } - index := indexStruct(typ) + index := jsonstruct.IndexStruct(typ) var nameBuf strings.Builder dec.decodeObject(typ, func() { dec.posStackPush() @@ -549,10 +546,10 @@ func (dec *Decoder) decode(val reflect.Value, nullOK bool) { name := nameBuf.String() dec.structStackPush(typ, name) defer dec.structStackPop() - idx, ok := index.byName[name] + idx, ok := index.ByName[name] if !ok { - for oidx := range index.byPos { - if strings.EqualFold(name, index.byPos[oidx].Name) { + for oidx := range index.ByPos { + if strings.EqualFold(name, index.ByPos[oidx].Name) { idx = oidx ok = true break @@ -563,10 +560,10 @@ func (dec *Decoder) decode(val reflect.Value, nullOK bool) { if dec.disallowUnknownFields { dec.panicType("", typ, fmt.Errorf("json: unknown field %q", name)) } - dec.scan(internal.Discard) + dec.scan(fastio.Discard) return } - field := index.byPos[idx] + field := index.ByPos[idx] fVal := val for _, idx := range field.Path { if fVal.Kind() == reflect.Pointer { @@ -575,7 +572,7 @@ func (dec *Decoder) decode(val reflect.Value, nullOK bool) { fmt.Errorf("json: cannot set embedded pointer to unexported struct: %v", fVal.Type().Elem())) } - if dec.peekRuneType() != internal.RuneTypeNullN { + if dec.peekRuneType() != jsonparse.RuneTypeNullN { if fVal.IsNil() { fVal.Set(reflect.New(fVal.Type().Elem())) } @@ -586,7 +583,7 @@ func (dec *Decoder) decode(val reflect.Value, nullOK bool) { } if field.Quote { switch t := dec.peekRuneType(); t { - case internal.RuneTypeNullN: + case jsonparse.RuneTypeNullN: dec.decodeNull() switch fVal.Kind() { // XXX: I can't justify this list, other than "it's what encoding/json @@ -596,7 +593,7 @@ func (dec *Decoder) decode(val reflect.Value, nullOK bool) { default: // do nothing??? } - case internal.RuneTypeStringBeg: + case jsonparse.RuneTypeStringBeg: // TODO: Figure out how to do this without buffering, have correct offsets. var buf bytes.Buffer dec.decodeString(nil, &buf) @@ -618,10 +615,10 @@ func (dec *Decoder) decode(val reflect.Value, nullOK bool) { }) case reflect.Map: switch t := dec.peekRuneType(); t { - case internal.RuneTypeNullN: + case jsonparse.RuneTypeNullN: dec.decodeNull() val.Set(reflect.Zero(typ)) - case internal.RuneTypeObjectBeg: + case jsonparse.RuneTypeObjectBeg: if val.IsNil() { val.Set(reflect.MakeMap(typ)) } @@ -676,24 +673,24 @@ func (dec *Decoder) decode(val reflect.Value, nullOK bool) { } case reflect.Slice: switch { - case typ.Elem().Kind() == reflect.Uint8 && !(dec.peekRuneType() == internal.RuneTypeArrayBeg && (false || + case typ.Elem().Kind() == reflect.Uint8 && !(dec.peekRuneType() == jsonparse.RuneTypeArrayBeg && (false || reflect.PointerTo(typ.Elem()).Implements(decodableType) || reflect.PointerTo(typ.Elem()).Implements(jsonUnmarshalerType) || reflect.PointerTo(typ.Elem()).Implements(textUnmarshalerType))): switch t := dec.peekRuneType(); t { - case internal.RuneTypeNullN: + case jsonparse.RuneTypeNullN: dec.decodeNull() val.Set(reflect.Zero(typ)) - case internal.RuneTypeStringBeg: + case jsonparse.RuneTypeStringBeg: if typ.Elem() == byteType { var buf bytes.Buffer - dec.decodeString(typ, internal.NewBase64Decoder(&buf)) + dec.decodeString(typ, base64dec.NewBase64Decoder(&buf)) val.Set(reflect.ValueOf(buf.Bytes())) } else { // TODO: Surely there's a better way. At the very least, we should // avoid buffering. var buf bytes.Buffer - dec.decodeString(typ, internal.NewBase64Decoder(&buf)) + dec.decodeString(typ, base64dec.NewBase64Decoder(&buf)) bs := buf.Bytes() val.Set(reflect.MakeSlice(typ, len(bs), len(bs))) for i := 0; i < len(bs); i++ { @@ -705,10 +702,10 @@ func (dec *Decoder) decode(val reflect.Value, nullOK bool) { } default: switch t := dec.peekRuneType(); t { - case internal.RuneTypeNullN: + case jsonparse.RuneTypeNullN: dec.decodeNull() val.Set(reflect.Zero(typ)) - case internal.RuneTypeArrayBeg: + case jsonparse.RuneTypeArrayBeg: if val.IsNil() { val.Set(reflect.MakeSlice(typ, 0, 0)) } @@ -731,7 +728,7 @@ func (dec *Decoder) decode(val reflect.Value, nullOK bool) { } } case reflect.Array: - if nullOK && dec.peekRuneType() == internal.RuneTypeNullN { + if nullOK && dec.peekRuneType() == jsonparse.RuneTypeNullN { dec.decodeNull() return } @@ -747,7 +744,7 @@ func (dec *Decoder) decode(val reflect.Value, nullOK bool) { dec.decode(mValPtr.Elem(), false) val.Index(i).Set(mValPtr.Elem()) } else { - dec.scan(internal.Discard) + dec.scan(fastio.Discard) } i++ }) @@ -756,7 +753,7 @@ func (dec *Decoder) decode(val reflect.Value, nullOK bool) { } case reflect.Pointer: switch dec.peekRuneType() { - case internal.RuneTypeNullN: + case jsonparse.RuneTypeNullN: dec.decodeNull() val.Set(reflect.Zero(typ)) default: @@ -771,7 +768,7 @@ func (dec *Decoder) decode(val reflect.Value, nullOK bool) { } } -func (dec *Decoder) scan(out internal.RuneWriter) { +func (dec *Decoder) scan(out fastio.RuneWriter) { limiter := dec.limitingScanner() for { c, _, err := limiter.ReadRune() @@ -782,7 +779,7 @@ func (dec *Decoder) scan(out internal.RuneWriter) { } } -func (dec *Decoder) scanNumber(gTyp reflect.Type, out internal.RuneWriter) { +func (dec *Decoder) scanNumber(gTyp reflect.Type, out fastio.RuneWriter) { if t := dec.peekRuneType(); !t.IsNumber() { dec.panicType(t.JSONType(), gTyp, nil) } @@ -907,23 +904,23 @@ func DecodeObject(r io.RuneScanner, decodeKey, decodeVal func(io.RuneScanner) er } func (dec *Decoder) decodeObject(gTyp reflect.Type, decodeKey, decodeVal func()) { - dec.expectRuneType('{', internal.RuneTypeObjectBeg, gTyp) + dec.expectRuneType('{', jsonparse.RuneTypeObjectBeg, gTyp) _, t := dec.readRune() switch t { - case internal.RuneTypeObjectEnd: + case jsonparse.RuneTypeObjectEnd: return - case internal.RuneTypeStringBeg: + case jsonparse.RuneTypeStringBeg: decodeMember: dec.unreadRune() decodeKey() - dec.expectRune(':', internal.RuneTypeObjectColon) + dec.expectRune(':', jsonparse.RuneTypeObjectColon) decodeVal() _, t := dec.readRune() switch t { - case internal.RuneTypeObjectComma: - dec.expectRune('"', internal.RuneTypeStringBeg) + case jsonparse.RuneTypeObjectComma: + dec.expectRune('"', jsonparse.RuneTypeStringBeg) goto decodeMember - case internal.RuneTypeObjectEnd: + case jsonparse.RuneTypeObjectEnd: return default: panic("should not happen") @@ -978,10 +975,10 @@ func DecodeArray(r io.RuneScanner, decodeMember func(r io.RuneScanner) error) (e } func (dec *Decoder) decodeArray(gTyp reflect.Type, decodeMember func()) { - dec.expectRuneType('[', internal.RuneTypeArrayBeg, gTyp) + dec.expectRuneType('[', jsonparse.RuneTypeArrayBeg, gTyp) _, t := dec.readRune() switch t { - case internal.RuneTypeArrayEnd: + case jsonparse.RuneTypeArrayEnd: return default: dec.unreadRune() @@ -989,9 +986,9 @@ func (dec *Decoder) decodeArray(gTyp reflect.Type, decodeMember func()) { decodeMember() _, t := dec.readRune() switch t { - case internal.RuneTypeArrayComma: + case jsonparse.RuneTypeArrayComma: goto decodeNextMember - case internal.RuneTypeArrayEnd: + case jsonparse.RuneTypeArrayEnd: return default: panic("should not happen") @@ -999,17 +996,17 @@ func (dec *Decoder) decodeArray(gTyp reflect.Type, decodeMember func()) { } } -func (dec *Decoder) decodeString(gTyp reflect.Type, out internal.RuneWriter) { - dec.expectRuneType('"', internal.RuneTypeStringBeg, gTyp) +func (dec *Decoder) decodeString(gTyp reflect.Type, out fastio.RuneWriter) { + dec.expectRuneType('"', jsonparse.RuneTypeStringBeg, gTyp) var uhex [4]byte for { c, t := dec.readRune() switch t { - case internal.RuneTypeStringChar: + case jsonparse.RuneTypeStringChar: _, _ = out.WriteRune(c) - case internal.RuneTypeStringEsc, internal.RuneTypeStringEscU: + case jsonparse.RuneTypeStringEsc, jsonparse.RuneTypeStringEscU: // do nothing - case internal.RuneTypeStringEsc1: + case jsonparse.RuneTypeStringEsc1: switch c { case '"': _, _ = out.WriteRune('"') @@ -1030,14 +1027,14 @@ func (dec *Decoder) decodeString(gTyp reflect.Type, out internal.RuneWriter) { default: panic("should not happen") } - case internal.RuneTypeStringEscUA: - uhex[0], _ = internal.HexToInt(c) - case internal.RuneTypeStringEscUB: - uhex[1], _ = internal.HexToInt(c) - case internal.RuneTypeStringEscUC: - uhex[2], _ = internal.HexToInt(c) - case internal.RuneTypeStringEscUD: - uhex[3], _ = internal.HexToInt(c) + case jsonparse.RuneTypeStringEscUA: + uhex[0], _ = jsonparse.HexToInt(c) + case jsonparse.RuneTypeStringEscUB: + uhex[1], _ = jsonparse.HexToInt(c) + case jsonparse.RuneTypeStringEscUC: + uhex[2], _ = jsonparse.HexToInt(c) + case jsonparse.RuneTypeStringEscUD: + uhex[3], _ = jsonparse.HexToInt(c) c = 0 | rune(uhex[0])<<12 | rune(uhex[1])<<8 | @@ -1045,25 +1042,25 @@ func (dec *Decoder) decodeString(gTyp reflect.Type, out internal.RuneWriter) { rune(uhex[3])<<0 handleUnicode: if utf16.IsSurrogate(c) { - if dec.peekRuneType() != internal.RuneTypeStringEsc { + if dec.peekRuneType() != jsonparse.RuneTypeStringEsc { _, _ = out.WriteRune(utf8.RuneError) break } - dec.expectRune('\\', internal.RuneTypeStringEsc) - if dec.peekRuneType() != internal.RuneTypeStringEscU { + dec.expectRune('\\', jsonparse.RuneTypeStringEsc) + if dec.peekRuneType() != jsonparse.RuneTypeStringEscU { _, _ = out.WriteRune(utf8.RuneError) break } - dec.expectRune('u', internal.RuneTypeStringEscU) + dec.expectRune('u', jsonparse.RuneTypeStringEscU) b, _ := dec.readRune() - uhex[0], _ = internal.HexToInt(b) + uhex[0], _ = jsonparse.HexToInt(b) b, _ = dec.readRune() - uhex[1], _ = internal.HexToInt(b) + uhex[1], _ = jsonparse.HexToInt(b) b, _ = dec.readRune() - uhex[2], _ = internal.HexToInt(b) + uhex[2], _ = jsonparse.HexToInt(b) b, _ = dec.readRune() - uhex[3], _ = internal.HexToInt(b) + uhex[3], _ = jsonparse.HexToInt(b) c2 := 0 | rune(uhex[0])<<12 | rune(uhex[1])<<8 | @@ -1079,7 +1076,7 @@ func (dec *Decoder) decodeString(gTyp reflect.Type, out internal.RuneWriter) { } else { _, _ = out.WriteRune(c) } - case internal.RuneTypeStringEnd: + case jsonparse.RuneTypeStringEnd: return default: panic("should not happen") @@ -1091,15 +1088,15 @@ func (dec *Decoder) decodeBool(gTyp reflect.Type) bool { c, t := dec.readRune() switch c { case 't': - dec.expectRune('r', internal.RuneTypeTrueR) - dec.expectRune('u', internal.RuneTypeTrueU) - dec.expectRune('e', internal.RuneTypeTrueE) + dec.expectRune('r', jsonparse.RuneTypeTrueR) + dec.expectRune('u', jsonparse.RuneTypeTrueU) + dec.expectRune('e', jsonparse.RuneTypeTrueE) return true case 'f': - dec.expectRune('a', internal.RuneTypeFalseA) - dec.expectRune('l', internal.RuneTypeFalseL) - dec.expectRune('s', internal.RuneTypeFalseS) - dec.expectRune('e', internal.RuneTypeFalseE) + dec.expectRune('a', jsonparse.RuneTypeFalseA) + dec.expectRune('l', jsonparse.RuneTypeFalseL) + dec.expectRune('s', jsonparse.RuneTypeFalseS) + dec.expectRune('e', jsonparse.RuneTypeFalseE) return false default: dec.panicType(t.JSONType(), gTyp, nil) @@ -1108,8 +1105,8 @@ func (dec *Decoder) decodeBool(gTyp reflect.Type) bool { } func (dec *Decoder) decodeNull() { - dec.expectRune('n', internal.RuneTypeNullN) - dec.expectRune('u', internal.RuneTypeNullU) - dec.expectRune('l', internal.RuneTypeNullL1) - dec.expectRune('l', internal.RuneTypeNullL2) + dec.expectRune('n', jsonparse.RuneTypeNullN) + dec.expectRune('u', jsonparse.RuneTypeNullU) + dec.expectRune('l', jsonparse.RuneTypeNullL1) + dec.expectRune('l', jsonparse.RuneTypeNullL2) } |