...

Source file src/github.com/json-iterator/go/reflect_map.go

Documentation: github.com/json-iterator/go

     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 }
   347  

View as plain text