|
19 | 19 | OverflowIntegerError = errors.New("Value is number, but overflowed while parsing")
|
20 | 20 | MalformedStringEscapeError = errors.New("Encountered an invalid escape sequence in a string")
|
21 | 21 | NullValueError = errors.New("Value is null")
|
| 22 | + DoneError = errors.New("Done. Reached End of Iterator") |
22 | 23 | )
|
23 | 24 |
|
24 | 25 | // How much stack space to allocate for unescaping JSON strings; if a string longer
|
@@ -707,12 +708,10 @@ func WriteToBuffer(buffer []byte, str string) int {
|
707 | 708 | }
|
708 | 709 |
|
709 | 710 | /*
|
710 |
| -
|
711 | 711 | Del - Receives existing data structure, path to delete.
|
712 | 712 |
|
713 | 713 | Returns:
|
714 | 714 | `data` - return modified data
|
715 |
| -
|
716 | 715 | */
|
717 | 716 | func Delete(data []byte, keys ...string) []byte {
|
718 | 717 | lk := len(keys)
|
@@ -793,13 +792,11 @@ func Delete(data []byte, keys ...string) []byte {
|
793 | 792 | }
|
794 | 793 |
|
795 | 794 | /*
|
796 |
| -
|
797 | 795 | Set - Receives existing data structure, path to set, and data to set at that key.
|
798 | 796 |
|
799 | 797 | Returns:
|
800 | 798 | `value` - modified byte array
|
801 | 799 | `err` - On any parsing error
|
802 |
| -
|
803 | 800 | */
|
804 | 801 | func Set(data []byte, setValue []byte, keys ...string) (value []byte, err error) {
|
805 | 802 | // ensure keys are set
|
@@ -1069,6 +1066,86 @@ func ArrayEach(data []byte, cb func(value []byte, dataType ValueType, offset int
|
1069 | 1066 | return offset, nil
|
1070 | 1067 | }
|
1071 | 1068 |
|
| 1069 | +func ArrayIterator(data []byte, keys ...string) (next func() ([]byte, ValueType, int, error), err error) { |
| 1070 | + |
| 1071 | + makeNextError := func(err error) func() ([]byte, ValueType, int, error) { |
| 1072 | + return func() ([]byte, ValueType, int, error) { return nil, NotExist, -1, err } |
| 1073 | + } |
| 1074 | + |
| 1075 | + if len(data) == 0 { |
| 1076 | + return makeNextError(MalformedObjectError), MalformedObjectError |
| 1077 | + } |
| 1078 | + |
| 1079 | + nT := nextToken(data) |
| 1080 | + if nT == -1 { |
| 1081 | + return makeNextError(MalformedJsonError), MalformedJsonError |
| 1082 | + } |
| 1083 | + |
| 1084 | + offset := nT + 1 |
| 1085 | + |
| 1086 | + if len(keys) > 0 { |
| 1087 | + if offset = searchKeys(data, keys...); offset == -1 { |
| 1088 | + return makeNextError(KeyPathNotFoundError), KeyPathNotFoundError |
| 1089 | + } |
| 1090 | + |
| 1091 | + // Go to closest value |
| 1092 | + nO := nextToken(data[offset:]) |
| 1093 | + if nO == -1 { |
| 1094 | + return makeNextError(MalformedJsonError), MalformedJsonError |
| 1095 | + } |
| 1096 | + |
| 1097 | + offset += nO |
| 1098 | + |
| 1099 | + if data[offset] != '[' { |
| 1100 | + return makeNextError(MalformedArrayError), MalformedArrayError |
| 1101 | + } |
| 1102 | + |
| 1103 | + offset++ |
| 1104 | + } |
| 1105 | + |
| 1106 | + isFirst, nextOffset := true, offset |
| 1107 | + |
| 1108 | + next = func() ([]byte, ValueType, int, error) { |
| 1109 | + offset = nextOffset |
| 1110 | + |
| 1111 | + nO := nextToken(data[offset:]) |
| 1112 | + if nO == -1 { |
| 1113 | + return nil, NotExist, -1, MalformedJsonError |
| 1114 | + } |
| 1115 | + offset += nO |
| 1116 | + if data[offset] == ']' { |
| 1117 | + return nil, NotExist, -1, DoneError |
| 1118 | + } |
| 1119 | + |
| 1120 | + if !isFirst && data[offset] != ',' { |
| 1121 | + return nil, NotExist, -1, MalformedArrayError |
| 1122 | + } |
| 1123 | + if !isFirst { |
| 1124 | + offset++ |
| 1125 | + } |
| 1126 | + |
| 1127 | + v, t, o, e := Get(data[offset:]) |
| 1128 | + |
| 1129 | + if e != nil { |
| 1130 | + return nil, NotExist, -1, e |
| 1131 | + } |
| 1132 | + |
| 1133 | + if o == 0 { |
| 1134 | + return nil, NotExist, -1, DoneError |
| 1135 | + } |
| 1136 | + |
| 1137 | + if t == NotExist { |
| 1138 | + return nil, NotExist, -1, DoneError |
| 1139 | + } |
| 1140 | + |
| 1141 | + isFirst = false |
| 1142 | + nextOffset = offset + o |
| 1143 | + |
| 1144 | + return v, t, offset - len(v), e |
| 1145 | + } |
| 1146 | + return next, nil |
| 1147 | +} |
| 1148 | + |
1072 | 1149 | // ObjectEach iterates over the key-value pairs of a JSON object, invoking a given callback for each such entry
|
1073 | 1150 | func ObjectEach(data []byte, callback func(key []byte, value []byte, dataType ValueType, offset int) error, keys ...string) (err error) {
|
1074 | 1151 | offset := 0
|
|
0 commit comments