1// Package gjson provides searching for json strings.
2package gjson
3
4import (
5	"encoding/json"
6	"strconv"
7	"strings"
8	"time"
9	"unicode/utf16"
10	"unicode/utf8"
11	"unsafe"
12
13	"github.com/tidwall/match"
14	"github.com/tidwall/pretty"
15)
16
17// Type is Result type
18type Type int
19
20const (
21	// Null is a null json value
22	Null Type = iota
23	// False is a json false boolean
24	False
25	// Number is json number
26	Number
27	// String is a json string
28	String
29	// True is a json true boolean
30	True
31	// JSON is a raw block of JSON
32	JSON
33)
34
35// String returns a string representation of the type.
36func (t Type) String() string {
37	switch t {
38	default:
39		return ""
40	case Null:
41		return "Null"
42	case False:
43		return "False"
44	case Number:
45		return "Number"
46	case String:
47		return "String"
48	case True:
49		return "True"
50	case JSON:
51		return "JSON"
52	}
53}
54
55// Result represents a json value that is returned from Get().
56type Result struct {
57	// Type is the json type
58	Type Type
59	// Raw is the raw json
60	Raw string
61	// Str is the json string
62	Str string
63	// Num is the json number
64	Num float64
65	// Index of raw value in original json, zero means index unknown
66	Index int
67	// Indexes of all the elements that match on a path containing the '#'
68	// query character.
69	Indexes []int
70}
71
72// String returns a string representation of the value.
73func (t Result) String() string {
74	switch t.Type {
75	default:
76		return ""
77	case False:
78		return "false"
79	case Number:
80		if len(t.Raw) == 0 {
81			// calculated result
82			return strconv.FormatFloat(t.Num, 'f', -1, 64)
83		}
84		var i int
85		if t.Raw[0] == '-' {
86			i++
87		}
88		for ; i < len(t.Raw); i++ {
89			if t.Raw[i] < '0' || t.Raw[i] > '9' {
90				return strconv.FormatFloat(t.Num, 'f', -1, 64)
91			}
92		}
93		return t.Raw
94	case String:
95		return t.Str
96	case JSON:
97		return t.Raw
98	case True:
99		return "true"
100	}
101}
102
103// Bool returns an boolean representation.
104func (t Result) Bool() bool {
105	switch t.Type {
106	default:
107		return false
108	case True:
109		return true
110	case String:
111		b, _ := strconv.ParseBool(strings.ToLower(t.Str))
112		return b
113	case Number:
114		return t.Num != 0
115	}
116}
117
118// Int returns an integer representation.
119func (t Result) Int() int64 {
120	switch t.Type {
121	default:
122		return 0
123	case True:
124		return 1
125	case String:
126		n, _ := parseInt(t.Str)
127		return n
128	case Number:
129		// try to directly convert the float64 to int64
130		i, ok := safeInt(t.Num)
131		if ok {
132			return i
133		}
134		// now try to parse the raw string
135		i, ok = parseInt(t.Raw)
136		if ok {
137			return i
138		}
139		// fallback to a standard conversion
140		return int64(t.Num)
141	}
142}
143
144// Uint returns an unsigned integer representation.
145func (t Result) Uint() uint64 {
146	switch t.Type {
147	default:
148		return 0
149	case True:
150		return 1
151	case String:
152		n, _ := parseUint(t.Str)
153		return n
154	case Number:
155		// try to directly convert the float64 to uint64
156		i, ok := safeInt(t.Num)
157		if ok && i >= 0 {
158			return uint64(i)
159		}
160		// now try to parse the raw string
161		u, ok := parseUint(t.Raw)
162		if ok {
163			return u
164		}
165		// fallback to a standard conversion
166		return uint64(t.Num)
167	}
168}
169
170// Float returns an float64 representation.
171func (t Result) Float() float64 {
172	switch t.Type {
173	default:
174		return 0
175	case True:
176		return 1
177	case String:
178		n, _ := strconv.ParseFloat(t.Str, 64)
179		return n
180	case Number:
181		return t.Num
182	}
183}
184
185// Time returns a time.Time representation.
186func (t Result) Time() time.Time {
187	res, _ := time.Parse(time.RFC3339, t.String())
188	return res
189}
190
191// Array returns back an array of values.
192// If the result represents a non-existent value, then an empty array will be
193// returned. If the result is not a JSON array, the return value will be an
194// array containing one result.
195func (t Result) Array() []Result {
196	if t.Type == Null {
197		return []Result{}
198	}
199	if t.Type != JSON {
200		return []Result{t}
201	}
202	r := t.arrayOrMap('[', false)
203	return r.a
204}
205
206// IsObject returns true if the result value is a JSON object.
207func (t Result) IsObject() bool {
208	return t.Type == JSON && len(t.Raw) > 0 && t.Raw[0] == '{'
209}
210
211// IsArray returns true if the result value is a JSON array.
212func (t Result) IsArray() bool {
213	return t.Type == JSON && len(t.Raw) > 0 && t.Raw[0] == '['
214}
215
216// ForEach iterates through values.
217// If the result represents a non-existent value, then no values will be
218// iterated. If the result is an Object, the iterator will pass the key and
219// value of each item. If the result is an Array, the iterator will only pass
220// the value of each item. If the result is not a JSON array or object, the
221// iterator will pass back one value equal to the result.
222func (t Result) ForEach(iterator func(key, value Result) bool) {
223	if !t.Exists() {
224		return
225	}
226	if t.Type != JSON {
227		iterator(Result{}, t)
228		return
229	}
230	json := t.Raw
231	var keys bool
232	var i int
233	var key, value Result
234	for ; i < len(json); i++ {
235		if json[i] == '{' {
236			i++
237			key.Type = String
238			keys = true
239			break
240		} else if json[i] == '[' {
241			i++
242			break
243		}
244		if json[i] > ' ' {
245			return
246		}
247	}
248	var str string
249	var vesc bool
250	var ok bool
251	for ; i < len(json); i++ {
252		if keys {
253			if json[i] != '"' {
254				continue
255			}
256			s := i
257			i, str, vesc, ok = parseString(json, i+1)
258			if !ok {
259				return
260			}
261			if vesc {
262				key.Str = unescape(str[1 : len(str)-1])
263			} else {
264				key.Str = str[1 : len(str)-1]
265			}
266			key.Raw = str
267			key.Index = s
268		}
269		for ; i < len(json); i++ {
270			if json[i] <= ' ' || json[i] == ',' || json[i] == ':' {
271				continue
272			}
273			break
274		}
275		s := i
276		i, value, ok = parseAny(json, i, true)
277		if !ok {
278			return
279		}
280		value.Index = s
281		if !iterator(key, value) {
282			return
283		}
284	}
285}
286
287// Map returns back a map of values. The result should be a JSON object.
288// If the result is not a JSON object, the return value will be an empty map.
289func (t Result) Map() map[string]Result {
290	if t.Type != JSON {
291		return map[string]Result{}
292	}
293	r := t.arrayOrMap('{', false)
294	return r.o
295}
296
297// Get searches result for the specified path.
298// The result should be a JSON array or object.
299func (t Result) Get(path string) Result {
300	return Get(t.Raw, path)
301}
302
303type arrayOrMapResult struct {
304	a  []Result
305	ai []interface{}
306	o  map[string]Result
307	oi map[string]interface{}
308	vc byte
309}
310
311func (t Result) arrayOrMap(vc byte, valueize bool) (r arrayOrMapResult) {
312	var json = t.Raw
313	var i int
314	var value Result
315	var count int
316	var key Result
317	if vc == 0 {
318		for ; i < len(json); i++ {
319			if json[i] == '{' || json[i] == '[' {
320				r.vc = json[i]
321				i++
322				break
323			}
324			if json[i] > ' ' {
325				goto end
326			}
327		}
328	} else {
329		for ; i < len(json); i++ {
330			if json[i] == vc {
331				i++
332				break
333			}
334			if json[i] > ' ' {
335				goto end
336			}
337		}
338		r.vc = vc
339	}
340	if r.vc == '{' {
341		if valueize {
342			r.oi = make(map[string]interface{})
343		} else {
344			r.o = make(map[string]Result)
345		}
346	} else {
347		if valueize {
348			r.ai = make([]interface{}, 0)
349		} else {
350			r.a = make([]Result, 0)
351		}
352	}
353	for ; i < len(json); i++ {
354		if json[i] <= ' ' {
355			continue
356		}
357		// get next value
358		if json[i] == ']' || json[i] == '}' {
359			break
360		}
361		switch json[i] {
362		default:
363			if (json[i] >= '0' && json[i] <= '9') || json[i] == '-' {
364				value.Type = Number
365				value.Raw, value.Num = tonum(json[i:])
366				value.Str = ""
367			} else {
368				continue
369			}
370		case '{', '[':
371			value.Type = JSON
372			value.Raw = squash(json[i:])
373			value.Str, value.Num = "", 0
374		case 'n':
375			value.Type = Null
376			value.Raw = tolit(json[i:])
377			value.Str, value.Num = "", 0
378		case 't':
379			value.Type = True
380			value.Raw = tolit(json[i:])
381			value.Str, value.Num = "", 0
382		case 'f':
383			value.Type = False
384			value.Raw = tolit(json[i:])
385			value.Str, value.Num = "", 0
386		case '"':
387			value.Type = String
388			value.Raw, value.Str = tostr(json[i:])
389			value.Num = 0
390		}
391		i += len(value.Raw) - 1
392
393		if r.vc == '{' {
394			if count%2 == 0 {
395				key = value
396			} else {
397				if valueize {
398					if _, ok := r.oi[key.Str]; !ok {
399						r.oi[key.Str] = value.Value()
400					}
401				} else {
402					if _, ok := r.o[key.Str]; !ok {
403						r.o[key.Str] = value
404					}
405				}
406			}
407			count++
408		} else {
409			if valueize {
410				r.ai = append(r.ai, value.Value())
411			} else {
412				r.a = append(r.a, value)
413			}
414		}
415	}
416end:
417	return
418}
419
420// Parse parses the json and returns a result.
421//
422// This function expects that the json is well-formed, and does not validate.
423// Invalid json will not panic, but it may return back unexpected results.
424// If you are consuming JSON from an unpredictable source then you may want to
425// use the Valid function first.
426func Parse(json string) Result {
427	var value Result
428	for i := 0; i < len(json); i++ {
429		if json[i] == '{' || json[i] == '[' {
430			value.Type = JSON
431			value.Raw = json[i:] // just take the entire raw
432			break
433		}
434		if json[i] <= ' ' {
435			continue
436		}
437		switch json[i] {
438		default:
439			if (json[i] >= '0' && json[i] <= '9') || json[i] == '-' {
440				value.Type = Number
441				value.Raw, value.Num = tonum(json[i:])
442			} else {
443				return Result{}
444			}
445		case 'n':
446			value.Type = Null
447			value.Raw = tolit(json[i:])
448		case 't':
449			value.Type = True
450			value.Raw = tolit(json[i:])
451		case 'f':
452			value.Type = False
453			value.Raw = tolit(json[i:])
454		case '"':
455			value.Type = String
456			value.Raw, value.Str = tostr(json[i:])
457		}
458		break
459	}
460	return value
461}
462
463// ParseBytes parses the json and returns a result.
464// If working with bytes, this method preferred over Parse(string(data))
465func ParseBytes(json []byte) Result {
466	return Parse(string(json))
467}
468
469func squash(json string) string {
470	// expects that the lead character is a '[' or '{' or '(' or '"'
471	// squash the value, ignoring all nested arrays and objects.
472	var i, depth int
473	if json[0] != '"' {
474		i, depth = 1, 1
475	}
476	for ; i < len(json); i++ {
477		if json[i] >= '"' && json[i] <= '}' {
478			switch json[i] {
479			case '"':
480				i++
481				s2 := i
482				for ; i < len(json); i++ {
483					if json[i] > '\\' {
484						continue
485					}
486					if json[i] == '"' {
487						// look for an escaped slash
488						if json[i-1] == '\\' {
489							n := 0
490							for j := i - 2; j > s2-1; j-- {
491								if json[j] != '\\' {
492									break
493								}
494								n++
495							}
496							if n%2 == 0 {
497								continue
498							}
499						}
500						break
501					}
502				}
503				if depth == 0 {
504					if i >= len(json) {
505						return json
506					}
507					return json[:i+1]
508				}
509			case '{', '[', '(':
510				depth++
511			case '}', ']', ')':
512				depth--
513				if depth == 0 {
514					return json[:i+1]
515				}
516			}
517		}
518	}
519	return json
520}
521
522func tonum(json string) (raw string, num float64) {
523	for i := 1; i < len(json); i++ {
524		// less than dash might have valid characters
525		if json[i] <= '-' {
526			if json[i] <= ' ' || json[i] == ',' {
527				// break on whitespace and comma
528				raw = json[:i]
529				num, _ = strconv.ParseFloat(raw, 64)
530				return
531			}
532			// could be a '+' or '-'. let's assume so.
533			continue
534		}
535		if json[i] < ']' {
536			// probably a valid number
537			continue
538		}
539		if json[i] == 'e' || json[i] == 'E' {
540			// allow for exponential numbers
541			continue
542		}
543		// likely a ']' or '}'
544		raw = json[:i]
545		num, _ = strconv.ParseFloat(raw, 64)
546		return
547	}
548	raw = json
549	num, _ = strconv.ParseFloat(raw, 64)
550	return
551}
552
553func tolit(json string) (raw string) {
554	for i := 1; i < len(json); i++ {
555		if json[i] < 'a' || json[i] > 'z' {
556			return json[:i]
557		}
558	}
559	return json
560}
561
562func tostr(json string) (raw string, str string) {
563	// expects that the lead character is a '"'
564	for i := 1; i < len(json); i++ {
565		if json[i] > '\\' {
566			continue
567		}
568		if json[i] == '"' {
569			return json[:i+1], json[1:i]
570		}
571		if json[i] == '\\' {
572			i++
573			for ; i < len(json); i++ {
574				if json[i] > '\\' {
575					continue
576				}
577				if json[i] == '"' {
578					// look for an escaped slash
579					if json[i-1] == '\\' {
580						n := 0
581						for j := i - 2; j > 0; j-- {
582							if json[j] != '\\' {
583								break
584							}
585							n++
586						}
587						if n%2 == 0 {
588							continue
589						}
590					}
591					return json[:i+1], unescape(json[1:i])
592				}
593			}
594			var ret string
595			if i+1 < len(json) {
596				ret = json[:i+1]
597			} else {
598				ret = json[:i]
599			}
600			return ret, unescape(json[1:i])
601		}
602	}
603	return json, json[1:]
604}
605
606// Exists returns true if value exists.
607//
608//  if gjson.Get(json, "name.last").Exists(){
609//		println("value exists")
610//  }
611func (t Result) Exists() bool {
612	return t.Type != Null || len(t.Raw) != 0
613}
614
615// Value returns one of these types:
616//
617//	bool, for JSON booleans
618//	float64, for JSON numbers
619//	Number, for JSON numbers
620//	string, for JSON string literals
621//	nil, for JSON null
622//	map[string]interface{}, for JSON objects
623//	[]interface{}, for JSON arrays
624//
625func (t Result) Value() interface{} {
626	if t.Type == String {
627		return t.Str
628	}
629	switch t.Type {
630	default:
631		return nil
632	case False:
633		return false
634	case Number:
635		return t.Num
636	case JSON:
637		r := t.arrayOrMap(0, true)
638		if r.vc == '{' {
639			return r.oi
640		} else if r.vc == '[' {
641			return r.ai
642		}
643		return nil
644	case True:
645		return true
646	}
647}
648
649func parseString(json string, i int) (int, string, bool, bool) {
650	var s = i
651	for ; i < len(json); i++ {
652		if json[i] > '\\' {
653			continue
654		}
655		if json[i] == '"' {
656			return i + 1, json[s-1 : i+1], false, true
657		}
658		if json[i] == '\\' {
659			i++
660			for ; i < len(json); i++ {
661				if json[i] > '\\' {
662					continue
663				}
664				if json[i] == '"' {
665					// look for an escaped slash
666					if json[i-1] == '\\' {
667						n := 0
668						for j := i - 2; j > 0; j-- {
669							if json[j] != '\\' {
670								break
671							}
672							n++
673						}
674						if n%2 == 0 {
675							continue
676						}
677					}
678					return i + 1, json[s-1 : i+1], true, true
679				}
680			}
681			break
682		}
683	}
684	return i, json[s-1:], false, false
685}
686
687func parseNumber(json string, i int) (int, string) {
688	var s = i
689	i++
690	for ; i < len(json); i++ {
691		if json[i] <= ' ' || json[i] == ',' || json[i] == ']' ||
692			json[i] == '}' {
693			return i, json[s:i]
694		}
695	}
696	return i, json[s:]
697}
698
699func parseLiteral(json string, i int) (int, string) {
700	var s = i
701	i++
702	for ; i < len(json); i++ {
703		if json[i] < 'a' || json[i] > 'z' {
704			return i, json[s:i]
705		}
706	}
707	return i, json[s:]
708}
709
710type arrayPathResult struct {
711	part    string
712	path    string
713	pipe    string
714	piped   bool
715	more    bool
716	alogok  bool
717	arrch   bool
718	alogkey string
719	query   struct {
720		on    bool
721		all   bool
722		path  string
723		op    string
724		value string
725	}
726}
727
728func parseArrayPath(path string) (r arrayPathResult) {
729	for i := 0; i < len(path); i++ {
730		if path[i] == '|' {
731			r.part = path[:i]
732			r.pipe = path[i+1:]
733			r.piped = true
734			return
735		}
736		if path[i] == '.' {
737			r.part = path[:i]
738			if !r.arrch && i < len(path)-1 && isDotPiperChar(path[i+1]) {
739				r.pipe = path[i+1:]
740				r.piped = true
741			} else {
742				r.path = path[i+1:]
743				r.more = true
744			}
745			return
746		}
747		if path[i] == '#' {
748			r.arrch = true
749			if i == 0 && len(path) > 1 {
750				if path[1] == '.' {
751					r.alogok = true
752					r.alogkey = path[2:]
753					r.path = path[:1]
754				} else if path[1] == '[' || path[1] == '(' {
755					// query
756					r.query.on = true
757					qpath, op, value, _, fi, vesc, ok :=
758						parseQuery(path[i:])
759					if !ok {
760						// bad query, end now
761						break
762					}
763					if len(value) > 2 && value[0] == '"' &&
764						value[len(value)-1] == '"' {
765						value = value[1 : len(value)-1]
766						if vesc {
767							value = unescape(value)
768						}
769					}
770					r.query.path = qpath
771					r.query.op = op
772					r.query.value = value
773
774					i = fi - 1
775					if i+1 < len(path) && path[i+1] == '#' {
776						r.query.all = true
777					}
778				}
779			}
780			continue
781		}
782	}
783	r.part = path
784	r.path = ""
785	return
786}
787
788// splitQuery takes a query and splits it into three parts:
789//   path, op, middle, and right.
790// So for this query:
791//   #(first_name=="Murphy").last
792// Becomes
793//   first_name   # path
794//   =="Murphy"   # middle
795//   .last        # right
796// Or,
797//   #(service_roles.#(=="one")).cap
798// Becomes
799//   service_roles.#(=="one")   # path
800//                              # middle
801//   .cap                       # right
802func parseQuery(query string) (
803	path, op, value, remain string, i int, vesc, ok bool,
804) {
805	if len(query) < 2 || query[0] != '#' ||
806		(query[1] != '(' && query[1] != '[') {
807		return "", "", "", "", i, false, false
808	}
809	i = 2
810	j := 0 // start of value part
811	depth := 1
812	for ; i < len(query); i++ {
813		if depth == 1 && j == 0 {
814			switch query[i] {
815			case '!', '=', '<', '>', '%':
816				// start of the value part
817				j = i
818				continue
819			}
820		}
821		if query[i] == '\\' {
822			i++
823		} else if query[i] == '[' || query[i] == '(' {
824			depth++
825		} else if query[i] == ']' || query[i] == ')' {
826			depth--
827			if depth == 0 {
828				break
829			}
830		} else if query[i] == '"' {
831			// inside selector string, balance quotes
832			i++
833			for ; i < len(query); i++ {
834				if query[i] == '\\' {
835					vesc = true
836					i++
837				} else if query[i] == '"' {
838					break
839				}
840			}
841		}
842	}
843	if depth > 0 {
844		return "", "", "", "", i, false, false
845	}
846	if j > 0 {
847		path = trim(query[2:j])
848		value = trim(query[j:i])
849		remain = query[i+1:]
850		// parse the compare op from the value
851		var opsz int
852		switch {
853		case len(value) == 1:
854			opsz = 1
855		case value[0] == '!' && value[1] == '=':
856			opsz = 2
857		case value[0] == '!' && value[1] == '%':
858			opsz = 2
859		case value[0] == '<' && value[1] == '=':
860			opsz = 2
861		case value[0] == '>' && value[1] == '=':
862			opsz = 2
863		case value[0] == '=' && value[1] == '=':
864			value = value[1:]
865			opsz = 1
866		case value[0] == '<':
867			opsz = 1
868		case value[0] == '>':
869			opsz = 1
870		case value[0] == '=':
871			opsz = 1
872		case value[0] == '%':
873			opsz = 1
874		}
875		op = value[:opsz]
876		value = trim(value[opsz:])
877	} else {
878		path = trim(query[2:i])
879		remain = query[i+1:]
880	}
881	return path, op, value, remain, i + 1, vesc, true
882}
883
884func trim(s string) string {
885left:
886	if len(s) > 0 && s[0] <= ' ' {
887		s = s[1:]
888		goto left
889	}
890right:
891	if len(s) > 0 && s[len(s)-1] <= ' ' {
892		s = s[:len(s)-1]
893		goto right
894	}
895	return s
896}
897
898// peek at the next byte and see if it's a '@', '[', or '{'.
899func isDotPiperChar(c byte) bool {
900	return !DisableModifiers && (c == '@' || c == '[' || c == '{')
901}
902
903type objectPathResult struct {
904	part  string
905	path  string
906	pipe  string
907	piped bool
908	wild  bool
909	more  bool
910}
911
912func parseObjectPath(path string) (r objectPathResult) {
913	for i := 0; i < len(path); i++ {
914		if path[i] == '|' {
915			r.part = path[:i]
916			r.pipe = path[i+1:]
917			r.piped = true
918			return
919		}
920		if path[i] == '.' {
921			r.part = path[:i]
922			if i < len(path)-1 && isDotPiperChar(path[i+1]) {
923				r.pipe = path[i+1:]
924				r.piped = true
925			} else {
926				r.path = path[i+1:]
927				r.more = true
928			}
929			return
930		}
931		if path[i] == '*' || path[i] == '?' {
932			r.wild = true
933			continue
934		}
935		if path[i] == '\\' {
936			// go into escape mode. this is a slower path that
937			// strips off the escape character from the part.
938			epart := []byte(path[:i])
939			i++
940			if i < len(path) {
941				epart = append(epart, path[i])
942				i++
943				for ; i < len(path); i++ {
944					if path[i] == '\\' {
945						i++
946						if i < len(path) {
947							epart = append(epart, path[i])
948						}
949						continue
950					} else if path[i] == '.' {
951						r.part = string(epart)
952						if i < len(path)-1 && isDotPiperChar(path[i+1]) {
953							r.pipe = path[i+1:]
954							r.piped = true
955						} else {
956							r.path = path[i+1:]
957						}
958						r.more = true
959						return
960					} else if path[i] == '|' {
961						r.part = string(epart)
962						r.pipe = path[i+1:]
963						r.piped = true
964						return
965					} else if path[i] == '*' || path[i] == '?' {
966						r.wild = true
967					}
968					epart = append(epart, path[i])
969				}
970			}
971			// append the last part
972			r.part = string(epart)
973			return
974		}
975	}
976	r.part = path
977	return
978}
979
980func parseSquash(json string, i int) (int, string) {
981	// expects that the lead character is a '[' or '{' or '('
982	// squash the value, ignoring all nested arrays and objects.
983	// the first '[' or '{' or '(' has already been read
984	s := i
985	i++
986	depth := 1
987	for ; i < len(json); i++ {
988		if json[i] >= '"' && json[i] <= '}' {
989			switch json[i] {
990			case '"':
991				i++
992				s2 := i
993				for ; i < len(json); i++ {
994					if json[i] > '\\' {
995						continue
996					}
997					if json[i] == '"' {
998						// look for an escaped slash
999						if json[i-1] == '\\' {
1000							n := 0
1001							for j := i - 2; j > s2-1; j-- {
1002								if json[j] != '\\' {
1003									break
1004								}
1005								n++
1006							}
1007							if n%2 == 0 {
1008								continue
1009							}
1010						}
1011						break
1012					}
1013				}
1014			case '{', '[', '(':
1015				depth++
1016			case '}', ']', ')':
1017				depth--
1018				if depth == 0 {
1019					i++
1020					return i, json[s:i]
1021				}
1022			}
1023		}
1024	}
1025	return i, json[s:]
1026}
1027
1028func parseObject(c *parseContext, i int, path string) (int, bool) {
1029	var pmatch, kesc, vesc, ok, hit bool
1030	var key, val string
1031	rp := parseObjectPath(path)
1032	if !rp.more && rp.piped {
1033		c.pipe = rp.pipe
1034		c.piped = true
1035	}
1036	for i < len(c.json) {
1037		for ; i < len(c.json); i++ {
1038			if c.json[i] == '"' {
1039				// parse_key_string
1040				// this is slightly different from getting s string value
1041				// because we don't need the outer quotes.
1042				i++
1043				var s = i
1044				for ; i < len(c.json); i++ {
1045					if c.json[i] > '\\' {
1046						continue
1047					}
1048					if c.json[i] == '"' {
1049						i, key, kesc, ok = i+1, c.json[s:i], false, true
1050						goto parse_key_string_done
1051					}
1052					if c.json[i] == '\\' {
1053						i++
1054						for ; i < len(c.json); i++ {
1055							if c.json[i] > '\\' {
1056								continue
1057							}
1058							if c.json[i] == '"' {
1059								// look for an escaped slash
1060								if c.json[i-1] == '\\' {
1061									n := 0
1062									for j := i - 2; j > 0; j-- {
1063										if c.json[j] != '\\' {
1064											break
1065										}
1066										n++
1067									}
1068									if n%2 == 0 {
1069										continue
1070									}
1071								}
1072								i, key, kesc, ok = i+1, c.json[s:i], true, true
1073								goto parse_key_string_done
1074							}
1075						}
1076						break
1077					}
1078				}
1079				key, kesc, ok = c.json[s:], false, false
1080			parse_key_string_done:
1081				break
1082			}
1083			if c.json[i] == '}' {
1084				return i + 1, false
1085			}
1086		}
1087		if !ok {
1088			return i, false
1089		}
1090		if rp.wild {
1091			if kesc {
1092				pmatch = matchLimit(unescape(key), rp.part)
1093			} else {
1094				pmatch = matchLimit(key, rp.part)
1095			}
1096		} else {
1097			if kesc {
1098				pmatch = rp.part == unescape(key)
1099			} else {
1100				pmatch = rp.part == key
1101			}
1102		}
1103		hit = pmatch && !rp.more
1104		for ; i < len(c.json); i++ {
1105			switch c.json[i] {
1106			default:
1107				continue
1108			case '"':
1109				i++
1110				i, val, vesc, ok = parseString(c.json, i)
1111				if !ok {
1112					return i, false
1113				}
1114				if hit {
1115					if vesc {
1116						c.value.Str = unescape(val[1 : len(val)-1])
1117					} else {
1118						c.value.Str = val[1 : len(val)-1]
1119					}
1120					c.value.Raw = val
1121					c.value.Type = String
1122					return i, true
1123				}
1124			case '{':
1125				if pmatch && !hit {
1126					i, hit = parseObject(c, i+1, rp.path)
1127					if hit {
1128						return i, true
1129					}
1130				} else {
1131					i, val = parseSquash(c.json, i)
1132					if hit {
1133						c.value.Raw = val
1134						c.value.Type = JSON
1135						return i, true
1136					}
1137				}
1138			case '[':
1139				if pmatch && !hit {
1140					i, hit = parseArray(c, i+1, rp.path)
1141					if hit {
1142						return i, true
1143					}
1144				} else {
1145					i, val = parseSquash(c.json, i)
1146					if hit {
1147						c.value.Raw = val
1148						c.value.Type = JSON
1149						return i, true
1150					}
1151				}
1152			case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
1153				i, val = parseNumber(c.json, i)
1154				if hit {
1155					c.value.Raw = val
1156					c.value.Type = Number
1157					c.value.Num, _ = strconv.ParseFloat(val, 64)
1158					return i, true
1159				}
1160			case 't', 'f', 'n':
1161				vc := c.json[i]
1162				i, val = parseLiteral(c.json, i)
1163				if hit {
1164					c.value.Raw = val
1165					switch vc {
1166					case 't':
1167						c.value.Type = True
1168					case 'f':
1169						c.value.Type = False
1170					}
1171					return i, true
1172				}
1173			}
1174			break
1175		}
1176	}
1177	return i, false
1178}
1179
1180// matchLimit will limit the complexity of the match operation to avoid ReDos
1181// attacks from arbritary inputs.
1182// See the github.com/tidwall/match.MatchLimit function for more information.
1183func matchLimit(str, pattern string) bool {
1184	matched, _ := match.MatchLimit(str, pattern, 10000)
1185	return matched
1186}
1187
1188func queryMatches(rp *arrayPathResult, value Result) bool {
1189	rpv := rp.query.value
1190	if len(rpv) > 0 && rpv[0] == '~' {
1191		// convert to bool
1192		rpv = rpv[1:]
1193		if value.Bool() {
1194			value = Result{Type: True}
1195		} else {
1196			value = Result{Type: False}
1197		}
1198	}
1199	if !value.Exists() {
1200		return false
1201	}
1202	if rp.query.op == "" {
1203		// the query is only looking for existence, such as:
1204		//   friends.#(name)
1205		// which makes sure that the array "friends" has an element of
1206		// "name" that exists
1207		return true
1208	}
1209	switch value.Type {
1210	case String:
1211		switch rp.query.op {
1212		case "=":
1213			return value.Str == rpv
1214		case "!=":
1215			return value.Str != rpv
1216		case "<":
1217			return value.Str < rpv
1218		case "<=":
1219			return value.Str <= rpv
1220		case ">":
1221			return value.Str > rpv
1222		case ">=":
1223			return value.Str >= rpv
1224		case "%":
1225			return matchLimit(value.Str, rpv)
1226		case "!%":
1227			return !matchLimit(value.Str, rpv)
1228		}
1229	case Number:
1230		rpvn, _ := strconv.ParseFloat(rpv, 64)
1231		switch rp.query.op {
1232		case "=":
1233			return value.Num == rpvn
1234		case "!=":
1235			return value.Num != rpvn
1236		case "<":
1237			return value.Num < rpvn
1238		case "<=":
1239			return value.Num <= rpvn
1240		case ">":
1241			return value.Num > rpvn
1242		case ">=":
1243			return value.Num >= rpvn
1244		}
1245	case True:
1246		switch rp.query.op {
1247		case "=":
1248			return rpv == "true"
1249		case "!=":
1250			return rpv != "true"
1251		case ">":
1252			return rpv == "false"
1253		case ">=":
1254			return true
1255		}
1256	case False:
1257		switch rp.query.op {
1258		case "=":
1259			return rpv == "false"
1260		case "!=":
1261			return rpv != "false"
1262		case "<":
1263			return rpv == "true"
1264		case "<=":
1265			return true
1266		}
1267	}
1268	return false
1269}
1270func parseArray(c *parseContext, i int, path string) (int, bool) {
1271	var pmatch, vesc, ok, hit bool
1272	var val string
1273	var h int
1274	var alog []int
1275	var partidx int
1276	var multires []byte
1277	var queryIndexes []int
1278	rp := parseArrayPath(path)
1279	if !rp.arrch {
1280		n, ok := parseUint(rp.part)
1281		if !ok {
1282			partidx = -1
1283		} else {
1284			partidx = int(n)
1285		}
1286	}
1287	if !rp.more && rp.piped {
1288		c.pipe = rp.pipe
1289		c.piped = true
1290	}
1291
1292	procQuery := func(qval Result) bool {
1293		if rp.query.all {
1294			if len(multires) == 0 {
1295				multires = append(multires, '[')
1296			}
1297		}
1298		var tmp parseContext
1299		tmp.value = qval
1300		fillIndex(c.json, &tmp)
1301		parentIndex := tmp.value.Index
1302		var res Result
1303		if qval.Type == JSON {
1304			res = qval.Get(rp.query.path)
1305		} else {
1306			if rp.query.path != "" {
1307				return false
1308			}
1309			res = qval
1310		}
1311		if queryMatches(&rp, res) {
1312			if rp.more {
1313				left, right, ok := splitPossiblePipe(rp.path)
1314				if ok {
1315					rp.path = left
1316					c.pipe = right
1317					c.piped = true
1318				}
1319				res = qval.Get(rp.path)
1320			} else {
1321				res = qval
1322			}
1323			if rp.query.all {
1324				raw := res.Raw
1325				if len(raw) == 0 {
1326					raw = res.String()
1327				}
1328				if raw != "" {
1329					if len(multires) > 1 {
1330						multires = append(multires, ',')
1331					}
1332					multires = append(multires, raw...)
1333					queryIndexes = append(queryIndexes, res.Index+parentIndex)
1334				}
1335			} else {
1336				c.value = res
1337				return true
1338			}
1339		}
1340		return false
1341	}
1342	for i < len(c.json)+1 {
1343		if !rp.arrch {
1344			pmatch = partidx == h
1345			hit = pmatch && !rp.more
1346		}
1347		h++
1348		if rp.alogok {
1349			alog = append(alog, i)
1350		}
1351		for ; ; i++ {
1352			var ch byte
1353			if i > len(c.json) {
1354				break
1355			} else if i == len(c.json) {
1356				ch = ']'
1357			} else {
1358				ch = c.json[i]
1359			}
1360			switch ch {
1361			default:
1362				continue
1363			case '"':
1364				i++
1365				i, val, vesc, ok = parseString(c.json, i)
1366				if !ok {
1367					return i, false
1368				}
1369				if rp.query.on {
1370					var qval Result
1371					if vesc {
1372						qval.Str = unescape(val[1 : len(val)-1])
1373					} else {
1374						qval.Str = val[1 : len(val)-1]
1375					}
1376					qval.Raw = val
1377					qval.Type = String
1378					if procQuery(qval) {
1379						return i, true
1380					}
1381				} else if hit {
1382					if rp.alogok {
1383						break
1384					}
1385					if vesc {
1386						c.value.Str = unescape(val[1 : len(val)-1])
1387					} else {
1388						c.value.Str = val[1 : len(val)-1]
1389					}
1390					c.value.Raw = val
1391					c.value.Type = String
1392					return i, true
1393				}
1394			case '{':
1395				if pmatch && !hit {
1396					i, hit = parseObject(c, i+1, rp.path)
1397					if hit {
1398						if rp.alogok {
1399							break
1400						}
1401						return i, true
1402					}
1403				} else {
1404					i, val = parseSquash(c.json, i)
1405					if rp.query.on {
1406						if procQuery(Result{Raw: val, Type: JSON}) {
1407							return i, true
1408						}
1409					} else if hit {
1410						if rp.alogok {
1411							break
1412						}
1413						c.value.Raw = val
1414						c.value.Type = JSON
1415						return i, true
1416					}
1417				}
1418			case '[':
1419				if pmatch && !hit {
1420					i, hit = parseArray(c, i+1, rp.path)
1421					if hit {
1422						if rp.alogok {
1423							break
1424						}
1425						return i, true
1426					}
1427				} else {
1428					i, val = parseSquash(c.json, i)
1429					if rp.query.on {
1430						if procQuery(Result{Raw: val, Type: JSON}) {
1431							return i, true
1432						}
1433					} else if hit {
1434						if rp.alogok {
1435							break
1436						}
1437						c.value.Raw = val
1438						c.value.Type = JSON
1439						return i, true
1440					}
1441				}
1442			case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
1443				i, val = parseNumber(c.json, i)
1444				if rp.query.on {
1445					var qval Result
1446					qval.Raw = val
1447					qval.Type = Number
1448					qval.Num, _ = strconv.ParseFloat(val, 64)
1449					if procQuery(qval) {
1450						return i, true
1451					}
1452				} else if hit {
1453					if rp.alogok {
1454						break
1455					}
1456					c.value.Raw = val
1457					c.value.Type = Number
1458					c.value.Num, _ = strconv.ParseFloat(val, 64)
1459					return i, true
1460				}
1461			case 't', 'f', 'n':
1462				vc := c.json[i]
1463				i, val = parseLiteral(c.json, i)
1464				if rp.query.on {
1465					var qval Result
1466					qval.Raw = val
1467					switch vc {
1468					case 't':
1469						qval.Type = True
1470					case 'f':
1471						qval.Type = False
1472					}
1473					if procQuery(qval) {
1474						return i, true
1475					}
1476				} else if hit {
1477					if rp.alogok {
1478						break
1479					}
1480					c.value.Raw = val
1481					switch vc {
1482					case 't':
1483						c.value.Type = True
1484					case 'f':
1485						c.value.Type = False
1486					}
1487					return i, true
1488				}
1489			case ']':
1490				if rp.arrch && rp.part == "#" {
1491					if rp.alogok {
1492						left, right, ok := splitPossiblePipe(rp.alogkey)
1493						if ok {
1494							rp.alogkey = left
1495							c.pipe = right
1496							c.piped = true
1497						}
1498						var indexes = make([]int, 0, 64)
1499						var jsons = make([]byte, 0, 64)
1500						jsons = append(jsons, '[')
1501						for j, k := 0, 0; j < len(alog); j++ {
1502							idx := alog[j]
1503							for idx < len(c.json) {
1504								switch c.json[idx] {
1505								case ' ', '\t', '\r', '\n':
1506									idx++
1507									continue
1508								}
1509								break
1510							}
1511							if idx < len(c.json) && c.json[idx] != ']' {
1512								_, res, ok := parseAny(c.json, idx, true)
1513								parentIndex := res.Index
1514								if ok {
1515									res := res.Get(rp.alogkey)
1516									if res.Exists() {
1517										if k > 0 {
1518											jsons = append(jsons, ',')
1519										}
1520										raw := res.Raw
1521										if len(raw) == 0 {
1522											raw = res.String()
1523										}
1524										jsons = append(jsons, []byte(raw)...)
1525										indexes = append(indexes,
1526											res.Index+parentIndex)
1527										k++
1528									}
1529								}
1530							}
1531						}
1532						jsons = append(jsons, ']')
1533						c.value.Type = JSON
1534						c.value.Raw = string(jsons)
1535						c.value.Indexes = indexes
1536						return i + 1, true
1537					}
1538					if rp.alogok {
1539						break
1540					}
1541
1542					c.value.Type = Number
1543					c.value.Num = float64(h - 1)
1544					c.value.Raw = strconv.Itoa(h - 1)
1545					c.calcd = true
1546					return i + 1, true
1547				}
1548				if !c.value.Exists() {
1549					if len(multires) > 0 {
1550						c.value = Result{
1551							Raw:     string(append(multires, ']')),
1552							Type:    JSON,
1553							Indexes: queryIndexes,
1554						}
1555					} else if rp.query.all {
1556						c.value = Result{
1557							Raw:  "[]",
1558							Type: JSON,
1559						}
1560					}
1561				}
1562				return i + 1, false
1563			}
1564			break
1565		}
1566	}
1567	return i, false
1568}
1569
1570func splitPossiblePipe(path string) (left, right string, ok bool) {
1571	// take a quick peek for the pipe character. If found we'll split the piped
1572	// part of the path into the c.pipe field and shorten the rp.
1573	var possible bool
1574	for i := 0; i < len(path); i++ {
1575		if path[i] == '|' {
1576			possible = true
1577			break
1578		}
1579	}
1580	if !possible {
1581		return
1582	}
1583
1584	if len(path) > 0 && path[0] == '{' {
1585		squashed := squash(path[1:])
1586		if len(squashed) < len(path)-1 {
1587			squashed = path[:len(squashed)+1]
1588			remain := path[len(squashed):]
1589			if remain[0] == '|' {
1590				return squashed, remain[1:], true
1591			}
1592		}
1593		return
1594	}
1595
1596	// split the left and right side of the path with the pipe character as
1597	// the delimiter. This is a little tricky because we'll need to basically
1598	// parse the entire path.
1599	for i := 0; i < len(path); i++ {
1600		if path[i] == '\\' {
1601			i++
1602		} else if path[i] == '.' {
1603			if i == len(path)-1 {
1604				return
1605			}
1606			if path[i+1] == '#' {
1607				i += 2
1608				if i == len(path) {
1609					return
1610				}
1611				if path[i] == '[' || path[i] == '(' {
1612					var start, end byte
1613					if path[i] == '[' {
1614						start, end = '[', ']'
1615					} else {
1616						start, end = '(', ')'
1617					}
1618					// inside selector, balance brackets
1619					i++
1620					depth := 1
1621					for ; i < len(path); i++ {
1622						if path[i] == '\\' {
1623							i++
1624						} else if path[i] == start {
1625							depth++
1626						} else if path[i] == end {
1627							depth--
1628							if depth == 0 {
1629								break
1630							}
1631						} else if path[i] == '"' {
1632							// inside selector string, balance quotes
1633							i++
1634							for ; i < len(path); i++ {
1635								if path[i] == '\\' {
1636									i++
1637								} else if path[i] == '"' {
1638									break
1639								}
1640							}
1641						}
1642					}
1643				}
1644			}
1645		} else if path[i] == '|' {
1646			return path[:i], path[i+1:], true
1647		}
1648	}
1649	return
1650}
1651
1652// ForEachLine iterates through lines of JSON as specified by the JSON Lines
1653// format (http://jsonlines.org/).
1654// Each line is returned as a GJSON Result.
1655func ForEachLine(json string, iterator func(line Result) bool) {
1656	var res Result
1657	var i int
1658	for {
1659		i, res, _ = parseAny(json, i, true)
1660		if !res.Exists() {
1661			break
1662		}
1663		if !iterator(res) {
1664			return
1665		}
1666	}
1667}
1668
1669type subSelector struct {
1670	name string
1671	path string
1672}
1673
1674// parseSubSelectors returns the subselectors belonging to a '[path1,path2]' or
1675// '{"field1":path1,"field2":path2}' type subSelection. It's expected that the
1676// first character in path is either '[' or '{', and has already been checked
1677// prior to calling this function.
1678func parseSubSelectors(path string) (sels []subSelector, out string, ok bool) {
1679	modifer := 0
1680	depth := 1
1681	colon := 0
1682	start := 1
1683	i := 1
1684	pushSel := func() {
1685		var sel subSelector
1686		if colon == 0 {
1687			sel.path = path[start:i]
1688		} else {
1689			sel.name = path[start:colon]
1690			sel.path = path[colon+1 : i]
1691		}
1692		sels = append(sels, sel)
1693		colon = 0
1694		start = i + 1
1695	}
1696	for ; i < len(path); i++ {
1697		switch path[i] {
1698		case '\\':
1699			i++
1700		case '@':
1701			if modifer == 0 && i > 0 && (path[i-1] == '.' || path[i-1] == '|') {
1702				modifer = i
1703			}
1704		case ':':
1705			if modifer == 0 && colon == 0 && depth == 1 {
1706				colon = i
1707			}
1708		case ',':
1709			if depth == 1 {
1710				pushSel()
1711			}
1712		case '"':
1713			i++
1714		loop:
1715			for ; i < len(path); i++ {
1716				switch path[i] {
1717				case '\\':
1718					i++
1719				case '"':
1720					break loop
1721				}
1722			}
1723		case '[', '(', '{':
1724			depth++
1725		case ']', ')', '}':
1726			depth--
1727			if depth == 0 {
1728				pushSel()
1729				path = path[i+1:]
1730				return sels, path, true
1731			}
1732		}
1733	}
1734	return
1735}
1736
1737// nameOfLast returns the name of the last component
1738func nameOfLast(path string) string {
1739	for i := len(path) - 1; i >= 0; i-- {
1740		if path[i] == '|' || path[i] == '.' {
1741			if i > 0 {
1742				if path[i-1] == '\\' {
1743					continue
1744				}
1745			}
1746			return path[i+1:]
1747		}
1748	}
1749	return path
1750}
1751
1752func isSimpleName(component string) bool {
1753	for i := 0; i < len(component); i++ {
1754		if component[i] < ' ' {
1755			return false
1756		}
1757		switch component[i] {
1758		case '[', ']', '{', '}', '(', ')', '#', '|':
1759			return false
1760		}
1761	}
1762	return true
1763}
1764
1765func appendJSONString(dst []byte, s string) []byte {
1766	for i := 0; i < len(s); i++ {
1767		if s[i] < ' ' || s[i] == '\\' || s[i] == '"' || s[i] > 126 {
1768			d, _ := json.Marshal(s)
1769			return append(dst, string(d)...)
1770		}
1771	}
1772	dst = append(dst, '"')
1773	dst = append(dst, s...)
1774	dst = append(dst, '"')
1775	return dst
1776}
1777
1778type parseContext struct {
1779	json  string
1780	value Result
1781	pipe  string
1782	piped bool
1783	calcd bool
1784	lines bool
1785}
1786
1787// Get searches json for the specified path.
1788// A path is in dot syntax, such as "name.last" or "age".
1789// When the value is found it's returned immediately.
1790//
1791// A path is a series of keys separated by a dot.
1792// A key may contain special wildcard characters '*' and '?'.
1793// To access an array value use the index as the key.
1794// To get the number of elements in an array or to access a child path, use
1795// the '#' character.
1796// The dot and wildcard character can be escaped with '\'.
1797//
1798//  {
1799//    "name": {"first": "Tom", "last": "Anderson"},
1800//    "age":37,
1801//    "children": ["Sara","Alex","Jack"],
1802//    "friends": [
1803//      {"first": "James", "last": "Murphy"},
1804//      {"first": "Roger", "last": "Craig"}
1805//    ]
1806//  }
1807//  "name.last"          >> "Anderson"
1808//  "age"                >> 37
1809//  "children"           >> ["Sara","Alex","Jack"]
1810//  "children.#"         >> 3
1811//  "children.1"         >> "Alex"
1812//  "child*.2"           >> "Jack"
1813//  "c?ildren.0"         >> "Sara"
1814//  "friends.#.first"    >> ["James","Roger"]
1815//
1816// This function expects that the json is well-formed, and does not validate.
1817// Invalid json will not panic, but it may return back unexpected results.
1818// If you are consuming JSON from an unpredictable source then you may want to
1819// use the Valid function first.
1820func Get(json, path string) Result {
1821	if len(path) > 1 {
1822		if !DisableModifiers {
1823			if path[0] == '@' {
1824				// possible modifier
1825				var ok bool
1826				var npath string
1827				var rjson string
1828				npath, rjson, ok = execModifier(json, path)
1829				if ok {
1830					path = npath
1831					if len(path) > 0 && (path[0] == '|' || path[0] == '.') {
1832						res := Get(rjson, path[1:])
1833						res.Index = 0
1834						res.Indexes = nil
1835						return res
1836					}
1837					return Parse(rjson)
1838				}
1839			}
1840		}
1841		if path[0] == '[' || path[0] == '{' {
1842			// using a subselector path
1843			kind := path[0]
1844			var ok bool
1845			var subs []subSelector
1846			subs, path, ok = parseSubSelectors(path)
1847			if ok {
1848				if len(path) == 0 || (path[0] == '|' || path[0] == '.') {
1849					var b []byte
1850					b = append(b, kind)
1851					var i int
1852					for _, sub := range subs {
1853						res := Get(json, sub.path)
1854						if res.Exists() {
1855							if i > 0 {
1856								b = append(b, ',')
1857							}
1858							if kind == '{' {
1859								if len(sub.name) > 0 {
1860									if sub.name[0] == '"' && Valid(sub.name) {
1861										b = append(b, sub.name...)
1862									} else {
1863										b = appendJSONString(b, sub.name)
1864									}
1865								} else {
1866									last := nameOfLast(sub.path)
1867									if isSimpleName(last) {
1868										b = appendJSONString(b, last)
1869									} else {
1870										b = appendJSONString(b, "_")
1871									}
1872								}
1873								b = append(b, ':')
1874							}
1875							var raw string
1876							if len(res.Raw) == 0 {
1877								raw = res.String()
1878								if len(raw) == 0 {
1879									raw = "null"
1880								}
1881							} else {
1882								raw = res.Raw
1883							}
1884							b = append(b, raw...)
1885							i++
1886						}
1887					}
1888					b = append(b, kind+2)
1889					var res Result
1890					res.Raw = string(b)
1891					res.Type = JSON
1892					if len(path) > 0 {
1893						res = res.Get(path[1:])
1894					}
1895					res.Index = 0
1896					return res
1897				}
1898			}
1899		}
1900	}
1901	var i int
1902	var c = &parseContext{json: json}
1903	if len(path) >= 2 && path[0] == '.' && path[1] == '.' {
1904		c.lines = true
1905		parseArray(c, 0, path[2:])
1906	} else {
1907		for ; i < len(c.json); i++ {
1908			if c.json[i] == '{' {
1909				i++
1910				parseObject(c, i, path)
1911				break
1912			}
1913			if c.json[i] == '[' {
1914				i++
1915				parseArray(c, i, path)
1916				break
1917			}
1918		}
1919	}
1920	if c.piped {
1921		res := c.value.Get(c.pipe)
1922		res.Index = 0
1923		return res
1924	}
1925	fillIndex(json, c)
1926	return c.value
1927}
1928
1929// GetBytes searches json for the specified path.
1930// If working with bytes, this method preferred over Get(string(data), path)
1931func GetBytes(json []byte, path string) Result {
1932	return getBytes(json, path)
1933}
1934
1935// runeit returns the rune from the the \uXXXX
1936func runeit(json string) rune {
1937	n, _ := strconv.ParseUint(json[:4], 16, 64)
1938	return rune(n)
1939}
1940
1941// unescape unescapes a string
1942func unescape(json string) string {
1943	var str = make([]byte, 0, len(json))
1944	for i := 0; i < len(json); i++ {
1945		switch {
1946		default:
1947			str = append(str, json[i])
1948		case json[i] < ' ':
1949			return string(str)
1950		case json[i] == '\\':
1951			i++
1952			if i >= len(json) {
1953				return string(str)
1954			}
1955			switch json[i] {
1956			default:
1957				return string(str)
1958			case '\\':
1959				str = append(str, '\\')
1960			case '/':
1961				str = append(str, '/')
1962			case 'b':
1963				str = append(str, '\b')
1964			case 'f':
1965				str = append(str, '\f')
1966			case 'n':
1967				str = append(str, '\n')
1968			case 'r':
1969				str = append(str, '\r')
1970			case 't':
1971				str = append(str, '\t')
1972			case '"':
1973				str = append(str, '"')
1974			case 'u':
1975				if i+5 > len(json) {
1976					return string(str)
1977				}
1978				r := runeit(json[i+1:])
1979				i += 5
1980				if utf16.IsSurrogate(r) {
1981					// need another code
1982					if len(json[i:]) >= 6 && json[i] == '\\' &&
1983						json[i+1] == 'u' {
1984						// we expect it to be correct so just consume it
1985						r = utf16.DecodeRune(r, runeit(json[i+2:]))
1986						i += 6
1987					}
1988				}
1989				// provide enough space to encode the largest utf8 possible
1990				str = append(str, 0, 0, 0, 0, 0, 0, 0, 0)
1991				n := utf8.EncodeRune(str[len(str)-8:], r)
1992				str = str[:len(str)-8+n]
1993				i-- // backtrack index by one
1994			}
1995		}
1996	}
1997	return string(str)
1998}
1999
2000// Less return true if a token is less than another token.
2001// The caseSensitive paramater is used when the tokens are Strings.
2002// The order when comparing two different type is:
2003//
2004//  Null < False < Number < String < True < JSON
2005//
2006func (t Result) Less(token Result, caseSensitive bool) bool {
2007	if t.Type < token.Type {
2008		return true
2009	}
2010	if t.Type > token.Type {
2011		return false
2012	}
2013	if t.Type == String {
2014		if caseSensitive {
2015			return t.Str < token.Str
2016		}
2017		return stringLessInsensitive(t.Str, token.Str)
2018	}
2019	if t.Type == Number {
2020		return t.Num < token.Num
2021	}
2022	return t.Raw < token.Raw
2023}
2024
2025func stringLessInsensitive(a, b string) bool {
2026	for i := 0; i < len(a) && i < len(b); i++ {
2027		if a[i] >= 'A' && a[i] <= 'Z' {
2028			if b[i] >= 'A' && b[i] <= 'Z' {
2029				// both are uppercase, do nothing
2030				if a[i] < b[i] {
2031					return true
2032				} else if a[i] > b[i] {
2033					return false
2034				}
2035			} else {
2036				// a is uppercase, convert a to lowercase
2037				if a[i]+32 < b[i] {
2038					return true
2039				} else if a[i]+32 > b[i] {
2040					return false
2041				}
2042			}
2043		} else if b[i] >= 'A' && b[i] <= 'Z' {
2044			// b is uppercase, convert b to lowercase
2045			if a[i] < b[i]+32 {
2046				return true
2047			} else if a[i] > b[i]+32 {
2048				return false
2049			}
2050		} else {
2051			// neither are uppercase
2052			if a[i] < b[i] {
2053				return true
2054			} else if a[i] > b[i] {
2055				return false
2056			}
2057		}
2058	}
2059	return len(a) < len(b)
2060}
2061
2062// parseAny parses the next value from a json string.
2063// A Result is returned when the hit param is set.
2064// The return values are (i int, res Result, ok bool)
2065func parseAny(json string, i int, hit bool) (int, Result, bool) {
2066	var res Result
2067	var val string
2068	for ; i < len(json); i++ {
2069		if json[i] == '{' || json[i] == '[' {
2070			i, val = parseSquash(json, i)
2071			if hit {
2072				res.Raw = val
2073				res.Type = JSON
2074			}
2075			var tmp parseContext
2076			tmp.value = res
2077			fillIndex(json, &tmp)
2078			return i, tmp.value, true
2079		}
2080		if json[i] <= ' ' {
2081			continue
2082		}
2083		switch json[i] {
2084		case '"':
2085			i++
2086			var vesc bool
2087			var ok bool
2088			i, val, vesc, ok = parseString(json, i)
2089			if !ok {
2090				return i, res, false
2091			}
2092			if hit {
2093				res.Type = String
2094				res.Raw = val
2095				if vesc {
2096					res.Str = unescape(val[1 : len(val)-1])
2097				} else {
2098					res.Str = val[1 : len(val)-1]
2099				}
2100			}
2101			return i, res, true
2102		case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
2103			i, val = parseNumber(json, i)
2104			if hit {
2105				res.Raw = val
2106				res.Type = Number
2107				res.Num, _ = strconv.ParseFloat(val, 64)
2108			}
2109			return i, res, true
2110		case 't', 'f', 'n':
2111			vc := json[i]
2112			i, val = parseLiteral(json, i)
2113			if hit {
2114				res.Raw = val
2115				switch vc {
2116				case 't':
2117					res.Type = True
2118				case 'f':
2119					res.Type = False
2120				}
2121				return i, res, true
2122			}
2123		}
2124	}
2125	return i, res, false
2126}
2127
2128// GetMany searches json for the multiple paths.
2129// The return value is a Result array where the number of items
2130// will be equal to the number of input paths.
2131func GetMany(json string, path ...string) []Result {
2132	res := make([]Result, len(path))
2133	for i, path := range path {
2134		res[i] = Get(json, path)
2135	}
2136	return res
2137}
2138
2139// GetManyBytes searches json for the multiple paths.
2140// The return value is a Result array where the number of items
2141// will be equal to the number of input paths.
2142func GetManyBytes(json []byte, path ...string) []Result {
2143	res := make([]Result, len(path))
2144	for i, path := range path {
2145		res[i] = GetBytes(json, path)
2146	}
2147	return res
2148}
2149
2150func validpayload(data []byte, i int) (outi int, ok bool) {
2151	for ; i < len(data); i++ {
2152		switch data[i] {
2153		default:
2154			i, ok = validany(data, i)
2155			if !ok {
2156				return i, false
2157			}
2158			for ; i < len(data); i++ {
2159				switch data[i] {
2160				default:
2161					return i, false
2162				case ' ', '\t', '\n', '\r':
2163					continue
2164				}
2165			}
2166			return i, true
2167		case ' ', '\t', '\n', '\r':
2168			continue
2169		}
2170	}
2171	return i, false
2172}
2173func validany(data []byte, i int) (outi int, ok bool) {
2174	for ; i < len(data); i++ {
2175		switch data[i] {
2176		default:
2177			return i, false
2178		case ' ', '\t', '\n', '\r':
2179			continue
2180		case '{':
2181			return validobject(data, i+1)
2182		case '[':
2183			return validarray(data, i+1)
2184		case '"':
2185			return validstring(data, i+1)
2186		case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
2187			return validnumber(data, i+1)
2188		case 't':
2189			return validtrue(data, i+1)
2190		case 'f':
2191			return validfalse(data, i+1)
2192		case 'n':
2193			return validnull(data, i+1)
2194		}
2195	}
2196	return i, false
2197}
2198func validobject(data []byte, i int) (outi int, ok bool) {
2199	for ; i < len(data); i++ {
2200		switch data[i] {
2201		default:
2202			return i, false
2203		case ' ', '\t', '\n', '\r':
2204			continue
2205		case '}':
2206			return i + 1, true
2207		case '"':
2208		key:
2209			if i, ok = validstring(data, i+1); !ok {
2210				return i, false
2211			}
2212			if i, ok = validcolon(data, i); !ok {
2213				return i, false
2214			}
2215			if i, ok = validany(data, i); !ok {
2216				return i, false
2217			}
2218			if i, ok = validcomma(data, i, '}'); !ok {
2219				return i, false
2220			}
2221			if data[i] == '}' {
2222				return i + 1, true
2223			}
2224			i++
2225			for ; i < len(data); i++ {
2226				switch data[i] {
2227				default:
2228					return i, false
2229				case ' ', '\t', '\n', '\r':
2230					continue
2231				case '"':
2232					goto key
2233				}
2234			}
2235			return i, false
2236		}
2237	}
2238	return i, false
2239}
2240func validcolon(data []byte, i int) (outi int, ok bool) {
2241	for ; i < len(data); i++ {
2242		switch data[i] {
2243		default:
2244			return i, false
2245		case ' ', '\t', '\n', '\r':
2246			continue
2247		case ':':
2248			return i + 1, true
2249		}
2250	}
2251	return i, false
2252}
2253func validcomma(data []byte, i int, end byte) (outi int, ok bool) {
2254	for ; i < len(data); i++ {
2255		switch data[i] {
2256		default:
2257			return i, false
2258		case ' ', '\t', '\n', '\r':
2259			continue
2260		case ',':
2261			return i, true
2262		case end:
2263			return i, true
2264		}
2265	}
2266	return i, false
2267}
2268func validarray(data []byte, i int) (outi int, ok bool) {
2269	for ; i < len(data); i++ {
2270		switch data[i] {
2271		default:
2272			for ; i < len(data); i++ {
2273				if i, ok = validany(data, i); !ok {
2274					return i, false
2275				}
2276				if i, ok = validcomma(data, i, ']'); !ok {
2277					return i, false
2278				}
2279				if data[i] == ']' {
2280					return i + 1, true
2281				}
2282			}
2283		case ' ', '\t', '\n', '\r':
2284			continue
2285		case ']':
2286			return i + 1, true
2287		}
2288	}
2289	return i, false
2290}
2291func validstring(data []byte, i int) (outi int, ok bool) {
2292	for ; i < len(data); i++ {
2293		if data[i] < ' ' {
2294			return i, false
2295		} else if data[i] == '\\' {
2296			i++
2297			if i == len(data) {
2298				return i, false
2299			}
2300			switch data[i] {
2301			default:
2302				return i, false
2303			case '"', '\\', '/', 'b', 'f', 'n', 'r', 't':
2304			case 'u':
2305				for j := 0; j < 4; j++ {
2306					i++
2307					if i >= len(data) {
2308						return i, false
2309					}
2310					if !((data[i] >= '0' && data[i] <= '9') ||
2311						(data[i] >= 'a' && data[i] <= 'f') ||
2312						(data[i] >= 'A' && data[i] <= 'F')) {
2313						return i, false
2314					}
2315				}
2316			}
2317		} else if data[i] == '"' {
2318			return i + 1, true
2319		}
2320	}
2321	return i, false
2322}
2323func validnumber(data []byte, i int) (outi int, ok bool) {
2324	i--
2325	// sign
2326	if data[i] == '-' {
2327		i++
2328		if i == len(data) {
2329			return i, false
2330		}
2331		if data[i] < '0' || data[i] > '9' {
2332			return i, false
2333		}
2334	}
2335	// int
2336	if i == len(data) {
2337		return i, false
2338	}
2339	if data[i] == '0' {
2340		i++
2341	} else {
2342		for ; i < len(data); i++ {
2343			if data[i] >= '0' && data[i] <= '9' {
2344				continue
2345			}
2346			break
2347		}
2348	}
2349	// frac
2350	if i == len(data) {
2351		return i, true
2352	}
2353	if data[i] == '.' {
2354		i++
2355		if i == len(data) {
2356			return i, false
2357		}
2358		if data[i] < '0' || data[i] > '9' {
2359			return i, false
2360		}
2361		i++
2362		for ; i < len(data); i++ {
2363			if data[i] >= '0' && data[i] <= '9' {
2364				continue
2365			}
2366			break
2367		}
2368	}
2369	// exp
2370	if i == len(data) {
2371		return i, true
2372	}
2373	if data[i] == 'e' || data[i] == 'E' {
2374		i++
2375		if i == len(data) {
2376			return i, false
2377		}
2378		if data[i] == '+' || data[i] == '-' {
2379			i++
2380		}
2381		if i == len(data) {
2382			return i, false
2383		}
2384		if data[i] < '0' || data[i] > '9' {
2385			return i, false
2386		}
2387		i++
2388		for ; i < len(data); i++ {
2389			if data[i] >= '0' && data[i] <= '9' {
2390				continue
2391			}
2392			break
2393		}
2394	}
2395	return i, true
2396}
2397
2398func validtrue(data []byte, i int) (outi int, ok bool) {
2399	if i+3 <= len(data) && data[i] == 'r' && data[i+1] == 'u' &&
2400		data[i+2] == 'e' {
2401		return i + 3, true
2402	}
2403	return i, false
2404}
2405func validfalse(data []byte, i int) (outi int, ok bool) {
2406	if i+4 <= len(data) && data[i] == 'a' && data[i+1] == 'l' &&
2407		data[i+2] == 's' && data[i+3] == 'e' {
2408		return i + 4, true
2409	}
2410	return i, false
2411}
2412func validnull(data []byte, i int) (outi int, ok bool) {
2413	if i+3 <= len(data) && data[i] == 'u' && data[i+1] == 'l' &&
2414		data[i+2] == 'l' {
2415		return i + 3, true
2416	}
2417	return i, false
2418}
2419
2420// Valid returns true if the input is valid json.
2421//
2422//  if !gjson.Valid(json) {
2423//  	return errors.New("invalid json")
2424//  }
2425//  value := gjson.Get(json, "name.last")
2426//
2427func Valid(json string) bool {
2428	_, ok := validpayload(stringBytes(json), 0)
2429	return ok
2430}
2431
2432// ValidBytes returns true if the input is valid json.
2433//
2434//  if !gjson.Valid(json) {
2435//  	return errors.New("invalid json")
2436//  }
2437//  value := gjson.Get(json, "name.last")
2438//
2439// If working with bytes, this method preferred over ValidBytes(string(data))
2440//
2441func ValidBytes(json []byte) bool {
2442	_, ok := validpayload(json, 0)
2443	return ok
2444}
2445
2446func parseUint(s string) (n uint64, ok bool) {
2447	var i int
2448	if i == len(s) {
2449		return 0, false
2450	}
2451	for ; i < len(s); i++ {
2452		if s[i] >= '0' && s[i] <= '9' {
2453			n = n*10 + uint64(s[i]-'0')
2454		} else {
2455			return 0, false
2456		}
2457	}
2458	return n, true
2459}
2460
2461func parseInt(s string) (n int64, ok bool) {
2462	var i int
2463	var sign bool
2464	if len(s) > 0 && s[0] == '-' {
2465		sign = true
2466		i++
2467	}
2468	if i == len(s) {
2469		return 0, false
2470	}
2471	for ; i < len(s); i++ {
2472		if s[i] >= '0' && s[i] <= '9' {
2473			n = n*10 + int64(s[i]-'0')
2474		} else {
2475			return 0, false
2476		}
2477	}
2478	if sign {
2479		return n * -1, true
2480	}
2481	return n, true
2482}
2483
2484// safeInt validates a given JSON number
2485// ensures it lies within the minimum and maximum representable JSON numbers
2486func safeInt(f float64) (n int64, ok bool) {
2487	// https://tc39.es/ecma262/#sec-number.min_safe_integer
2488	// https://tc39.es/ecma262/#sec-number.max_safe_integer
2489	if f < -9007199254740991 || f > 9007199254740991 {
2490		return 0, false
2491	}
2492	return int64(f), true
2493}
2494
2495// execModifier parses the path to find a matching modifier function.
2496// then input expects that the path already starts with a '@'
2497func execModifier(json, path string) (pathOut, res string, ok bool) {
2498	name := path[1:]
2499	var hasArgs bool
2500	for i := 1; i < len(path); i++ {
2501		if path[i] == ':' {
2502			pathOut = path[i+1:]
2503			name = path[1:i]
2504			hasArgs = len(pathOut) > 0
2505			break
2506		}
2507		if path[i] == '|' {
2508			pathOut = path[i:]
2509			name = path[1:i]
2510			break
2511		}
2512		if path[i] == '.' {
2513			pathOut = path[i:]
2514			name = path[1:i]
2515			break
2516		}
2517	}
2518	if fn, ok := modifiers[name]; ok {
2519		var args string
2520		if hasArgs {
2521			var parsedArgs bool
2522			switch pathOut[0] {
2523			case '{', '[', '"':
2524				res := Parse(pathOut)
2525				if res.Exists() {
2526					args = squash(pathOut)
2527					pathOut = pathOut[len(args):]
2528					parsedArgs = true
2529				}
2530			}
2531			if !parsedArgs {
2532				idx := strings.IndexByte(pathOut, '|')
2533				if idx == -1 {
2534					args = pathOut
2535					pathOut = ""
2536				} else {
2537					args = pathOut[:idx]
2538					pathOut = pathOut[idx:]
2539				}
2540			}
2541		}
2542		return pathOut, fn(json, args), true
2543	}
2544	return pathOut, res, false
2545}
2546
2547// unwrap removes the '[]' or '{}' characters around json
2548func unwrap(json string) string {
2549	json = trim(json)
2550	if len(json) >= 2 && (json[0] == '[' || json[0] == '{') {
2551		json = json[1 : len(json)-1]
2552	}
2553	return json
2554}
2555
2556// DisableModifiers will disable the modifier syntax
2557var DisableModifiers = false
2558
2559var modifiers = map[string]func(json, arg string) string{
2560	"pretty":  modPretty,
2561	"ugly":    modUgly,
2562	"reverse": modReverse,
2563	"this":    modThis,
2564	"flatten": modFlatten,
2565	"join":    modJoin,
2566	"valid":   modValid,
2567}
2568
2569// AddModifier binds a custom modifier command to the GJSON syntax.
2570// This operation is not thread safe and should be executed prior to
2571// using all other gjson function.
2572func AddModifier(name string, fn func(json, arg string) string) {
2573	modifiers[name] = fn
2574}
2575
2576// ModifierExists returns true when the specified modifier exists.
2577func ModifierExists(name string, fn func(json, arg string) string) bool {
2578	_, ok := modifiers[name]
2579	return ok
2580}
2581
2582// cleanWS remove any non-whitespace from string
2583func cleanWS(s string) string {
2584	for i := 0; i < len(s); i++ {
2585		switch s[i] {
2586		case ' ', '\t', '\n', '\r':
2587			continue
2588		default:
2589			var s2 []byte
2590			for i := 0; i < len(s); i++ {
2591				switch s[i] {
2592				case ' ', '\t', '\n', '\r':
2593					s2 = append(s2, s[i])
2594				}
2595			}
2596			return string(s2)
2597		}
2598	}
2599	return s
2600}
2601
2602// @pretty modifier makes the json look nice.
2603func modPretty(json, arg string) string {
2604	if len(arg) > 0 {
2605		opts := *pretty.DefaultOptions
2606		Parse(arg).ForEach(func(key, value Result) bool {
2607			switch key.String() {
2608			case "sortKeys":
2609				opts.SortKeys = value.Bool()
2610			case "indent":
2611				opts.Indent = cleanWS(value.String())
2612			case "prefix":
2613				opts.Prefix = cleanWS(value.String())
2614			case "width":
2615				opts.Width = int(value.Int())
2616			}
2617			return true
2618		})
2619		return bytesString(pretty.PrettyOptions(stringBytes(json), &opts))
2620	}
2621	return bytesString(pretty.Pretty(stringBytes(json)))
2622}
2623
2624// @this returns the current element. Can be used to retrieve the root element.
2625func modThis(json, arg string) string {
2626	return json
2627}
2628
2629// @ugly modifier removes all whitespace.
2630func modUgly(json, arg string) string {
2631	return bytesString(pretty.Ugly(stringBytes(json)))
2632}
2633
2634// @reverse reverses array elements or root object members.
2635func modReverse(json, arg string) string {
2636	res := Parse(json)
2637	if res.IsArray() {
2638		var values []Result
2639		res.ForEach(func(_, value Result) bool {
2640			values = append(values, value)
2641			return true
2642		})
2643		out := make([]byte, 0, len(json))
2644		out = append(out, '[')
2645		for i, j := len(values)-1, 0; i >= 0; i, j = i-1, j+1 {
2646			if j > 0 {
2647				out = append(out, ',')
2648			}
2649			out = append(out, values[i].Raw...)
2650		}
2651		out = append(out, ']')
2652		return bytesString(out)
2653	}
2654	if res.IsObject() {
2655		var keyValues []Result
2656		res.ForEach(func(key, value Result) bool {
2657			keyValues = append(keyValues, key, value)
2658			return true
2659		})
2660		out := make([]byte, 0, len(json))
2661		out = append(out, '{')
2662		for i, j := len(keyValues)-2, 0; i >= 0; i, j = i-2, j+1 {
2663			if j > 0 {
2664				out = append(out, ',')
2665			}
2666			out = append(out, keyValues[i+0].Raw...)
2667			out = append(out, ':')
2668			out = append(out, keyValues[i+1].Raw...)
2669		}
2670		out = append(out, '}')
2671		return bytesString(out)
2672	}
2673	return json
2674}
2675
2676// @flatten an array with child arrays.
2677//   [1,[2],[3,4],[5,[6,7]]] -> [1,2,3,4,5,[6,7]]
2678// The {"deep":true} arg can be provide for deep flattening.
2679//   [1,[2],[3,4],[5,[6,7]]] -> [1,2,3,4,5,6,7]
2680// The original json is returned when the json is not an array.
2681func modFlatten(json, arg string) string {
2682	res := Parse(json)
2683	if !res.IsArray() {
2684		return json
2685	}
2686	var deep bool
2687	if arg != "" {
2688		Parse(arg).ForEach(func(key, value Result) bool {
2689			if key.String() == "deep" {
2690				deep = value.Bool()
2691			}
2692			return true
2693		})
2694	}
2695	var out []byte
2696	out = append(out, '[')
2697	var idx int
2698	res.ForEach(func(_, value Result) bool {
2699		var raw string
2700		if value.IsArray() {
2701			if deep {
2702				raw = unwrap(modFlatten(value.Raw, arg))
2703			} else {
2704				raw = unwrap(value.Raw)
2705			}
2706		} else {
2707			raw = value.Raw
2708		}
2709		raw = strings.TrimSpace(raw)
2710		if len(raw) > 0 {
2711			if idx > 0 {
2712				out = append(out, ',')
2713			}
2714			out = append(out, raw...)
2715			idx++
2716		}
2717		return true
2718	})
2719	out = append(out, ']')
2720	return bytesString(out)
2721}
2722
2723// @join multiple objects into a single object.
2724//   [{"first":"Tom"},{"last":"Smith"}] -> {"first","Tom","last":"Smith"}
2725// The arg can be "true" to specify that duplicate keys should be preserved.
2726//   [{"first":"Tom","age":37},{"age":41}] -> {"first","Tom","age":37,"age":41}
2727// Without preserved keys:
2728//   [{"first":"Tom","age":37},{"age":41}] -> {"first","Tom","age":41}
2729// The original json is returned when the json is not an object.
2730func modJoin(json, arg string) string {
2731	res := Parse(json)
2732	if !res.IsArray() {
2733		return json
2734	}
2735	var preserve bool
2736	if arg != "" {
2737		Parse(arg).ForEach(func(key, value Result) bool {
2738			if key.String() == "preserve" {
2739				preserve = value.Bool()
2740			}
2741			return true
2742		})
2743	}
2744	var out []byte
2745	out = append(out, '{')
2746	if preserve {
2747		// Preserve duplicate keys.
2748		var idx int
2749		res.ForEach(func(_, value Result) bool {
2750			if !value.IsObject() {
2751				return true
2752			}
2753			if idx > 0 {
2754				out = append(out, ',')
2755			}
2756			out = append(out, unwrap(value.Raw)...)
2757			idx++
2758			return true
2759		})
2760	} else {
2761		// Deduplicate keys and generate an object with stable ordering.
2762		var keys []Result
2763		kvals := make(map[string]Result)
2764		res.ForEach(func(_, value Result) bool {
2765			if !value.IsObject() {
2766				return true
2767			}
2768			value.ForEach(func(key, value Result) bool {
2769				k := key.String()
2770				if _, ok := kvals[k]; !ok {
2771					keys = append(keys, key)
2772				}
2773				kvals[k] = value
2774				return true
2775			})
2776			return true
2777		})
2778		for i := 0; i < len(keys); i++ {
2779			if i > 0 {
2780				out = append(out, ',')
2781			}
2782			out = append(out, keys[i].Raw...)
2783			out = append(out, ':')
2784			out = append(out, kvals[keys[i].String()].Raw...)
2785		}
2786	}
2787	out = append(out, '}')
2788	return bytesString(out)
2789}
2790
2791// @valid ensures that the json is valid before moving on. An empty string is
2792// returned when the json is not valid, otherwise it returns the original json.
2793func modValid(json, arg string) string {
2794	if !Valid(json) {
2795		return ""
2796	}
2797	return json
2798}
2799
2800// stringHeader instead of reflect.StringHeader
2801type stringHeader struct {
2802	data unsafe.Pointer
2803	len  int
2804}
2805
2806// sliceHeader instead of reflect.SliceHeader
2807type sliceHeader struct {
2808	data unsafe.Pointer
2809	len  int
2810	cap  int
2811}
2812
2813// getBytes casts the input json bytes to a string and safely returns the
2814// results as uniquely allocated data. This operation is intended to minimize
2815// copies and allocations for the large json string->[]byte.
2816func getBytes(json []byte, path string) Result {
2817	var result Result
2818	if json != nil {
2819		// unsafe cast to string
2820		result = Get(*(*string)(unsafe.Pointer(&json)), path)
2821		// safely get the string headers
2822		rawhi := *(*stringHeader)(unsafe.Pointer(&result.Raw))
2823		strhi := *(*stringHeader)(unsafe.Pointer(&result.Str))
2824		// create byte slice headers
2825		rawh := sliceHeader{data: rawhi.data, len: rawhi.len, cap: rawhi.len}
2826		strh := sliceHeader{data: strhi.data, len: strhi.len, cap: rawhi.len}
2827		if strh.data == nil {
2828			// str is nil
2829			if rawh.data == nil {
2830				// raw is nil
2831				result.Raw = ""
2832			} else {
2833				// raw has data, safely copy the slice header to a string
2834				result.Raw = string(*(*[]byte)(unsafe.Pointer(&rawh)))
2835			}
2836			result.Str = ""
2837		} else if rawh.data == nil {
2838			// raw is nil
2839			result.Raw = ""
2840			// str has data, safely copy the slice header to a string
2841			result.Str = string(*(*[]byte)(unsafe.Pointer(&strh)))
2842		} else if uintptr(strh.data) >= uintptr(rawh.data) &&
2843			uintptr(strh.data)+uintptr(strh.len) <=
2844				uintptr(rawh.data)+uintptr(rawh.len) {
2845			// Str is a substring of Raw.
2846			start := uintptr(strh.data) - uintptr(rawh.data)
2847			// safely copy the raw slice header
2848			result.Raw = string(*(*[]byte)(unsafe.Pointer(&rawh)))
2849			// substring the raw
2850			result.Str = result.Raw[start : start+uintptr(strh.len)]
2851		} else {
2852			// safely copy both the raw and str slice headers to strings
2853			result.Raw = string(*(*[]byte)(unsafe.Pointer(&rawh)))
2854			result.Str = string(*(*[]byte)(unsafe.Pointer(&strh)))
2855		}
2856	}
2857	return result
2858}
2859
2860// fillIndex finds the position of Raw data and assigns it to the Index field
2861// of the resulting value. If the position cannot be found then Index zero is
2862// used instead.
2863func fillIndex(json string, c *parseContext) {
2864	if len(c.value.Raw) > 0 && !c.calcd {
2865		jhdr := *(*stringHeader)(unsafe.Pointer(&json))
2866		rhdr := *(*stringHeader)(unsafe.Pointer(&(c.value.Raw)))
2867		c.value.Index = int(uintptr(rhdr.data) - uintptr(jhdr.data))
2868		if c.value.Index < 0 || c.value.Index >= len(json) {
2869			c.value.Index = 0
2870		}
2871	}
2872}
2873
2874func stringBytes(s string) []byte {
2875	return *(*[]byte)(unsafe.Pointer(&sliceHeader{
2876		data: (*stringHeader)(unsafe.Pointer(&s)).data,
2877		len:  len(s),
2878		cap:  len(s),
2879	}))
2880}
2881
2882func bytesString(b []byte) string {
2883	return *(*string)(unsafe.Pointer(&b))
2884}
2885