gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

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 }