blob: f88722d14d198fe477bd69ae05bd405625be974d [file] [log] [blame]
Scott Bakere7144bc2019-10-01 14:16:47 -07001package jsoniter
2
3import (
4 "encoding/base64"
5 "reflect"
6 "strconv"
7 "unsafe"
8
9 "github.com/modern-go/reflect2"
10)
11
12const ptrSize = 32 << uintptr(^uintptr(0)>>63)
13
14func 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
110func 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
205type stringCodec struct {
206}
207
208func (codec *stringCodec) Decode(ptr unsafe.Pointer, iter *Iterator) {
209 *((*string)(ptr)) = iter.ReadString()
210}
211
212func (codec *stringCodec) Encode(ptr unsafe.Pointer, stream *Stream) {
213 str := *((*string)(ptr))
214 stream.WriteString(str)
215}
216
217func (codec *stringCodec) IsEmpty(ptr unsafe.Pointer) bool {
218 return *((*string)(ptr)) == ""
219}
220
221type int8Codec struct {
222}
223
224func (codec *int8Codec) Decode(ptr unsafe.Pointer, iter *Iterator) {
225 if !iter.ReadNil() {
226 *((*int8)(ptr)) = iter.ReadInt8()
227 }
228}
229
230func (codec *int8Codec) Encode(ptr unsafe.Pointer, stream *Stream) {
231 stream.WriteInt8(*((*int8)(ptr)))
232}
233
234func (codec *int8Codec) IsEmpty(ptr unsafe.Pointer) bool {
235 return *((*int8)(ptr)) == 0
236}
237
238type int16Codec struct {
239}
240
241func (codec *int16Codec) Decode(ptr unsafe.Pointer, iter *Iterator) {
242 if !iter.ReadNil() {
243 *((*int16)(ptr)) = iter.ReadInt16()
244 }
245}
246
247func (codec *int16Codec) Encode(ptr unsafe.Pointer, stream *Stream) {
248 stream.WriteInt16(*((*int16)(ptr)))
249}
250
251func (codec *int16Codec) IsEmpty(ptr unsafe.Pointer) bool {
252 return *((*int16)(ptr)) == 0
253}
254
255type int32Codec struct {
256}
257
258func (codec *int32Codec) Decode(ptr unsafe.Pointer, iter *Iterator) {
259 if !iter.ReadNil() {
260 *((*int32)(ptr)) = iter.ReadInt32()
261 }
262}
263
264func (codec *int32Codec) Encode(ptr unsafe.Pointer, stream *Stream) {
265 stream.WriteInt32(*((*int32)(ptr)))
266}
267
268func (codec *int32Codec) IsEmpty(ptr unsafe.Pointer) bool {
269 return *((*int32)(ptr)) == 0
270}
271
272type int64Codec struct {
273}
274
275func (codec *int64Codec) Decode(ptr unsafe.Pointer, iter *Iterator) {
276 if !iter.ReadNil() {
277 *((*int64)(ptr)) = iter.ReadInt64()
278 }
279}
280
281func (codec *int64Codec) Encode(ptr unsafe.Pointer, stream *Stream) {
282 stream.WriteInt64(*((*int64)(ptr)))
283}
284
285func (codec *int64Codec) IsEmpty(ptr unsafe.Pointer) bool {
286 return *((*int64)(ptr)) == 0
287}
288
289type uint8Codec struct {
290}
291
292func (codec *uint8Codec) Decode(ptr unsafe.Pointer, iter *Iterator) {
293 if !iter.ReadNil() {
294 *((*uint8)(ptr)) = iter.ReadUint8()
295 }
296}
297
298func (codec *uint8Codec) Encode(ptr unsafe.Pointer, stream *Stream) {
299 stream.WriteUint8(*((*uint8)(ptr)))
300}
301
302func (codec *uint8Codec) IsEmpty(ptr unsafe.Pointer) bool {
303 return *((*uint8)(ptr)) == 0
304}
305
306type uint16Codec struct {
307}
308
309func (codec *uint16Codec) Decode(ptr unsafe.Pointer, iter *Iterator) {
310 if !iter.ReadNil() {
311 *((*uint16)(ptr)) = iter.ReadUint16()
312 }
313}
314
315func (codec *uint16Codec) Encode(ptr unsafe.Pointer, stream *Stream) {
316 stream.WriteUint16(*((*uint16)(ptr)))
317}
318
319func (codec *uint16Codec) IsEmpty(ptr unsafe.Pointer) bool {
320 return *((*uint16)(ptr)) == 0
321}
322
323type uint32Codec struct {
324}
325
326func (codec *uint32Codec) Decode(ptr unsafe.Pointer, iter *Iterator) {
327 if !iter.ReadNil() {
328 *((*uint32)(ptr)) = iter.ReadUint32()
329 }
330}
331
332func (codec *uint32Codec) Encode(ptr unsafe.Pointer, stream *Stream) {
333 stream.WriteUint32(*((*uint32)(ptr)))
334}
335
336func (codec *uint32Codec) IsEmpty(ptr unsafe.Pointer) bool {
337 return *((*uint32)(ptr)) == 0
338}
339
340type uint64Codec struct {
341}
342
343func (codec *uint64Codec) Decode(ptr unsafe.Pointer, iter *Iterator) {
344 if !iter.ReadNil() {
345 *((*uint64)(ptr)) = iter.ReadUint64()
346 }
347}
348
349func (codec *uint64Codec) Encode(ptr unsafe.Pointer, stream *Stream) {
350 stream.WriteUint64(*((*uint64)(ptr)))
351}
352
353func (codec *uint64Codec) IsEmpty(ptr unsafe.Pointer) bool {
354 return *((*uint64)(ptr)) == 0
355}
356
357type float32Codec struct {
358}
359
360func (codec *float32Codec) Decode(ptr unsafe.Pointer, iter *Iterator) {
361 if !iter.ReadNil() {
362 *((*float32)(ptr)) = iter.ReadFloat32()
363 }
364}
365
366func (codec *float32Codec) Encode(ptr unsafe.Pointer, stream *Stream) {
367 stream.WriteFloat32(*((*float32)(ptr)))
368}
369
370func (codec *float32Codec) IsEmpty(ptr unsafe.Pointer) bool {
371 return *((*float32)(ptr)) == 0
372}
373
374type float64Codec struct {
375}
376
377func (codec *float64Codec) Decode(ptr unsafe.Pointer, iter *Iterator) {
378 if !iter.ReadNil() {
379 *((*float64)(ptr)) = iter.ReadFloat64()
380 }
381}
382
383func (codec *float64Codec) Encode(ptr unsafe.Pointer, stream *Stream) {
384 stream.WriteFloat64(*((*float64)(ptr)))
385}
386
387func (codec *float64Codec) IsEmpty(ptr unsafe.Pointer) bool {
388 return *((*float64)(ptr)) == 0
389}
390
391type boolCodec struct {
392}
393
394func (codec *boolCodec) Decode(ptr unsafe.Pointer, iter *Iterator) {
395 if !iter.ReadNil() {
396 *((*bool)(ptr)) = iter.ReadBool()
397 }
398}
399
400func (codec *boolCodec) Encode(ptr unsafe.Pointer, stream *Stream) {
401 stream.WriteBool(*((*bool)(ptr)))
402}
403
404func (codec *boolCodec) IsEmpty(ptr unsafe.Pointer) bool {
405 return !(*((*bool)(ptr)))
406}
407
408type base64Codec struct {
409 sliceType *reflect2.UnsafeSliceType
410 sliceDecoder ValDecoder
411}
412
413func (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
434func (codec *base64Codec) Encode(ptr unsafe.Pointer, stream *Stream) {
Scott Bakerf579f132019-10-24 14:31:41 -0700435 if codec.sliceType.UnsafeIsNil(ptr) {
Scott Bakere7144bc2019-10-01 14:16:47 -0700436 stream.WriteNil()
437 return
438 }
Scott Bakerf579f132019-10-24 14:31:41 -0700439 src := *((*[]byte)(ptr))
Scott Bakere7144bc2019-10-01 14:16:47 -0700440 encoding := base64.StdEncoding
441 stream.writeByte('"')
Scott Bakerf579f132019-10-24 14:31:41 -0700442 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 }
Scott Bakere7144bc2019-10-01 14:16:47 -0700448 stream.writeByte('"')
449}
450
451func (codec *base64Codec) IsEmpty(ptr unsafe.Pointer) bool {
452 return len(*((*[]byte)(ptr))) == 0
453}