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

Function ObjectEach

parser.go:1729–1838  ·  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

1727// SYS-REQ-007, SYS-REQ-030, SYS-REQ-031, SYS-REQ-032, SYS-REQ-054, SYS-REQ-084
1728// ObjectEach iterates over the key-value pairs of a JSON object, invoking a given callback for each such entry
1729func ObjectEach(data []byte, callback func(key []byte, value []byte, dataType ValueType, offset int) error, keys ...string) (err error) {
1730 offset := 0
1731
1732 // Descend to the desired key, if requested
1733 if len(keys) > 0 {
1734 if off := searchKeys(data, keys...); off == -1 {
1735 return KeyPathNotFoundError
1736 } else {
1737 offset = off
1738 }
1739 }
1740
1741 // Validate and skip past opening brace
1742 if off := nextToken(data[offset:]); off == -1 {
1743 return MalformedObjectError
1744 } else if offset += off; data[offset] != '{' {
1745 return MalformedObjectError
1746 } else {
1747 offset++
1748 }
1749
1750 // Skip to the first token inside the object, or stop if we find the ending brace
1751 if off := nextToken(data[offset:]); off == -1 {
1752 return MalformedJsonError
1753 } else if offset += off; data[offset] == '}' {
1754 return nil
1755 }
1756
1757 // Loop pre-condition: data[offset] points to what should be either the next entry's key,
1758 // or the closing brace (if it's anything else, the JSON is malformed).
1759 // Every iteration either returns or advances offset past a token, so the loop
1760 // always exits via return; the former `offset < len(data)` guard was structurally
1761 // always true because internal nextToken/stringEnd calls return errors before
1762 // offset can reach len(data).
1763 for {
1764 // Step 1: find the next key
1765 var key []byte
1766
1767 // Check what the the next token is: start of string, end of object, or something else (error)
1768 switch data[offset] {
1769 case '"':
1770 offset++ // accept as string and skip opening quote
1771 case '}':
1772 return nil // we found the end of the object; stop and return success
1773 default:
1774 return MalformedObjectError
1775 }
1776
1777 // Find the end of the key string
1778 var keyEscaped bool
1779 if off, esc := stringEnd(data[offset:]); off == -1 {
1780 return MalformedJsonError
1781 } else {
1782 key, keyEscaped = data[offset:offset+off-1], esc
1783 offset += off
1784 }
1785
1786 // Unescape the string if needed

Calls 5

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