github.com/fufuok/utils@v1.0.10/xjson/gjson/gjson.go (about)

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