1package gojay
2
3import (
4	"reflect"
5	"unsafe"
6)
7
8// DecodeObject reads the next JSON-encoded value from the decoder's input (io.Reader) and stores it in the value pointed to by v.
9//
10// v must implement UnmarshalerJSONObject.
11//
12// See the documentation for Unmarshal for details about the conversion of JSON into a Go value.
13func (dec *Decoder) DecodeObject(j UnmarshalerJSONObject) error {
14	if dec.isPooled == 1 {
15		panic(InvalidUsagePooledDecoderError("Invalid usage of pooled decoder"))
16	}
17	_, err := dec.decodeObject(j)
18	return err
19}
20func (dec *Decoder) decodeObject(j UnmarshalerJSONObject) (int, error) {
21	keys := j.NKeys()
22	for ; dec.cursor < dec.length || dec.read(); dec.cursor++ {
23		switch dec.data[dec.cursor] {
24		case ' ', '\n', '\t', '\r', ',':
25		case '{':
26			dec.cursor = dec.cursor + 1
27			// if keys is zero we will parse all keys
28			// we run two loops for micro optimization
29			if keys == 0 {
30				for dec.cursor < dec.length || dec.read() {
31					k, done, err := dec.nextKey()
32					if err != nil {
33						return 0, err
34					} else if done {
35						return dec.cursor, nil
36					}
37					err = j.UnmarshalJSONObject(dec, k)
38					if err != nil {
39						dec.err = err
40						return 0, err
41					} else if dec.called&1 == 0 {
42						err := dec.skipData()
43						if err != nil {
44							return 0, err
45						}
46					} else {
47						dec.keysDone++
48					}
49					dec.called &= 0
50				}
51			} else {
52				for (dec.cursor < dec.length || dec.read()) && dec.keysDone < keys {
53					k, done, err := dec.nextKey()
54					if err != nil {
55						return 0, err
56					} else if done {
57						return dec.cursor, nil
58					}
59					err = j.UnmarshalJSONObject(dec, k)
60					if err != nil {
61						dec.err = err
62						return 0, err
63					} else if dec.called&1 == 0 {
64						err := dec.skipData()
65						if err != nil {
66							return 0, err
67						}
68					} else {
69						dec.keysDone++
70					}
71					dec.called &= 0
72				}
73			}
74			// will get to that point when keysDone is not lower than keys anymore
75			// in that case, we make sure cursor goes to the end of object, but we skip
76			// unmarshalling
77			if dec.child&1 != 0 {
78				end, err := dec.skipObject()
79				dec.cursor = end
80				return dec.cursor, err
81			}
82			return dec.cursor, nil
83		case 'n':
84			dec.cursor++
85			err := dec.assertNull()
86			if err != nil {
87				return 0, err
88			}
89			return dec.cursor, nil
90		default:
91			// can't unmarshal to struct
92			dec.err = dec.makeInvalidUnmarshalErr(j)
93			err := dec.skipData()
94			if err != nil {
95				return 0, err
96			}
97			return dec.cursor, nil
98		}
99	}
100	return 0, dec.raiseInvalidJSONErr(dec.cursor)
101}
102
103func (dec *Decoder) decodeObjectNull(v interface{}) (int, error) {
104	// make sure the value is a pointer
105	vv := reflect.ValueOf(v)
106	vvt := vv.Type()
107	if vvt.Kind() != reflect.Ptr || vvt.Elem().Kind() != reflect.Ptr {
108		dec.err = ErrUnmarshalPtrExpected
109		return 0, dec.err
110	}
111	for ; dec.cursor < dec.length || dec.read(); dec.cursor++ {
112		switch dec.data[dec.cursor] {
113		case ' ', '\n', '\t', '\r', ',':
114		case '{':
115			elt := vv.Elem()
116			n := reflect.New(elt.Type().Elem())
117			elt.Set(n)
118			var j UnmarshalerJSONObject
119			var ok bool
120			if j, ok = n.Interface().(UnmarshalerJSONObject); !ok {
121				dec.err = dec.makeInvalidUnmarshalErr((UnmarshalerJSONObject)(nil))
122				return 0, dec.err
123			}
124			keys := j.NKeys()
125			dec.cursor = dec.cursor + 1
126			// if keys is zero we will parse all keys
127			// we run two loops for micro optimization
128			if keys == 0 {
129				for dec.cursor < dec.length || dec.read() {
130					k, done, err := dec.nextKey()
131					if err != nil {
132						return 0, err
133					} else if done {
134						return dec.cursor, nil
135					}
136					err = j.UnmarshalJSONObject(dec, k)
137					if err != nil {
138						dec.err = err
139						return 0, err
140					} else if dec.called&1 == 0 {
141						err := dec.skipData()
142						if err != nil {
143							return 0, err
144						}
145					} else {
146						dec.keysDone++
147					}
148					dec.called &= 0
149				}
150			} else {
151				for (dec.cursor < dec.length || dec.read()) && dec.keysDone < keys {
152					k, done, err := dec.nextKey()
153					if err != nil {
154						return 0, err
155					} else if done {
156						return dec.cursor, nil
157					}
158					err = j.UnmarshalJSONObject(dec, k)
159					if err != nil {
160						dec.err = err
161						return 0, err
162					} else if dec.called&1 == 0 {
163						err := dec.skipData()
164						if err != nil {
165							return 0, err
166						}
167					} else {
168						dec.keysDone++
169					}
170					dec.called &= 0
171				}
172			}
173			// will get to that point when keysDone is not lower than keys anymore
174			// in that case, we make sure cursor goes to the end of object, but we skip
175			// unmarshalling
176			if dec.child&1 != 0 {
177				end, err := dec.skipObject()
178				dec.cursor = end
179				return dec.cursor, err
180			}
181			return dec.cursor, nil
182		case 'n':
183			dec.cursor++
184			err := dec.assertNull()
185			if err != nil {
186				return 0, err
187			}
188			return dec.cursor, nil
189		default:
190			// can't unmarshal to struct
191			dec.err = dec.makeInvalidUnmarshalErr((UnmarshalerJSONObject)(nil))
192			err := dec.skipData()
193			if err != nil {
194				return 0, err
195			}
196			return dec.cursor, nil
197		}
198	}
199	return 0, dec.raiseInvalidJSONErr(dec.cursor)
200}
201
202func (dec *Decoder) skipObject() (int, error) {
203	var objectsOpen = 1
204	var objectsClosed = 0
205	for j := dec.cursor; j < dec.length || dec.read(); j++ {
206		switch dec.data[j] {
207		case '}':
208			objectsClosed++
209			// everything is closed return
210			if objectsOpen == objectsClosed {
211				// add char to object data
212				return j + 1, nil
213			}
214		case '{':
215			objectsOpen++
216		case '"':
217			j++
218			var isInEscapeSeq bool
219			var isFirstQuote = true
220			for ; j < dec.length || dec.read(); j++ {
221				if dec.data[j] != '"' {
222					continue
223				}
224				if dec.data[j-1] != '\\' || (!isInEscapeSeq && !isFirstQuote) {
225					break
226				} else {
227					isInEscapeSeq = false
228				}
229				if isFirstQuote {
230					isFirstQuote = false
231				}
232				// loop backward and count how many anti slash found
233				// to see if string is effectively escaped
234				ct := 0
235				for i := j - 1; i > 0; i-- {
236					if dec.data[i] != '\\' {
237						break
238					}
239					ct++
240				}
241				// is pair number of slashes, quote is not escaped
242				if ct&1 == 0 {
243					break
244				}
245				isInEscapeSeq = true
246			}
247		default:
248			continue
249		}
250	}
251	return 0, dec.raiseInvalidJSONErr(dec.cursor)
252}
253
254func (dec *Decoder) nextKey() (string, bool, error) {
255	for ; dec.cursor < dec.length || dec.read(); dec.cursor++ {
256		switch dec.data[dec.cursor] {
257		case ' ', '\n', '\t', '\r', ',':
258			continue
259		case '"':
260			dec.cursor = dec.cursor + 1
261			start, end, err := dec.getString()
262			if err != nil {
263				return "", false, err
264			}
265			var found byte
266			for ; dec.cursor < dec.length || dec.read(); dec.cursor++ {
267				if dec.data[dec.cursor] == ':' {
268					found |= 1
269					break
270				}
271			}
272			if found&1 != 0 {
273				dec.cursor++
274				d := dec.data[start : end-1]
275				return *(*string)(unsafe.Pointer(&d)), false, nil
276			}
277			return "", false, dec.raiseInvalidJSONErr(dec.cursor)
278		case '}':
279			dec.cursor = dec.cursor + 1
280			return "", true, nil
281		default:
282			// can't unmarshall to struct
283			return "", false, dec.raiseInvalidJSONErr(dec.cursor)
284		}
285	}
286	return "", false, dec.raiseInvalidJSONErr(dec.cursor)
287}
288
289func (dec *Decoder) skipData() error {
290	for ; dec.cursor < dec.length || dec.read(); dec.cursor++ {
291		switch dec.data[dec.cursor] {
292		case ' ', '\n', '\t', '\r', ',':
293			continue
294		// is null
295		case 'n':
296			dec.cursor++
297			err := dec.assertNull()
298			if err != nil {
299				return err
300			}
301			return nil
302		case 't':
303			dec.cursor++
304			err := dec.assertTrue()
305			if err != nil {
306				return err
307			}
308			return nil
309		// is false
310		case 'f':
311			dec.cursor++
312			err := dec.assertFalse()
313			if err != nil {
314				return err
315			}
316			return nil
317		// is an object
318		case '{':
319			dec.cursor = dec.cursor + 1
320			end, err := dec.skipObject()
321			dec.cursor = end
322			return err
323		// is string
324		case '"':
325			dec.cursor = dec.cursor + 1
326			err := dec.skipString()
327			return err
328		// is array
329		case '[':
330			dec.cursor = dec.cursor + 1
331			end, err := dec.skipArray()
332			dec.cursor = end
333			return err
334		case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-':
335			end, err := dec.skipNumber()
336			dec.cursor = end
337			return err
338		}
339		return dec.raiseInvalidJSONErr(dec.cursor)
340	}
341	return dec.raiseInvalidJSONErr(dec.cursor)
342}
343
344// DecodeObjectFunc is a func type implementing UnmarshalerJSONObject.
345// Use it to cast a `func(*Decoder, k string) error` to Unmarshal an object on the fly.
346type DecodeObjectFunc func(*Decoder, string) error
347
348// UnmarshalJSONObject implements UnmarshalerJSONObject.
349func (f DecodeObjectFunc) UnmarshalJSONObject(dec *Decoder, k string) error {
350	return f(dec, k)
351}
352
353// NKeys implements UnmarshalerJSONObject.
354func (f DecodeObjectFunc) NKeys() int {
355	return 0
356}
357
358// Add Values functions
359
360// AddObject decodes the JSON value within an object or an array to a UnmarshalerJSONObject.
361func (dec *Decoder) AddObject(v UnmarshalerJSONObject) error {
362	return dec.Object(v)
363}
364
365// AddObjectNull decodes the JSON value within an object or an array to a UnmarshalerJSONObject.
366func (dec *Decoder) AddObjectNull(v interface{}) error {
367	return dec.ObjectNull(v)
368}
369
370// Object decodes the JSON value within an object or an array to a UnmarshalerJSONObject.
371func (dec *Decoder) Object(value UnmarshalerJSONObject) error {
372	initialKeysDone := dec.keysDone
373	initialChild := dec.child
374	dec.keysDone = 0
375	dec.called = 0
376	dec.child |= 1
377	newCursor, err := dec.decodeObject(value)
378	if err != nil {
379		return err
380	}
381	dec.cursor = newCursor
382	dec.keysDone = initialKeysDone
383	dec.child = initialChild
384	dec.called |= 1
385	return nil
386}
387
388// ObjectNull decodes the JSON value within an object or an array to a UnmarshalerJSONObject.
389// v should be a pointer to an UnmarshalerJSONObject,
390// if `null` value is encountered in JSON, it will leave the value v untouched,
391// else it will create a new instance of the UnmarshalerJSONObject behind v.
392func (dec *Decoder) ObjectNull(v interface{}) error {
393	initialKeysDone := dec.keysDone
394	initialChild := dec.child
395	dec.keysDone = 0
396	dec.called = 0
397	dec.child |= 1
398	newCursor, err := dec.decodeObjectNull(v)
399	if err != nil {
400		return err
401	}
402	dec.cursor = newCursor
403	dec.keysDone = initialKeysDone
404	dec.child = initialChild
405	dec.called |= 1
406	return nil
407}
408