SYS-REQ-001, SYS-REQ-020, SYS-REQ-021, SYS-REQ-022, SYS-REQ-023, SYS-REQ-047, SYS-REQ-111
(data []byte, keys ...string)
| 359 | |
| 360 | // SYS-REQ-001, SYS-REQ-020, SYS-REQ-021, SYS-REQ-022, SYS-REQ-023, SYS-REQ-047, SYS-REQ-111 |
| 361 | func searchKeys(data []byte, keys ...string) int { |
| 362 | keyLevel := 0 |
| 363 | level := 0 |
| 364 | i := 0 |
| 365 | ln := len(data) |
| 366 | lk := len(keys) |
| 367 | lastMatched := true |
| 368 | |
| 369 | if lk == 0 { |
| 370 | return 0 |
| 371 | } |
| 372 | |
| 373 | var stackbuf [unescapeStackBufSize]byte // stack-allocated array for allocation-free unescaping of small strings |
| 374 | |
| 375 | for i < ln { |
| 376 | switch data[i] { |
| 377 | case '"': |
| 378 | i++ |
| 379 | keyBegin := i |
| 380 | |
| 381 | strEnd, keyEscaped := stringEnd(data[i:]) |
| 382 | if strEnd == -1 { |
| 383 | return -1 |
| 384 | } |
| 385 | i += strEnd |
| 386 | keyEnd := i - 1 |
| 387 | |
| 388 | valueOffset := nextToken(data[i:]) |
| 389 | if valueOffset == -1 { |
| 390 | return -1 |
| 391 | } |
| 392 | |
| 393 | i += valueOffset |
| 394 | |
| 395 | // if string is a key |
| 396 | if data[i] == ':' { |
| 397 | if level < 1 { |
| 398 | return -1 |
| 399 | } |
| 400 | |
| 401 | key := data[keyBegin:keyEnd] |
| 402 | |
| 403 | // for unescape: if there are no escape sequences, this is cheap; if there are, it is a |
| 404 | // bit more expensive, but causes no allocations unless len(key) > unescapeStackBufSize |
| 405 | var keyUnesc []byte |
| 406 | if !keyEscaped { |
| 407 | keyUnesc = key |
| 408 | } else if ku, err := Unescape(key, stackbuf[:]); err != nil { |
| 409 | return -1 |
| 410 | } else { |
| 411 | keyUnesc = ku |
| 412 | } |
| 413 | |
| 414 | if level <= len(keys) { |
| 415 | if equalStr(&keyUnesc, keys[level-1]) { |
| 416 | lastMatched = true |
| 417 | |
| 418 | // if key level match |