reflect_map.go raw

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