-
Notifications
You must be signed in to change notification settings - Fork 2
/
arena.go
128 lines (115 loc) · 2.98 KB
/
arena.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
package astjson
import (
"strconv"
)
// Arena may be used for fast creation and re-use of Values.
//
// Typical Arena lifecycle:
//
// 1. Construct Values via the Arena and Value.Set* calls.
// 2. Marshal the constructed Values with Value.MarshalTo call.
// 3. Reset all the constructed Values at once by Arena.Reset call.
// 4. Go to 1 and re-use the Arena.
//
// It is unsafe calling Arena methods from concurrent goroutines.
// Use per-goroutine Arenas or ArenaPool instead.
type Arena struct {
b []byte
c cache
}
// Reset resets all the Values allocated by a.
//
// Values previously allocated by a cannot be used after the Reset call.
func (a *Arena) Reset() {
a.b = a.b[:0]
a.c.reset()
}
// NewObject returns new empty object value.
//
// New entries may be added to the returned object via Set call.
//
// The returned object is valid until Reset is called on a.
func (a *Arena) NewObject() *Value {
v := a.c.getValue()
v.t = TypeObject
v.o.reset()
return v
}
// NewArray returns new empty array value.
//
// New entries may be added to the returned array via Set* calls.
//
// The returned array is valid until Reset is called on a.
func (a *Arena) NewArray() *Value {
v := a.c.getValue()
v.t = TypeArray
v.a = v.a[:0]
return v
}
// NewString returns new string value containing s.
//
// The returned string is valid until Reset is called on a.
func (a *Arena) NewString(s string) *Value {
v := a.c.getValue()
v.t = TypeString
bLen := len(a.b)
a.b = escapeString(a.b, s)
v.s = b2s(a.b[bLen+1 : len(a.b)-1])
v.s = unescapeStringBestEffort(v.s)
return v
}
// NewStringBytes returns new string value containing b.
//
// The returned string is valid until Reset is called on a.
func (a *Arena) NewStringBytes(b []byte) *Value {
v := a.c.getValue()
v.t = TypeString
bLen := len(a.b)
a.b = escapeString(a.b, b2s(b))
v.s = b2s(a.b[bLen+1 : len(a.b)-1])
v.s = unescapeStringBestEffort(v.s)
return v
}
// NewNumberFloat64 returns new number value containing f.
//
// The returned number is valid until Reset is called on a.
func (a *Arena) NewNumberFloat64(f float64) *Value {
v := a.c.getValue()
v.t = TypeNumber
bLen := len(a.b)
a.b = strconv.AppendFloat(a.b, f, 'g', -1, 64)
v.s = b2s(a.b[bLen:])
return v
}
// NewNumberInt returns new number value containing n.
//
// The returned number is valid until Reset is called on a.
func (a *Arena) NewNumberInt(n int) *Value {
v := a.c.getValue()
v.t = TypeNumber
bLen := len(a.b)
a.b = strconv.AppendInt(a.b, int64(n), 10)
v.s = b2s(a.b[bLen:])
return v
}
// NewNumberString returns new number value containing s.
//
// The returned number is valid until Reset is called on a.
func (a *Arena) NewNumberString(s string) *Value {
v := a.c.getValue()
v.t = TypeNumber
v.s = s
return v
}
// NewNull returns null value.
func (a *Arena) NewNull() *Value {
return valueNull
}
// NewTrue returns true value.
func (a *Arena) NewTrue() *Value {
return valueTrue
}
// NewFalse return false value.
func (a *Arena) NewFalse() *Value {
return valueFalse
}