...
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
13 func (n Number) String() string { return string(n) }
14
15
16 func (n Number) Float64() (float64, error) {
17 return strconv.ParseFloat(string(n), 64)
18 }
19
20
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 }
113
View as plain text