...

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

Documentation: github.com/json-iterator/go

     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  

View as plain text