reflect_native.go raw

   1  package jsoniter
   2  
   3  import (
   4  	"encoding/base64"
   5  	"reflect"
   6  	"strconv"
   7  	"unsafe"
   8  
   9  	"github.com/modern-go/reflect2"
  10  )
  11  
  12  const ptrSize = 32 << uintptr(^uintptr(0)>>63)
  13  
  14  func createEncoderOfNative(ctx *ctx, typ reflect2.Type) ValEncoder {
  15  	if typ.Kind() == reflect.Slice && typ.(reflect2.SliceType).Elem().Kind() == reflect.Uint8 {
  16  		sliceDecoder := decoderOfSlice(ctx, typ)
  17  		return &base64Codec{sliceDecoder: sliceDecoder}
  18  	}
  19  	typeName := typ.String()
  20  	kind := typ.Kind()
  21  	switch kind {
  22  	case reflect.String:
  23  		if typeName != "string" {
  24  			return encoderOfType(ctx, reflect2.TypeOfPtr((*string)(nil)).Elem())
  25  		}
  26  		return &stringCodec{}
  27  	case reflect.Int:
  28  		if typeName != "int" {
  29  			return encoderOfType(ctx, reflect2.TypeOfPtr((*int)(nil)).Elem())
  30  		}
  31  		if strconv.IntSize == 32 {
  32  			return &int32Codec{}
  33  		}
  34  		return &int64Codec{}
  35  	case reflect.Int8:
  36  		if typeName != "int8" {
  37  			return encoderOfType(ctx, reflect2.TypeOfPtr((*int8)(nil)).Elem())
  38  		}
  39  		return &int8Codec{}
  40  	case reflect.Int16:
  41  		if typeName != "int16" {
  42  			return encoderOfType(ctx, reflect2.TypeOfPtr((*int16)(nil)).Elem())
  43  		}
  44  		return &int16Codec{}
  45  	case reflect.Int32:
  46  		if typeName != "int32" {
  47  			return encoderOfType(ctx, reflect2.TypeOfPtr((*int32)(nil)).Elem())
  48  		}
  49  		return &int32Codec{}
  50  	case reflect.Int64:
  51  		if typeName != "int64" {
  52  			return encoderOfType(ctx, reflect2.TypeOfPtr((*int64)(nil)).Elem())
  53  		}
  54  		return &int64Codec{}
  55  	case reflect.Uint:
  56  		if typeName != "uint" {
  57  			return encoderOfType(ctx, reflect2.TypeOfPtr((*uint)(nil)).Elem())
  58  		}
  59  		if strconv.IntSize == 32 {
  60  			return &uint32Codec{}
  61  		}
  62  		return &uint64Codec{}
  63  	case reflect.Uint8:
  64  		if typeName != "uint8" {
  65  			return encoderOfType(ctx, reflect2.TypeOfPtr((*uint8)(nil)).Elem())
  66  		}
  67  		return &uint8Codec{}
  68  	case reflect.Uint16:
  69  		if typeName != "uint16" {
  70  			return encoderOfType(ctx, reflect2.TypeOfPtr((*uint16)(nil)).Elem())
  71  		}
  72  		return &uint16Codec{}
  73  	case reflect.Uint32:
  74  		if typeName != "uint32" {
  75  			return encoderOfType(ctx, reflect2.TypeOfPtr((*uint32)(nil)).Elem())
  76  		}
  77  		return &uint32Codec{}
  78  	case reflect.Uintptr:
  79  		if typeName != "uintptr" {
  80  			return encoderOfType(ctx, reflect2.TypeOfPtr((*uintptr)(nil)).Elem())
  81  		}
  82  		if ptrSize == 32 {
  83  			return &uint32Codec{}
  84  		}
  85  		return &uint64Codec{}
  86  	case reflect.Uint64:
  87  		if typeName != "uint64" {
  88  			return encoderOfType(ctx, reflect2.TypeOfPtr((*uint64)(nil)).Elem())
  89  		}
  90  		return &uint64Codec{}
  91  	case reflect.Float32:
  92  		if typeName != "float32" {
  93  			return encoderOfType(ctx, reflect2.TypeOfPtr((*float32)(nil)).Elem())
  94  		}
  95  		return &float32Codec{}
  96  	case reflect.Float64:
  97  		if typeName != "float64" {
  98  			return encoderOfType(ctx, reflect2.TypeOfPtr((*float64)(nil)).Elem())
  99  		}
 100  		return &float64Codec{}
 101  	case reflect.Bool:
 102  		if typeName != "bool" {
 103  			return encoderOfType(ctx, reflect2.TypeOfPtr((*bool)(nil)).Elem())
 104  		}
 105  		return &boolCodec{}
 106  	}
 107  	return nil
 108  }
 109  
 110  func createDecoderOfNative(ctx *ctx, typ reflect2.Type) ValDecoder {
 111  	if typ.Kind() == reflect.Slice && typ.(reflect2.SliceType).Elem().Kind() == reflect.Uint8 {
 112  		sliceDecoder := decoderOfSlice(ctx, typ)
 113  		return &base64Codec{sliceDecoder: sliceDecoder}
 114  	}
 115  	typeName := typ.String()
 116  	switch typ.Kind() {
 117  	case reflect.String:
 118  		if typeName != "string" {
 119  			return decoderOfType(ctx, reflect2.TypeOfPtr((*string)(nil)).Elem())
 120  		}
 121  		return &stringCodec{}
 122  	case reflect.Int:
 123  		if typeName != "int" {
 124  			return decoderOfType(ctx, reflect2.TypeOfPtr((*int)(nil)).Elem())
 125  		}
 126  		if strconv.IntSize == 32 {
 127  			return &int32Codec{}
 128  		}
 129  		return &int64Codec{}
 130  	case reflect.Int8:
 131  		if typeName != "int8" {
 132  			return decoderOfType(ctx, reflect2.TypeOfPtr((*int8)(nil)).Elem())
 133  		}
 134  		return &int8Codec{}
 135  	case reflect.Int16:
 136  		if typeName != "int16" {
 137  			return decoderOfType(ctx, reflect2.TypeOfPtr((*int16)(nil)).Elem())
 138  		}
 139  		return &int16Codec{}
 140  	case reflect.Int32:
 141  		if typeName != "int32" {
 142  			return decoderOfType(ctx, reflect2.TypeOfPtr((*int32)(nil)).Elem())
 143  		}
 144  		return &int32Codec{}
 145  	case reflect.Int64:
 146  		if typeName != "int64" {
 147  			return decoderOfType(ctx, reflect2.TypeOfPtr((*int64)(nil)).Elem())
 148  		}
 149  		return &int64Codec{}
 150  	case reflect.Uint:
 151  		if typeName != "uint" {
 152  			return decoderOfType(ctx, reflect2.TypeOfPtr((*uint)(nil)).Elem())
 153  		}
 154  		if strconv.IntSize == 32 {
 155  			return &uint32Codec{}
 156  		}
 157  		return &uint64Codec{}
 158  	case reflect.Uint8:
 159  		if typeName != "uint8" {
 160  			return decoderOfType(ctx, reflect2.TypeOfPtr((*uint8)(nil)).Elem())
 161  		}
 162  		return &uint8Codec{}
 163  	case reflect.Uint16:
 164  		if typeName != "uint16" {
 165  			return decoderOfType(ctx, reflect2.TypeOfPtr((*uint16)(nil)).Elem())
 166  		}
 167  		return &uint16Codec{}
 168  	case reflect.Uint32:
 169  		if typeName != "uint32" {
 170  			return decoderOfType(ctx, reflect2.TypeOfPtr((*uint32)(nil)).Elem())
 171  		}
 172  		return &uint32Codec{}
 173  	case reflect.Uintptr:
 174  		if typeName != "uintptr" {
 175  			return decoderOfType(ctx, reflect2.TypeOfPtr((*uintptr)(nil)).Elem())
 176  		}
 177  		if ptrSize == 32 {
 178  			return &uint32Codec{}
 179  		}
 180  		return &uint64Codec{}
 181  	case reflect.Uint64:
 182  		if typeName != "uint64" {
 183  			return decoderOfType(ctx, reflect2.TypeOfPtr((*uint64)(nil)).Elem())
 184  		}
 185  		return &uint64Codec{}
 186  	case reflect.Float32:
 187  		if typeName != "float32" {
 188  			return decoderOfType(ctx, reflect2.TypeOfPtr((*float32)(nil)).Elem())
 189  		}
 190  		return &float32Codec{}
 191  	case reflect.Float64:
 192  		if typeName != "float64" {
 193  			return decoderOfType(ctx, reflect2.TypeOfPtr((*float64)(nil)).Elem())
 194  		}
 195  		return &float64Codec{}
 196  	case reflect.Bool:
 197  		if typeName != "bool" {
 198  			return decoderOfType(ctx, reflect2.TypeOfPtr((*bool)(nil)).Elem())
 199  		}
 200  		return &boolCodec{}
 201  	}
 202  	return nil
 203  }
 204  
 205  type stringCodec struct {
 206  }
 207  
 208  func (codec *stringCodec) Decode(ptr unsafe.Pointer, iter *Iterator) {
 209  	*((*string)(ptr)) = iter.ReadString()
 210  }
 211  
 212  func (codec *stringCodec) Encode(ptr unsafe.Pointer, stream *Stream) {
 213  	str := *((*string)(ptr))
 214  	stream.WriteString(str)
 215  }
 216  
 217  func (codec *stringCodec) IsEmpty(ptr unsafe.Pointer) bool {
 218  	return *((*string)(ptr)) == ""
 219  }
 220  
 221  type int8Codec struct {
 222  }
 223  
 224  func (codec *int8Codec) Decode(ptr unsafe.Pointer, iter *Iterator) {
 225  	if !iter.ReadNil() {
 226  		*((*int8)(ptr)) = iter.ReadInt8()
 227  	}
 228  }
 229  
 230  func (codec *int8Codec) Encode(ptr unsafe.Pointer, stream *Stream) {
 231  	stream.WriteInt8(*((*int8)(ptr)))
 232  }
 233  
 234  func (codec *int8Codec) IsEmpty(ptr unsafe.Pointer) bool {
 235  	return *((*int8)(ptr)) == 0
 236  }
 237  
 238  type int16Codec struct {
 239  }
 240  
 241  func (codec *int16Codec) Decode(ptr unsafe.Pointer, iter *Iterator) {
 242  	if !iter.ReadNil() {
 243  		*((*int16)(ptr)) = iter.ReadInt16()
 244  	}
 245  }
 246  
 247  func (codec *int16Codec) Encode(ptr unsafe.Pointer, stream *Stream) {
 248  	stream.WriteInt16(*((*int16)(ptr)))
 249  }
 250  
 251  func (codec *int16Codec) IsEmpty(ptr unsafe.Pointer) bool {
 252  	return *((*int16)(ptr)) == 0
 253  }
 254  
 255  type int32Codec struct {
 256  }
 257  
 258  func (codec *int32Codec) Decode(ptr unsafe.Pointer, iter *Iterator) {
 259  	if !iter.ReadNil() {
 260  		*((*int32)(ptr)) = iter.ReadInt32()
 261  	}
 262  }
 263  
 264  func (codec *int32Codec) Encode(ptr unsafe.Pointer, stream *Stream) {
 265  	stream.WriteInt32(*((*int32)(ptr)))
 266  }
 267  
 268  func (codec *int32Codec) IsEmpty(ptr unsafe.Pointer) bool {
 269  	return *((*int32)(ptr)) == 0
 270  }
 271  
 272  type int64Codec struct {
 273  }
 274  
 275  func (codec *int64Codec) Decode(ptr unsafe.Pointer, iter *Iterator) {
 276  	if !iter.ReadNil() {
 277  		*((*int64)(ptr)) = iter.ReadInt64()
 278  	}
 279  }
 280  
 281  func (codec *int64Codec) Encode(ptr unsafe.Pointer, stream *Stream) {
 282  	stream.WriteInt64(*((*int64)(ptr)))
 283  }
 284  
 285  func (codec *int64Codec) IsEmpty(ptr unsafe.Pointer) bool {
 286  	return *((*int64)(ptr)) == 0
 287  }
 288  
 289  type uint8Codec struct {
 290  }
 291  
 292  func (codec *uint8Codec) Decode(ptr unsafe.Pointer, iter *Iterator) {
 293  	if !iter.ReadNil() {
 294  		*((*uint8)(ptr)) = iter.ReadUint8()
 295  	}
 296  }
 297  
 298  func (codec *uint8Codec) Encode(ptr unsafe.Pointer, stream *Stream) {
 299  	stream.WriteUint8(*((*uint8)(ptr)))
 300  }
 301  
 302  func (codec *uint8Codec) IsEmpty(ptr unsafe.Pointer) bool {
 303  	return *((*uint8)(ptr)) == 0
 304  }
 305  
 306  type uint16Codec struct {
 307  }
 308  
 309  func (codec *uint16Codec) Decode(ptr unsafe.Pointer, iter *Iterator) {
 310  	if !iter.ReadNil() {
 311  		*((*uint16)(ptr)) = iter.ReadUint16()
 312  	}
 313  }
 314  
 315  func (codec *uint16Codec) Encode(ptr unsafe.Pointer, stream *Stream) {
 316  	stream.WriteUint16(*((*uint16)(ptr)))
 317  }
 318  
 319  func (codec *uint16Codec) IsEmpty(ptr unsafe.Pointer) bool {
 320  	return *((*uint16)(ptr)) == 0
 321  }
 322  
 323  type uint32Codec struct {
 324  }
 325  
 326  func (codec *uint32Codec) Decode(ptr unsafe.Pointer, iter *Iterator) {
 327  	if !iter.ReadNil() {
 328  		*((*uint32)(ptr)) = iter.ReadUint32()
 329  	}
 330  }
 331  
 332  func (codec *uint32Codec) Encode(ptr unsafe.Pointer, stream *Stream) {
 333  	stream.WriteUint32(*((*uint32)(ptr)))
 334  }
 335  
 336  func (codec *uint32Codec) IsEmpty(ptr unsafe.Pointer) bool {
 337  	return *((*uint32)(ptr)) == 0
 338  }
 339  
 340  type uint64Codec struct {
 341  }
 342  
 343  func (codec *uint64Codec) Decode(ptr unsafe.Pointer, iter *Iterator) {
 344  	if !iter.ReadNil() {
 345  		*((*uint64)(ptr)) = iter.ReadUint64()
 346  	}
 347  }
 348  
 349  func (codec *uint64Codec) Encode(ptr unsafe.Pointer, stream *Stream) {
 350  	stream.WriteUint64(*((*uint64)(ptr)))
 351  }
 352  
 353  func (codec *uint64Codec) IsEmpty(ptr unsafe.Pointer) bool {
 354  	return *((*uint64)(ptr)) == 0
 355  }
 356  
 357  type float32Codec struct {
 358  }
 359  
 360  func (codec *float32Codec) Decode(ptr unsafe.Pointer, iter *Iterator) {
 361  	if !iter.ReadNil() {
 362  		*((*float32)(ptr)) = iter.ReadFloat32()
 363  	}
 364  }
 365  
 366  func (codec *float32Codec) Encode(ptr unsafe.Pointer, stream *Stream) {
 367  	stream.WriteFloat32(*((*float32)(ptr)))
 368  }
 369  
 370  func (codec *float32Codec) IsEmpty(ptr unsafe.Pointer) bool {
 371  	return *((*float32)(ptr)) == 0
 372  }
 373  
 374  type float64Codec struct {
 375  }
 376  
 377  func (codec *float64Codec) Decode(ptr unsafe.Pointer, iter *Iterator) {
 378  	if !iter.ReadNil() {
 379  		*((*float64)(ptr)) = iter.ReadFloat64()
 380  	}
 381  }
 382  
 383  func (codec *float64Codec) Encode(ptr unsafe.Pointer, stream *Stream) {
 384  	stream.WriteFloat64(*((*float64)(ptr)))
 385  }
 386  
 387  func (codec *float64Codec) IsEmpty(ptr unsafe.Pointer) bool {
 388  	return *((*float64)(ptr)) == 0
 389  }
 390  
 391  type boolCodec struct {
 392  }
 393  
 394  func (codec *boolCodec) Decode(ptr unsafe.Pointer, iter *Iterator) {
 395  	if !iter.ReadNil() {
 396  		*((*bool)(ptr)) = iter.ReadBool()
 397  	}
 398  }
 399  
 400  func (codec *boolCodec) Encode(ptr unsafe.Pointer, stream *Stream) {
 401  	stream.WriteBool(*((*bool)(ptr)))
 402  }
 403  
 404  func (codec *boolCodec) IsEmpty(ptr unsafe.Pointer) bool {
 405  	return !(*((*bool)(ptr)))
 406  }
 407  
 408  type base64Codec struct {
 409  	sliceType    *reflect2.UnsafeSliceType
 410  	sliceDecoder ValDecoder
 411  }
 412  
 413  func (codec *base64Codec) Decode(ptr unsafe.Pointer, iter *Iterator) {
 414  	if iter.ReadNil() {
 415  		codec.sliceType.UnsafeSetNil(ptr)
 416  		return
 417  	}
 418  	switch iter.WhatIsNext() {
 419  	case StringValue:
 420  		src := iter.ReadString()
 421  		dst, err := base64.StdEncoding.DecodeString(src)
 422  		if err != nil {
 423  			iter.ReportError("decode base64", err.Error())
 424  		} else {
 425  			codec.sliceType.UnsafeSet(ptr, unsafe.Pointer(&dst))
 426  		}
 427  	case ArrayValue:
 428  		codec.sliceDecoder.Decode(ptr, iter)
 429  	default:
 430  		iter.ReportError("base64Codec", "invalid input")
 431  	}
 432  }
 433  
 434  func (codec *base64Codec) Encode(ptr unsafe.Pointer, stream *Stream) {
 435  	if codec.sliceType.UnsafeIsNil(ptr) {
 436  		stream.WriteNil()
 437  		return
 438  	}
 439  	src := *((*[]byte)(ptr))
 440  	encoding := base64.StdEncoding
 441  	stream.writeByte('"')
 442  	if len(src) != 0 {
 443  		size := encoding.EncodedLen(len(src))
 444  		buf := make([]byte, size)
 445  		encoding.Encode(buf, src)
 446  		stream.buf = append(stream.buf, buf...)
 447  	}
 448  	stream.writeByte('"')
 449  }
 450  
 451  func (codec *base64Codec) IsEmpty(ptr unsafe.Pointer) bool {
 452  	return len(*((*[]byte)(ptr))) == 0
 453  }
 454