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

Function Set

parser.go:841–912  ·  view source on GitHub ↗

* Set - Receives existing data structure, path to set, and data to set at that key. Returns: `value` - modified byte array `err` - On any parsing error */ SYS-REQ-009, SYS-REQ-051, SYS-REQ-068, SYS-REQ-069, SYS-REQ-070

(data []byte, setValue []byte, keys ...string)

Source from the content-addressed store, hash-verified

839*/
840// SYS-REQ-009, SYS-REQ-051, SYS-REQ-068, SYS-REQ-069, SYS-REQ-070
841func Set(data []byte, setValue []byte, keys ...string) (value []byte, err error) {
842 // ensure keys are set
843 if len(keys) == 0 {
844 return nil, KeyPathNotFoundError
845 }
846
847 _, _, startOffset, endOffset, err := internalGet(data, keys...)
848 if err != nil {
849 if err != KeyPathNotFoundError {
850 // problem parsing the data
851 return nil, err
852 }
853 // full path doesnt exist
854 // does any subpath exist?
855 var depth int
856 for i := range keys {
857 _, _, start, end, sErr := internalGet(data, keys[:i+1]...)
858 if sErr != nil {
859 break
860 } else {
861 endOffset = end
862 startOffset = start
863 depth++
864 }
865 }
866 comma := true
867 object := false
868 if endOffset == -1 {
869 firstToken := nextToken(data)
870 // We can't set a top-level key if data isn't an object
871 if firstToken < 0 || data[firstToken] != '{' {
872 return nil, KeyPathNotFoundError
873 }
874 // Don't need a comma if the input is an empty object
875 secondToken := firstToken + 1 + nextToken(data[firstToken+1:])
876 if data[secondToken] == '}' {
877 comma = false
878 }
879 // Set the top level key at the end (accounting for any trailing whitespace)
880 // This assumes last token is valid like '}', could check and return error
881 endOffset = lastToken(data)
882 }
883 depthOffset := endOffset
884 if depth != 0 {
885 // if subpath is a non-empty object, add to it
886 // or if subpath is a non-empty array, add to it
887 if (data[startOffset] == '{' && data[startOffset+1+nextToken(data[startOffset+1:])] != '}') ||
888 (data[startOffset] == '[' && data[startOffset+1+nextToken(data[startOffset+1:])] == '{') && keys[depth:][0][0] == 91 {
889 depthOffset--
890 startOffset = depthOffset
891 // otherwise, over-write it with a new object
892 } else {
893 comma = false
894 object = true
895 }
896 } else {
897 startOffset = depthOffset
898 }

Callers 13

BenchmarkSetLargeFunction · 0.92
TestSetIdempotencyFunction · 0.85
TestMutationNilSafetyFunction · 0.85
TestMutationUnicodeKeysFunction · 0.85
FuzzSetFunction · 0.85
TestSetFunction · 0.85
TestSetTruncatedInputFunction · 0.85
TestSetPathBeyondEOFFunction · 0.85
TestSetNestedMutationFunction · 0.85

Calls 4

internalGetFunction · 0.85
nextTokenFunction · 0.85
lastTokenFunction · 0.85
createInsertComponentFunction · 0.85

Tested by 12

BenchmarkSetLargeFunction · 0.74
TestSetIdempotencyFunction · 0.68
TestMutationNilSafetyFunction · 0.68
TestMutationUnicodeKeysFunction · 0.68
TestSetFunction · 0.68
TestSetTruncatedInputFunction · 0.68
TestSetPathBeyondEOFFunction · 0.68
TestSetNestedMutationFunction · 0.68
TestSetNoPathFunction · 0.68