gofront 1.7.0 → 1.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -14
- package/package.json +10 -38
- package/src/backend/js/expressions.js +2060 -389
- package/src/backend/js/index.js +586 -174
- package/src/backend/js/natives.js +383 -0
- package/src/backend/js/runtime.js +936 -1644
- package/src/backend/js/statements.js +1349 -132
- package/src/backend/js/stdlib/index.js +51 -94
- package/src/backend/js/templ.js +67 -118
- package/src/backend/js/type-info.js +436 -0
- package/src/backend/shared/fixed-float.js +20 -0
- package/src/backend/shared/fmt-types.js +80 -0
- package/src/backend/shared/host-unicode.js +36 -0
- package/src/backend/wasm/boundary.js +753 -872
- package/src/backend/wasm/emit-builtins.js +914 -237
- package/src/backend/wasm/emit-exprs.js +1456 -195
- package/src/backend/wasm/emit-maps.js +78 -380
- package/src/backend/wasm/emit-stmts.js +1659 -214
- package/src/backend/wasm/emit.js +614 -88
- package/src/backend/wasm/encode.js +43 -13
- package/src/backend/wasm/globals.js +491 -0
- package/src/backend/wasm/glue.js +2 -4
- package/src/backend/wasm/index.js +406 -3195
- package/src/backend/wasm/method-expr.js +392 -0
- package/src/backend/wasm/module-emitter.js +1615 -0
- package/src/backend/wasm/monomorph.js +164 -9
- package/src/backend/wasm/natives.js +596 -0
- package/src/backend/wasm/prescan.js +249 -0
- package/src/backend/wasm/prune-funcs.js +89 -0
- package/src/backend/wasm/stdlib/index.js +2 -37
- package/src/backend/wasm/stdlib/simd.js +293 -28
- package/src/backend/wasm/types.js +260 -27
- package/src/backend/wasm/variadic.js +93 -0
- package/src/backend/wasm/wat.js +47 -20
- package/src/{cli-core.js → cli/cli-core.js} +241 -11
- package/src/{test-runner.js → cli/test-runner.js} +188 -122
- package/src/{vendor.js → cli/vendor.js} +3 -4
- package/src/compiler.js +202 -386
- package/src/index.js +15 -169
- package/src/{lexer.js → lexer/lexer.js} +203 -62
- package/src/{templ-lexer.js → lexer/templ-lexer.js} +61 -18
- package/src/{tokens.js → lexer/tokens.js} +2 -0
- package/src/link/sourcemap.js +97 -0
- package/src/link/stdlib.js +737 -0
- package/src/link/type-names.js +148 -0
- package/src/link/wasm.js +318 -0
- package/src/lower/bounds.js +547 -0
- package/src/lower/boxing.js +1 -1
- package/src/lower/captures.js +267 -64
- package/src/lower/embedding.js +32 -3
- package/src/lower/errors-as.js +196 -0
- package/src/lower/fmt-formatters.js +905 -0
- package/src/lower/functions.js +2 -0
- package/src/lower/gen-types.js +274 -0
- package/src/lower/index.js +33 -19
- package/src/lower/json-codecs.js +1379 -0
- package/src/lower/ownership.js +47 -8
- package/src/lower/range.js +86 -1
- package/src/lower/reachability.js +150 -0
- package/src/lower/walk.js +12 -0
- package/src/parser/declarations.js +83 -15
- package/src/parser/expressions.js +110 -18
- package/src/parser/index.js +2 -1
- package/src/parser/statements.js +38 -22
- package/src/{templ-parser.js → parser/templ.js} +179 -17
- package/src/parser/types.js +70 -9
- package/src/resolver.js +21 -1
- package/src/typechecker/assignability.js +291 -19
- package/src/typechecker/const-fold.js +399 -0
- package/src/typechecker/constants.js +282 -0
- package/src/typechecker/expressions.js +1220 -183
- package/src/typechecker/index.js +659 -92
- package/src/typechecker/init-order.js +426 -0
- package/src/typechecker/operand-text.js +40 -0
- package/src/typechecker/resolve.js +613 -62
- package/src/typechecker/statements.js +212 -20
- package/src/typechecker/stdlib/excluded.js +902 -0
- package/src/typechecker/stdlib/index.js +38 -0
- package/src/typechecker/stdlib/simd.js +65 -15
- package/src/typechecker/termination.js +11 -2
- package/src/typechecker/types.js +268 -514
- package/stdlib/bytes/buffer.go +479 -0
- package/stdlib/bytes/bytes.go +1010 -0
- package/stdlib/bytes/reader.go +161 -0
- package/stdlib/cmp/cmp.go +65 -0
- package/stdlib/context/context.go +115 -0
- package/stdlib/crypto/rand/rand.go +34 -0
- package/stdlib/crypto/sha256/sha256.go +249 -0
- package/stdlib/encoding/base64/base64.go +331 -0
- package/stdlib/encoding/binary/binary.go +332 -0
- package/stdlib/encoding/hex/hex.go +140 -0
- package/stdlib/encoding/json/errors.go +31 -0
- package/stdlib/encoding/json/indent.go +71 -0
- package/stdlib/encoding/json/json.go +62 -0
- package/stdlib/encoding/json/number.go +12 -0
- package/stdlib/encoding/json/stream.go +173 -0
- package/stdlib/errors/errors.go +174 -0
- package/stdlib/fmt/errors.go +110 -0
- package/stdlib/fmt/format.go +732 -0
- package/stdlib/fmt/print.go +1232 -0
- package/stdlib/gom/gom.go +293 -0
- package/stdlib/hash/hash.go +53 -0
- package/stdlib/html/html.go +251 -0
- package/stdlib/internal/fmtrt/fmtrt.go +163 -0
- package/stdlib/internal/jsonrt/dec.go +871 -0
- package/stdlib/internal/jsonrt/enc.go +516 -0
- package/stdlib/internal/jsonrt/indent.go +135 -0
- package/stdlib/internal/jsonrt/number.go +27 -0
- package/stdlib/internal/jsonrt/reader.go +73 -0
- package/stdlib/internal/jsonrt/scanner.go +658 -0
- package/stdlib/io/io.go +502 -0
- package/stdlib/iter/iter.go +18 -0
- package/stdlib/maps/maps.go +131 -0
- package/stdlib/math/bits/bits.go +507 -0
- package/stdlib/math/extra.go +272 -0
- package/stdlib/math/math.go +439 -0
- package/stdlib/math/rand/rand.go +297 -0
- package/stdlib/os/os.go +93 -0
- package/stdlib/path/filepath/filepath.go +47 -0
- package/stdlib/path/path.go +394 -0
- package/stdlib/regexp/regexp.go +231 -0
- package/stdlib/slices/slices.go +526 -0
- package/stdlib/slices/sort.go +209 -0
- package/stdlib/slices/zsort_cmp.go +480 -0
- package/stdlib/slices/zsort_ordered.go +482 -0
- package/stdlib/sort/sort.go +500 -0
- package/stdlib/sort/zsort_func.go +480 -0
- package/stdlib/sort/zsort_iface.go +480 -0
- package/stdlib/strconv/float.go +1699 -0
- package/stdlib/strconv/isprint.go +752 -0
- package/stdlib/strconv/quote.go +526 -0
- package/stdlib/strconv/strconv.go +616 -0
- package/stdlib/strings/builder.go +95 -0
- package/stdlib/strings/reader.go +163 -0
- package/stdlib/strings/replacer.go +102 -0
- package/stdlib/strings/strings.go +807 -0
- package/stdlib/sync/sync.go +268 -0
- package/stdlib/testing/async_js.go +61 -0
- package/stdlib/testing/benchmark.go +297 -0
- package/stdlib/testing/testing.go +523 -0
- package/stdlib/time/duration.go +233 -0
- package/stdlib/time/format.go +745 -0
- package/stdlib/time/parse.go +790 -0
- package/stdlib/time/sleep_js.go +63 -0
- package/stdlib/time/time.go +834 -0
- package/stdlib/unicode/unicode.go +250 -0
- package/stdlib/unicode/utf8/utf8.go +464 -0
- package/src/backend/js/stdlib/base64.js +0 -12
- package/src/backend/js/stdlib/binary.js +0 -102
- package/src/backend/js/stdlib/bits.js +0 -46
- package/src/backend/js/stdlib/builder.js +0 -63
- package/src/backend/js/stdlib/bytes.js +0 -122
- package/src/backend/js/stdlib/errors.js +0 -44
- package/src/backend/js/stdlib/fmt.js +0 -178
- package/src/backend/js/stdlib/gom.js +0 -155
- package/src/backend/js/stdlib/hex.js +0 -17
- package/src/backend/js/stdlib/html.js +0 -20
- package/src/backend/js/stdlib/io.js +0 -137
- package/src/backend/js/stdlib/json.js +0 -972
- package/src/backend/js/stdlib/maps.js +0 -45
- package/src/backend/js/stdlib/math.js +0 -69
- package/src/backend/js/stdlib/os.js +0 -13
- package/src/backend/js/stdlib/path.js +0 -48
- package/src/backend/js/stdlib/rand.js +0 -32
- package/src/backend/js/stdlib/regexp.js +0 -54
- package/src/backend/js/stdlib/sha256.js +0 -12
- package/src/backend/js/stdlib/shared.js +0 -17
- package/src/backend/js/stdlib/simd.js +0 -24
- package/src/backend/js/stdlib/slices.js +0 -77
- package/src/backend/js/stdlib/sort.js +0 -30
- package/src/backend/js/stdlib/strconv.js +0 -74
- package/src/backend/js/stdlib/strings.js +0 -222
- package/src/backend/js/stdlib/sync.js +0 -13
- package/src/backend/js/stdlib/testing.js +0 -34
- package/src/backend/js/stdlib/time.js +0 -128
- package/src/backend/js/stdlib/unicode.js +0 -25
- package/src/backend/js/stdlib/utf8.js +0 -26
- package/src/backend/wasm/const-fold.js +0 -205
- package/src/backend/wasm/emit-stdlib.js +0 -13
- package/src/backend/wasm/stdlib/bytes.js +0 -5039
- package/src/backend/wasm/stdlib/core.js +0 -8903
- package/src/backend/wasm/stdlib/io.js +0 -2161
- package/src/backend/wasm/stdlib/packages.js +0 -2400
- package/src/backend/wasm/stdlib/pure.js +0 -720
- package/src/backend/wasm/stdlib/time.js +0 -1200
- package/src/typechecker/stdlib/core.js +0 -801
- package/src/typechecker/stdlib/extended.js +0 -914
- package/src/typechecker/stdlib.js +0 -22
- /package/src/{asset-manager.js → cli/asset-manager.js} +0 -0
- /package/src/{colors.js → cli/colors.js} +0 -0
- /package/src/{dev-server.js → cli/dev-server.js} +0 -0
- /package/src/{minifier.js → cli/minifier.js} +0 -0
- /package/src/{project-config.js → cli/project-config.js} +0 -0
- /package/src/{pwa.js → cli/pwa.js} +0 -0
|
@@ -0,0 +1,871 @@
|
|
|
1
|
+
// Copyright 2010 The Go Authors. All rights reserved.
|
|
2
|
+
// Use of this source code is governed by a BSD-style
|
|
3
|
+
// license that can be found in the LICENSE file.
|
|
4
|
+
|
|
5
|
+
//go:build gofront
|
|
6
|
+
|
|
7
|
+
//gofront:target both
|
|
8
|
+
|
|
9
|
+
package jsonrt
|
|
10
|
+
|
|
11
|
+
import (
|
|
12
|
+
"encoding/base64"
|
|
13
|
+
"errors"
|
|
14
|
+
"fmt"
|
|
15
|
+
"math"
|
|
16
|
+
"strconv"
|
|
17
|
+
"strings"
|
|
18
|
+
"unicode/utf8"
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
// An UnmarshalTypeError describes a JSON value that was not appropriate for
|
|
22
|
+
// a value of a specific Go type.
|
|
23
|
+
type UnmarshalTypeError struct {
|
|
24
|
+
Value string // description of JSON value - "bool", "array", "number -5"
|
|
25
|
+
Type string // type of Go value it could not be assigned to
|
|
26
|
+
Offset int64 // error occurred after reading Offset bytes
|
|
27
|
+
Struct string // name of the struct type containing the field
|
|
28
|
+
Field string // the full path from the root struct to the value
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
func (e *UnmarshalTypeError) Error() string {
|
|
32
|
+
if e.Struct != "" || e.Field != "" {
|
|
33
|
+
return "json: cannot unmarshal " + e.Value + " into Go struct field " + e.Struct + "." + e.Field + " of type " + e.Type
|
|
34
|
+
}
|
|
35
|
+
return "json: cannot unmarshal " + e.Value + " into Go value of type " + e.Type
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// An InvalidUnmarshalError describes an invalid argument passed to Unmarshal.
|
|
39
|
+
type InvalidUnmarshalError struct {
|
|
40
|
+
Type string // "" for a nil argument
|
|
41
|
+
IsPtr bool
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
func (e *InvalidUnmarshalError) Error() string {
|
|
45
|
+
if e.Type == "" {
|
|
46
|
+
return "json: Unmarshal(nil)"
|
|
47
|
+
}
|
|
48
|
+
if !e.IsPtr {
|
|
49
|
+
return "json: Unmarshal(non-pointer " + e.Type + ")"
|
|
50
|
+
}
|
|
51
|
+
return "json: Unmarshal(nil " + e.Type + ")"
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Dec is the state of one Unmarshal call. The input has been checked to be
|
|
55
|
+
// valid JSON, so the readers below do not look for syntax errors.
|
|
56
|
+
type Dec struct {
|
|
57
|
+
data []byte
|
|
58
|
+
pos int
|
|
59
|
+
Err error
|
|
60
|
+
fatal bool
|
|
61
|
+
structs []string // stack of struct names, depth entries live
|
|
62
|
+
fields []string // stack of field names, depth entries live
|
|
63
|
+
depth int
|
|
64
|
+
key string
|
|
65
|
+
UseNumber bool
|
|
66
|
+
DisallowUnknownFields bool
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// NewDec checks that data is one valid JSON value and returns a decoder
|
|
70
|
+
// positioned at it.
|
|
71
|
+
func NewDec(data []byte) (*Dec, error) {
|
|
72
|
+
if err := CheckValid(data); err != nil {
|
|
73
|
+
return nil, err
|
|
74
|
+
}
|
|
75
|
+
return &Dec{data: data}, nil
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// UnknownField records an error when an unknown struct field is encountered with DisallowUnknownFields.
|
|
79
|
+
func (d *Dec) UnknownField(field string) {
|
|
80
|
+
d.Save(fmt.Errorf("json: unknown field %q", field))
|
|
81
|
+
d.Skip()
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// InvalidUnmarshal is the error for a Unmarshal target v that is not a pointer
|
|
85
|
+
// to a type the compiler generated a decoder for.
|
|
86
|
+
func InvalidUnmarshal(v any) error {
|
|
87
|
+
if v == nil {
|
|
88
|
+
return &InvalidUnmarshalError{}
|
|
89
|
+
}
|
|
90
|
+
name := fmt.Sprintf("%T", v)
|
|
91
|
+
return &InvalidUnmarshalError{Type: name, IsPtr: strings.HasPrefix(name, "*")}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// Done returns the first error found while decoding, if any.
|
|
95
|
+
func (d *Dec) Done() error {
|
|
96
|
+
return d.Err
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Fatal records an error from an Unmarshaler; decoding stops at once.
|
|
100
|
+
func (d *Dec) Fatal(err error) {
|
|
101
|
+
d.Err = err
|
|
102
|
+
d.fatal = true
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// Failed reports whether decoding was stopped by Fatal.
|
|
106
|
+
func (d *Dec) Failed() bool {
|
|
107
|
+
return d.fatal
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Enter and Leave track the struct field being decoded for error messages.
|
|
111
|
+
// The stacks keep their entries and move an index, so no slice is resliced
|
|
112
|
+
// or copied per struct.
|
|
113
|
+
func (d *Dec) Enter(structName, field string) {
|
|
114
|
+
if d.depth < len(d.fields) {
|
|
115
|
+
d.structs[d.depth] = structName
|
|
116
|
+
d.fields[d.depth] = field
|
|
117
|
+
} else {
|
|
118
|
+
d.structs = append(d.structs, structName)
|
|
119
|
+
d.fields = append(d.fields, field)
|
|
120
|
+
}
|
|
121
|
+
d.depth++
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
func (d *Dec) Leave() {
|
|
125
|
+
d.depth--
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
func (d *Dec) ws() {
|
|
129
|
+
for d.pos < len(d.data) {
|
|
130
|
+
c := d.data[d.pos]
|
|
131
|
+
if c == ' ' || c == '\t' || c == '\n' || c == '\r' {
|
|
132
|
+
d.pos++
|
|
133
|
+
} else {
|
|
134
|
+
return
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
func (d *Dec) peek() byte {
|
|
140
|
+
d.ws()
|
|
141
|
+
if d.pos >= len(d.data) {
|
|
142
|
+
return 0
|
|
143
|
+
}
|
|
144
|
+
return d.data[d.pos]
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// kind names the JSON value at the current position.
|
|
148
|
+
func (d *Dec) kind() string {
|
|
149
|
+
switch d.peek() {
|
|
150
|
+
case '"':
|
|
151
|
+
return "string"
|
|
152
|
+
case '{':
|
|
153
|
+
return "object"
|
|
154
|
+
case '[':
|
|
155
|
+
return "array"
|
|
156
|
+
case 't', 'f':
|
|
157
|
+
return "bool"
|
|
158
|
+
case 'n':
|
|
159
|
+
return "null"
|
|
160
|
+
}
|
|
161
|
+
return "number"
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
func (d *Dec) typeErr(value, typ string) {
|
|
165
|
+
if d.Err != nil {
|
|
166
|
+
return
|
|
167
|
+
}
|
|
168
|
+
e := &UnmarshalTypeError{Value: value, Type: typ, Offset: int64(d.pos)}
|
|
169
|
+
if d.depth > 0 {
|
|
170
|
+
e.Struct = d.structs[d.depth-1]
|
|
171
|
+
e.Field = strings.Join(d.fields[:d.depth], ".")
|
|
172
|
+
}
|
|
173
|
+
d.Err = e
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// Mismatch records a type error for the next value, which cannot be stored
|
|
177
|
+
// in a value of type typ, and skips it.
|
|
178
|
+
func (d *Dec) Mismatch(typ string) {
|
|
179
|
+
if d.fatal {
|
|
180
|
+
return
|
|
181
|
+
}
|
|
182
|
+
k := d.kind()
|
|
183
|
+
d.Skip()
|
|
184
|
+
d.typeErr(k, typ)
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// IsArray reports whether the next value is an array.
|
|
188
|
+
func (d *Dec) IsArray() bool {
|
|
189
|
+
return d.peek() == '['
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// Bytes decodes a base64 string into a byte slice. ok is false for null and
|
|
193
|
+
// for a value that is not a string (an error is recorded unless it is null).
|
|
194
|
+
func (d *Dec) Bytes(typ string) (v []byte, ok bool) {
|
|
195
|
+
s, ok := d.String(typ)
|
|
196
|
+
if !ok {
|
|
197
|
+
return nil, false
|
|
198
|
+
}
|
|
199
|
+
b, err := base64.StdEncoding.DecodeString(s)
|
|
200
|
+
if err != nil {
|
|
201
|
+
d.Save(err)
|
|
202
|
+
return nil, false
|
|
203
|
+
}
|
|
204
|
+
return b, true
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
// KeyInt parses the current object member name as an integer map key.
|
|
208
|
+
func (d *Dec) KeyInt(bits int, signed bool, typ string) (int64, bool) {
|
|
209
|
+
s := d.key
|
|
210
|
+
if signed {
|
|
211
|
+
n, err := strconv.ParseInt(s, 10, bits)
|
|
212
|
+
if err != nil {
|
|
213
|
+
d.typeErr("number "+s, typ)
|
|
214
|
+
return 0, false
|
|
215
|
+
}
|
|
216
|
+
return n, true
|
|
217
|
+
}
|
|
218
|
+
n, err := strconv.ParseUint(s, 10, bits)
|
|
219
|
+
if err != nil {
|
|
220
|
+
d.typeErr("number "+s, typ)
|
|
221
|
+
return 0, false
|
|
222
|
+
}
|
|
223
|
+
return int64(n), true
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
// Unquote reads the string value of a ,string field and returns a decoder
|
|
227
|
+
// for the JSON text inside it, which must be a literal of the given kind
|
|
228
|
+
// ("string", "bool" or "number"). It returns nil for null, and for a value
|
|
229
|
+
// that does not qualify, after recording Go's error.
|
|
230
|
+
func (d *Dec) Unquote(typ, kind string) *Dec {
|
|
231
|
+
if d.fatal || d.Null() {
|
|
232
|
+
return nil
|
|
233
|
+
}
|
|
234
|
+
if d.peek() != '"' {
|
|
235
|
+
d.Save(errors.New("json: invalid use of ,string struct tag, trying to unmarshal unquoted value into " + typ))
|
|
236
|
+
d.Skip()
|
|
237
|
+
return nil
|
|
238
|
+
}
|
|
239
|
+
s := readStr(d)
|
|
240
|
+
b := []byte(s)
|
|
241
|
+
if s == "null" {
|
|
242
|
+
return nil
|
|
243
|
+
}
|
|
244
|
+
ok := len(b) > 0 && CheckValid(b) == nil
|
|
245
|
+
// A number that starts like one but is not valid fails like any other
|
|
246
|
+
// malformed number.
|
|
247
|
+
if !ok && kind == "number" && len(b) > 0 && (b[0] == '-' || (b[0] >= '0' && b[0] <= '9')) {
|
|
248
|
+
d.typeErr("number "+s, typ)
|
|
249
|
+
return nil
|
|
250
|
+
}
|
|
251
|
+
if ok {
|
|
252
|
+
c := b[0]
|
|
253
|
+
switch kind {
|
|
254
|
+
case "string":
|
|
255
|
+
ok = c == '"'
|
|
256
|
+
case "bool":
|
|
257
|
+
ok = c == 't' || c == 'f'
|
|
258
|
+
default:
|
|
259
|
+
ok = c == '-' || (c >= '0' && c <= '9')
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
if !ok {
|
|
263
|
+
d.Save(errors.New("json: invalid use of ,string struct tag, trying to unmarshal " + strconv.Quote(s) + " into " + typ))
|
|
264
|
+
return nil
|
|
265
|
+
}
|
|
266
|
+
return &Dec{data: b, structs: d.structs, fields: d.fields, depth: d.depth}
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
// Merge takes over the first error of a decoder made by Unquote.
|
|
270
|
+
func (d *Dec) Merge(sub *Dec) {
|
|
271
|
+
if d.Err == nil {
|
|
272
|
+
d.Err = sub.Err
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
// Save records a non-fatal error (the first one wins).
|
|
277
|
+
func (d *Dec) Save(err error) {
|
|
278
|
+
if d.Err == nil {
|
|
279
|
+
d.Err = err
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
// Null consumes a null and reports whether there was one.
|
|
284
|
+
func (d *Dec) Null() bool {
|
|
285
|
+
if d.fatal {
|
|
286
|
+
return true
|
|
287
|
+
}
|
|
288
|
+
if d.peek() == 'n' {
|
|
289
|
+
d.pos += 4
|
|
290
|
+
return true
|
|
291
|
+
}
|
|
292
|
+
return false
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
// IsNull reports whether the next value is null, without consuming it.
|
|
296
|
+
func (d *Dec) IsNull() bool {
|
|
297
|
+
return d.peek() == 'n'
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
// Skip consumes the next value.
|
|
301
|
+
func (d *Dec) Skip() {
|
|
302
|
+
switch d.peek() {
|
|
303
|
+
case '"':
|
|
304
|
+
d.skipString()
|
|
305
|
+
case '{', '[':
|
|
306
|
+
d.skipContainer()
|
|
307
|
+
default:
|
|
308
|
+
d.skipScalar()
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
func (d *Dec) skipContainer() {
|
|
313
|
+
depth := 0
|
|
314
|
+
for d.pos < len(d.data) {
|
|
315
|
+
c := d.data[d.pos]
|
|
316
|
+
if c == '"' {
|
|
317
|
+
d.skipString()
|
|
318
|
+
continue
|
|
319
|
+
}
|
|
320
|
+
d.pos++
|
|
321
|
+
if c == '{' || c == '[' {
|
|
322
|
+
depth++
|
|
323
|
+
} else if c == '}' || c == ']' {
|
|
324
|
+
depth--
|
|
325
|
+
if depth == 0 {
|
|
326
|
+
return
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
func (d *Dec) skipScalar() {
|
|
333
|
+
for d.pos < len(d.data) {
|
|
334
|
+
c := d.data[d.pos]
|
|
335
|
+
if c == ',' || c == ']' || c == '}' || c == ' ' || c == '\t' || c == '\n' || c == '\r' {
|
|
336
|
+
return
|
|
337
|
+
}
|
|
338
|
+
d.pos++
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
func (d *Dec) skipString() {
|
|
343
|
+
d.pos++ // opening quote
|
|
344
|
+
for d.pos < len(d.data) {
|
|
345
|
+
c := d.data[d.pos]
|
|
346
|
+
d.pos++
|
|
347
|
+
if c == '\\' {
|
|
348
|
+
d.pos++
|
|
349
|
+
} else if c == '"' {
|
|
350
|
+
return
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
// Raw consumes the next value and returns a copy of its bytes.
|
|
356
|
+
func (d *Dec) Raw() []byte {
|
|
357
|
+
d.ws()
|
|
358
|
+
start := d.pos
|
|
359
|
+
d.Skip()
|
|
360
|
+
out := make([]byte, d.pos-start)
|
|
361
|
+
copy(out, d.data[start:d.pos])
|
|
362
|
+
return out
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
// Offset is the number of input bytes consumed so far.
|
|
366
|
+
func (d *Dec) Offset() int {
|
|
367
|
+
return d.pos
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
// readNum consumes the number literal at the current position.
|
|
371
|
+
//
|
|
372
|
+
//gofront:native jsonrt.readNum
|
|
373
|
+
func readNum(d *Dec) string {
|
|
374
|
+
start := d.pos
|
|
375
|
+
for d.pos < len(d.data) {
|
|
376
|
+
c := d.data[d.pos]
|
|
377
|
+
if c >= '0' && c <= '9' || c == '-' || c == '+' || c == '.' || c == 'e' || c == 'E' {
|
|
378
|
+
d.pos++
|
|
379
|
+
} else {
|
|
380
|
+
break
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
return string(d.data[start:d.pos])
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
// Number decodes a number or string as a Number. ok is false for null.
|
|
387
|
+
func (d *Dec) Number(typ string) (string, bool) {
|
|
388
|
+
if d.fatal || d.Null() {
|
|
389
|
+
return "", false
|
|
390
|
+
}
|
|
391
|
+
if d.peek() == '"' {
|
|
392
|
+
start := d.pos
|
|
393
|
+
s, ok := d.String(typ)
|
|
394
|
+
if !ok {
|
|
395
|
+
return "", false
|
|
396
|
+
}
|
|
397
|
+
if !isValidNumber(s) {
|
|
398
|
+
// Go quotes the whole JSON literal and stops decoding.
|
|
399
|
+
d.Fatal(fmt.Errorf("json: invalid number literal, trying to unmarshal %q into Number", string(d.data[start:d.pos])))
|
|
400
|
+
return "", false
|
|
401
|
+
}
|
|
402
|
+
return s, true
|
|
403
|
+
}
|
|
404
|
+
if d.kind() == "number" {
|
|
405
|
+
return readNum(d), true
|
|
406
|
+
}
|
|
407
|
+
d.Mismatch(typ)
|
|
408
|
+
return "", false
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
// Bool decodes a bool. ok is false for null (leave the target alone) and for
|
|
412
|
+
// a value of another kind (a type error is recorded).
|
|
413
|
+
func (d *Dec) Bool(typ string) (v bool, ok bool) {
|
|
414
|
+
if d.fatal || d.Null() {
|
|
415
|
+
return false, false
|
|
416
|
+
}
|
|
417
|
+
c := d.peek()
|
|
418
|
+
if c == 't' {
|
|
419
|
+
d.pos += 4
|
|
420
|
+
return true, true
|
|
421
|
+
}
|
|
422
|
+
if c == 'f' {
|
|
423
|
+
d.pos += 5
|
|
424
|
+
return false, true
|
|
425
|
+
}
|
|
426
|
+
k := d.kind()
|
|
427
|
+
d.Skip()
|
|
428
|
+
d.typeErr(k, typ)
|
|
429
|
+
return false, false
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
// String decodes a string.
|
|
433
|
+
func (d *Dec) String(typ string) (v string, ok bool) {
|
|
434
|
+
if d.fatal || d.Null() {
|
|
435
|
+
return "", false
|
|
436
|
+
}
|
|
437
|
+
if d.peek() != '"' {
|
|
438
|
+
k := d.kind()
|
|
439
|
+
d.Skip()
|
|
440
|
+
d.typeErr(k, typ)
|
|
441
|
+
return "", false
|
|
442
|
+
}
|
|
443
|
+
return readStr(d), true
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
// plainInt consumes a decimal integer of at most 15 digits, with no fraction
|
|
447
|
+
// or exponent, that fits in bits bits (and is not negative unless signed), and
|
|
448
|
+
// returns it. It leaves the input alone and reports false for anything else,
|
|
449
|
+
// which the caller then parses and reports from its text. The value stays in
|
|
450
|
+
// an int, which is a plain number in JavaScript.
|
|
451
|
+
func (d *Dec) plainInt(bits int, signed bool) (int, bool) {
|
|
452
|
+
data := d.data
|
|
453
|
+
end := len(data)
|
|
454
|
+
i := d.pos
|
|
455
|
+
neg := false
|
|
456
|
+
if i < end && data[i] == '-' {
|
|
457
|
+
if !signed {
|
|
458
|
+
return 0, false
|
|
459
|
+
}
|
|
460
|
+
neg = true
|
|
461
|
+
i++
|
|
462
|
+
}
|
|
463
|
+
start := i
|
|
464
|
+
v := 0
|
|
465
|
+
for i < end {
|
|
466
|
+
c := data[i]
|
|
467
|
+
if c < '0' || c > '9' {
|
|
468
|
+
break
|
|
469
|
+
}
|
|
470
|
+
if i-start == 15 {
|
|
471
|
+
return 0, false
|
|
472
|
+
}
|
|
473
|
+
v = v*10 + int(c-'0')
|
|
474
|
+
i++
|
|
475
|
+
}
|
|
476
|
+
if i == start {
|
|
477
|
+
return 0, false
|
|
478
|
+
}
|
|
479
|
+
if i < end {
|
|
480
|
+
if c := data[i]; c == '.' || c == 'e' || c == 'E' || c == '+' || c == '-' {
|
|
481
|
+
return 0, false
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
if neg {
|
|
485
|
+
v = -v
|
|
486
|
+
}
|
|
487
|
+
if bits < 53 {
|
|
488
|
+
lim := 1 << (bits - 1)
|
|
489
|
+
if !signed {
|
|
490
|
+
lim = 1 << bits
|
|
491
|
+
if v >= lim {
|
|
492
|
+
return 0, false
|
|
493
|
+
}
|
|
494
|
+
} else if v >= lim || v < -lim {
|
|
495
|
+
return 0, false
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
d.pos = i
|
|
499
|
+
return v, true
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
var pow10 = [...]float64{1, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 1e11, 1e12, 1e13, 1e14, 1e15}
|
|
503
|
+
|
|
504
|
+
// plainFloat consumes a decimal number of at most 15 digits with no exponent.
|
|
505
|
+
// Such a number is a mantissa that a float64 holds exactly divided by a power
|
|
506
|
+
// of ten that it holds exactly, so one division rounds it correctly. It
|
|
507
|
+
// leaves the input alone and reports false for anything else.
|
|
508
|
+
func (d *Dec) plainFloat() (float64, bool) {
|
|
509
|
+
data := d.data
|
|
510
|
+
end := len(data)
|
|
511
|
+
i := d.pos
|
|
512
|
+
neg := false
|
|
513
|
+
if i < end && data[i] == '-' {
|
|
514
|
+
neg = true
|
|
515
|
+
i++
|
|
516
|
+
}
|
|
517
|
+
start := i
|
|
518
|
+
digits := 0
|
|
519
|
+
frac := 0
|
|
520
|
+
v := 0
|
|
521
|
+
seenDot := false
|
|
522
|
+
for i < end {
|
|
523
|
+
c := data[i]
|
|
524
|
+
if c == '.' && !seenDot {
|
|
525
|
+
seenDot = true
|
|
526
|
+
i++
|
|
527
|
+
continue
|
|
528
|
+
}
|
|
529
|
+
if c < '0' || c > '9' {
|
|
530
|
+
break
|
|
531
|
+
}
|
|
532
|
+
if digits == 15 {
|
|
533
|
+
return 0, false
|
|
534
|
+
}
|
|
535
|
+
v = v*10 + int(c-'0')
|
|
536
|
+
digits++
|
|
537
|
+
if seenDot {
|
|
538
|
+
frac++
|
|
539
|
+
}
|
|
540
|
+
i++
|
|
541
|
+
}
|
|
542
|
+
if digits == 0 || i-start == 0 {
|
|
543
|
+
return 0, false
|
|
544
|
+
}
|
|
545
|
+
if i < end {
|
|
546
|
+
if c := data[i]; c == 'e' || c == 'E' || c == '+' || c == '-' {
|
|
547
|
+
return 0, false
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
f := float64(v) / pow10[frac]
|
|
551
|
+
if neg {
|
|
552
|
+
f = -f
|
|
553
|
+
}
|
|
554
|
+
d.pos = i
|
|
555
|
+
return f, true
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
// Int decodes an integer that must fit in bits bits.
|
|
559
|
+
func (d *Dec) Int(bits int, typ string) (v int64, ok bool) {
|
|
560
|
+
if d.fatal || d.Null() {
|
|
561
|
+
return 0, false
|
|
562
|
+
}
|
|
563
|
+
if c := d.peek(); c == '"' || c == '{' || c == '[' || c == 't' || c == 'f' {
|
|
564
|
+
k := d.kind()
|
|
565
|
+
d.Skip()
|
|
566
|
+
d.typeErr(k, typ)
|
|
567
|
+
return 0, false
|
|
568
|
+
}
|
|
569
|
+
if n, ok := d.plainInt(bits, true); ok {
|
|
570
|
+
return int64(n), true
|
|
571
|
+
}
|
|
572
|
+
s := readNum(d)
|
|
573
|
+
n, err := strconv.ParseInt(s, 10, bits)
|
|
574
|
+
if err != nil {
|
|
575
|
+
d.typeErr("number "+s, typ)
|
|
576
|
+
return 0, false
|
|
577
|
+
}
|
|
578
|
+
return n, true
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
// Uint decodes an unsigned integer that must fit in bits bits.
|
|
582
|
+
func (d *Dec) Uint(bits int, typ string) (v uint64, ok bool) {
|
|
583
|
+
if d.fatal || d.Null() {
|
|
584
|
+
return 0, false
|
|
585
|
+
}
|
|
586
|
+
if c := d.peek(); c == '"' || c == '{' || c == '[' || c == 't' || c == 'f' {
|
|
587
|
+
k := d.kind()
|
|
588
|
+
d.Skip()
|
|
589
|
+
d.typeErr(k, typ)
|
|
590
|
+
return 0, false
|
|
591
|
+
}
|
|
592
|
+
if n, ok := d.plainInt(bits, false); ok {
|
|
593
|
+
return uint64(n), true
|
|
594
|
+
}
|
|
595
|
+
s := readNum(d)
|
|
596
|
+
n, err := strconv.ParseUint(s, 10, bits)
|
|
597
|
+
if err != nil {
|
|
598
|
+
d.typeErr("number "+s, typ)
|
|
599
|
+
return 0, false
|
|
600
|
+
}
|
|
601
|
+
return n, true
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
// Float decodes a floating-point number of the given size.
|
|
605
|
+
func (d *Dec) Float(bits int, typ string) (v float64, ok bool) {
|
|
606
|
+
if d.fatal || d.Null() {
|
|
607
|
+
return 0, false
|
|
608
|
+
}
|
|
609
|
+
if c := d.peek(); c == '"' || c == '{' || c == '[' || c == 't' || c == 'f' {
|
|
610
|
+
k := d.kind()
|
|
611
|
+
d.Skip()
|
|
612
|
+
d.typeErr(k, typ)
|
|
613
|
+
return 0, false
|
|
614
|
+
}
|
|
615
|
+
if bits == 64 {
|
|
616
|
+
if f, ok := d.plainFloat(); ok {
|
|
617
|
+
return f, true
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
s := readNum(d)
|
|
621
|
+
n, err := strconv.ParseFloat(s, bits)
|
|
622
|
+
if bits == 32 {
|
|
623
|
+
// Round to float32 here: the number may be out of float32 range.
|
|
624
|
+
n = float64(float32(n))
|
|
625
|
+
}
|
|
626
|
+
if err != nil || math.IsInf(n, 0) {
|
|
627
|
+
d.typeErr("number "+s, typ)
|
|
628
|
+
return 0, false
|
|
629
|
+
}
|
|
630
|
+
return n, true
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
// ObjBegin consumes the opening brace of an object. When the value is not an
|
|
634
|
+
// object it records a type error, skips the value and returns false.
|
|
635
|
+
func (d *Dec) ObjBegin(typ string) bool {
|
|
636
|
+
if d.fatal {
|
|
637
|
+
return false
|
|
638
|
+
}
|
|
639
|
+
if d.peek() != '{' {
|
|
640
|
+
k := d.kind()
|
|
641
|
+
d.Skip()
|
|
642
|
+
d.typeErr(k, typ)
|
|
643
|
+
return false
|
|
644
|
+
}
|
|
645
|
+
d.pos++
|
|
646
|
+
return true
|
|
647
|
+
}
|
|
648
|
+
|
|
649
|
+
// NextKey moves to the next member of an object; false at the closing brace.
|
|
650
|
+
// The member name is then available from Key.
|
|
651
|
+
func (d *Dec) NextKey() bool {
|
|
652
|
+
if d.fatal {
|
|
653
|
+
return false
|
|
654
|
+
}
|
|
655
|
+
c := d.peek()
|
|
656
|
+
if c == '}' {
|
|
657
|
+
d.pos++
|
|
658
|
+
return false
|
|
659
|
+
}
|
|
660
|
+
if c == ',' {
|
|
661
|
+
d.pos++
|
|
662
|
+
}
|
|
663
|
+
d.ws()
|
|
664
|
+
d.key = readStr(d)
|
|
665
|
+
d.ws()
|
|
666
|
+
d.pos++ // the colon
|
|
667
|
+
return true
|
|
668
|
+
}
|
|
669
|
+
|
|
670
|
+
// Key is the name of the member NextKey moved to.
|
|
671
|
+
func (d *Dec) Key() string {
|
|
672
|
+
return d.key
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
// ArrBegin consumes the opening bracket of an array.
|
|
676
|
+
func (d *Dec) ArrBegin(typ string) bool {
|
|
677
|
+
if d.fatal {
|
|
678
|
+
return false
|
|
679
|
+
}
|
|
680
|
+
if d.peek() != '[' {
|
|
681
|
+
k := d.kind()
|
|
682
|
+
d.Skip()
|
|
683
|
+
d.typeErr(k, typ)
|
|
684
|
+
return false
|
|
685
|
+
}
|
|
686
|
+
d.pos++
|
|
687
|
+
return true
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
// NextElem moves to the next element of an array; false at the closing bracket.
|
|
691
|
+
func (d *Dec) NextElem() bool {
|
|
692
|
+
if d.fatal {
|
|
693
|
+
return false
|
|
694
|
+
}
|
|
695
|
+
c := d.peek()
|
|
696
|
+
if c == ']' {
|
|
697
|
+
d.pos++
|
|
698
|
+
return false
|
|
699
|
+
}
|
|
700
|
+
if c == ',' {
|
|
701
|
+
d.pos++
|
|
702
|
+
}
|
|
703
|
+
return true
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
// EqualFold reports whether two member names match ignoring case.
|
|
707
|
+
func EqualFold(a, b string) bool {
|
|
708
|
+
return strings.EqualFold(a, b)
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
// readStr consumes the string at the current position.
|
|
712
|
+
//
|
|
713
|
+
//gofront:native jsonrt.readStr
|
|
714
|
+
func readStr(d *Dec) string {
|
|
715
|
+
d.pos++ // opening quote
|
|
716
|
+
start := d.pos
|
|
717
|
+
plain := true
|
|
718
|
+
for d.pos < len(d.data) {
|
|
719
|
+
c := d.data[d.pos]
|
|
720
|
+
if c == '"' {
|
|
721
|
+
break
|
|
722
|
+
}
|
|
723
|
+
if c == '\\' {
|
|
724
|
+
plain = false
|
|
725
|
+
d.pos++
|
|
726
|
+
} else if c >= utf8.RuneSelf {
|
|
727
|
+
plain = false
|
|
728
|
+
}
|
|
729
|
+
d.pos++
|
|
730
|
+
}
|
|
731
|
+
raw := d.data[start:d.pos]
|
|
732
|
+
d.pos++ // closing quote
|
|
733
|
+
if plain {
|
|
734
|
+
return string(raw)
|
|
735
|
+
}
|
|
736
|
+
return unquote(raw)
|
|
737
|
+
}
|
|
738
|
+
|
|
739
|
+
func getu4(s []byte, i int) rune {
|
|
740
|
+
if i+4 > len(s) {
|
|
741
|
+
return -1
|
|
742
|
+
}
|
|
743
|
+
var r rune
|
|
744
|
+
for j := i; j < i+4; j++ {
|
|
745
|
+
c := s[j]
|
|
746
|
+
switch {
|
|
747
|
+
case '0' <= c && c <= '9':
|
|
748
|
+
c = c - '0'
|
|
749
|
+
case 'a' <= c && c <= 'f':
|
|
750
|
+
c = c - 'a' + 10
|
|
751
|
+
case 'A' <= c && c <= 'F':
|
|
752
|
+
c = c - 'A' + 10
|
|
753
|
+
default:
|
|
754
|
+
return -1
|
|
755
|
+
}
|
|
756
|
+
r = r*16 + rune(c)
|
|
757
|
+
}
|
|
758
|
+
return r
|
|
759
|
+
}
|
|
760
|
+
|
|
761
|
+
// unquoteU decodes the \\u escape whose 'u' is at s[r], with a following
|
|
762
|
+
// \\u surrogate half when there is one. It returns the rune and the index of
|
|
763
|
+
// the first byte after the escape.
|
|
764
|
+
func unquoteU(s []byte, r int) (rune, int) {
|
|
765
|
+
rr := getu4(s, r+1)
|
|
766
|
+
r += 5
|
|
767
|
+
if rr >= 0xD800 && rr < 0xDC00 {
|
|
768
|
+
if r+1 < len(s) && s[r] == '\\' && s[r+1] == 'u' {
|
|
769
|
+
rr1 := getu4(s, r+2)
|
|
770
|
+
if rr1 >= 0xDC00 && rr1 < 0xE000 {
|
|
771
|
+
return 0x10000 + (rr-0xD800)<<10 + (rr1 - 0xDC00), r + 6
|
|
772
|
+
}
|
|
773
|
+
}
|
|
774
|
+
return utf8.RuneError, r
|
|
775
|
+
}
|
|
776
|
+
if rr >= 0xDC00 && rr < 0xE000 {
|
|
777
|
+
return utf8.RuneError, r
|
|
778
|
+
}
|
|
779
|
+
return rr, r
|
|
780
|
+
}
|
|
781
|
+
|
|
782
|
+
// unquote decodes the escapes of a JSON string body and coerces it to
|
|
783
|
+
// well-formed UTF-8.
|
|
784
|
+
func unquote(s []byte) string {
|
|
785
|
+
out := make([]byte, 0, len(s))
|
|
786
|
+
r := 0
|
|
787
|
+
for r < len(s) {
|
|
788
|
+
c := s[r]
|
|
789
|
+
if c == '\\' {
|
|
790
|
+
r++
|
|
791
|
+
switch s[r] {
|
|
792
|
+
case 'b':
|
|
793
|
+
out = append(out, '\b')
|
|
794
|
+
r++
|
|
795
|
+
case 'f':
|
|
796
|
+
out = append(out, '\f')
|
|
797
|
+
r++
|
|
798
|
+
case 'n':
|
|
799
|
+
out = append(out, '\n')
|
|
800
|
+
r++
|
|
801
|
+
case 'r':
|
|
802
|
+
out = append(out, '\r')
|
|
803
|
+
r++
|
|
804
|
+
case 't':
|
|
805
|
+
out = append(out, '\t')
|
|
806
|
+
r++
|
|
807
|
+
case 'u':
|
|
808
|
+
var rr rune
|
|
809
|
+
rr, r = unquoteU(s, r)
|
|
810
|
+
out = utf8.AppendRune(out, rr)
|
|
811
|
+
default:
|
|
812
|
+
out = append(out, s[r])
|
|
813
|
+
r++
|
|
814
|
+
}
|
|
815
|
+
} else if c < utf8.RuneSelf {
|
|
816
|
+
out = append(out, c)
|
|
817
|
+
r++
|
|
818
|
+
} else {
|
|
819
|
+
rr, size := utf8.DecodeRune(s[r:])
|
|
820
|
+
r += size
|
|
821
|
+
out = utf8.AppendRune(out, rr)
|
|
822
|
+
}
|
|
823
|
+
}
|
|
824
|
+
return string(out)
|
|
825
|
+
}
|
|
826
|
+
|
|
827
|
+
// Any decodes the next value into the empty interface: map[string]any,
|
|
828
|
+
// []any, float64, string, bool or nil.
|
|
829
|
+
func (d *Dec) Any() any {
|
|
830
|
+
if d.fatal {
|
|
831
|
+
return nil
|
|
832
|
+
}
|
|
833
|
+
switch d.peek() {
|
|
834
|
+
case '{':
|
|
835
|
+
d.pos++
|
|
836
|
+
m := make(map[string]any)
|
|
837
|
+
for d.NextKey() {
|
|
838
|
+
k := d.key
|
|
839
|
+
m[k] = d.Any()
|
|
840
|
+
}
|
|
841
|
+
return m
|
|
842
|
+
case '[':
|
|
843
|
+
d.pos++
|
|
844
|
+
a := make([]any, 0)
|
|
845
|
+
for d.NextElem() {
|
|
846
|
+
a = append(a, d.Any())
|
|
847
|
+
}
|
|
848
|
+
return a
|
|
849
|
+
case '"':
|
|
850
|
+
return readStr(d)
|
|
851
|
+
case 't':
|
|
852
|
+
d.pos += 4
|
|
853
|
+
return true
|
|
854
|
+
case 'f':
|
|
855
|
+
d.pos += 5
|
|
856
|
+
return false
|
|
857
|
+
case 'n':
|
|
858
|
+
d.pos += 4
|
|
859
|
+
return nil
|
|
860
|
+
}
|
|
861
|
+
s := readNum(d)
|
|
862
|
+
if d.UseNumber {
|
|
863
|
+
return Number(s)
|
|
864
|
+
}
|
|
865
|
+
f, err := strconv.ParseFloat(s, 64)
|
|
866
|
+
if err != nil {
|
|
867
|
+
d.typeErr("number "+s, "float64")
|
|
868
|
+
return nil
|
|
869
|
+
}
|
|
870
|
+
return f
|
|
871
|
+
}
|