reflect_native.go (11153B)
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 }