podman

Форк
0
/
reflect_json_number.go 
112 строк · 2.6 Кб
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
}
113

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.