MCPcopy Create free account
hub / github.com/buger/jsonparser / ObjectEach

Function ObjectEach

parser.go:1389–1498  ·  view source on GitHub ↗

SYS-REQ-007, SYS-REQ-030, SYS-REQ-031, SYS-REQ-032, SYS-REQ-054, SYS-REQ-084 ObjectEach iterates over the key-value pairs of a JSON object, invoking a given callback for each such entry

(data []byte, callback func(key []byte, value []byte, dataType ValueType, offset int) error, keys ...string)

Source from the content-addressed store, hash-verified

1387// SYS-REQ-007, SYS-REQ-030, SYS-REQ-031, SYS-REQ-032, SYS-REQ-054, SYS-REQ-084
1388// ObjectEach iterates over the key-value pairs of a JSON object, invoking a given callback for each such entry
1389func ObjectEach(data []byte, callback func(key []byte, value []byte, dataType ValueType, offset int) error, keys ...string) (err error) {
1390 offset := 0
1391
1392 // Descend to the desired key, if requested
1393 if len(keys) > 0 {
1394 if off := searchKeys(data, keys...); off == -1 {
1395 return KeyPathNotFoundError
1396 } else {
1397 offset = off
1398 }
1399 }
1400
1401 // Validate and skip past opening brace
1402 if off := nextToken(data[offset:]); off == -1 {
1403 return MalformedObjectError
1404 } else if offset += off; data[offset] != '{' {
1405 return MalformedObjectError
1406 } else {
1407 offset++
1408 }
1409
1410 // Skip to the first token inside the object, or stop if we find the ending brace
1411 if off := nextToken(data[offset:]); off == -1 {
1412 return MalformedJsonError
1413 } else if offset += off; data[offset] == '}' {
1414 return nil
1415 }
1416
1417 // Loop pre-condition: data[offset] points to what should be either the next entry's key,
1418 // or the closing brace (if it's anything else, the JSON is malformed).
1419 // Every iteration either returns or advances offset past a token, so the loop
1420 // always exits via return; the former `offset < len(data)` guard was structurally
1421 // always true because internal nextToken/stringEnd calls return errors before
1422 // offset can reach len(data).
1423 for {
1424 // Step 1: find the next key
1425 var key []byte
1426
1427 // Check what the the next token is: start of string, end of object, or something else (error)
1428 switch data[offset] {
1429 case '"':
1430 offset++ // accept as string and skip opening quote
1431 case '}':
1432 return nil // we found the end of the object; stop and return success
1433 default:
1434 return MalformedObjectError
1435 }
1436
1437 // Find the end of the key string
1438 var keyEscaped bool
1439 if off, esc := stringEnd(data[offset:]); off == -1 {
1440 return MalformedJsonError
1441 } else {
1442 key, keyEscaped = data[offset:offset+off-1], esc
1443 offset += off
1444 }
1445
1446 // Unescape the string if needed

Calls 5

searchKeysFunction · 0.85
nextTokenFunction · 0.85
stringEndFunction · 0.85
UnescapeFunction · 0.85
GetFunction · 0.85