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