SYS-REQ-001, SYS-REQ-020, SYS-REQ-021, SYS-REQ-022, SYS-REQ-023, SYS-REQ-047
(data []byte, keys ...string)
| 229 | |
| 230 | // SYS-REQ-001, SYS-REQ-020, SYS-REQ-021, SYS-REQ-022, SYS-REQ-023, SYS-REQ-047 |
| 231 | func searchKeys(data []byte, keys ...string) int { |
| 232 | keyLevel := 0 |
| 233 | level := 0 |
| 234 | i := 0 |
| 235 | ln := len(data) |
| 236 | lk := len(keys) |
| 237 | lastMatched := true |
| 238 | |
| 239 | if lk == 0 { |
| 240 | return 0 |
| 241 | } |
| 242 | |
| 243 | var stackbuf [unescapeStackBufSize]byte // stack-allocated array for allocation-free unescaping of small strings |
| 244 | |
| 245 | for i < ln { |
| 246 | switch data[i] { |
| 247 | case '"': |
| 248 | i++ |
| 249 | keyBegin := i |
| 250 | |
| 251 | strEnd, keyEscaped := stringEnd(data[i:]) |
| 252 | if strEnd == -1 { |
| 253 | return -1 |
| 254 | } |
| 255 | i += strEnd |
| 256 | keyEnd := i - 1 |
| 257 | |
| 258 | valueOffset := nextToken(data[i:]) |
| 259 | if valueOffset == -1 { |
| 260 | return -1 |
| 261 | } |
| 262 | |
| 263 | i += valueOffset |
| 264 | |
| 265 | // if string is a key |
| 266 | if data[i] == ':' { |
| 267 | if level < 1 { |
| 268 | return -1 |
| 269 | } |
| 270 | |
| 271 | key := data[keyBegin:keyEnd] |
| 272 | |
| 273 | // for unescape: if there are no escape sequences, this is cheap; if there are, it is a |
| 274 | // bit more expensive, but causes no allocations unless len(key) > unescapeStackBufSize |
| 275 | var keyUnesc []byte |
| 276 | if !keyEscaped { |
| 277 | keyUnesc = key |
| 278 | } else if ku, err := Unescape(key, stackbuf[:]); err != nil { |
| 279 | return -1 |
| 280 | } else { |
| 281 | keyUnesc = ku |
| 282 | } |
| 283 | |
| 284 | if level <= len(keys) { |
| 285 | if equalStr(&keyUnesc, keys[level-1]) { |
| 286 | lastMatched = true |
| 287 | |
| 288 | // if key level match |
searching dependent graphs…