-
Notifications
You must be signed in to change notification settings - Fork 21
/
Copy pathinterface.go
129 lines (117 loc) · 2.9 KB
/
interface.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
package djson
// A SyntaxError is a description of a JSON syntax error.
type SyntaxError struct {
msg string // description of error
Offset int // error occurred after reading Offset bytes
}
func (e *SyntaxError) Error() string { return e.msg }
// Predefined errors
var (
ErrUnexpectedEOF = &SyntaxError{"unexpected end of JSON input", -1}
ErrInvalidHexEscape = &SyntaxError{"invalid hexadecimal escape sequence", -1}
ErrStringEscape = &SyntaxError{"encountered an invalid escape sequence in a string", -1}
)
// ValueType identifies the type of a parsed value.
type ValueType int
func (v ValueType) String() string {
return types[v]
}
const (
Null ValueType = iota
Bool
String
Number
Object
Array
Unknown
)
var types = map[ValueType]string{
Null: "null",
Bool: "boolean",
String: "string",
Number: "number",
Object: "object",
Array: "array",
Unknown: "unknown",
}
// Type returns the JSON-type of the given value
func Type(v interface{}) ValueType {
t := Unknown
switch v.(type) {
case nil:
t = Null
case bool:
t = Bool
case string:
t = String
case float64:
t = Number
case []interface{}:
t = Array
case map[string]interface{}:
t = Object
}
return t
}
// Decode parses the JSON-encoded data and returns an interface value.
// The interface value could be one of these:
//
// bool, for JSON booleans
// float64, for JSON numbers
// string, for JSON strings
// []interface{}, for JSON arrays
// map[string]interface{}, for JSON objects
// nil for JSON null
//
// Note that the Decode is compatible with the the following
// insructions:
//
// var v interface{}
// err := json.Unmarshal(data, &v)
//
func Decode(data []byte) (interface{}, error) {
d := NewDecoder(data)
val, err := d.any()
if err != nil {
return nil, err
}
if c := d.skipSpaces(); d.pos < d.end {
return nil, d.error(c, "after top-level value")
}
return val, nil
}
// DecodeObject is the same as Decode but it returns map[string]interface{}.
// You should use it to parse JSON objects.
func DecodeObject(data []byte) (map[string]interface{}, error) {
d := NewDecoder(data)
if c := d.skipSpaces(); c != '{' {
return nil, d.error(c, "looking for beginning of object")
}
val, err := d.object()
if err != nil {
return nil, err
}
if c := d.skipSpaces(); d.pos < d.end {
return nil, d.error(c, "after top-level value")
}
return val, nil
}
// DecodeArray is the same as Decode but it returns []interface{}.
// You should use it to parse JSON arrays.
func DecodeArray(data []byte) ([]interface{}, error) {
d := NewDecoder(data)
if c := d.skipSpaces(); c != '[' {
return nil, d.error(c, "looking for beginning of array")
}
val, err := d.array()
if err != nil {
return nil, err
}
if c := d.skipSpaces(); d.pos < d.end {
return nil, d.error(c, "after top-level value")
}
return val, nil
}
// TODO(a8m): the 3 methods above could be written like this:
//
// return NewDecoder(data).DecodeXXX()