iter_object.go (6362B)
1 package jsoniter 2 3 import ( 4 "fmt" 5 "strings" 6 ) 7 8 // ReadObject read one field from object. 9 // If object ended, returns empty string. 10 // Otherwise, returns the field name. 11 func (iter *Iterator) ReadObject() (ret string) { 12 c := iter.nextToken() 13 switch c { 14 case 'n': 15 iter.skipThreeBytes('u', 'l', 'l') 16 return "" // null 17 case '{': 18 c = iter.nextToken() 19 if c == '"' { 20 iter.unreadByte() 21 field := iter.ReadString() 22 c = iter.nextToken() 23 if c != ':' { 24 iter.ReportError("ReadObject", "expect : after object field, but found "+string([]byte{c})) 25 } 26 return field 27 } 28 if c == '}' { 29 return "" // end of object 30 } 31 iter.ReportError("ReadObject", `expect " after {, but found `+string([]byte{c})) 32 return 33 case ',': 34 field := iter.ReadString() 35 c = iter.nextToken() 36 if c != ':' { 37 iter.ReportError("ReadObject", "expect : after object field, but found "+string([]byte{c})) 38 } 39 return field 40 case '}': 41 return "" // end of object 42 default: 43 iter.ReportError("ReadObject", fmt.Sprintf(`expect { or , or } or n, but found %s`, string([]byte{c}))) 44 return 45 } 46 } 47 48 // CaseInsensitive 49 func (iter *Iterator) readFieldHash() int64 { 50 hash := int64(0x811c9dc5) 51 c := iter.nextToken() 52 if c != '"' { 53 iter.ReportError("readFieldHash", `expect ", but found `+string([]byte{c})) 54 return 0 55 } 56 for { 57 for i := iter.head; i < iter.tail; i++ { 58 // require ascii string and no escape 59 b := iter.buf[i] 60 if b == '\\' { 61 iter.head = i 62 for _, b := range iter.readStringSlowPath() { 63 if 'A' <= b && b <= 'Z' && !iter.cfg.caseSensitive { 64 b += 'a' - 'A' 65 } 66 hash ^= int64(b) 67 hash *= 0x1000193 68 } 69 c = iter.nextToken() 70 if c != ':' { 71 iter.ReportError("readFieldHash", `expect :, but found `+string([]byte{c})) 72 return 0 73 } 74 return hash 75 } 76 if b == '"' { 77 iter.head = i + 1 78 c = iter.nextToken() 79 if c != ':' { 80 iter.ReportError("readFieldHash", `expect :, but found `+string([]byte{c})) 81 return 0 82 } 83 return hash 84 } 85 if 'A' <= b && b <= 'Z' && !iter.cfg.caseSensitive { 86 b += 'a' - 'A' 87 } 88 hash ^= int64(b) 89 hash *= 0x1000193 90 } 91 if !iter.loadMore() { 92 iter.ReportError("readFieldHash", `incomplete field name`) 93 return 0 94 } 95 } 96 } 97 98 func calcHash(str string, caseSensitive bool) int64 { 99 if !caseSensitive { 100 str = strings.ToLower(str) 101 } 102 hash := int64(0x811c9dc5) 103 for _, b := range []byte(str) { 104 hash ^= int64(b) 105 hash *= 0x1000193 106 } 107 return int64(hash) 108 } 109 110 // ReadObjectCB read object with callback, the key is ascii only and field name not copied 111 func (iter *Iterator) ReadObjectCB(callback func(*Iterator, string) bool) bool { 112 c := iter.nextToken() 113 var field string 114 if c == '{' { 115 if !iter.incrementDepth() { 116 return false 117 } 118 c = iter.nextToken() 119 if c == '"' { 120 iter.unreadByte() 121 field = iter.ReadString() 122 c = iter.nextToken() 123 if c != ':' { 124 iter.ReportError("ReadObject", "expect : after object field, but found "+string([]byte{c})) 125 } 126 if !callback(iter, field) { 127 iter.decrementDepth() 128 return false 129 } 130 c = iter.nextToken() 131 for c == ',' { 132 field = iter.ReadString() 133 c = iter.nextToken() 134 if c != ':' { 135 iter.ReportError("ReadObject", "expect : after object field, but found "+string([]byte{c})) 136 } 137 if !callback(iter, field) { 138 iter.decrementDepth() 139 return false 140 } 141 c = iter.nextToken() 142 } 143 if c != '}' { 144 iter.ReportError("ReadObjectCB", `object not ended with }`) 145 iter.decrementDepth() 146 return false 147 } 148 return iter.decrementDepth() 149 } 150 if c == '}' { 151 return iter.decrementDepth() 152 } 153 iter.ReportError("ReadObjectCB", `expect " after {, but found `+string([]byte{c})) 154 iter.decrementDepth() 155 return false 156 } 157 if c == 'n' { 158 iter.skipThreeBytes('u', 'l', 'l') 159 return true // null 160 } 161 iter.ReportError("ReadObjectCB", `expect { or n, but found `+string([]byte{c})) 162 return false 163 } 164 165 // ReadMapCB read map with callback, the key can be any string 166 func (iter *Iterator) ReadMapCB(callback func(*Iterator, string) bool) bool { 167 c := iter.nextToken() 168 if c == '{' { 169 if !iter.incrementDepth() { 170 return false 171 } 172 c = iter.nextToken() 173 if c == '"' { 174 iter.unreadByte() 175 field := iter.ReadString() 176 if iter.nextToken() != ':' { 177 iter.ReportError("ReadMapCB", "expect : after object field, but found "+string([]byte{c})) 178 iter.decrementDepth() 179 return false 180 } 181 if !callback(iter, field) { 182 iter.decrementDepth() 183 return false 184 } 185 c = iter.nextToken() 186 for c == ',' { 187 field = iter.ReadString() 188 if iter.nextToken() != ':' { 189 iter.ReportError("ReadMapCB", "expect : after object field, but found "+string([]byte{c})) 190 iter.decrementDepth() 191 return false 192 } 193 if !callback(iter, field) { 194 iter.decrementDepth() 195 return false 196 } 197 c = iter.nextToken() 198 } 199 if c != '}' { 200 iter.ReportError("ReadMapCB", `object not ended with }`) 201 iter.decrementDepth() 202 return false 203 } 204 return iter.decrementDepth() 205 } 206 if c == '}' { 207 return iter.decrementDepth() 208 } 209 iter.ReportError("ReadMapCB", `expect " after {, but found `+string([]byte{c})) 210 iter.decrementDepth() 211 return false 212 } 213 if c == 'n' { 214 iter.skipThreeBytes('u', 'l', 'l') 215 return true // null 216 } 217 iter.ReportError("ReadMapCB", `expect { or n, but found `+string([]byte{c})) 218 return false 219 } 220 221 func (iter *Iterator) readObjectStart() bool { 222 c := iter.nextToken() 223 if c == '{' { 224 c = iter.nextToken() 225 if c == '}' { 226 return false 227 } 228 iter.unreadByte() 229 return true 230 } else if c == 'n' { 231 iter.skipThreeBytes('u', 'l', 'l') 232 return false 233 } 234 iter.ReportError("readObjectStart", "expect { or n, but found "+string([]byte{c})) 235 return false 236 } 237 238 func (iter *Iterator) readObjectFieldAsBytes() (ret []byte) { 239 str := iter.ReadStringAsSlice() 240 if iter.skipWhitespacesWithoutLoadMore() { 241 if ret == nil { 242 ret = make([]byte, len(str)) 243 copy(ret, str) 244 } 245 if !iter.loadMore() { 246 return 247 } 248 } 249 if iter.buf[iter.head] != ':' { 250 iter.ReportError("readObjectFieldAsBytes", "expect : after object field, but found "+string([]byte{iter.buf[iter.head]})) 251 return 252 } 253 iter.head++ 254 if iter.skipWhitespacesWithoutLoadMore() { 255 if ret == nil { 256 ret = make([]byte, len(str)) 257 copy(ret, str) 258 } 259 if !iter.loadMore() { 260 return 261 } 262 } 263 if ret == nil { 264 return str 265 } 266 return ret 267 }