summaryrefslogtreecommitdiff
path: root/decode.go
diff options
context:
space:
mode:
authorLuke Shumaker <lukeshu@lukeshu.com>2023-02-07 12:18:29 -0700
committerLuke Shumaker <lukeshu@lukeshu.com>2023-02-07 14:05:26 -0700
commit2b9473f5e8816eeea76b2fdada184532be00d3a2 (patch)
tree387757b00f02521d1b3824a0e92f7778dbd32440 /decode.go
parenteab38672b2467810592b61fe5b0067086d3cbd2c (diff)
internal: Split in to sub-packages
Diffstat (limited to 'decode.go')
-rw-r--r--decode.go164
1 files changed, 83 insertions, 81 deletions
diff --git a/decode.go b/decode.go
index 8638148..3a9a4b1 100644
--- a/decode.go
+++ b/decode.go
@@ -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)
}