podman

Форк
0
192 строки · 4.4 Кб
1
// Copyright 2019 The Go Authors. All rights reserved.
2
// Use of this source code is governed by a BSD-style
3
// license that can be found in the LICENSE file.
4

5
package json
6

7
import (
8
	"bytes"
9
	"fmt"
10
	"strconv"
11
)
12

13
// Kind represents a token kind expressible in the JSON format.
14
type Kind uint16
15

16
const (
17
	Invalid Kind = (1 << iota) / 2
18
	EOF
19
	Null
20
	Bool
21
	Number
22
	String
23
	Name
24
	ObjectOpen
25
	ObjectClose
26
	ArrayOpen
27
	ArrayClose
28

29
	// comma is only for parsing in between tokens and
30
	// does not need to be exported.
31
	comma
32
)
33

34
func (k Kind) String() string {
35
	switch k {
36
	case EOF:
37
		return "eof"
38
	case Null:
39
		return "null"
40
	case Bool:
41
		return "bool"
42
	case Number:
43
		return "number"
44
	case String:
45
		return "string"
46
	case ObjectOpen:
47
		return "{"
48
	case ObjectClose:
49
		return "}"
50
	case Name:
51
		return "name"
52
	case ArrayOpen:
53
		return "["
54
	case ArrayClose:
55
		return "]"
56
	case comma:
57
		return ","
58
	}
59
	return "<invalid>"
60
}
61

62
// Token provides a parsed token kind and value.
63
//
64
// Values are provided by the difference accessor methods. The accessor methods
65
// Name, Bool, and ParsedString will panic if called on the wrong kind. There
66
// are different accessor methods for the Number kind for converting to the
67
// appropriate Go numeric type and those methods have the ok return value.
68
type Token struct {
69
	// Token kind.
70
	kind Kind
71
	// pos provides the position of the token in the original input.
72
	pos int
73
	// raw bytes of the serialized token.
74
	// This is a subslice into the original input.
75
	raw []byte
76
	// boo is parsed boolean value.
77
	boo bool
78
	// str is parsed string value.
79
	str string
80
}
81

82
// Kind returns the token kind.
83
func (t Token) Kind() Kind {
84
	return t.kind
85
}
86

87
// RawString returns the read value in string.
88
func (t Token) RawString() string {
89
	return string(t.raw)
90
}
91

92
// Pos returns the token position from the input.
93
func (t Token) Pos() int {
94
	return t.pos
95
}
96

97
// Name returns the object name if token is Name, else it panics.
98
func (t Token) Name() string {
99
	if t.kind == Name {
100
		return t.str
101
	}
102
	panic(fmt.Sprintf("Token is not a Name: %v", t.RawString()))
103
}
104

105
// Bool returns the bool value if token kind is Bool, else it panics.
106
func (t Token) Bool() bool {
107
	if t.kind == Bool {
108
		return t.boo
109
	}
110
	panic(fmt.Sprintf("Token is not a Bool: %v", t.RawString()))
111
}
112

113
// ParsedString returns the string value for a JSON string token or the read
114
// value in string if token is not a string.
115
func (t Token) ParsedString() string {
116
	if t.kind == String {
117
		return t.str
118
	}
119
	panic(fmt.Sprintf("Token is not a String: %v", t.RawString()))
120
}
121

122
// Float returns the floating-point number if token kind is Number.
123
//
124
// The floating-point precision is specified by the bitSize parameter: 32 for
125
// float32 or 64 for float64. If bitSize=32, the result still has type float64,
126
// but it will be convertible to float32 without changing its value. It will
127
// return false if the number exceeds the floating point limits for given
128
// bitSize.
129
func (t Token) Float(bitSize int) (float64, bool) {
130
	if t.kind != Number {
131
		return 0, false
132
	}
133
	f, err := strconv.ParseFloat(t.RawString(), bitSize)
134
	if err != nil {
135
		return 0, false
136
	}
137
	return f, true
138
}
139

140
// Int returns the signed integer number if token is Number.
141
//
142
// The given bitSize specifies the integer type that the result must fit into.
143
// It returns false if the number is not an integer value or if the result
144
// exceeds the limits for given bitSize.
145
func (t Token) Int(bitSize int) (int64, bool) {
146
	s, ok := t.getIntStr()
147
	if !ok {
148
		return 0, false
149
	}
150
	n, err := strconv.ParseInt(s, 10, bitSize)
151
	if err != nil {
152
		return 0, false
153
	}
154
	return n, true
155
}
156

157
// Uint returns the signed integer number if token is Number.
158
//
159
// The given bitSize specifies the unsigned integer type that the result must
160
// fit into. It returns false if the number is not an unsigned integer value
161
// or if the result exceeds the limits for given bitSize.
162
func (t Token) Uint(bitSize int) (uint64, bool) {
163
	s, ok := t.getIntStr()
164
	if !ok {
165
		return 0, false
166
	}
167
	n, err := strconv.ParseUint(s, 10, bitSize)
168
	if err != nil {
169
		return 0, false
170
	}
171
	return n, true
172
}
173

174
func (t Token) getIntStr() (string, bool) {
175
	if t.kind != Number {
176
		return "", false
177
	}
178
	parts, ok := parseNumberParts(t.raw)
179
	if !ok {
180
		return "", false
181
	}
182
	return normalizeToIntString(parts)
183
}
184

185
// TokenEquals returns true if given Tokens are equal, else false.
186
func TokenEquals(x, y Token) bool {
187
	return x.kind == y.kind &&
188
		x.pos == y.pos &&
189
		bytes.Equal(x.raw, y.raw) &&
190
		x.boo == y.boo &&
191
		x.str == y.str
192
}
193

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

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

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

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