-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathinter_type.go
executable file
·165 lines (157 loc) · 3.88 KB
/
inter_type.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
package jin
import "strconv"
const (
TypeArray string = "array"
TypeObject string = "object"
TypeString string = "string"
TypeBoolean string = "boolean"
TypeNull string = "null"
TypeNumber string = "number"
)
// IsObject is a type control function.
// If path points to an object it will return true, otherwise it will return false.
// In this instance 'object' means everything that has starts and ends with curly brace.
func IsObject(json []byte, path ...string) (bool, error) {
state, _, err := typeControlCore(json, []byte{91, 123}, true, path...)
if err != nil {
return false, err
}
return state, nil
}
// IsArray is a type control function.
// If path points to an array it will return true, otherwise it will return false.
// In this instance 'array' means everything that has starts and ends with square brace.
func IsArray(json []byte, path ...string) (bool, error) {
state, _, err := typeControlCore(json, []byte{91}, true, path...)
if err != nil {
return false, err
}
return state, nil
}
// IsValue is a type control function.
// If path points to an value it will return true, otherwise it will return false.
// In this instance 'value' means everything that has not starts and ends with any brace.
func IsValue(json []byte, path ...string) (bool, error) {
state, _, err := typeControlCore(json, []byte{91, 123}, false, path...)
if err != nil {
return false, err
}
return state, nil
}
// GetType returns the types of value that path has point.
// possible return types 'array' | 'object' | 'string' | 'boolean' | 'null' | 'number'
func GetType(json []byte, path ...string) (string, error) {
_, start, err := typeControlCore(json, []byte{}, false, path...)
if err != nil {
return "", err
}
switch json[start] {
case '[':
return TypeArray, nil
case '{':
return TypeObject, nil
case '"':
return TypeString, nil
}
val, err := GetString(json, path...)
if err != nil {
return "", err
}
switch val {
case "true", "false":
return TypeBoolean, nil
case "null":
return TypeNull, nil
}
_, err = strconv.ParseInt(val, 10, 64)
if err == nil {
return TypeNumber, nil
}
_, err = strconv.ParseFloat(val, 64)
if err == nil {
return TypeNumber, nil
}
return TypeString, nil
}
// IsEmpty is a control function.
// If path points to an value it will return 'value' string
// If path points to an array that has zero element in it,
// then it will return true, otherwise it will return false.
func IsEmpty(json []byte, path ...string) (bool, error) {
if len(json) == 0 {
return false, errBadJSON(0)
}
var start int
var end int = len(json) - 1
var err error
if len(path) == 0 {
for space(json[start]) {
if start > len(json)-1 {
return false, errBadJSON(start)
}
start++
continue
}
for space(json[end]) {
if end < 1 {
return false, errBadJSON(end)
}
end--
continue
}
} else {
_, start, end, err = core(json, false, path...)
if err != nil {
return false, err
}
end--
}
braceStart := json[start]
braceEnd := json[end]
if braceStart == 91 || braceStart == 123 {
if braceStart+2 != braceEnd {
return false, errBadJSON(end)
}
for i := start + 1; i < end-1; i++ {
if !space(json[i]) {
return false, nil
}
}
} else {
return false, errObjectExpected()
}
return true, nil
}
func typeControlCore(json []byte, control []byte, equal bool, path ...string) (bool, int, error) {
if len(json) == 0 {
return false, -1, errBadJSON(0)
}
var start int
var err error
if len(path) == 0 {
for space(json[start]) {
if start > len(json)-1 {
return false, -1, errBadJSON(start)
}
start++
continue
}
} else {
_, start, _, err = core(json, true, path...)
if err != nil {
return false, start, err
}
}
for _, v := range control {
if json[start] == v {
if equal {
return true, start, nil
}
return false, start, nil
}
}
if equal {
return false, start, nil
}
return true, start, nil
}