diff options
author | Luke Shumaker <lukeshu@lukeshu.com> | 2023-02-07 12:18:29 -0700 |
---|---|---|
committer | Luke Shumaker <lukeshu@lukeshu.com> | 2023-02-07 14:05:26 -0700 |
commit | 2b9473f5e8816eeea76b2fdada184532be00d3a2 (patch) | |
tree | 387757b00f02521d1b3824a0e92f7778dbd32440 /decode.go | |
parent | eab38672b2467810592b61fe5b0067086d3cbd2c (diff) |
internal: Split in to sub-packages
Diffstat (limited to 'decode.go')
-rw-r--r-- | decode.go | 164 |
1 files changed, 83 insertions, 81 deletions
@@ -23,7 +23,9 @@ 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" ) // Decodable is the interface implemented by types that can decode a @@ -105,7 +107,7 @@ func NewDecoder(r io.RuneScanner) *Decoder { return &Decoder{ io: runeTypeScanner{ inner: r, - parser: internal.Parser{ + parser: jsonparse.Parser{ MaxDepth: maxNestingDepth, }, }, @@ -145,7 +147,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() { @@ -206,7 +208,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 { @@ -274,7 +276,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{ @@ -295,20 +297,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) @@ -325,7 +327,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 @@ -412,7 +414,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 } @@ -425,13 +427,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 } @@ -443,7 +445,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 } @@ -455,7 +457,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 } @@ -467,7 +469,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 } @@ -508,25 +510,25 @@ 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 } @@ -557,7 +559,7 @@ 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] @@ -569,7 +571,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())) } @@ -580,7 +582,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 @@ -590,7 +592,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) @@ -612,10 +614,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)) } @@ -670,24 +672,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++ { @@ -699,10 +701,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)) } @@ -725,7 +727,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 } @@ -741,7 +743,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++ }) @@ -750,7 +752,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: @@ -765,7 +767,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() @@ -776,7 +778,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) } @@ -901,23 +903,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") @@ -972,10 +974,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() @@ -983,9 +985,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") @@ -993,17 +995,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('"') @@ -1024,14 +1026,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 | @@ -1039,25 +1041,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 | @@ -1073,7 +1075,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") @@ -1085,15 +1087,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) @@ -1102,8 +1104,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) } |