MCPcopy
hub / github.com/buger/jsonparser / ObjectEach

Function ObjectEach

parser.go:1113–1222  ·  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

1111// SYS-REQ-007, SYS-REQ-030, SYS-REQ-031, SYS-REQ-032, SYS-REQ-054, SYS-REQ-084
1112// ObjectEach iterates over the key-value pairs of a JSON object, invoking a given callback for each such entry
1113func ObjectEach(data []byte, callback func(key []byte, value []byte, dataType ValueType, offset int) error, keys ...string) (err error) {
1114 offset := 0
1115
1116 // Descend to the desired key, if requested
1117 if len(keys) > 0 {
1118 if off := searchKeys(data, keys...); off == -1 {
1119 return KeyPathNotFoundError
1120 } else {
1121 offset = off
1122 }
1123 }
1124
1125 // Validate and skip past opening brace
1126 if off := nextToken(data[offset:]); off == -1 {
1127 return MalformedObjectError
1128 } else if offset += off; data[offset] != '{' {
1129 return MalformedObjectError
1130 } else {
1131 offset++
1132 }
1133
1134 // Skip to the first token inside the object, or stop if we find the ending brace
1135 if off := nextToken(data[offset:]); off == -1 {
1136 return MalformedJsonError
1137 } else if offset += off; data[offset] == '}' {
1138 return nil
1139 }
1140
1141 // Loop pre-condition: data[offset] points to what should be either the next entry's key,
1142 // or the closing brace (if it's anything else, the JSON is malformed).
1143 // Every iteration either returns or advances offset past a token, so the loop
1144 // always exits via return; the former `offset < len(data)` guard was structurally
1145 // always true because internal nextToken/stringEnd calls return errors before
1146 // offset can reach len(data).
1147 for {
1148 // Step 1: find the next key
1149 var key []byte
1150
1151 // Check what the the next token is: start of string, end of object, or something else (error)
1152 switch data[offset] {
1153 case '"':
1154 offset++ // accept as string and skip opening quote
1155 case '}':
1156 return nil // we found the end of the object; stop and return success
1157 default:
1158 return MalformedObjectError
1159 }
1160
1161 // Find the end of the key string
1162 var keyEscaped bool
1163 if off, esc := stringEnd(data[offset:]); off == -1 {
1164 return MalformedJsonError
1165 } else {
1166 key, keyEscaped = data[offset:offset+off-1], esc
1167 offset += off
1168 }
1169
1170 // Unescape the string if needed

Calls 5

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

Used in the wild real call sites across dependent graphs

searching dependent graphs…