@@ -36,6 +36,28 @@ func tokenEnd(data []byte) int {
3636 return len (data )
3737}
3838
39+ func findLastTokenEnd (data []byte , token byte ) int {
40+ for i := len (data ) - 1 ; i >= 0 ; i -- {
41+ switch data [i ] {
42+ case token :
43+ return i
44+ }
45+ }
46+
47+ return 0
48+ }
49+
50+ func lastTokenEnd (data []byte ) int {
51+ for i := len (data ) - 1 ; i >= 0 ; i -- {
52+ switch data [i ] {
53+ case ' ' , '\n' , '\r' , '\t' , ',' , '}' , ']' :
54+ return i
55+ }
56+ }
57+
58+ return 0
59+ }
60+
3961// Find position of next character which is not whitespace
4062func nextToken (data []byte ) int {
4163 for i , c := range data {
@@ -173,7 +195,7 @@ func searchKeys(data []byte, keys ...string) int {
173195 keyUnesc = ku
174196 }
175197
176- if equalStr (& keyUnesc , keys [level - 1 ]) {
198+ if equalStr (keyUnesc , keys [level - 1 ]) {
177199 keyLevel ++
178200 // If we found all keys in path
179201 if keyLevel == lk {
@@ -200,14 +222,15 @@ func searchKeys(data []byte, keys ...string) int {
200222 var curIdx int
201223 var valueFound []byte
202224 var valueOffset int
225+ var curI = i
203226 ArrayEach (data [i :], func (value []byte , dataType ValueType , offset int , err error ) {
204227 if curIdx == aIdx {
205228 valueFound = value
206229 valueOffset = offset
207- if dataType == String {
230+ if dataType == String {
208231 valueOffset = valueOffset - 2
209- valueFound = data [i + valueOffset : i + valueOffset + len (value ) + 2 ]
210- }
232+ valueFound = data [curI + valueOffset : curI + valueOffset + len (value )+ 2 ]
233+ }
211234 }
212235 curIdx += 1
213236 })
@@ -314,13 +337,13 @@ func EachKey(data []byte, cb func(int, []byte, ValueType, error), paths ...[]str
314337
315338 if maxPath >= level {
316339 if level < 1 {
317- cb (- 1 , [] byte {} , Unknown , MalformedJsonError )
340+ cb (- 1 , nil , Unknown , MalformedJsonError )
318341 return - 1
319342 }
320- pathsBuf [level - 1 ] = bytesToString (& keyUnesc )
321343
344+ pathsBuf [level - 1 ] = bytesToString (keyUnesc )
322345 for pi , p := range paths {
323- if len (p ) != level || pathFlags & bitwiseFlags [pi + 1 ] != 0 || ! equalStr (& keyUnesc , p [level - 1 ]) || ! sameTree (p , pathsBuf [:level ]) {
346+ if len (p ) != level || pathFlags & bitwiseFlags [pi + 1 ] != 0 || ! equalStr (keyUnesc , p [level - 1 ]) || ! sameTree (p , pathsBuf [:level ]) {
324347 continue
325348 }
326349
@@ -338,9 +361,12 @@ func EachKey(data []byte, cb func(int, []byte, ValueType, error), paths ...[]str
338361 }
339362
340363 if pathsMatched == len (paths ) {
341- return i
364+ break
342365 }
343366 }
367+ if pathsMatched == len (paths ) {
368+ return i
369+ }
344370 }
345371
346372 if match == - 1 {
@@ -369,7 +395,7 @@ func EachKey(data []byte, cb func(int, []byte, ValueType, error), paths ...[]str
369395 var pIdxFlags int64
370396
371397 if level < 0 {
372- cb (- 1 , [] byte {} , Unknown , MalformedJsonError )
398+ cb (- 1 , nil , Unknown , MalformedJsonError )
373399 return - 1
374400 }
375401
@@ -501,6 +527,68 @@ func createInsertComponent(keys []string, setValue []byte, comma, object bool) [
501527
502528/*
503529
530+ Del - Receives existing data structure, path to delete.
531+
532+ Returns:
533+ `data` - return modified data
534+
535+ */
536+ func Del (data []byte , keys ... string ) []byte {
537+ lk := len (keys )
538+ if lk == 0 {
539+ return data [:0 ]
540+ }
541+
542+ array := false
543+ if len (keys [lk - 1 ]) > 0 && string (keys [lk - 1 ][0 ]) == "[" {
544+ array = true
545+ }
546+
547+ _ , _ , startOffset , endOffset , err := internalGet (data , keys ... )
548+ if err == nil {
549+ if ! array {
550+ lastTok := lastTokenEnd (data [:startOffset ])
551+ keyOffset , _ := stringEnd (data [:lastTok ])
552+ lastTokEnd := tokenEnd (data [endOffset :])
553+
554+ if keyOffset == - 1 {
555+ keyOffset = 0
556+ } else {
557+ keyOffset --
558+ }
559+ if lastTok != 0 {
560+ startOffset = lastTok + keyOffset
561+ }
562+
563+ if lastTokEnd >= len (data [endOffset :])- 1 {
564+ lastTokEnd = 0
565+ startOffset = lastTok
566+ } else {
567+ lastTokEnd ++
568+ }
569+ endOffset = endOffset + lastTokEnd
570+ } else {
571+ tokEnd := tokenEnd (data [endOffset :])
572+ tokStart := findLastTokenEnd (data [:startOffset ], "," [0 ])
573+
574+ if data [endOffset + tokEnd ] == "," [0 ] {
575+ endOffset += tokEnd + 1
576+ } else if data [endOffset + tokEnd ] == "]" [0 ] && data [tokStart ] == "," [0 ] {
577+ startOffset = tokStart
578+ }
579+ }
580+
581+ copy (data [startOffset :], data [endOffset :])
582+ for k , n := len (data )- endOffset + startOffset , len (data ); k < n ; k ++ {
583+ data [k ] = 0 // or the zero value of T
584+ }
585+ data = data [:len (data )- endOffset + startOffset ]
586+ }
587+ return data
588+ }
589+
590+ /*
591+
504592Set - Receives existing data structure, path to set, and data to set at that key.
505593
506594Returns:
@@ -518,7 +606,7 @@ func Set(data []byte, setValue []byte, keys ...string) (value []byte, err error)
518606 if err != nil {
519607 if err != KeyPathNotFoundError {
520608 // problem parsing the data
521- return [] byte {} , err
609+ return nil , err
522610 }
523611 // full path doesnt exist
524612 // does any subpath exist?
@@ -553,10 +641,10 @@ func Set(data []byte, setValue []byte, keys ...string) (value []byte, err error)
553641 depthOffset := endOffset
554642 if depth != 0 {
555643 // if subpath is a non-empty object, add to it
556- if data [startOffset ] == '{' && data [startOffset + 1 + nextToken (data [startOffset + 1 :])]!= '}' {
644+ if data [startOffset ] == '{' && data [startOffset + 1 + nextToken (data [startOffset + 1 :])] != '}' {
557645 depthOffset --
558646 startOffset = depthOffset
559- // otherwise, over-write it with a new object
647+ // otherwise, over-write it with a new object
560648 } else {
561649 comma = false
562650 object = true
@@ -589,15 +677,15 @@ func getType(data []byte, offset int) ([]byte, ValueType, int, error) {
589677 if idx , _ := stringEnd (data [offset + 1 :]); idx != - 1 {
590678 endOffset += idx + 1
591679 } else {
592- return [] byte {} , dataType , offset , MalformedStringError
680+ return nil , dataType , offset , MalformedStringError
593681 }
594682 } else if data [offset ] == '[' { // if array value
595683 dataType = Array
596684 // break label, for stopping nested loops
597685 endOffset = blockEnd (data [offset :], '[' , ']' )
598686
599687 if endOffset == - 1 {
600- return [] byte {} , dataType , offset , MalformedArrayError
688+ return nil , dataType , offset , MalformedArrayError
601689 }
602690
603691 endOffset += offset
@@ -607,7 +695,7 @@ func getType(data []byte, offset int) ([]byte, ValueType, int, error) {
607695 endOffset = blockEnd (data [offset :], '{' , '}' )
608696
609697 if endOffset == - 1 {
610- return [] byte {} , dataType , offset , MalformedObjectError
698+ return nil , dataType , offset , MalformedObjectError
611699 }
612700
613701 endOffset += offset
@@ -665,14 +753,14 @@ func Get(data []byte, keys ...string) (value []byte, dataType ValueType, offset
665753func internalGet (data []byte , keys ... string ) (value []byte , dataType ValueType , offset , endOffset int , err error ) {
666754 if len (keys ) > 0 {
667755 if offset = searchKeys (data , keys ... ); offset == - 1 {
668- return [] byte {} , NotExist , - 1 , - 1 , KeyPathNotFoundError
756+ return nil , NotExist , - 1 , - 1 , KeyPathNotFoundError
669757 }
670758 }
671759
672760 // Go to closest value
673761 nO := nextToken (data [offset :])
674762 if nO == - 1 {
675- return [] byte {} , NotExist , offset , - 1 , MalformedJsonError
763+ return nil , NotExist , offset , - 1 , MalformedJsonError
676764 }
677765
678766 offset += nO
@@ -884,7 +972,7 @@ func GetUnsafeString(data []byte, keys ...string) (val string, err error) {
884972 return "" , e
885973 }
886974
887- return bytesToString (& v ), nil
975+ return bytesToString (v ), nil
888976}
889977
890978// GetString returns the value retrieved by `Get`, cast to a string if possible, trying to properly handle escape and utf8 symbols
@@ -982,7 +1070,7 @@ func ParseString(b []byte) (string, error) {
9821070
9831071// ParseNumber parses a Number ValueType into a Go float64
9841072func ParseFloat (b []byte ) (float64 , error ) {
985- if v , err := parseFloat (& b ); err != nil {
1073+ if v , err := parseFloat (b ); err != nil {
9861074 return 0 , MalformedValueError
9871075 } else {
9881076 return v , nil
0 commit comments