reflect_map.go (9162B)
1 package jsoniter 2 3 import ( 4 "fmt" 5 "github.com/modern-go/reflect2" 6 "io" 7 "reflect" 8 "sort" 9 "unsafe" 10 ) 11 12 func decoderOfMap(ctx *ctx, typ reflect2.Type) ValDecoder { 13 mapType := typ.(*reflect2.UnsafeMapType) 14 keyDecoder := decoderOfMapKey(ctx.append("[mapKey]"), mapType.Key()) 15 elemDecoder := decoderOfType(ctx.append("[mapElem]"), mapType.Elem()) 16 return &mapDecoder{ 17 mapType: mapType, 18 keyType: mapType.Key(), 19 elemType: mapType.Elem(), 20 keyDecoder: keyDecoder, 21 elemDecoder: elemDecoder, 22 } 23 } 24 25 func encoderOfMap(ctx *ctx, typ reflect2.Type) ValEncoder { 26 mapType := typ.(*reflect2.UnsafeMapType) 27 if ctx.sortMapKeys { 28 return &sortKeysMapEncoder{ 29 mapType: mapType, 30 keyEncoder: encoderOfMapKey(ctx.append("[mapKey]"), mapType.Key()), 31 elemEncoder: encoderOfType(ctx.append("[mapElem]"), mapType.Elem()), 32 } 33 } 34 return &mapEncoder{ 35 mapType: mapType, 36 keyEncoder: encoderOfMapKey(ctx.append("[mapKey]"), mapType.Key()), 37 elemEncoder: encoderOfType(ctx.append("[mapElem]"), mapType.Elem()), 38 } 39 } 40 41 func decoderOfMapKey(ctx *ctx, typ reflect2.Type) ValDecoder { 42 decoder := ctx.decoderExtension.CreateMapKeyDecoder(typ) 43 if decoder != nil { 44 return decoder 45 } 46 for _, extension := range ctx.extraExtensions { 47 decoder := extension.CreateMapKeyDecoder(typ) 48 if decoder != nil { 49 return decoder 50 } 51 } 52 53 ptrType := reflect2.PtrTo(typ) 54 if ptrType.Implements(unmarshalerType) { 55 return &referenceDecoder{ 56 &unmarshalerDecoder{ 57 valType: ptrType, 58 }, 59 } 60 } 61 if typ.Implements(unmarshalerType) { 62 return &unmarshalerDecoder{ 63 valType: typ, 64 } 65 } 66 if ptrType.Implements(textUnmarshalerType) { 67 return &referenceDecoder{ 68 &textUnmarshalerDecoder{ 69 valType: ptrType, 70 }, 71 } 72 } 73 if typ.Implements(textUnmarshalerType) { 74 return &textUnmarshalerDecoder{ 75 valType: typ, 76 } 77 } 78 79 switch typ.Kind() { 80 case reflect.String: 81 return decoderOfType(ctx, reflect2.DefaultTypeOfKind(reflect.String)) 82 case reflect.Bool, 83 reflect.Uint8, reflect.Int8, 84 reflect.Uint16, reflect.Int16, 85 reflect.Uint32, reflect.Int32, 86 reflect.Uint64, reflect.Int64, 87 reflect.Uint, reflect.Int, 88 reflect.Float32, reflect.Float64, 89 reflect.Uintptr: 90 typ = reflect2.DefaultTypeOfKind(typ.Kind()) 91 return &numericMapKeyDecoder{decoderOfType(ctx, typ)} 92 default: 93 return &lazyErrorDecoder{err: fmt.Errorf("unsupported map key type: %v", typ)} 94 } 95 } 96 97 func encoderOfMapKey(ctx *ctx, typ reflect2.Type) ValEncoder { 98 encoder := ctx.encoderExtension.CreateMapKeyEncoder(typ) 99 if encoder != nil { 100 return encoder 101 } 102 for _, extension := range ctx.extraExtensions { 103 encoder := extension.CreateMapKeyEncoder(typ) 104 if encoder != nil { 105 return encoder 106 } 107 } 108 109 if typ == textMarshalerType { 110 return &directTextMarshalerEncoder{ 111 stringEncoder: ctx.EncoderOf(reflect2.TypeOf("")), 112 } 113 } 114 if typ.Implements(textMarshalerType) { 115 return &textMarshalerEncoder{ 116 valType: typ, 117 stringEncoder: ctx.EncoderOf(reflect2.TypeOf("")), 118 } 119 } 120 121 switch typ.Kind() { 122 case reflect.String: 123 return encoderOfType(ctx, reflect2.DefaultTypeOfKind(reflect.String)) 124 case reflect.Bool, 125 reflect.Uint8, reflect.Int8, 126 reflect.Uint16, reflect.Int16, 127 reflect.Uint32, reflect.Int32, 128 reflect.Uint64, reflect.Int64, 129 reflect.Uint, reflect.Int, 130 reflect.Float32, reflect.Float64, 131 reflect.Uintptr: 132 typ = reflect2.DefaultTypeOfKind(typ.Kind()) 133 return &numericMapKeyEncoder{encoderOfType(ctx, typ)} 134 default: 135 if typ.Kind() == reflect.Interface { 136 return &dynamicMapKeyEncoder{ctx, typ} 137 } 138 return &lazyErrorEncoder{err: fmt.Errorf("unsupported map key type: %v", typ)} 139 } 140 } 141 142 type mapDecoder struct { 143 mapType *reflect2.UnsafeMapType 144 keyType reflect2.Type 145 elemType reflect2.Type 146 keyDecoder ValDecoder 147 elemDecoder ValDecoder 148 } 149 150 func (decoder *mapDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { 151 mapType := decoder.mapType 152 c := iter.nextToken() 153 if c == 'n' { 154 iter.skipThreeBytes('u', 'l', 'l') 155 *(*unsafe.Pointer)(ptr) = nil 156 mapType.UnsafeSet(ptr, mapType.UnsafeNew()) 157 return 158 } 159 if mapType.UnsafeIsNil(ptr) { 160 mapType.UnsafeSet(ptr, mapType.UnsafeMakeMap(0)) 161 } 162 if c != '{' { 163 iter.ReportError("ReadMapCB", `expect { or n, but found `+string([]byte{c})) 164 return 165 } 166 c = iter.nextToken() 167 if c == '}' { 168 return 169 } 170 iter.unreadByte() 171 key := decoder.keyType.UnsafeNew() 172 decoder.keyDecoder.Decode(key, iter) 173 c = iter.nextToken() 174 if c != ':' { 175 iter.ReportError("ReadMapCB", "expect : after object field, but found "+string([]byte{c})) 176 return 177 } 178 elem := decoder.elemType.UnsafeNew() 179 decoder.elemDecoder.Decode(elem, iter) 180 decoder.mapType.UnsafeSetIndex(ptr, key, elem) 181 for c = iter.nextToken(); c == ','; c = iter.nextToken() { 182 key := decoder.keyType.UnsafeNew() 183 decoder.keyDecoder.Decode(key, iter) 184 c = iter.nextToken() 185 if c != ':' { 186 iter.ReportError("ReadMapCB", "expect : after object field, but found "+string([]byte{c})) 187 return 188 } 189 elem := decoder.elemType.UnsafeNew() 190 decoder.elemDecoder.Decode(elem, iter) 191 decoder.mapType.UnsafeSetIndex(ptr, key, elem) 192 } 193 if c != '}' { 194 iter.ReportError("ReadMapCB", `expect }, but found `+string([]byte{c})) 195 } 196 } 197 198 type numericMapKeyDecoder struct { 199 decoder ValDecoder 200 } 201 202 func (decoder *numericMapKeyDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { 203 c := iter.nextToken() 204 if c != '"' { 205 iter.ReportError("ReadMapCB", `expect ", but found `+string([]byte{c})) 206 return 207 } 208 decoder.decoder.Decode(ptr, iter) 209 c = iter.nextToken() 210 if c != '"' { 211 iter.ReportError("ReadMapCB", `expect ", but found `+string([]byte{c})) 212 return 213 } 214 } 215 216 type numericMapKeyEncoder struct { 217 encoder ValEncoder 218 } 219 220 func (encoder *numericMapKeyEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { 221 stream.writeByte('"') 222 encoder.encoder.Encode(ptr, stream) 223 stream.writeByte('"') 224 } 225 226 func (encoder *numericMapKeyEncoder) IsEmpty(ptr unsafe.Pointer) bool { 227 return false 228 } 229 230 type dynamicMapKeyEncoder struct { 231 ctx *ctx 232 valType reflect2.Type 233 } 234 235 func (encoder *dynamicMapKeyEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { 236 obj := encoder.valType.UnsafeIndirect(ptr) 237 encoderOfMapKey(encoder.ctx, reflect2.TypeOf(obj)).Encode(reflect2.PtrOf(obj), stream) 238 } 239 240 func (encoder *dynamicMapKeyEncoder) IsEmpty(ptr unsafe.Pointer) bool { 241 obj := encoder.valType.UnsafeIndirect(ptr) 242 return encoderOfMapKey(encoder.ctx, reflect2.TypeOf(obj)).IsEmpty(reflect2.PtrOf(obj)) 243 } 244 245 type mapEncoder struct { 246 mapType *reflect2.UnsafeMapType 247 keyEncoder ValEncoder 248 elemEncoder ValEncoder 249 } 250 251 func (encoder *mapEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { 252 if *(*unsafe.Pointer)(ptr) == nil { 253 stream.WriteNil() 254 return 255 } 256 stream.WriteObjectStart() 257 iter := encoder.mapType.UnsafeIterate(ptr) 258 for i := 0; iter.HasNext(); i++ { 259 if i != 0 { 260 stream.WriteMore() 261 } 262 key, elem := iter.UnsafeNext() 263 encoder.keyEncoder.Encode(key, stream) 264 if stream.indention > 0 { 265 stream.writeTwoBytes(byte(':'), byte(' ')) 266 } else { 267 stream.writeByte(':') 268 } 269 encoder.elemEncoder.Encode(elem, stream) 270 } 271 stream.WriteObjectEnd() 272 } 273 274 func (encoder *mapEncoder) IsEmpty(ptr unsafe.Pointer) bool { 275 iter := encoder.mapType.UnsafeIterate(ptr) 276 return !iter.HasNext() 277 } 278 279 type sortKeysMapEncoder struct { 280 mapType *reflect2.UnsafeMapType 281 keyEncoder ValEncoder 282 elemEncoder ValEncoder 283 } 284 285 func (encoder *sortKeysMapEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { 286 if *(*unsafe.Pointer)(ptr) == nil { 287 stream.WriteNil() 288 return 289 } 290 stream.WriteObjectStart() 291 mapIter := encoder.mapType.UnsafeIterate(ptr) 292 subStream := stream.cfg.BorrowStream(nil) 293 subStream.Attachment = stream.Attachment 294 subIter := stream.cfg.BorrowIterator(nil) 295 keyValues := encodedKeyValues{} 296 for mapIter.HasNext() { 297 key, elem := mapIter.UnsafeNext() 298 subStreamIndex := subStream.Buffered() 299 encoder.keyEncoder.Encode(key, subStream) 300 if subStream.Error != nil && subStream.Error != io.EOF && stream.Error == nil { 301 stream.Error = subStream.Error 302 } 303 encodedKey := subStream.Buffer()[subStreamIndex:] 304 subIter.ResetBytes(encodedKey) 305 decodedKey := subIter.ReadString() 306 if stream.indention > 0 { 307 subStream.writeTwoBytes(byte(':'), byte(' ')) 308 } else { 309 subStream.writeByte(':') 310 } 311 encoder.elemEncoder.Encode(elem, subStream) 312 keyValues = append(keyValues, encodedKV{ 313 key: decodedKey, 314 keyValue: subStream.Buffer()[subStreamIndex:], 315 }) 316 } 317 sort.Sort(keyValues) 318 for i, keyValue := range keyValues { 319 if i != 0 { 320 stream.WriteMore() 321 } 322 stream.Write(keyValue.keyValue) 323 } 324 if subStream.Error != nil && stream.Error == nil { 325 stream.Error = subStream.Error 326 } 327 stream.WriteObjectEnd() 328 stream.cfg.ReturnStream(subStream) 329 stream.cfg.ReturnIterator(subIter) 330 } 331 332 func (encoder *sortKeysMapEncoder) IsEmpty(ptr unsafe.Pointer) bool { 333 iter := encoder.mapType.UnsafeIterate(ptr) 334 return !iter.HasNext() 335 } 336 337 type encodedKeyValues []encodedKV 338 339 type encodedKV struct { 340 key string 341 keyValue []byte 342 } 343 344 func (sv encodedKeyValues) Len() int { return len(sv) } 345 func (sv encodedKeyValues) Swap(i, j int) { sv[i], sv[j] = sv[j], sv[i] } 346 func (sv encodedKeyValues) Less(i, j int) bool { return sv[i].key < sv[j].key }