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

Function ObjectEach

parser.go:1363–1472  ·  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

1361// SYS-REQ-007, SYS-REQ-030, SYS-REQ-031, SYS-REQ-032, SYS-REQ-054, SYS-REQ-084
1362// ObjectEach iterates over the key-value pairs of a JSON object, invoking a given callback for each such entry
1363func ObjectEach(data []byte, callback func(key []byte, value []byte, dataType ValueType, offset int) error, keys ...string) (err error) {
1364 offset := 0
1365
1366 // Descend to the desired key, if requested
1367 if len(keys) > 0 {
1368 if off := searchKeys(data, keys...); off == -1 {
1369 return KeyPathNotFoundError
1370 } else {
1371 offset = off
1372 }
1373 }
1374
1375 // Validate and skip past opening brace
1376 if off := nextToken(data[offset:]); off == -1 {
1377 return MalformedObjectError
1378 } else if offset += off; data[offset] != '{' {
1379 return MalformedObjectError
1380 } else {
1381 offset++
1382 }
1383
1384 // Skip to the first token inside the object, or stop if we find the ending brace
1385 if off := nextToken(data[offset:]); off == -1 {
1386 return MalformedJsonError
1387 } else if offset += off; data[offset] == '}' {
1388 return nil
1389 }
1390
1391 // Loop pre-condition: data[offset] points to what should be either the next entry's key,
1392 // or the closing brace (if it's anything else, the JSON is malformed).
1393 // Every iteration either returns or advances offset past a token, so the loop
1394 // always exits via return; the former `offset < len(data)` guard was structurally
1395 // always true because internal nextToken/stringEnd calls return errors before
1396 // offset can reach len(data).
1397 for {
1398 // Step 1: find the next key
1399 var key []byte
1400
1401 // Check what the the next token is: start of string, end of object, or something else (error)
1402 switch data[offset] {
1403 case '"':
1404 offset++ // accept as string and skip opening quote
1405 case '}':
1406 return nil // we found the end of the object; stop and return success
1407 default:
1408 return MalformedObjectError
1409 }
1410
1411 // Find the end of the key string
1412 var keyEscaped bool
1413 if off, esc := stringEnd(data[offset:]); off == -1 {
1414 return MalformedJsonError
1415 } else {
1416 key, keyEscaped = data[offset:offset+off-1], esc
1417 offset += off
1418 }
1419
1420 // Unescape the string if needed

Calls 5

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