github.com/zhangdapeng520/zdpgo_json@v0.1.5/query/query.go (about)

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