summaryrefslogtreecommitdiff
path: root/decode.go
diff options
context:
space:
mode:
authorLuke Shumaker <lukeshu@lukeshu.com>2023-01-26 00:07:39 -0700
committerLuke Shumaker <lukeshu@lukeshu.com>2023-01-26 00:08:56 -0700
commit4148776399cb7ea5e10c74dc465e4e1e682cb399 (patch)
treedaf8a3aa6521d3d56aa986f10c3d23ea1b016f4b /decode.go
parente483afa206686ce748ad270140f99fad9d713aad (diff)
Move the Parser to the internal package
Diffstat (limited to 'decode.go')
-rw-r--r--decode.go184
1 files changed, 93 insertions, 91 deletions
diff --git a/decode.go b/decode.go
index fb94ba8..51c1ed5 100644
--- a/decode.go
+++ b/decode.go
@@ -15,6 +15,8 @@ import (
"strings"
"unicode/utf16"
"unicode/utf8"
+
+ "git.lukeshu.com/go/lowmemjson/internal"
)
type Decodable interface {
@@ -45,7 +47,7 @@ func NewDecoder(r io.RuneScanner) *Decoder {
io: &noWSRuneTypeScanner{
inner: &runeTypeScannerImpl{
inner: r,
- parser: Parser{
+ parser: internal.Parser{
MaxDepth: maxNestingDepth,
},
},
@@ -61,7 +63,7 @@ func (dec *Decoder) More() bool {
dec.io.Reset()
_, _, t, e := dec.io.ReadRuneType()
_ = dec.io.UnreadRune() // best effort
- return e == nil && t != RuneTypeEOF
+ return e == nil && t != internal.RuneTypeEOF
}
func (dec *Decoder) stackPush(par reflect.Type, idx any) {
@@ -110,7 +112,7 @@ func (dec *Decoder) DecodeThenEOF(ptr any) (err error) {
return err
}
c, s, t, _ := dec.io.ReadRuneType()
- if t != RuneTypeEOF {
+ if t != internal.RuneTypeEOF {
panic("should not happen")
}
if s > 0 {
@@ -171,7 +173,7 @@ func (dec *Decoder) panicType(jTyp string, gTyp reflect.Type, err error) {
})
}
-func (dec *Decoder) readRune() (rune, RuneType) {
+func (dec *Decoder) readRune() (rune, internal.RuneType) {
c, _, t, e := dec.io.ReadRuneType()
if e != nil {
panic(decodeError{
@@ -192,23 +194,23 @@ func (dec *Decoder) unreadRune() {
}
}
-func (dec *Decoder) peekRuneType() RuneType {
+func (dec *Decoder) peekRuneType() internal.RuneType {
_, t := dec.readRune()
dec.unreadRune()
return t
}
-func (dec *Decoder) expectRune(ec rune, et RuneType) {
+func (dec *Decoder) expectRune(ec rune, et internal.RuneType) {
ac, at := dec.readRune()
if ac != ec || at != et {
panic("should not happen")
}
}
-func (dec *Decoder) expectRuneType(ec rune, et RuneType, gt reflect.Type) {
+func (dec *Decoder) expectRuneType(ec rune, et internal.RuneType, gt reflect.Type) {
ac, at := dec.readRune()
if ac != ec || at != et {
- dec.panicType(at.jsonType(), gt, nil)
+ dec.panicType(at.JSONType(), gt, nil)
}
}
@@ -216,7 +218,7 @@ type decRuneTypeScanner struct {
dec *Decoder
}
-func (sc *decRuneTypeScanner) ReadRuneType() (rune, int, RuneType, error) {
+func (sc *decRuneTypeScanner) ReadRuneType() (rune, int, internal.RuneType, error) {
c, s, t, e := sc.dec.io.ReadRuneType()
if e != nil {
panic(decodeError{
@@ -231,7 +233,7 @@ func (sc *decRuneTypeScanner) ReadRuneType() (rune, int, RuneType, error) {
func (sc *decRuneTypeScanner) ReadRune() (rune, int, error) {
r, s, t, _ := sc.ReadRuneType()
switch t {
- case RuneTypeEOF:
+ case internal.RuneTypeEOF:
return 0, 0, io.EOF
default:
return r, s, nil
@@ -287,17 +289,17 @@ func (dec *Decoder) decode(val reflect.Value, nullOK bool) {
var buf bytes.Buffer
dec.scan(&buf)
if err := val.Addr().Interface().(*json.RawMessage).UnmarshalJSON(buf.Bytes()); err != nil {
- dec.panicType(t.jsonType(), typ, err)
+ dec.panicType(t.JSONType(), typ, err)
}
case val.CanAddr() && reflect.PointerTo(typ).Implements(decodableType):
t := dec.peekRuneType()
obj := val.Addr().Interface().(Decodable)
l := dec.limitingScanner()
if err := obj.DecodeJSON(l); err != nil {
- dec.panicType(t.jsonType(), typ, err)
+ dec.panicType(t.JSONType(), typ, err)
}
if _, _, err := l.ReadRune(); err != io.EOF {
- dec.panicType(t.jsonType(), typ, fmt.Errorf("did not consume entire %s", t.jsonType()))
+ dec.panicType(t.JSONType(), typ, fmt.Errorf("did not consume entire %s", t.JSONType()))
}
case val.CanAddr() && reflect.PointerTo(typ).Implements(jsonUnmarshalerType):
t := dec.peekRuneType()
@@ -305,10 +307,10 @@ func (dec *Decoder) decode(val reflect.Value, nullOK bool) {
dec.scan(&buf)
obj := val.Addr().Interface().(json.Unmarshaler)
if err := obj.UnmarshalJSON(buf.Bytes()); err != nil {
- dec.panicType(t.jsonType(), typ, err)
+ dec.panicType(t.JSONType(), typ, err)
}
case val.CanAddr() && reflect.PointerTo(typ).Implements(textUnmarshalerType):
- if nullOK && dec.peekRuneType() == RuneTypeNullN {
+ if nullOK && dec.peekRuneType() == internal.RuneTypeNullN {
dec.decodeNull()
return
}
@@ -321,13 +323,13 @@ func (dec *Decoder) decode(val reflect.Value, nullOK bool) {
default:
switch kind := typ.Kind(); kind {
case reflect.Bool:
- if nullOK && dec.peekRuneType() == RuneTypeNullN {
+ if nullOK && dec.peekRuneType() == internal.RuneTypeNullN {
dec.decodeNull()
return
}
val.SetBool(dec.decodeBool(typ))
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- if nullOK && dec.peekRuneType() == RuneTypeNullN {
+ if nullOK && dec.peekRuneType() == internal.RuneTypeNullN {
dec.decodeNull()
return
}
@@ -339,7 +341,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() == RuneTypeNullN {
+ if nullOK && dec.peekRuneType() == internal.RuneTypeNullN {
dec.decodeNull()
return
}
@@ -351,7 +353,7 @@ func (dec *Decoder) decode(val reflect.Value, nullOK bool) {
}
val.SetUint(n)
case reflect.Float32, reflect.Float64:
- if nullOK && dec.peekRuneType() == RuneTypeNullN {
+ if nullOK && dec.peekRuneType() == internal.RuneTypeNullN {
dec.decodeNull()
return
}
@@ -363,7 +365,7 @@ func (dec *Decoder) decode(val reflect.Value, nullOK bool) {
}
val.SetFloat(n)
case reflect.String:
- if nullOK && dec.peekRuneType() == RuneTypeNullN {
+ if nullOK && dec.peekRuneType() == internal.RuneTypeNullN {
dec.decodeNull()
return
}
@@ -372,7 +374,7 @@ func (dec *Decoder) decode(val reflect.Value, nullOK bool) {
t := dec.peekRuneType()
dec.scan(&buf)
if !t.IsNumber() {
- dec.panicType(t.jsonType(), typ,
+ dec.panicType(t.JSONType(), typ,
fmt.Errorf("json: invalid number literal, trying to unmarshal %q into Number",
buf.String()))
}
@@ -383,7 +385,7 @@ func (dec *Decoder) decode(val reflect.Value, nullOK bool) {
}
case reflect.Interface:
if typ.NumMethod() > 0 {
- dec.panicType(dec.peekRuneType().jsonType(), typ, ErrDecodeNonEmptyInterface)
+ dec.panicType(dec.peekRuneType().JSONType(), typ, ErrDecodeNonEmptyInterface)
}
// If the interface stores a pointer, try to use the type information of the pointer.
if !val.IsNil() && val.Elem().Kind() == reflect.Pointer {
@@ -404,25 +406,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() != RuneTypeNullN
+ // ptr.CanSet() || dec.peekRuneType() != internal.RuneTypeNullN
//
// We only need the pointer itself to be settable if we're
// decoding null.
- if ptr.Elem() != val && (ptr.CanSet() || dec.peekRuneType() != RuneTypeNullN) {
+ if ptr.Elem() != val && (ptr.CanSet() || dec.peekRuneType() != internal.RuneTypeNullN) {
dec.decode(ptr, false)
break
}
}
// Couldn't get type information from a pointer; fall back to untyped mode.
switch dec.peekRuneType() {
- case RuneTypeNullN:
+ case internal.RuneTypeNullN:
dec.decodeNull()
val.Set(reflect.Zero(typ))
default:
val.Set(reflect.ValueOf(dec.decodeAny()))
}
case reflect.Struct:
- if nullOK && dec.peekRuneType() == RuneTypeNullN {
+ if nullOK && dec.peekRuneType() == internal.RuneTypeNullN {
dec.decodeNull()
return
}
@@ -461,7 +463,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() != RuneTypeNullN {
+ if dec.peekRuneType() != internal.RuneTypeNullN {
if fVal.IsNil() {
fVal.Set(reflect.New(fVal.Type().Elem()))
}
@@ -472,7 +474,7 @@ func (dec *Decoder) decode(val reflect.Value, nullOK bool) {
}
if field.Quote {
switch t := dec.peekRuneType(); t {
- case RuneTypeNullN:
+ case internal.RuneTypeNullN:
dec.decodeNull()
switch fVal.Kind() {
// XXX: I can't justify this list, other than "it's what encoding/json
@@ -482,7 +484,7 @@ func (dec *Decoder) decode(val reflect.Value, nullOK bool) {
default:
// do nothing???
}
- case RuneTypeStringBeg:
+ case internal.RuneTypeStringBeg:
// TODO: Figure out how to do this without buffering, have correct offsets.
var buf bytes.Buffer
dec.decodeString(nil, &buf)
@@ -494,7 +496,7 @@ func (dec *Decoder) decode(val reflect.Value, nullOK bool) {
}
}
default:
- dec.panicType(t.jsonType(), fVal.Type(),
+ dec.panicType(t.JSONType(), fVal.Type(),
fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal unquoted value into %v",
fVal.Type()))
}
@@ -504,10 +506,10 @@ func (dec *Decoder) decode(val reflect.Value, nullOK bool) {
})
case reflect.Map:
switch t := dec.peekRuneType(); t {
- case RuneTypeNullN:
+ case internal.RuneTypeNullN:
dec.decodeNull()
val.Set(reflect.Zero(typ))
- case RuneTypeObjectBeg:
+ case internal.RuneTypeObjectBeg:
if val.IsNil() {
val.Set(reflect.MakeMap(typ))
}
@@ -553,19 +555,19 @@ func (dec *Decoder) decode(val reflect.Value, nullOK bool) {
val.SetMapIndex(nameValPtr.Elem(), fValPtr.Elem())
})
default:
- dec.panicType(t.jsonType(), typ, nil)
+ dec.panicType(t.JSONType(), typ, nil)
}
case reflect.Slice:
switch {
- case typ.Elem().Kind() == reflect.Uint8 && !(dec.peekRuneType() == RuneTypeArrayBeg && (false ||
+ case typ.Elem().Kind() == reflect.Uint8 && !(dec.peekRuneType() == internal.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 RuneTypeNullN:
+ case internal.RuneTypeNullN:
dec.decodeNull()
val.Set(reflect.Zero(typ))
- case RuneTypeStringBeg:
+ case internal.RuneTypeStringBeg:
if typ.Elem() == byteType {
var buf bytes.Buffer
dec.decodeString(typ, newBase64Decoder(&buf))
@@ -582,14 +584,14 @@ func (dec *Decoder) decode(val reflect.Value, nullOK bool) {
}
}
default:
- dec.panicType(t.jsonType(), typ, nil)
+ dec.panicType(t.JSONType(), typ, nil)
}
default:
switch t := dec.peekRuneType(); t {
- case RuneTypeNullN:
+ case internal.RuneTypeNullN:
dec.decodeNull()
val.Set(reflect.Zero(typ))
- case RuneTypeArrayBeg:
+ case internal.RuneTypeArrayBeg:
if val.IsNil() {
val.Set(reflect.MakeSlice(typ, 0, 0))
}
@@ -606,11 +608,11 @@ func (dec *Decoder) decode(val reflect.Value, nullOK bool) {
i++
})
default:
- dec.panicType(t.jsonType(), typ, nil)
+ dec.panicType(t.JSONType(), typ, nil)
}
}
case reflect.Array:
- if nullOK && dec.peekRuneType() == RuneTypeNullN {
+ if nullOK && dec.peekRuneType() == internal.RuneTypeNullN {
dec.decodeNull()
return
}
@@ -633,7 +635,7 @@ func (dec *Decoder) decode(val reflect.Value, nullOK bool) {
}
case reflect.Pointer:
switch dec.peekRuneType() {
- case RuneTypeNullN:
+ case internal.RuneTypeNullN:
dec.decodeNull()
val.Set(reflect.Zero(typ))
default:
@@ -661,7 +663,7 @@ func (dec *Decoder) scan(out io.Writer) {
func (dec *Decoder) scanNumber(gTyp reflect.Type, out io.Writer) {
if t := dec.peekRuneType(); !t.IsNumber() {
- dec.panicType(t.jsonType(), gTyp, nil)
+ dec.panicType(t.JSONType(), gTyp, nil)
}
dec.scan(out)
}
@@ -746,33 +748,33 @@ func DecodeObject(r io.RuneScanner, decodeKey, decodeVal func(io.RuneScanner) er
t := dec.peekRuneType()
l := dec.limitingScanner()
if err := decodeVal(l); err != nil {
- dec.panicType(t.jsonType(), nil, err)
+ dec.panicType(t.JSONType(), nil, err)
}
if _, _, err := l.ReadRune(); err != io.EOF {
- dec.panicType(t.jsonType(), nil, fmt.Errorf("did not consume entire %s", t.jsonType()))
+ dec.panicType(t.JSONType(), nil, fmt.Errorf("did not consume entire %s", t.JSONType()))
}
})
return
}
func (dec *Decoder) decodeObject(gTyp reflect.Type, decodeKey, decodeVal func()) {
- dec.expectRuneType('{', RuneTypeObjectBeg, gTyp)
+ dec.expectRuneType('{', internal.RuneTypeObjectBeg, gTyp)
_, t := dec.readRune()
switch t {
- case RuneTypeObjectEnd:
+ case internal.RuneTypeObjectEnd:
return
- case RuneTypeStringBeg:
+ case internal.RuneTypeStringBeg:
decodeMember:
dec.unreadRune()
decodeKey()
- dec.expectRune(':', RuneTypeObjectColon)
+ dec.expectRune(':', internal.RuneTypeObjectColon)
decodeVal()
_, t := dec.readRune()
switch t {
- case RuneTypeObjectComma:
- dec.expectRune('"', RuneTypeStringBeg)
+ case internal.RuneTypeObjectComma:
+ dec.expectRune('"', internal.RuneTypeStringBeg)
goto decodeMember
- case RuneTypeObjectEnd:
+ case internal.RuneTypeObjectEnd:
return
default:
panic("should not happen")
@@ -799,20 +801,20 @@ func DecodeArray(r io.RuneScanner, decodeMember func(r io.RuneScanner) error) (e
t := dec.peekRuneType()
l := dec.limitingScanner()
if err := decodeMember(l); err != nil {
- dec.panicType(t.jsonType(), nil, err)
+ dec.panicType(t.JSONType(), nil, err)
}
if _, _, err := l.ReadRune(); err != io.EOF {
- dec.panicType(t.jsonType(), nil, fmt.Errorf("did not consume entire %s", t.jsonType()))
+ dec.panicType(t.JSONType(), nil, fmt.Errorf("did not consume entire %s", t.JSONType()))
}
})
return
}
func (dec *Decoder) decodeArray(gTyp reflect.Type, decodeMember func()) {
- dec.expectRuneType('[', RuneTypeArrayBeg, gTyp)
+ dec.expectRuneType('[', internal.RuneTypeArrayBeg, gTyp)
_, t := dec.readRune()
switch t {
- case RuneTypeArrayEnd:
+ case internal.RuneTypeArrayEnd:
return
default:
dec.unreadRune()
@@ -820,9 +822,9 @@ func (dec *Decoder) decodeArray(gTyp reflect.Type, decodeMember func()) {
decodeMember()
_, t := dec.readRune()
switch t {
- case RuneTypeArrayComma:
+ case internal.RuneTypeArrayComma:
goto decodeNextMember
- case RuneTypeArrayEnd:
+ case internal.RuneTypeArrayEnd:
return
default:
panic("should not happen")
@@ -831,16 +833,16 @@ func (dec *Decoder) decodeArray(gTyp reflect.Type, decodeMember func()) {
}
func (dec *Decoder) decodeString(gTyp reflect.Type, out io.Writer) {
- dec.expectRuneType('"', RuneTypeStringBeg, gTyp)
+ dec.expectRuneType('"', internal.RuneTypeStringBeg, gTyp)
var uhex [4]byte
for {
c, t := dec.readRune()
switch t {
- case RuneTypeStringChar:
+ case internal.RuneTypeStringChar:
_, _ = writeRune(out, c)
- case RuneTypeStringEsc, RuneTypeStringEscU:
+ case internal.RuneTypeStringEsc, internal.RuneTypeStringEscU:
// do nothing
- case RuneTypeStringEsc1:
+ case internal.RuneTypeStringEsc1:
switch c {
case '"':
_, _ = writeRune(out, '"')
@@ -861,14 +863,14 @@ func (dec *Decoder) decodeString(gTyp reflect.Type, out io.Writer) {
default:
panic("should not happen")
}
- case RuneTypeStringEscUA:
- uhex[0], _ = hex2int(c)
- case RuneTypeStringEscUB:
- uhex[1], _ = hex2int(c)
- case RuneTypeStringEscUC:
- uhex[2], _ = hex2int(c)
- case RuneTypeStringEscUD:
- uhex[3], _ = hex2int(c)
+ 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)
c = 0 |
rune(uhex[0])<<12 |
rune(uhex[1])<<8 |
@@ -876,25 +878,25 @@ func (dec *Decoder) decodeString(gTyp reflect.Type, out io.Writer) {
rune(uhex[3])<<0
handleUnicode:
if utf16.IsSurrogate(c) {
- if dec.peekRuneType() != RuneTypeStringEsc {
+ if dec.peekRuneType() != internal.RuneTypeStringEsc {
_, _ = writeRune(out, utf8.RuneError)
break
}
- dec.expectRune('\\', RuneTypeStringEsc)
- if dec.peekRuneType() != RuneTypeStringEscU {
+ dec.expectRune('\\', internal.RuneTypeStringEsc)
+ if dec.peekRuneType() != internal.RuneTypeStringEscU {
_, _ = writeRune(out, utf8.RuneError)
break
}
- dec.expectRune('u', RuneTypeStringEscU)
+ dec.expectRune('u', internal.RuneTypeStringEscU)
b, _ := dec.readRune()
- uhex[0], _ = hex2int(b)
+ uhex[0], _ = internal.HexToInt(b)
b, _ = dec.readRune()
- uhex[1], _ = hex2int(b)
+ uhex[1], _ = internal.HexToInt(b)
b, _ = dec.readRune()
- uhex[2], _ = hex2int(b)
+ uhex[2], _ = internal.HexToInt(b)
b, _ = dec.readRune()
- uhex[3], _ = hex2int(b)
+ uhex[3], _ = internal.HexToInt(b)
c2 := 0 |
rune(uhex[0])<<12 |
rune(uhex[1])<<8 |
@@ -910,7 +912,7 @@ func (dec *Decoder) decodeString(gTyp reflect.Type, out io.Writer) {
} else {
_, _ = writeRune(out, c)
}
- case RuneTypeStringEnd:
+ case internal.RuneTypeStringEnd:
return
default:
panic("should not happen")
@@ -922,25 +924,25 @@ func (dec *Decoder) decodeBool(gTyp reflect.Type) bool {
c, t := dec.readRune()
switch c {
case 't':
- dec.expectRune('r', RuneTypeTrueR)
- dec.expectRune('u', RuneTypeTrueU)
- dec.expectRune('e', RuneTypeTrueE)
+ dec.expectRune('r', internal.RuneTypeTrueR)
+ dec.expectRune('u', internal.RuneTypeTrueU)
+ dec.expectRune('e', internal.RuneTypeTrueE)
return true
case 'f':
- dec.expectRune('a', RuneTypeFalseA)
- dec.expectRune('l', RuneTypeFalseL)
- dec.expectRune('s', RuneTypeFalseS)
- dec.expectRune('e', RuneTypeFalseE)
+ dec.expectRune('a', internal.RuneTypeFalseA)
+ dec.expectRune('l', internal.RuneTypeFalseL)
+ dec.expectRune('s', internal.RuneTypeFalseS)
+ dec.expectRune('e', internal.RuneTypeFalseE)
return false
default:
- dec.panicType(t.jsonType(), gTyp, nil)
+ dec.panicType(t.JSONType(), gTyp, nil)
panic("not reached")
}
}
func (dec *Decoder) decodeNull() {
- dec.expectRune('n', RuneTypeNullN)
- dec.expectRune('u', RuneTypeNullU)
- dec.expectRune('l', RuneTypeNullL1)
- dec.expectRune('l', RuneTypeNullL2)
+ dec.expectRune('n', internal.RuneTypeNullN)
+ dec.expectRune('u', internal.RuneTypeNullU)
+ dec.expectRune('l', internal.RuneTypeNullL1)
+ dec.expectRune('l', internal.RuneTypeNullL2)
}