reflect_json_number.go (2694B)
1 package jsoniter 2 3 import ( 4 "encoding/json" 5 "github.com/modern-go/reflect2" 6 "strconv" 7 "unsafe" 8 ) 9 10 type Number string 11 12 // String returns the literal text of the number. 13 func (n Number) String() string { return string(n) } 14 15 // Float64 returns the number as a float64. 16 func (n Number) Float64() (float64, error) { 17 return strconv.ParseFloat(string(n), 64) 18 } 19 20 // Int64 returns the number as an int64. 21 func (n Number) Int64() (int64, error) { 22 return strconv.ParseInt(string(n), 10, 64) 23 } 24 25 func CastJsonNumber(val interface{}) (string, bool) { 26 switch typedVal := val.(type) { 27 case json.Number: 28 return string(typedVal), true 29 case Number: 30 return string(typedVal), true 31 } 32 return "", false 33 } 34 35 var jsonNumberType = reflect2.TypeOfPtr((*json.Number)(nil)).Elem() 36 var jsoniterNumberType = reflect2.TypeOfPtr((*Number)(nil)).Elem() 37 38 func createDecoderOfJsonNumber(ctx *ctx, typ reflect2.Type) ValDecoder { 39 if typ.AssignableTo(jsonNumberType) { 40 return &jsonNumberCodec{} 41 } 42 if typ.AssignableTo(jsoniterNumberType) { 43 return &jsoniterNumberCodec{} 44 } 45 return nil 46 } 47 48 func createEncoderOfJsonNumber(ctx *ctx, typ reflect2.Type) ValEncoder { 49 if typ.AssignableTo(jsonNumberType) { 50 return &jsonNumberCodec{} 51 } 52 if typ.AssignableTo(jsoniterNumberType) { 53 return &jsoniterNumberCodec{} 54 } 55 return nil 56 } 57 58 type jsonNumberCodec struct { 59 } 60 61 func (codec *jsonNumberCodec) Decode(ptr unsafe.Pointer, iter *Iterator) { 62 switch iter.WhatIsNext() { 63 case StringValue: 64 *((*json.Number)(ptr)) = json.Number(iter.ReadString()) 65 case NilValue: 66 iter.skipFourBytes('n', 'u', 'l', 'l') 67 *((*json.Number)(ptr)) = "" 68 default: 69 *((*json.Number)(ptr)) = json.Number([]byte(iter.readNumberAsString())) 70 } 71 } 72 73 func (codec *jsonNumberCodec) Encode(ptr unsafe.Pointer, stream *Stream) { 74 number := *((*json.Number)(ptr)) 75 if len(number) == 0 { 76 stream.writeByte('0') 77 } else { 78 stream.WriteRaw(string(number)) 79 } 80 } 81 82 func (codec *jsonNumberCodec) IsEmpty(ptr unsafe.Pointer) bool { 83 return len(*((*json.Number)(ptr))) == 0 84 } 85 86 type jsoniterNumberCodec struct { 87 } 88 89 func (codec *jsoniterNumberCodec) Decode(ptr unsafe.Pointer, iter *Iterator) { 90 switch iter.WhatIsNext() { 91 case StringValue: 92 *((*Number)(ptr)) = Number(iter.ReadString()) 93 case NilValue: 94 iter.skipFourBytes('n', 'u', 'l', 'l') 95 *((*Number)(ptr)) = "" 96 default: 97 *((*Number)(ptr)) = Number([]byte(iter.readNumberAsString())) 98 } 99 } 100 101 func (codec *jsoniterNumberCodec) Encode(ptr unsafe.Pointer, stream *Stream) { 102 number := *((*Number)(ptr)) 103 if len(number) == 0 { 104 stream.writeByte('0') 105 } else { 106 stream.WriteRaw(string(number)) 107 } 108 } 109 110 func (codec *jsoniterNumberCodec) IsEmpty(ptr unsafe.Pointer) bool { 111 return len(*((*Number)(ptr))) == 0 112 }