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 }
454
View as plain text