summaryrefslogtreecommitdiff
path: root/decode.go
diff options
context:
space:
mode:
Diffstat (limited to 'decode.go')
-rw-r--r--decode.go183
1 files changed, 90 insertions, 93 deletions
diff --git a/decode.go b/decode.go
index 60b530f..487bce4 100644
--- a/decode.go
+++ b/decode.go
@@ -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)
}