github.com/sohaha/zlsgo@v1.7.13-0.20240501141223-10dd1a906f76/zjson/get.go (about) 1 package zjson 2 3 import ( 4 "encoding/base64" 5 "encoding/json" 6 "errors" 7 "reflect" 8 "strconv" 9 "strings" 10 "sync" 11 "time" 12 "unicode/utf16" 13 "unicode/utf8" 14 15 "github.com/sohaha/zlsgo/zreflect" 16 "github.com/sohaha/zlsgo/zstring" 17 "github.com/sohaha/zlsgo/ztime" 18 "github.com/sohaha/zlsgo/ztype" 19 ) 20 21 type ( 22 Type int 23 Res struct { 24 raw string 25 str string 26 typ Type 27 num float64 28 index int 29 } 30 fieldMaps struct { 31 m map[string]map[string]int 32 mu sync.RWMutex 33 } 34 ) 35 36 const ( 37 Null Type = iota 38 False 39 Number 40 String 41 True 42 JSON 43 ) 44 45 func (t Type) String() string { 46 switch t { 47 case Null: 48 return "Null" 49 case False: 50 return "False" 51 case Number: 52 return "Number" 53 case String: 54 return "String" 55 case True: 56 return "True" 57 case JSON: 58 return "JSON" 59 default: 60 return "" 61 } 62 } 63 64 func (r *Res) Raw() string { 65 return r.raw 66 } 67 68 func (r *Res) Bytes() []byte { 69 return zstring.String2Bytes(r.String()) 70 } 71 72 func (r *Res) String() string { 73 switch r.typ { 74 case False: 75 return "false" 76 case Number: 77 if len(r.raw) == 0 { 78 return strconv.FormatFloat(r.num, 'f', -1, 64) 79 } 80 var i int 81 if r.raw[0] == '-' { 82 i++ 83 } 84 for ; i < len(r.raw); i++ { 85 if r.raw[i] < '0' || r.raw[i] > '9' { 86 return strconv.FormatFloat(r.num, 'f', -1, 64) 87 } 88 } 89 return r.raw 90 case String: 91 return r.str 92 case JSON: 93 return r.raw 94 case True: 95 return "true" 96 default: 97 return "" 98 } 99 } 100 101 func (r *Res) Bool() bool { 102 switch r.typ { 103 case True: 104 return true 105 case String: 106 b, _ := strconv.ParseBool(strings.ToLower(r.str)) 107 return b 108 case Number: 109 return r.num != 0 110 default: 111 return false 112 } 113 } 114 115 func (r *Res) Int() int { 116 switch r.typ { 117 case True: 118 return 1 119 case String: 120 n, _ := parseInt(r.str) 121 return n 122 case Number: 123 i, ok := safeInt(r.num) 124 if ok { 125 return i 126 } 127 // now try to parse the raw string 128 i, ok = parseInt(r.raw) 129 if ok { 130 return i 131 } 132 return int(r.num) 133 default: 134 return 0 135 } 136 } 137 138 func (r *Res) Uint() uint { 139 switch r.typ { 140 default: 141 return 0 142 case True: 143 return 1 144 case String: 145 n, _ := parseUint(r.str) 146 return n 147 case Number: 148 i, ok := safeInt(r.num) 149 if ok && i >= 0 { 150 return uint(i) 151 } 152 u, ok := parseUint(r.raw) 153 if ok { 154 return u 155 } 156 return uint(r.num) 157 } 158 } 159 160 func (r *Res) Float() float64 { 161 switch r.typ { 162 default: 163 return 0 164 case True: 165 return 1 166 case String: 167 n, _ := strconv.ParseFloat(r.str, 64) 168 return n 169 case Number: 170 return r.num 171 } 172 } 173 174 func (r *Res) Unmarshal(v interface{}) error { 175 return Unmarshal(r.raw, v) 176 } 177 178 func (r *Res) Time(format ...string) (t time.Time) { 179 t, _ = ztime.Parse(r.String(), format...) 180 return t 181 } 182 183 func (r *Res) Array() []*Res { 184 if r.typ == Null { 185 return []*Res{} 186 } 187 if r.typ != JSON { 188 return []*Res{r} 189 } 190 rr := r.arrayOrMap('[', false) 191 return rr.a 192 } 193 194 func (r *Res) Slice() ztype.SliceType { 195 if !r.IsArray() { 196 return ztype.SliceType{} 197 } 198 199 return ztype.ToSlice(r.Value()) 200 } 201 202 func (r *Res) SliceString() []string { 203 return r.Slice().String() 204 } 205 206 func (r *Res) SliceInt() []int { 207 return r.Slice().Int() 208 } 209 210 func (r *Res) Maps() ztype.Maps { 211 if !r.IsArray() { 212 return ztype.Maps{} 213 } 214 215 return ztype.ToMaps(r.Value()) 216 } 217 218 func (r *Res) IsObject() bool { 219 return r.firstCharacter() == '{' 220 } 221 222 func (r *Res) IsArray() bool { 223 return r.firstCharacter() == '[' 224 } 225 226 func (r *Res) firstCharacter() uint8 { 227 if r.typ == JSON && len(r.raw) > 0 { 228 return r.raw[0] 229 } 230 return 0 231 } 232 233 func (r *Res) ForEach(fn func(key, value *Res) bool) { 234 if !r.Exists() || r.typ == Null { 235 return 236 } 237 if r.typ != JSON { 238 fn(&Res{}, r) 239 return 240 } 241 var ( 242 keys bool 243 i int 244 ) 245 key, value := Res{}, &Res{} 246 j := r.raw 247 for ; i < len(j); i++ { 248 if j[i] == '{' { 249 i++ 250 key.typ = String 251 keys = true 252 break 253 } else if j[i] == '[' { 254 i++ 255 key.typ = Number 256 key.num = -1 257 break 258 } 259 if j[i] > ' ' { 260 return 261 } 262 } 263 var ( 264 str string 265 vesc bool 266 ok bool 267 ) 268 269 for ; i < len(j); i++ { 270 if key.typ == Number { 271 key.num = key.num + 1 272 } else if keys { 273 if j[i] != '"' { 274 continue 275 } 276 s := i 277 i, str, vesc, ok = parseString(j, i+1) 278 if !ok { 279 return 280 } 281 if vesc { 282 key.str = unescape(str[1 : len(str)-1]) 283 } else { 284 key.str = str[1 : len(str)-1] 285 } 286 287 key.raw = str 288 key.index = s 289 } 290 for ; i < len(j); i++ { 291 if j[i] <= ' ' || j[i] == ',' || j[i] == ':' { 292 continue 293 } 294 break 295 } 296 s := i 297 i, value, ok = parseAny(j, i, true) 298 if !ok { 299 return 300 } 301 value.index = s 302 if !fn(&key, value) { 303 return 304 } 305 } 306 } 307 308 func (r *Res) MapRes() map[string]*Res { 309 if r.typ != JSON { 310 return map[string]*Res{} 311 } 312 rr := r.arrayOrMap('{', false) 313 return rr.o 314 } 315 316 func (r *Res) Map() ztype.Map { 317 if !r.IsObject() { 318 return map[string]interface{}{} 319 } 320 v, _ := r.Value().(map[string]interface{}) 321 return v 322 } 323 324 func (r *Res) MapKeys(exclude ...string) (keys []string) { 325 m := r.MapRes() 326 keys = make([]string, 0, len(m)) 327 lo: 328 for k := range m { 329 for i := range exclude { 330 if k == exclude[i] { 331 continue lo 332 } 333 } 334 keys = append(keys, k) 335 } 336 return 337 } 338 339 func (r *Res) Get(path string) *Res { 340 return Get(r.raw, path) 341 } 342 343 func (r *Res) Set(path string, value interface{}) (err error) { 344 r.raw, err = Set(r.raw, path, value) 345 return 346 } 347 348 func (r *Res) Delete(path string) (err error) { 349 r.raw, err = Delete(r.raw, path) 350 return 351 } 352 353 type arrayOrMapResult struct { 354 o map[string]*Res 355 oi map[string]interface{} 356 a []*Res 357 ai []interface{} 358 vc byte 359 } 360 361 func (r *Res) arrayOrMap(vc byte, valueize bool) (ar arrayOrMapResult) { 362 var ( 363 count int 364 key Res 365 i int 366 j = r.raw 367 ) 368 369 if vc == 0 { 370 for ; i < len(j); i++ { 371 if j[i] == '{' || j[i] == '[' { 372 ar.vc = j[i] 373 i++ 374 break 375 } 376 if j[i] > ' ' { 377 goto end 378 } 379 } 380 } else { 381 for ; i < len(j); i++ { 382 if j[i] == vc { 383 i++ 384 break 385 } 386 if j[i] > ' ' { 387 goto end 388 } 389 } 390 ar.vc = vc 391 } 392 if ar.vc == '{' { 393 if valueize { 394 ar.oi = make(map[string]interface{}) 395 } else { 396 ar.o = make(map[string]*Res) 397 } 398 } else { 399 if valueize { 400 ar.ai = make([]interface{}, 0) 401 } else { 402 ar.a = make([]*Res, 0) 403 } 404 } 405 for ; i < len(j); i++ { 406 if j[i] <= ' ' { 407 continue 408 } 409 if j[i] == ']' || j[i] == '}' { 410 break 411 } 412 413 var value Res 414 switch j[i] { 415 default: 416 if (j[i] >= '0' && j[i] <= '9') || j[i] == '-' { 417 value.typ = Number 418 value.raw, value.num = tonum(j[i:]) 419 value.str = "" 420 } else { 421 continue 422 } 423 case '{', '[': 424 value.typ = JSON 425 value.raw = squash(j[i:]) 426 value.str, value.num = "", 0 427 case 'n': 428 value.typ = Null 429 value.raw = tolit(j[i:]) 430 value.str, value.num = "", 0 431 case 'r': 432 value.typ = True 433 value.raw = tolit(j[i:]) 434 value.str, value.num = "", 0 435 case 'f': 436 value.typ = False 437 value.raw = tolit(j[i:]) 438 value.str, value.num = "", 0 439 case '"': 440 value.typ = String 441 value.raw, value.str = tostr(j[i:]) 442 value.num = 0 443 } 444 i += len(value.raw) - 1 445 446 if ar.vc == '{' { 447 if count%2 == 0 { 448 key = value 449 } else { 450 if valueize { 451 if _, ok := ar.oi[key.str]; !ok { 452 ar.oi[key.str] = value.Value() 453 } 454 } else { 455 if _, ok := ar.o[key.str]; !ok { 456 ar.o[key.str] = &value 457 } 458 } 459 } 460 count++ 461 } else { 462 if valueize { 463 ar.ai = append(ar.ai, value.Value()) 464 } else { 465 ar.a = append(ar.a, &value) 466 } 467 } 468 } 469 end: 470 return 471 } 472 473 func Parse(json string) *Res { 474 value := &Res{} 475 for i := 0; i < len(json); i++ { 476 if json[i] == '{' || json[i] == '[' { 477 value.typ = JSON 478 value.raw = json[i:] 479 break 480 } 481 if json[i] <= ' ' { 482 continue 483 } 484 switch json[i] { 485 default: 486 if (json[i] >= '0' && json[i] <= '9') || json[i] == '-' { 487 value.typ = Number 488 value.raw, value.num = tonum(json[i:]) 489 } else { 490 return &Res{} 491 } 492 case 'n': 493 value.typ = Null 494 value.raw = tolit(json[i:]) 495 case 't': 496 value.typ = True 497 value.raw = tolit(json[i:]) 498 case 'f': 499 value.typ = False 500 value.raw = tolit(json[i:]) 501 case '"': 502 value.typ = String 503 value.raw, value.str = tostr(json[i:]) 504 } 505 break 506 } 507 return value 508 } 509 510 func ParseBytes(json []byte) *Res { 511 return Parse(zstring.Bytes2String(json)) 512 } 513 514 func tonum(json string) (raw string, num float64) { 515 for i := 1; i < len(json); i++ { 516 if json[i] <= '-' { 517 if json[i] <= ' ' || json[i] == ',' { 518 raw = json[:i] 519 num, _ = strconv.ParseFloat(raw, 64) 520 return 521 } 522 continue 523 } 524 if json[i] < ']' { 525 continue 526 } 527 if json[i] == 'e' || json[i] == 'E' { 528 continue 529 } 530 raw = json[:i] 531 num, _ = strconv.ParseFloat(raw, 64) 532 return 533 } 534 raw = json 535 num, _ = strconv.ParseFloat(raw, 64) 536 return 537 } 538 539 func tolit(json string) (raw string) { 540 for i := 1; i < len(json); i++ { 541 if json[i] < 'a' || json[i] > 'z' { 542 return json[:i] 543 } 544 } 545 return json 546 } 547 548 func tostr(json string) (raw string, str string) { 549 for i := 1; i < len(json); i++ { 550 if json[i] > '\\' { 551 continue 552 } 553 if json[i] == '"' { 554 return json[:i+1], json[1:i] 555 } 556 if json[i] == '\\' { 557 i++ 558 for ; i < len(json); i++ { 559 if json[i] > '\\' { 560 continue 561 } 562 if json[i] == '"' { 563 if json[i-1] == '\\' { 564 n := 0 565 for j := i - 2; j > 0; j-- { 566 if json[j] != '\\' { 567 break 568 } 569 n++ 570 } 571 if n%2 == 0 { 572 continue 573 } 574 } 575 break 576 } 577 } 578 var ret string 579 if i+1 < len(json) { 580 ret = json[:i+1] 581 } else { 582 ret = json[:i] 583 } 584 return ret, unescape(json[1:i]) 585 } 586 } 587 return json, json[1:] 588 } 589 590 func (r *Res) Exists() bool { 591 return r.typ != Null || len(r.raw) != 0 592 } 593 594 func (r *Res) Value() interface{} { 595 if r.typ == String { 596 return r.str 597 } 598 switch r.typ { 599 default: 600 return nil 601 case False: 602 return false 603 case Number: 604 return r.num 605 case JSON: 606 r := r.arrayOrMap(0, true) 607 if r.vc == '{' { 608 return r.oi 609 } else if r.vc == '[' { 610 return r.ai 611 } 612 return nil 613 case True: 614 return true 615 } 616 } 617 618 func parseString(json string, i int) (int, string, bool, bool) { 619 var s = i 620 for ; i < len(json); i++ { 621 if json[i] > '\\' { 622 continue 623 } 624 if json[i] == '"' { 625 return i + 1, json[s-1 : i+1], false, true 626 } 627 if json[i] == '\\' { 628 i++ 629 for ; i < len(json); i++ { 630 if json[i] > '\\' { 631 continue 632 } 633 if json[i] == '"' { 634 if json[i-1] == '\\' { 635 n := 0 636 for j := i - 2; j > 0; j-- { 637 if json[j] != '\\' { 638 break 639 } 640 n++ 641 } 642 if n%2 == 0 { 643 continue 644 } 645 } 646 return i + 1, json[s-1 : i+1], true, true 647 } 648 } 649 break 650 } 651 } 652 return i, json[s-1:], false, false 653 } 654 655 func parseNumber(json string, i int) (int, string) { 656 var s = i 657 i++ 658 for ; i < len(json); i++ { 659 if json[i] <= ' ' || json[i] == ',' || json[i] == ']' || 660 json[i] == '}' { 661 return i, json[s:i] 662 } 663 } 664 return i, json[s:] 665 } 666 667 func parseLiteral(json string, i int) (int, string) { 668 var s = i 669 i++ 670 for ; i < len(json); i++ { 671 if json[i] < 'a' || json[i] > 'z' { 672 return i, json[s:i] 673 } 674 } 675 return i, json[s:] 676 } 677 678 type arrayPathResult struct { 679 part string 680 path string 681 pipe string 682 alogkey string 683 query struct { 684 path string 685 op string 686 value string 687 on bool 688 all bool 689 } 690 piped bool 691 more bool 692 alogok bool 693 arrch bool 694 } 695 696 func parseArrayPath(path string) (r arrayPathResult) { 697 for i := 0; i < len(path); i++ { 698 if path[i] == '|' { 699 r.part = path[:i] 700 r.pipe = path[i+1:] 701 r.piped = true 702 return 703 } 704 if path[i] == '.' { 705 r.part = path[:i] 706 r.path = path[i+1:] 707 r.more = true 708 return 709 } 710 if path[i] == '#' { 711 r.arrch = true 712 if i == 0 && len(path) > 1 { 713 if path[1] == '.' { 714 r.alogok = true 715 r.alogkey = path[2:] 716 r.path = path[:1] 717 } else if path[1] == '[' || path[1] == '(' { 718 r.query.on = true 719 if true { 720 qpath, op, value, _, fi, ok := parseQuery(path[i:]) 721 if !ok { 722 break 723 } 724 r.query.path = qpath 725 r.query.op = op 726 r.query.value = value 727 i = fi - 1 728 if i+1 < len(path) && path[i+1] == '#' { 729 r.query.all = true 730 } 731 } else { 732 var end byte 733 if path[1] == '[' { 734 end = ']' 735 } else { 736 end = ')' 737 } 738 i += 2 739 for ; i < len(path); i++ { 740 if path[i] > ' ' { 741 break 742 } 743 } 744 s := i 745 for ; i < len(path); i++ { 746 if path[i] <= ' ' || 747 path[i] == '!' || 748 path[i] == '=' || 749 path[i] == '<' || 750 path[i] == '>' || 751 path[i] == '%' || 752 path[i] == end { 753 break 754 } 755 } 756 r.query.path = path[s:i] 757 for ; i < len(path); i++ { 758 if path[i] > ' ' { 759 break 760 } 761 } 762 if i < len(path) { 763 s = i 764 if path[i] == '!' { 765 if i < len(path)-1 && (path[i+1] == '=' || 766 path[i+1] == '%') { 767 i++ 768 } 769 } else if path[i] == '<' || path[i] == '>' { 770 if i < len(path)-1 && path[i+1] == '=' { 771 i++ 772 } 773 } else if path[i] == '=' { 774 if i < len(path)-1 && path[i+1] == '=' { 775 s++ 776 i++ 777 } 778 } 779 i++ 780 r.query.op = path[s:i] 781 for ; i < len(path); i++ { 782 if path[i] > ' ' { 783 break 784 } 785 } 786 s = i 787 for ; i < len(path); i++ { 788 if path[i] == '"' { 789 i++ 790 s2 := i 791 for ; i < len(path); i++ { 792 if path[i] > '\\' { 793 continue 794 } 795 if path[i] == '"' { 796 if path[i-1] == '\\' { 797 n := 0 798 for j := i - 2; j > s2-1; j-- { 799 if path[j] != '\\' { 800 break 801 } 802 n++ 803 } 804 if n%2 == 0 { 805 continue 806 } 807 } 808 break 809 } 810 } 811 } else if path[i] == end { 812 if i+1 < len(path) && path[i+1] == '#' { 813 r.query.all = true 814 } 815 break 816 } 817 } 818 if i > len(path) { 819 i = len(path) 820 } 821 v := path[s:i] 822 for len(v) > 0 && v[len(v)-1] <= ' ' { 823 v = v[:len(v)-1] 824 } 825 r.query.value = v 826 } 827 } 828 } 829 } 830 continue 831 } 832 } 833 r.part = path 834 r.path = "" 835 return 836 } 837 838 func parseQuery(query string) ( 839 path, op, value, remain string, i int, ok bool, 840 ) { 841 if len(query) < 2 || query[0] != '#' || 842 (query[1] != '(' && query[1] != '[') { 843 return "", "", "", "", i, false 844 } 845 i = 2 846 j := 0 847 depth := 1 848 for ; i < len(query); i++ { 849 if depth == 1 && j == 0 { 850 switch query[i] { 851 case '!', '=', '<', '>', '%': 852 j = i 853 continue 854 } 855 } 856 if query[i] == '\\' { 857 i++ 858 } else if query[i] == '[' || query[i] == '(' { 859 depth++ 860 } else if query[i] == ']' || query[i] == ')' { 861 depth-- 862 if depth == 0 { 863 break 864 } 865 } else if query[i] == '"' { 866 i++ 867 for ; i < len(query); i++ { 868 if query[i] == '\\' { 869 i++ 870 } else if query[i] == '"' { 871 break 872 } 873 } 874 } 875 } 876 if depth > 0 { 877 return "", "", "", "", i, false 878 } 879 if j > 0 { 880 path = zstring.TrimSpace(query[2:j]) 881 value = zstring.TrimSpace(query[j:i]) 882 remain = query[i+1:] 883 var opsz int 884 switch { 885 case len(value) == 1: 886 opsz = 1 887 case value[0] == '!' && value[1] == '=': 888 opsz = 2 889 case value[0] == '!' && value[1] == '%': 890 opsz = 2 891 case value[0] == '<' && value[1] == '=': 892 opsz = 2 893 case value[0] == '>' && value[1] == '=': 894 opsz = 2 895 case value[0] == '=' && value[1] == '=': 896 value = value[1:] 897 opsz = 1 898 case value[0] == '<': 899 opsz = 1 900 case value[0] == '>': 901 opsz = 1 902 case value[0] == '=': 903 opsz = 1 904 case value[0] == '%': 905 opsz = 1 906 } 907 op = value[:opsz] 908 value = zstring.TrimSpace(value[opsz:]) 909 } else { 910 path = zstring.TrimSpace(query[2:i]) 911 remain = query[i+1:] 912 } 913 return path, op, value, remain, i + 1, true 914 } 915 916 type objectPathResult struct { 917 part string 918 path string 919 pipe string 920 piped bool 921 wild bool 922 more bool 923 } 924 925 func parseObjectPath(path string) (r objectPathResult) { 926 for i := 0; i < len(path); i++ { 927 if path[i] == '|' { 928 r.part = path[:i] 929 r.pipe = path[i+1:] 930 r.piped = true 931 return 932 } 933 if path[i] == '.' { 934 r.part = path[:i] 935 if ModifiersState() && 936 i < len(path)-1 && 937 (path[i+1] == '@' || 938 path[i+1] == '[' || path[i+1] == '{') { 939 r.pipe = path[i+1:] 940 r.piped = true 941 } else { 942 r.path = path[i+1:] 943 r.more = true 944 } 945 return 946 } 947 if path[i] == '*' || path[i] == '?' { 948 r.wild = true 949 continue 950 } 951 if path[i] == '\\' { 952 epart := []byte(path[:i]) 953 i++ 954 if i < len(path) { 955 epart = append(epart, path[i]) 956 i++ 957 for ; i < len(path); i++ { 958 if path[i] == '\\' { 959 i++ 960 if i < len(path) { 961 epart = append(epart, path[i]) 962 } 963 continue 964 } else if path[i] == '.' { 965 r.part = zstring.Bytes2String(epart) 966 if ModifiersState() && 967 i < len(path)-1 && path[i+1] == '@' { 968 r.pipe = path[i+1:] 969 r.piped = true 970 } else { 971 r.path = path[i+1:] 972 r.more = true 973 } 974 r.more = true 975 return 976 } else if path[i] == '|' { 977 r.part = zstring.Bytes2String(epart) 978 r.pipe = path[i+1:] 979 r.piped = true 980 return 981 } else if path[i] == '*' || path[i] == '?' { 982 r.wild = true 983 } 984 epart = append(epart, path[i]) 985 } 986 } 987 r.part = zstring.Bytes2String(epart) 988 return 989 } 990 } 991 r.part = path 992 return 993 } 994 995 func parseObject(c *parseContext, i int, path string) (int, bool) { 996 var pmatch, kesc, vesc, ok, hit bool 997 var key, val string 998 rp := parseObjectPath(path) 999 if !rp.more && rp.piped { 1000 c.pipe = rp.pipe 1001 c.piped = true 1002 } 1003 for i < len(c.json) { 1004 for ; i < len(c.json); i++ { 1005 if c.json[i] == '"' { 1006 i++ 1007 var s = i 1008 for ; i < len(c.json); i++ { 1009 if c.json[i] > '\\' { 1010 continue 1011 } 1012 if c.json[i] == '"' { 1013 i, key, kesc, ok = i+1, c.json[s:i], false, true 1014 goto parseKeyStringDone 1015 } 1016 if c.json[i] == '\\' { 1017 i++ 1018 for ; i < len(c.json); i++ { 1019 if c.json[i] > '\\' { 1020 continue 1021 } 1022 if c.json[i] == '"' { 1023 if c.json[i-1] == '\\' { 1024 n := 0 1025 for j := i - 2; j > 0; j-- { 1026 if c.json[j] != '\\' { 1027 break 1028 } 1029 n++ 1030 } 1031 if n%2 == 0 { 1032 continue 1033 } 1034 } 1035 i, key, kesc, ok = i+1, c.json[s:i], true, true 1036 goto parseKeyStringDone 1037 } 1038 } 1039 break 1040 } 1041 } 1042 key, kesc, ok = c.json[s:], false, false 1043 parseKeyStringDone: 1044 break 1045 } 1046 if c.json[i] == '}' { 1047 return i + 1, false 1048 } 1049 } 1050 if !ok { 1051 return i, false 1052 } 1053 if rp.wild { 1054 if kesc { 1055 pmatch = zstring.Match(unescape(key), rp.part) 1056 } else { 1057 pmatch = zstring.Match(key, rp.part) 1058 } 1059 } else { 1060 if kesc { 1061 pmatch = rp.part == unescape(key) 1062 } else { 1063 pmatch = rp.part == key 1064 } 1065 } 1066 hit = pmatch && !rp.more 1067 for ; i < len(c.json); i++ { 1068 switch c.json[i] { 1069 default: 1070 continue 1071 case '"': 1072 i++ 1073 i, val, vesc, ok = parseString(c.json, i) 1074 if !ok { 1075 return i, false 1076 } 1077 if hit { 1078 if vesc { 1079 c.value.str = unescape(val[1 : len(val)-1]) 1080 } else { 1081 c.value.str = val[1 : len(val)-1] 1082 } 1083 c.value.raw = val 1084 c.value.typ = String 1085 return i, true 1086 } 1087 case '{': 1088 if pmatch && !hit { 1089 i, hit = parseObject(c, i+1, rp.path) 1090 if hit { 1091 return i, true 1092 } 1093 } else { 1094 val, i = parseSquash(c.json, i) 1095 if hit { 1096 c.value.raw = val 1097 c.value.typ = JSON 1098 return i, true 1099 } 1100 } 1101 case '[': 1102 if pmatch && !hit { 1103 i, hit = parseArray(c, i+1, rp.path) 1104 if hit { 1105 return i, true 1106 } 1107 } else { 1108 val, i = parseSquash(c.json, i) 1109 if hit { 1110 c.value.raw = val 1111 c.value.typ = JSON 1112 return i, true 1113 } 1114 } 1115 case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': 1116 i, val = parseNumber(c.json, i) 1117 if hit { 1118 c.value.raw = val 1119 c.value.typ = Number 1120 c.value.num, _ = strconv.ParseFloat(val, 64) 1121 return i, true 1122 } 1123 case 't', 'f', 'n': 1124 vc := c.json[i] 1125 i, val = parseLiteral(c.json, i) 1126 if hit { 1127 c.value.raw = val 1128 switch vc { 1129 case 't': 1130 c.value.typ = True 1131 case 'f': 1132 c.value.typ = False 1133 } 1134 return i, true 1135 } 1136 } 1137 break 1138 } 1139 } 1140 return i, false 1141 } 1142 func queryMatches(rp *arrayPathResult, value *Res) bool { 1143 rpv := rp.query.value 1144 if len(rpv) > 2 && rpv[0] == '"' && rpv[len(rpv)-1] == '"' { 1145 rpv = rpv[1 : len(rpv)-1] 1146 } 1147 if !value.Exists() { 1148 return false 1149 } 1150 if rp.query.op == "" { 1151 return true 1152 } 1153 switch value.typ { 1154 case String: 1155 switch rp.query.op { 1156 case "=": 1157 return value.str == rpv 1158 case "!=": 1159 return value.str != rpv 1160 case "<": 1161 return value.str < rpv 1162 case "<=": 1163 return value.str <= rpv 1164 case ">": 1165 return value.str > rpv 1166 case ">=": 1167 return value.str >= rpv 1168 case "%": 1169 return zstring.Match(value.str, rpv) 1170 case "!%": 1171 return !zstring.Match(value.str, rpv) 1172 } 1173 case Number: 1174 rpvn, _ := strconv.ParseFloat(rpv, 64) 1175 switch rp.query.op { 1176 case "=": 1177 return value.num == rpvn 1178 case "!=": 1179 return value.num != rpvn 1180 case "<": 1181 return value.num < rpvn 1182 case "<=": 1183 return value.num <= rpvn 1184 case ">": 1185 return value.num > rpvn 1186 case ">=": 1187 return value.num >= rpvn 1188 } 1189 case True: 1190 switch rp.query.op { 1191 case "=": 1192 return rpv == "true" 1193 case "!=": 1194 return rpv != "true" 1195 case ">": 1196 return rpv == "false" 1197 case ">=": 1198 return true 1199 } 1200 case False: 1201 switch rp.query.op { 1202 case "=": 1203 return rpv == "false" 1204 case "!=": 1205 return rpv != "false" 1206 case "<": 1207 return rpv == "true" 1208 case "<=": 1209 return true 1210 } 1211 } 1212 return false 1213 } 1214 func parseArray(c *parseContext, i int, path string) (int, bool) { 1215 var pmatch, vesc, ok, hit bool 1216 var val string 1217 var h int 1218 var alog []int 1219 var partidx int 1220 var multires []byte 1221 rp := parseArrayPath(path) 1222 if !rp.arrch { 1223 n, ok := parseUint(rp.part) 1224 if !ok { 1225 partidx = -1 1226 } else { 1227 partidx = int(n) 1228 } 1229 } 1230 if !rp.more && rp.piped { 1231 c.pipe = rp.pipe 1232 c.piped = true 1233 } 1234 1235 procQuery := func(qval *Res) bool { 1236 if rp.query.all && len(multires) == 0 { 1237 multires = append(multires, '[') 1238 } 1239 var res *Res 1240 if qval.typ == JSON { 1241 res = qval.Get(rp.query.path) 1242 } else { 1243 if rp.query.path != "" { 1244 return false 1245 } 1246 res = qval 1247 } 1248 if queryMatches(&rp, res) { 1249 if rp.more { 1250 left, right, ok := splitPossiblePipe(rp.path) 1251 if ok { 1252 rp.path = left 1253 c.pipe = right 1254 c.piped = true 1255 } 1256 res = qval.Get(rp.path) 1257 } else { 1258 res = qval 1259 } 1260 if rp.query.all { 1261 raw := res.raw 1262 if len(raw) == 0 { 1263 raw = res.String() 1264 } 1265 if raw != "" { 1266 if len(multires) > 1 { 1267 multires = append(multires, ',') 1268 } 1269 multires = append(multires, raw...) 1270 } 1271 } else { 1272 c.value = res 1273 return true 1274 } 1275 } 1276 return false 1277 } 1278 1279 for i < len(c.json)+1 { 1280 if !rp.arrch { 1281 pmatch = partidx == h 1282 hit = pmatch && !rp.more 1283 } 1284 h++ 1285 if rp.alogok { 1286 alog = append(alog, i) 1287 } 1288 for ; ; i++ { 1289 var ch byte 1290 if i > len(c.json) { 1291 break 1292 } else if i == len(c.json) { 1293 ch = ']' 1294 } else { 1295 ch = c.json[i] 1296 } 1297 switch ch { 1298 default: 1299 continue 1300 case '"': 1301 i++ 1302 i, val, vesc, ok = parseString(c.json, i) 1303 if !ok { 1304 return i, false 1305 } 1306 if rp.query.on { 1307 var qval *Res 1308 if vesc { 1309 qval.str = unescape(val[1 : len(val)-1]) 1310 } else { 1311 qval.str = val[1 : len(val)-1] 1312 } 1313 qval.raw = val 1314 qval.typ = String 1315 if procQuery(qval) { 1316 return i, true 1317 } 1318 } else if hit { 1319 if rp.alogok { 1320 break 1321 } 1322 if vesc { 1323 c.value.str = unescape(val[1 : len(val)-1]) 1324 } else { 1325 c.value.str = val[1 : len(val)-1] 1326 } 1327 c.value.raw = val 1328 c.value.typ = String 1329 return i, true 1330 } 1331 case '{': 1332 if pmatch && !hit { 1333 i, hit = parseObject(c, i+1, rp.path) 1334 if hit { 1335 if rp.alogok { 1336 break 1337 } 1338 return i, true 1339 } 1340 } else { 1341 val, i = parseSquash(c.json, i) 1342 if rp.query.on { 1343 if procQuery(&Res{raw: val, typ: JSON}) { 1344 return i, true 1345 } 1346 } else if hit { 1347 if rp.alogok { 1348 break 1349 } 1350 c.value.raw = val 1351 c.value.typ = JSON 1352 return i, true 1353 } 1354 } 1355 case '[': 1356 if pmatch && !hit { 1357 i, hit = parseArray(c, i+1, rp.path) 1358 if hit { 1359 if rp.alogok { 1360 break 1361 } 1362 return i, true 1363 } 1364 } else { 1365 val, i = parseSquash(c.json, i) 1366 if rp.query.on { 1367 if procQuery(&Res{raw: val, typ: JSON}) { 1368 return i, true 1369 } 1370 } else if hit { 1371 if rp.alogok { 1372 break 1373 } 1374 c.value.raw = val 1375 c.value.typ = JSON 1376 return i, true 1377 } 1378 } 1379 case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': 1380 i, val = parseNumber(c.json, i) 1381 if rp.query.on { 1382 qval := &Res{ 1383 raw: val, 1384 typ: Number, 1385 } 1386 qval.num, _ = strconv.ParseFloat(val, 64) 1387 if procQuery(qval) { 1388 return i, true 1389 } 1390 } else if hit { 1391 if rp.alogok { 1392 break 1393 } 1394 c.value.raw = val 1395 c.value.typ = Number 1396 c.value.num, _ = strconv.ParseFloat(val, 64) 1397 return i, true 1398 } 1399 case 't', 'f', 'n': 1400 vc := c.json[i] 1401 i, val = parseLiteral(c.json, i) 1402 if rp.query.on { 1403 var qval *Res 1404 qval.raw = val 1405 switch vc { 1406 case 't': 1407 qval.typ = True 1408 case 'f': 1409 qval.typ = False 1410 } 1411 if procQuery(qval) { 1412 return i, true 1413 } 1414 } else if hit { 1415 if rp.alogok { 1416 break 1417 } 1418 c.value.raw = val 1419 switch vc { 1420 case 't': 1421 c.value.typ = True 1422 case 'f': 1423 c.value.typ = False 1424 } 1425 return i, true 1426 } 1427 case ']': 1428 if rp.arrch && rp.part == "#" { 1429 if rp.alogok { 1430 left, right, ok := splitPossiblePipe(rp.alogkey) 1431 if ok { 1432 rp.alogkey = left 1433 c.pipe = right 1434 c.piped = true 1435 } 1436 var jsons = make([]byte, 0, 64) 1437 jsons = append(jsons, '[') 1438 for j, k := 0, 0; j < len(alog); j++ { 1439 _, res, ok := parseAny(c.json, alog[j], true) 1440 if ok { 1441 res := res.Get(rp.alogkey) 1442 if res.Exists() { 1443 if k > 0 { 1444 jsons = append(jsons, ',') 1445 } 1446 raw := res.raw 1447 if len(raw) == 0 { 1448 raw = res.String() 1449 } 1450 jsons = append(jsons, zstring.String2Bytes(raw)...) 1451 k++ 1452 } 1453 } 1454 } 1455 jsons = append(jsons, ']') 1456 c.value.typ = JSON 1457 c.value.raw = zstring.Bytes2String(jsons) 1458 return i + 1, true 1459 } 1460 if rp.alogok { 1461 break 1462 } 1463 1464 c.value.typ = Number 1465 c.value.num = float64(h - 1) 1466 c.value.raw = strconv.Itoa(h - 1) 1467 c.calcd = true 1468 return i + 1, true 1469 } 1470 if len(multires) > 0 && !c.value.Exists() { 1471 c.value = &Res{ 1472 raw: zstring.Bytes2String(append(multires, ']')), 1473 typ: JSON, 1474 } 1475 } 1476 return i + 1, false 1477 } 1478 break 1479 } 1480 } 1481 return i, false 1482 } 1483 1484 func splitPossiblePipe(path string) (left, right string, ok bool) { 1485 var possible bool 1486 for i := 0; i < len(path); i++ { 1487 if path[i] == '|' { 1488 possible = true 1489 break 1490 } 1491 } 1492 if !possible { 1493 return 1494 } 1495 for i := 0; i < len(path); i++ { 1496 if path[i] == '\\' { 1497 i++ 1498 } else if path[i] == '.' { 1499 if i == len(path)-1 { 1500 return 1501 } 1502 if path[i+1] == '#' { 1503 i += 2 1504 if i == len(path) { 1505 return 1506 } 1507 if path[i] == '[' || path[i] == '(' { 1508 var start, end byte 1509 if path[i] == '[' { 1510 start, end = '[', ']' 1511 } else { 1512 start, end = '(', ')' 1513 } 1514 i++ 1515 depth := 1 1516 for ; i < len(path); i++ { 1517 if path[i] == '\\' { 1518 i++ 1519 } else if path[i] == start { 1520 depth++ 1521 } else if path[i] == end { 1522 depth-- 1523 if depth == 0 { 1524 break 1525 } 1526 } else if path[i] == '"' { 1527 i++ 1528 for ; i < len(path); i++ { 1529 if path[i] == '\\' { 1530 i++ 1531 } else if path[i] == '"' { 1532 break 1533 } 1534 } 1535 } 1536 } 1537 } 1538 } 1539 } else if path[i] == '|' { 1540 return path[:i], path[i+1:], true 1541 } 1542 } 1543 return 1544 } 1545 1546 func ForEachLine(json string, fn func(line *Res) bool) { 1547 var res *Res 1548 var i int 1549 for { 1550 i, res, _ = parseAny(json, i, true) 1551 if !res.Exists() { 1552 break 1553 } 1554 if !fn(res) { 1555 return 1556 } 1557 } 1558 } 1559 1560 type subSelector struct { 1561 name string 1562 path string 1563 } 1564 1565 func parseSubSelectors(path string) (sels []subSelector, out string, ok bool) { 1566 depth := 1 1567 colon := 0 1568 start := 1 1569 i := 1 1570 pushSel := func() { 1571 var sel subSelector 1572 if colon == 0 { 1573 sel.path = path[start:i] 1574 } else { 1575 sel.name = path[start:colon] 1576 sel.path = path[colon+1 : i] 1577 } 1578 sels = append(sels, sel) 1579 colon = 0 1580 start = i + 1 1581 } 1582 for ; i < len(path); i++ { 1583 switch path[i] { 1584 case '\\': 1585 i++ 1586 case ':': 1587 if depth == 1 { 1588 colon = i 1589 } 1590 case ',': 1591 if depth == 1 { 1592 pushSel() 1593 } 1594 case '"': 1595 i++ 1596 loop: 1597 for ; i < len(path); i++ { 1598 switch path[i] { 1599 case '\\': 1600 i++ 1601 case '"': 1602 break loop 1603 } 1604 } 1605 case '[', '(', '{': 1606 depth++ 1607 case ']', ')', '}': 1608 depth-- 1609 if depth == 0 { 1610 pushSel() 1611 path = path[i+1:] 1612 return sels, path, true 1613 } 1614 } 1615 } 1616 return 1617 } 1618 1619 func nameOfLast(path string) string { 1620 for i := len(path) - 1; i >= 0; i-- { 1621 if path[i] == '|' || path[i] == '.' { 1622 if i > 0 && path[i-1] == '\\' { 1623 continue 1624 } 1625 1626 return path[i+1:] 1627 } 1628 } 1629 return path 1630 } 1631 1632 func isSimpleName(component string) bool { 1633 for i := 0; i < len(component); i++ { 1634 if component[i] < ' ' { 1635 return false 1636 } 1637 switch component[i] { 1638 case '[', ']', '{', '}', '(', ')', '#', '|': 1639 return false 1640 } 1641 } 1642 return true 1643 } 1644 1645 func appendJSONString(dst []byte, s string) []byte { 1646 for i := 0; i < len(s); i++ { 1647 if s[i] < ' ' || s[i] == '\\' || s[i] == '"' || s[i] > 126 { 1648 d, _ := json.Marshal(s) 1649 return append(dst, zstring.Bytes2String(d)...) 1650 } 1651 } 1652 dst = append(dst, '"') 1653 dst = append(dst, s...) 1654 dst = append(dst, '"') 1655 return dst 1656 } 1657 1658 type parseContext struct { 1659 json string 1660 value *Res 1661 pipe string 1662 piped bool 1663 calcd bool 1664 lines bool 1665 } 1666 1667 func ModifiersState() bool { 1668 return openModifiers 1669 } 1670 1671 func SetModifiersState(b bool) { 1672 openModifiers = b 1673 } 1674 1675 func Get(json, path string) *Res { 1676 if len(path) > 1 { 1677 if ModifiersState() && path[0] == '@' { 1678 var ok bool 1679 var npath string 1680 var rjson string 1681 npath, rjson, ok = execModifier(json, path) 1682 if ok { 1683 path = npath 1684 if len(path) > 0 && (path[0] == '|' || path[0] == '.') { 1685 res := Get(rjson, path[1:]) 1686 res.index = 0 1687 return res 1688 } 1689 return Parse(rjson) 1690 } 1691 } 1692 if path[0] == '[' || path[0] == '{' { 1693 kind := path[0] 1694 var ok bool 1695 var subs []subSelector 1696 subs, path, ok = parseSubSelectors(path) 1697 if ok && len(path) == 0 || (path[0] == '|' || path[0] == '.') { 1698 var b []byte 1699 b = append(b, kind) 1700 var i int 1701 for _, sub := range subs { 1702 res := Get(json, sub.path) 1703 if res.Exists() { 1704 if i > 0 { 1705 b = append(b, ',') 1706 } 1707 if kind == '{' { 1708 if len(sub.name) > 0 { 1709 if sub.name[0] == '"' && Valid(sub.name) { 1710 b = append(b, sub.name...) 1711 } else { 1712 b = appendJSONString(b, sub.name) 1713 } 1714 } else { 1715 last := nameOfLast(sub.path) 1716 if isSimpleName(last) { 1717 b = appendJSONString(b, last) 1718 } else { 1719 b = appendJSONString(b, "_") 1720 } 1721 } 1722 b = append(b, ':') 1723 } 1724 var raw string 1725 if len(res.raw) == 0 { 1726 raw = res.String() 1727 if len(raw) == 0 { 1728 raw = "null" 1729 } 1730 } else { 1731 raw = res.raw 1732 } 1733 b = append(b, raw...) 1734 i++ 1735 } 1736 } 1737 b = append(b, kind+2) 1738 res := &Res{} 1739 res.raw = zstring.Bytes2String(b) 1740 res.typ = JSON 1741 if len(path) > 0 { 1742 res = res.Get(path[1:]) 1743 } 1744 res.index = 0 1745 return res 1746 } 1747 } 1748 } 1749 1750 var i int 1751 var c = &parseContext{json: json, value: &Res{}} 1752 if len(path) >= 2 && path[0] == '.' && path[1] == '.' { 1753 c.lines = true 1754 parseArray(c, 0, path[2:]) 1755 } else { 1756 for ; i < len(c.json); i++ { 1757 if c.json[i] == '{' { 1758 i++ 1759 parseObject(c, i, path) 1760 break 1761 } 1762 if c.json[i] == '[' { 1763 i++ 1764 parseArray(c, i, path) 1765 break 1766 } 1767 } 1768 } 1769 if c.piped { 1770 res := c.value.Get(c.pipe) 1771 res.index = 0 1772 return res 1773 } 1774 fillIndex(json, c) 1775 return c.value 1776 } 1777 1778 func GetBytes(json []byte, path string) *Res { 1779 return Get(zstring.Bytes2String(json), path) 1780 } 1781 1782 func runeit(json string) rune { 1783 n, _ := strconv.ParseUint(json[:4], 16, 64) 1784 return rune(n) 1785 } 1786 1787 func unescape(json string) string { 1788 var str = make([]byte, 0, len(json)) 1789 for i := 0; i < len(json); i++ { 1790 switch { 1791 case json[i] < ' ': 1792 return zstring.Bytes2String(str) 1793 case json[i] == '\\': 1794 i++ 1795 if i >= len(json) { 1796 return zstring.Bytes2String(str) 1797 } 1798 switch json[i] { 1799 default: 1800 return zstring.Bytes2String(str) 1801 case '\\': 1802 str = append(str, '\\') 1803 case '/': 1804 str = append(str, '/') 1805 case 'b': 1806 str = append(str, '\b') 1807 case 'f': 1808 str = append(str, '\f') 1809 case 'n': 1810 str = append(str, '\n') 1811 case 'r': 1812 str = append(str, '\r') 1813 case 't': 1814 str = append(str, '\t') 1815 case '"': 1816 str = append(str, '"') 1817 case 'u': 1818 if i+5 > len(json) { 1819 return zstring.Bytes2String(str) 1820 } 1821 r := runeit(json[i+1:]) 1822 i += 5 1823 if utf16.IsSurrogate(r) && len(json[i:]) >= 6 && json[i] == '\\' && 1824 json[i+1] == 'u' { 1825 r = utf16.DecodeRune(r, runeit(json[i+2:])) 1826 i += 6 1827 } 1828 1829 str = append(str, 0, 0, 0, 0, 0, 0, 0, 0) 1830 n := utf8.EncodeRune(str[len(str)-8:], r) 1831 str = str[:len(str)-8+n] 1832 i-- 1833 } 1834 default: 1835 str = append(str, json[i]) 1836 } 1837 } 1838 return zstring.Bytes2String(str) 1839 } 1840 1841 func parseAny(json string, i int, hit bool) (int, *Res, bool) { 1842 res := &Res{} 1843 var val string 1844 for ; i < len(json); i++ { 1845 if json[i] == '{' || json[i] == '[' { 1846 val, i = parseSquash(json, i) 1847 if hit { 1848 res.raw = val 1849 res.typ = JSON 1850 } 1851 return i, res, true 1852 } 1853 if json[i] <= ' ' { 1854 continue 1855 } 1856 switch json[i] { 1857 case '"': 1858 i++ 1859 var vesc bool 1860 var ok bool 1861 i, val, vesc, ok = parseString(json, i) 1862 if !ok { 1863 return i, res, false 1864 } 1865 if hit { 1866 res.typ = String 1867 res.raw = val 1868 if vesc { 1869 res.str = unescape(val[1 : len(val)-1]) 1870 } else { 1871 res.str = val[1 : len(val)-1] 1872 } 1873 } 1874 return i, res, true 1875 case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': 1876 i, val = parseNumber(json, i) 1877 if hit { 1878 res.raw = val 1879 res.typ = Number 1880 res.num, _ = strconv.ParseFloat(val, 64) 1881 } 1882 return i, res, true 1883 case 't', 'f', 'n': 1884 vc := json[i] 1885 i, val = parseLiteral(json, i) 1886 if hit { 1887 res.raw = val 1888 switch vc { 1889 case 't': 1890 res.typ = True 1891 case 'f': 1892 res.typ = False 1893 } 1894 return i, res, true 1895 } 1896 } 1897 } 1898 return i, res, false 1899 } 1900 1901 func GetMultiple(json string, path ...string) []*Res { 1902 res := make([]*Res, len(path)) 1903 for i, path := range path { 1904 res[i] = Get(json, path) 1905 } 1906 return res 1907 } 1908 1909 func GetMultipleBytes(json []byte, path ...string) []*Res { 1910 res := make([]*Res, len(path)) 1911 for i, path := range path { 1912 res[i] = GetBytes(json, path) 1913 } 1914 return res 1915 } 1916 1917 func assign(jsval *Res, val reflect.Value, fmap *fieldMaps) { 1918 if jsval.typ == Null { 1919 return 1920 } 1921 // TODO Dev 1922 t := val.Type() 1923 switch val.Kind() { 1924 default: 1925 case reflect.Ptr: 1926 if !val.IsNil() { 1927 elem := val.Elem() 1928 assign(jsval, elem, fmap) 1929 } else { 1930 newval := reflect.New(t.Elem()) 1931 assign(jsval, newval.Elem(), fmap) 1932 val.Set(newval) 1933 } 1934 case reflect.Struct: 1935 fmap.mu.RLock() 1936 name := t.String() 1937 sf := fmap.m[name] 1938 fmap.mu.RUnlock() 1939 if sf == nil { 1940 fmap.mu.Lock() 1941 sf = make(map[string]int) 1942 for i := 0; i < t.NumField(); i++ { 1943 tag, _ := zreflect.GetStructTag(t.Field(i), "json") 1944 sf[tag] = i 1945 } 1946 fmap.m[name] = sf 1947 fmap.mu.Unlock() 1948 } 1949 jsval.ForEach(func(key, value *Res) bool { 1950 if idx, ok := sf[key.str]; ok { 1951 f := val.Field(idx) 1952 if f.CanSet() { 1953 assign(value, f, fmap) 1954 } 1955 } 1956 return true 1957 }) 1958 case reflect.Slice: 1959 if t.Elem().Kind() == reflect.Uint8 && 1960 jsval.typ == String { 1961 data, _ := base64.StdEncoding.DecodeString(jsval.String()) 1962 val.Set(zreflect.ValueOf(data)) 1963 } else { 1964 jsvals := jsval.Array() 1965 l := len(jsvals) 1966 slice := reflect.MakeSlice(t, l, l) 1967 for i := 0; i < l; i++ { 1968 assign(jsvals[i], slice.Index(i), fmap) 1969 } 1970 val.Set(slice) 1971 } 1972 case reflect.Array: 1973 i, n := 0, val.Len() 1974 jsval.ForEach(func(_, value *Res) bool { 1975 if i == n { 1976 return false 1977 } 1978 assign(value, val.Index(i), fmap) 1979 i++ 1980 return true 1981 }) 1982 case reflect.Map: 1983 key := t.Key() 1984 s := key.Kind() == reflect.String 1985 if s { 1986 kind := t.Elem().Kind() 1987 switch kind { 1988 case reflect.Interface: 1989 val.Set(zreflect.ValueOf(jsval.Value())) 1990 case reflect.Struct, reflect.Ptr: 1991 v := reflect.MakeMap(t) 1992 jsval.ForEach(func(key, value *Res) bool { 1993 newval := reflect.New(t.Elem()) 1994 elem := newval.Elem() 1995 assign(value, elem, fmap) 1996 v.SetMapIndex(zreflect.ValueOf(key.Value()), elem) 1997 return true 1998 }) 1999 val.Set(v) 2000 } 2001 } 2002 case reflect.Interface: 2003 val.Set(zreflect.ValueOf(jsval.Value())) 2004 case reflect.Bool: 2005 val.SetBool(jsval.Bool()) 2006 case reflect.Float32, reflect.Float64: 2007 val.SetFloat(jsval.Float()) 2008 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, 2009 reflect.Int64: 2010 val.SetInt(int64(jsval.Int())) 2011 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, 2012 reflect.Uint64: 2013 val.SetUint(uint64(jsval.Uint())) 2014 case reflect.String: 2015 val.SetString(jsval.String()) 2016 } 2017 if len(t.PkgPath()) > 0 { 2018 v := val.Addr() 2019 if v.Type().NumMethod() > 0 { 2020 if u, ok := v.Interface().(json.Unmarshaler); ok { 2021 _ = u.UnmarshalJSON([]byte(jsval.raw)) 2022 } 2023 } 2024 } 2025 } 2026 2027 func Unmarshal(json, v interface{}) error { 2028 var r *Res 2029 switch v := json.(type) { 2030 case string: 2031 r = Parse(v) 2032 case []byte: 2033 r = ParseBytes(v) 2034 case Res: 2035 r = &v 2036 } 2037 if v := zreflect.ValueOf(v); v.Kind() == reflect.Ptr { 2038 if r.String() == "" { 2039 return errors.New("invalid json") 2040 } 2041 assign(r, v, &fieldMaps{m: make(map[string]map[string]int)}) 2042 return nil 2043 } 2044 return errors.New("assignment must be a pointer") 2045 } 2046 2047 func validPayload(data []byte, i int) (outi int, ok bool) { 2048 for ; i < len(data); i++ { 2049 switch data[i] { 2050 default: 2051 i, ok = validany(data, i) 2052 if !ok { 2053 return i, false 2054 } 2055 for ; i < len(data); i++ { 2056 switch data[i] { 2057 default: 2058 return i, false 2059 case ' ', '\t', '\n', '\r': 2060 continue 2061 } 2062 } 2063 return i, true 2064 case ' ', '\t', '\n', '\r': 2065 continue 2066 } 2067 } 2068 return i, false 2069 } 2070 2071 func validany(data []byte, i int) (outi int, ok bool) { 2072 for ; i < len(data); i++ { 2073 switch data[i] { 2074 case ' ', '\t', '\n', '\r': 2075 continue 2076 case '{': 2077 return validobject(data, i+1) 2078 case '[': 2079 return validarray(data, i+1) 2080 case '"': 2081 return validstring(data, i+1) 2082 case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': 2083 return validnumber(data, i+1) 2084 case 't': 2085 return validtrue(data, i+1) 2086 case 'f': 2087 return validfalse(data, i+1) 2088 case 'n': 2089 return validnull(data, i+1) 2090 default: 2091 return i, false 2092 } 2093 } 2094 return i, false 2095 } 2096 2097 func validobject(data []byte, i int) (outi int, ok bool) { 2098 for ; i < len(data); i++ { 2099 switch data[i] { 2100 default: 2101 return i, false 2102 case ' ', '\t', '\n', '\r': 2103 continue 2104 case '}': 2105 return i + 1, true 2106 case '"': 2107 key: 2108 if i, ok = validstring(data, i+1); !ok { 2109 return i, false 2110 } 2111 if i, ok = validcolon(data, i); !ok { 2112 return i, false 2113 } 2114 if i, ok = validany(data, i); !ok { 2115 return i, false 2116 } 2117 if i, ok = validcomma(data, i, '}'); !ok { 2118 return i, false 2119 } 2120 if data[i] == '}' { 2121 return i + 1, true 2122 } 2123 i++ 2124 for ; i < len(data); i++ { 2125 switch data[i] { 2126 default: 2127 return i, false 2128 case ' ', '\t', '\n', '\r': 2129 continue 2130 case '"': 2131 goto key 2132 } 2133 } 2134 return i, false 2135 } 2136 } 2137 return i, false 2138 } 2139 2140 func validcolon(data []byte, i int) (outi int, ok bool) { 2141 for ; i < len(data); i++ { 2142 switch data[i] { 2143 default: 2144 return i, false 2145 case ' ', '\t', '\n', '\r': 2146 continue 2147 case ':': 2148 return i + 1, true 2149 } 2150 } 2151 return i, false 2152 } 2153 2154 func validcomma(data []byte, i int, end byte) (outi int, ok bool) { 2155 for ; i < len(data); i++ { 2156 switch data[i] { 2157 default: 2158 return i, false 2159 case ' ', '\t', '\n', '\r': 2160 continue 2161 case ',': 2162 return i, true 2163 case end: 2164 return i, true 2165 } 2166 } 2167 return i, false 2168 } 2169 2170 func validarray(data []byte, i int) (outi int, ok bool) { 2171 for ; i < len(data); i++ { 2172 switch data[i] { 2173 default: 2174 for ; i < len(data); i++ { 2175 if i, ok = validany(data, i); !ok { 2176 return i, false 2177 } 2178 if i, ok = validcomma(data, i, ']'); !ok { 2179 return i, false 2180 } 2181 if data[i] == ']' { 2182 return i + 1, true 2183 } 2184 } 2185 case ' ', '\t', '\n', '\r': 2186 continue 2187 case ']': 2188 return i + 1, true 2189 } 2190 } 2191 return i, false 2192 } 2193 2194 func validstring(data []byte, i int) (outi int, ok bool) { 2195 for ; i < len(data); i++ { 2196 if data[i] < ' ' { 2197 return i, false 2198 } else if data[i] == '\\' { 2199 i++ 2200 if i == len(data) { 2201 return i, false 2202 } 2203 switch data[i] { 2204 default: 2205 return i, false 2206 case '"', '\\', '/', 'b', 'f', 'n', 'r', 't': 2207 case 'u': 2208 for j := 0; j < 4; j++ { 2209 i++ 2210 if i >= len(data) { 2211 return i, false 2212 } 2213 if !((data[i] >= '0' && data[i] <= '9') || 2214 (data[i] >= 'a' && data[i] <= 'f') || 2215 (data[i] >= 'A' && data[i] <= 'F')) { 2216 return i, false 2217 } 2218 } 2219 } 2220 } else if data[i] == '"' { 2221 return i + 1, true 2222 } 2223 } 2224 return i, false 2225 } 2226 func validnumber(data []byte, i int) (outi int, ok bool) { 2227 i-- 2228 if data[i] == '-' { 2229 i++ 2230 } 2231 if i == len(data) { 2232 return i, false 2233 } 2234 if data[i] == '0' { 2235 i++ 2236 } else { 2237 for ; i < len(data); i++ { 2238 if data[i] >= '0' && data[i] <= '9' { 2239 continue 2240 } 2241 break 2242 } 2243 } 2244 if i == len(data) { 2245 return i, true 2246 } 2247 if data[i] == '.' { 2248 i++ 2249 if i == len(data) { 2250 return i, false 2251 } 2252 if data[i] < '0' || data[i] > '9' { 2253 return i, false 2254 } 2255 i++ 2256 for ; i < len(data); i++ { 2257 if data[i] >= '0' && data[i] <= '9' { 2258 continue 2259 } 2260 break 2261 } 2262 } 2263 if i == len(data) { 2264 return i, true 2265 } 2266 if data[i] == 'e' || data[i] == 'E' { 2267 i++ 2268 if i == len(data) { 2269 return i, false 2270 } 2271 if data[i] == '+' || data[i] == '-' { 2272 i++ 2273 } 2274 if i == len(data) { 2275 return i, false 2276 } 2277 if data[i] < '0' || data[i] > '9' { 2278 return i, false 2279 } 2280 i++ 2281 for ; i < len(data); i++ { 2282 if data[i] >= '0' && data[i] <= '9' { 2283 continue 2284 } 2285 break 2286 } 2287 } 2288 return i, true 2289 } 2290 2291 func validtrue(data []byte, i int) (outi int, ok bool) { 2292 if i+3 <= len(data) && data[i] == 'r' && data[i+1] == 'u' && 2293 data[i+2] == 'e' { 2294 return i + 3, true 2295 } 2296 return i, false 2297 } 2298 func validfalse(data []byte, i int) (outi int, ok bool) { 2299 if i+4 <= len(data) && data[i] == 'a' && data[i+1] == 'l' && 2300 data[i+2] == 's' && data[i+3] == 'e' { 2301 return i + 4, true 2302 } 2303 return i, false 2304 } 2305 2306 func validnull(data []byte, i int) (outi int, ok bool) { 2307 if i+3 <= len(data) && data[i] == 'u' && data[i+1] == 'l' && 2308 data[i+2] == 'l' { 2309 return i + 3, true 2310 } 2311 return i, false 2312 } 2313 2314 func Valid(json string) (ok bool) { 2315 _, ok = validPayload(zstring.String2Bytes(json), 0) 2316 return 2317 } 2318 2319 func ValidBytes(json []byte) bool { 2320 _, ok := validPayload(json, 0) 2321 return ok 2322 } 2323 2324 func parseUint(s string) (n uint, ok bool) { 2325 var i int 2326 if i == len(s) { 2327 return 0, false 2328 } 2329 for ; i < len(s); i++ { 2330 if s[i] >= '0' && s[i] <= '9' { 2331 n = n*10 + uint(s[i]-'0') 2332 } else { 2333 return 0, false 2334 } 2335 } 2336 return n, true 2337 } 2338 2339 func parseInt(s string) (n int, ok bool) { 2340 var i int 2341 var sign bool 2342 if len(s) > 0 && s[0] == '-' { 2343 sign = true 2344 i++ 2345 } 2346 if i == len(s) { 2347 return 0, false 2348 } 2349 for ; i < len(s); i++ { 2350 if s[i] >= '0' && s[i] <= '9' { 2351 n = n*10 + int(s[i]-'0') 2352 } else { 2353 return 0, false 2354 } 2355 } 2356 if sign { 2357 return n * -1, true 2358 } 2359 return n, true 2360 } 2361 2362 func execModifier(json, path string) (pathOut, res string, ok bool) { 2363 name := path[1:] 2364 var hasArgs bool 2365 for i := 1; i < len(path); i++ { 2366 if path[i] == ':' { 2367 pathOut = path[i+1:] 2368 name = path[1:i] 2369 hasArgs = len(pathOut) > 0 2370 break 2371 } 2372 if path[i] == '|' { 2373 pathOut = path[i:] 2374 name = path[1:i] 2375 break 2376 } 2377 if path[i] == '.' { 2378 pathOut = path[i:] 2379 name = path[1:i] 2380 break 2381 } 2382 } 2383 if fn, ok := modifiers[name]; ok { 2384 var args string 2385 if hasArgs { 2386 var parsedArgs bool 2387 switch pathOut[0] { 2388 case '{', '[', '"': 2389 res := Parse(pathOut) 2390 if res.Exists() { 2391 args, _ = parseSquash(pathOut, 0) 2392 pathOut = pathOut[len(args):] 2393 parsedArgs = true 2394 } 2395 } 2396 if !parsedArgs { 2397 idx := strings.IndexByte(pathOut, '|') 2398 if idx == -1 { 2399 args = pathOut 2400 pathOut = "" 2401 } else { 2402 args = pathOut[:idx] 2403 pathOut = pathOut[idx:] 2404 } 2405 } 2406 } 2407 return pathOut, fn(json, args), true 2408 } 2409 return pathOut, res, false 2410 } 2411 2412 var ( 2413 openModifiers = false 2414 modifiers = map[string]func(json, arg string) string{ 2415 "format": modifierPretty, 2416 "ugly": modifierUgly, 2417 "reverse": modifierReverse, 2418 } 2419 ) 2420 2421 func AddModifier(name string, fn func(json, arg string) string) { 2422 modifiers[name] = fn 2423 } 2424 2425 func ModifierExists(name string) bool { 2426 _, ok := modifiers[name] 2427 return ok 2428 } 2429 2430 func modifierPretty(json, arg string) string { 2431 if len(arg) > 0 { 2432 opts := *DefOptions 2433 Parse(arg).ForEach(func(key, value *Res) bool { 2434 switch key.String() { 2435 case "sortKeys": 2436 opts.SortKeys = value.Bool() 2437 case "indent": 2438 opts.Indent = value.String() 2439 case "prefix": 2440 opts.Prefix = value.String() 2441 case "width": 2442 opts.Width = value.Int() 2443 } 2444 return true 2445 }) 2446 return zstring.Bytes2String(FormatOptions(zstring.String2Bytes(json), &opts)) 2447 } 2448 return zstring.Bytes2String(Format(zstring.String2Bytes(json))) 2449 } 2450 2451 func modifierUgly(json, _ string) string { 2452 return zstring.Bytes2String(Ugly(zstring.String2Bytes(json))) 2453 } 2454 2455 func modifierReverse(json, _ string) string { 2456 res := Parse(json) 2457 if res.IsArray() { 2458 var values []*Res 2459 res.ForEach(func(_, value *Res) bool { 2460 values = append(values, value) 2461 return true 2462 }) 2463 out := make([]byte, 0, len(json)) 2464 out = append(out, '[') 2465 for i, j := len(values)-1, 0; i >= 0; i, j = i-1, j+1 { 2466 if j > 0 { 2467 out = append(out, ',') 2468 } 2469 out = append(out, values[i].raw...) 2470 } 2471 out = append(out, ']') 2472 return zstring.Bytes2String(out) 2473 } 2474 if res.IsObject() { 2475 var keyValues []*Res 2476 res.ForEach(func(key, value *Res) bool { 2477 keyValues = append(keyValues, key, value) 2478 return true 2479 }) 2480 out := make([]byte, 0, len(json)) 2481 out = append(out, '{') 2482 for i, j := len(keyValues)-2, 0; i >= 0; i, j = i-2, j+1 { 2483 if j > 0 { 2484 out = append(out, ',') 2485 } 2486 out = append(out, keyValues[i+0].raw...) 2487 out = append(out, ':') 2488 out = append(out, keyValues[i+1].raw...) 2489 } 2490 out = append(out, '}') 2491 return zstring.Bytes2String(out) 2492 } 2493 return json 2494 } 2495 2496 func switchJson(json string, i int, isParse bool) (string, int) { 2497 depth := 1 2498 s := i 2499 i++ 2500 for ; i < len(json); i++ { 2501 if json[i] >= '"' && json[i] <= '}' { 2502 switch json[i] { 2503 case '"': 2504 i++ 2505 s2 := i 2506 for ; i < len(json); i++ { 2507 if json[i] > '\\' { 2508 continue 2509 } 2510 if json[i] == '"' { 2511 if json[i-1] == '\\' { 2512 n := 0 2513 for j := i - 2; j > s2-1; j-- { 2514 if json[j] != '\\' { 2515 break 2516 } 2517 n++ 2518 } 2519 if n%2 == 0 { 2520 continue 2521 } 2522 } 2523 break 2524 } 2525 } 2526 case '{', '[': 2527 depth++ 2528 case '}', ']': 2529 depth-- 2530 if depth == 0 { 2531 if isParse { 2532 i++ 2533 return json[s:i], i 2534 } else { 2535 return json[:i+1], i 2536 } 2537 } 2538 } 2539 } 2540 } 2541 if isParse { 2542 return json[s:], i 2543 } else { 2544 return json, i 2545 } 2546 }