SYS-REQ-115
(config Config, data []byte, keys ...string)
| 443 | |
| 444 | // SYS-REQ-115 |
| 445 | func searchKeysConfig(config Config, data []byte, keys ...string) int { |
| 446 | keyLevel := 0 |
| 447 | level := 0 |
| 448 | i := 0 |
| 449 | ln := len(data) |
| 450 | lk := len(keys) |
| 451 | lastMatched := true |
| 452 | |
| 453 | if lk == 0 { |
| 454 | return 0 |
| 455 | } |
| 456 | |
| 457 | var stackbuf [unescapeStackBufSize]byte // stack-allocated array for allocation-free unescaping of small strings |
| 458 | |
| 459 | for i < ln { |
| 460 | // Fast-skip non-structural bytes before dispatching to the switch. |
| 461 | // Skip control/whitespace (<= 0x20) and bytes > 0x5C that are not '{' |
| 462 | // (0x7B) or '}' (0x7D) — the only structural chars handled below that |
| 463 | // exceed the 0x5C threshold. '"' (0x22), '\'' (0x27), '[' (0x5B) and |
| 464 | // ':' (0x3A) are all <= 0x5C and always reach the switch. This is the |
| 465 | // gjson key-scan trick: a single unsigned comparison advances past |
| 466 | // value content (true/false/null letters, high bytes) and indentation. |
| 467 | for i < ln { |
| 468 | c := data[i] |
| 469 | if c <= ' ' { |
| 470 | i++ |
| 471 | continue |
| 472 | } |
| 473 | if c > '\\' && c != '{' && c != '}' { |
| 474 | i++ |
| 475 | continue |
| 476 | } |
| 477 | break |
| 478 | } |
| 479 | if i >= ln { |
| 480 | break |
| 481 | } |
| 482 | switch data[i] { |
| 483 | case '"', '\'': |
| 484 | quote := data[i] |
| 485 | if quote == '\'' && !config.AllowSingleQuotes { |
| 486 | break |
| 487 | } |
| 488 | i++ |
| 489 | keyBegin := i |
| 490 | |
| 491 | strEnd, keyEscaped := stringEndConfig(config, data[i:], quote) |
| 492 | if strEnd == -1 { |
| 493 | return -1 |
| 494 | } |
| 495 | i += strEnd |
| 496 | keyEnd := i - 1 |
| 497 | |
| 498 | valueOffset := nextTokenConfig(config, data[i:]) |
| 499 | if valueOffset == -1 { |
| 500 | return -1 |
| 501 | } |
| 502 |
no test coverage detected