1package jsoniter 2 3import ( 4 "encoding/json" 5 "github.com/modern-go/reflect2" 6 "strconv" 7 "unsafe" 8) 9 10type Number string 11 12// String returns the literal text of the number. 13func (n Number) String() string { return string(n) } 14 15// Float64 returns the number as a float64. 16func (n Number) Float64() (float64, error) { 17 return strconv.ParseFloat(string(n), 64) 18} 19 20// Int64 returns the number as an int64. 21func (n Number) Int64() (int64, error) { 22 return strconv.ParseInt(string(n), 10, 64) 23} 24 25func 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 35var jsonNumberType = reflect2.TypeOfPtr((*json.Number)(nil)).Elem() 36var jsoniterNumberType = reflect2.TypeOfPtr((*Number)(nil)).Elem() 37 38func 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 48func 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 58type jsonNumberCodec struct { 59} 60 61func (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 73func (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 82func (codec *jsonNumberCodec) IsEmpty(ptr unsafe.Pointer) bool { 83 return len(*((*json.Number)(ptr))) == 0 84} 85 86type jsoniterNumberCodec struct { 87} 88 89func (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 101func (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 110func (codec *jsoniterNumberCodec) IsEmpty(ptr unsafe.Pointer) bool { 111 return len(*((*Number)(ptr))) == 0 112} 113