package jsoniter import ( "unsafe" "reflect" ) type mapDecoder struct { mapType reflect.Type elemType reflect.Type elemDecoder Decoder mapInterface emptyInterface } func (decoder *mapDecoder) decode(ptr unsafe.Pointer, iter *Iterator) { // dark magic to cast unsafe.Pointer back to interface{} using reflect.Type mapInterface := decoder.mapInterface mapInterface.word = ptr realInterface := (*interface{})(unsafe.Pointer(&mapInterface)) realVal := reflect.ValueOf(*realInterface).Elem() if realVal.IsNil() { realVal.Set(reflect.MakeMap(realVal.Type())) } for field := iter.ReadObject(); field != ""; field = iter.ReadObject() { elem := reflect.New(decoder.elemType) decoder.elemDecoder.decode(unsafe.Pointer(elem.Pointer()), iter) // to put into map, we have to use reflection realVal.SetMapIndex(reflect.ValueOf(string([]byte(field))), elem.Elem()) } } type mapEncoder struct { mapType reflect.Type elemType reflect.Type elemEncoder Encoder mapInterface emptyInterface } func (encoder *mapEncoder) encode(ptr unsafe.Pointer, stream *Stream) { mapInterface := encoder.mapInterface mapInterface.word = ptr realInterface := (*interface{})(unsafe.Pointer(&mapInterface)) realVal := reflect.ValueOf(*realInterface) stream.WriteObjectStart() for i, key := range realVal.MapKeys() { if i != 0 { stream.WriteMore() } stream.WriteObjectField(key.String()) val := realVal.MapIndex(key).Interface() encoder.elemEncoder.encodeInterface(val, stream) } stream.WriteObjectEnd() } func (encoder *mapEncoder) encodeInterface(val interface{}, stream *Stream) { writeToStream(val, stream, encoder) } func (encoder *mapEncoder) isEmpty(ptr unsafe.Pointer) bool { mapInterface := encoder.mapInterface mapInterface.word = ptr realInterface := (*interface{})(unsafe.Pointer(&mapInterface)) realVal := reflect.ValueOf(*realInterface) return realVal.Len() == 0 } type mapInterfaceEncoder struct { mapType reflect.Type elemType reflect.Type elemEncoder Encoder mapInterface emptyInterface } func (encoder *mapInterfaceEncoder) encode(ptr unsafe.Pointer, stream *Stream) { mapInterface := encoder.mapInterface mapInterface.word = ptr realInterface := (*interface{})(unsafe.Pointer(&mapInterface)) realVal := reflect.ValueOf(*realInterface) stream.WriteObjectStart() for i, key := range realVal.MapKeys() { if i != 0 { stream.WriteMore() } stream.WriteObjectField(key.String()) val := realVal.MapIndex(key).Interface() encoder.elemEncoder.encode(unsafe.Pointer(&val), stream) } stream.WriteObjectEnd() } func (encoder *mapInterfaceEncoder) encodeInterface(val interface{}, stream *Stream) { writeToStream(val, stream, encoder) } func (encoder *mapInterfaceEncoder) isEmpty(ptr unsafe.Pointer) bool { mapInterface := encoder.mapInterface mapInterface.word = ptr realInterface := (*interface{})(unsafe.Pointer(&mapInterface)) realVal := reflect.ValueOf(*realInterface) return realVal.Len() == 0 }