1
2
3
4
5
6
7 package json
8
9 import (
10 "bytes"
11 "errors"
12 "io"
13
14 "encoding/json/jsontext"
15 jsonv2 "encoding/json/v2"
16 )
17
18
19 type Decoder struct {
20 dec *jsontext.Decoder
21 opts jsonv2.Options
22 err error
23
24
25
26 hadPeeked bool
27 }
28
29
30
31
32
33 func NewDecoder(r io.Reader) *Decoder {
34
35
36
37 if _, ok := r.(*bytes.Buffer); ok {
38 r = struct{ io.Reader }{r}
39 }
40
41 dec := new(Decoder)
42 dec.opts = DefaultOptionsV1()
43 dec.dec = jsontext.NewDecoder(r, dec.opts)
44 return dec
45 }
46
47
48
49 func (dec *Decoder) UseNumber() {
50 if useNumber, _ := jsonv2.GetOption(dec.opts, unmarshalAnyWithRawNumber); !useNumber {
51 dec.opts = jsonv2.JoinOptions(dec.opts, unmarshalAnyWithRawNumber(true))
52 }
53 }
54
55
56
57
58 func (dec *Decoder) DisallowUnknownFields() {
59 if reject, _ := jsonv2.GetOption(dec.opts, jsonv2.RejectUnknownMembers); !reject {
60 dec.opts = jsonv2.JoinOptions(dec.opts, jsonv2.RejectUnknownMembers(true))
61 }
62 }
63
64
65
66
67
68
69 func (dec *Decoder) Decode(v any) error {
70 if dec.err != nil {
71 return dec.err
72 }
73 b, err := dec.dec.ReadValue()
74 if err != nil {
75 dec.err = transformSyntacticError(err)
76 if dec.err.Error() == errUnexpectedEnd.Error() {
77
78
79 dec.err = io.ErrUnexpectedEOF
80 }
81 return dec.err
82 }
83 dec.hadPeeked = false
84 return jsonv2.Unmarshal(b, v, dec.opts)
85 }
86
87
88
89 func (dec *Decoder) Buffered() io.Reader {
90 return bytes.NewReader(dec.dec.UnreadBuffer())
91 }
92
93
94 type Encoder struct {
95 w io.Writer
96 opts jsonv2.Options
97 err error
98
99 buf bytes.Buffer
100 indentBuf bytes.Buffer
101
102 indentPrefix string
103 indentValue string
104 }
105
106
107 func NewEncoder(w io.Writer) *Encoder {
108 enc := new(Encoder)
109 enc.w = w
110 enc.opts = DefaultOptionsV1()
111 return enc
112 }
113
114
115
116
117
118
119 func (enc *Encoder) Encode(v any) error {
120 if enc.err != nil {
121 return enc.err
122 }
123
124 buf := &enc.buf
125 buf.Reset()
126 if err := jsonv2.MarshalWrite(buf, v, enc.opts); err != nil {
127 return err
128 }
129 if len(enc.indentPrefix)+len(enc.indentValue) > 0 {
130 enc.indentBuf.Reset()
131 if err := Indent(&enc.indentBuf, buf.Bytes(), enc.indentPrefix, enc.indentValue); err != nil {
132 return err
133 }
134 buf = &enc.indentBuf
135 }
136 buf.WriteByte('\n')
137
138 if _, err := enc.w.Write(buf.Bytes()); err != nil {
139 enc.err = err
140 return err
141 }
142 return nil
143 }
144
145
146
147
148 func (enc *Encoder) SetIndent(prefix, indent string) {
149 enc.indentPrefix = prefix
150 enc.indentValue = indent
151 }
152
153
154
155
156
157
158
159
160 func (enc *Encoder) SetEscapeHTML(on bool) {
161 if escape, _ := jsonv2.GetOption(enc.opts, jsontext.EscapeForHTML); escape != on {
162 enc.opts = jsonv2.JoinOptions(enc.opts, jsontext.EscapeForHTML(on))
163 }
164 }
165
166
167
168
169 type RawMessage = jsontext.Value
170
171
172
173
174
175
176
177
178
179 type Token any
180
181
182 type Delim rune
183
184 func (d Delim) String() string {
185 return string(d)
186 }
187
188
189
190
191
192
193
194
195
196
197
198
199 func (dec *Decoder) Token() (Token, error) {
200 tok, err := dec.dec.ReadToken()
201 if err != nil {
202
203
204
205
206 if errors.Is(err, io.ErrUnexpectedEOF) {
207 if len(bytes.Trim(dec.dec.UnreadBuffer(), " \r\n\t,:")) == 0 {
208 return nil, io.EOF
209 }
210 return nil, io.ErrUnexpectedEOF
211 }
212 return nil, transformSyntacticError(err)
213 }
214 dec.hadPeeked = false
215 switch k := tok.Kind(); k {
216 case 'n':
217 return nil, nil
218 case 'f':
219 return false, nil
220 case 't':
221 return true, nil
222 case '"':
223 return tok.String(), nil
224 case '0':
225 if useNumber, _ := jsonv2.GetOption(dec.opts, unmarshalAnyWithRawNumber); useNumber {
226 return Number(tok.String()), nil
227 }
228 return tok.Float(), nil
229 case '{', '}', '[', ']':
230 return Delim(k), nil
231 default:
232 panic("unreachable")
233 }
234 }
235
236
237
238 func (dec *Decoder) More() bool {
239 dec.hadPeeked = true
240 k := dec.dec.PeekKind()
241 return k > 0 && k != ']' && k != '}'
242 }
243
244
245
246
247 func (dec *Decoder) InputOffset() int64 {
248 offset := dec.dec.InputOffset()
249 if dec.hadPeeked {
250
251
252
253
254 unreadBuffer := dec.dec.UnreadBuffer()
255 trailingTokens := bytes.TrimLeft(unreadBuffer, " \n\r\t")
256 if len(trailingTokens) > 0 {
257 leadingWhitespace := len(unreadBuffer) - len(trailingTokens)
258 offset += int64(leadingWhitespace)
259 }
260 }
261 return offset
262 }
263
View as plain text