1package json
2
3import (
4	"encoding/json"
5	"fmt"
6	"math"
7	"strconv"
8)
9
10func AppendBool(dst []byte, val bool) []byte {
11	return strconv.AppendBool(dst, val)
12}
13
14func AppendBools(dst []byte, vals []bool) []byte {
15	if len(vals) == 0 {
16		return append(dst, '[', ']')
17	}
18	dst = append(dst, '[')
19	dst = strconv.AppendBool(dst, vals[0])
20	if len(vals) > 1 {
21		for _, val := range vals[1:] {
22			dst = strconv.AppendBool(append(dst, ','), val)
23		}
24	}
25	dst = append(dst, ']')
26	return dst
27}
28
29func AppendInt(dst []byte, val int) []byte {
30	return strconv.AppendInt(dst, int64(val), 10)
31}
32
33func AppendInts(dst []byte, vals []int) []byte {
34	if len(vals) == 0 {
35		return append(dst, '[', ']')
36	}
37	dst = append(dst, '[')
38	dst = strconv.AppendInt(dst, int64(vals[0]), 10)
39	if len(vals) > 1 {
40		for _, val := range vals[1:] {
41			dst = strconv.AppendInt(append(dst, ','), int64(val), 10)
42		}
43	}
44	dst = append(dst, ']')
45	return dst
46}
47
48func AppendInt8(dst []byte, val int8) []byte {
49	return strconv.AppendInt(dst, int64(val), 10)
50}
51
52func AppendInts8(dst []byte, vals []int8) []byte {
53	if len(vals) == 0 {
54		return append(dst, '[', ']')
55	}
56	dst = append(dst, '[')
57	dst = strconv.AppendInt(dst, int64(vals[0]), 10)
58	if len(vals) > 1 {
59		for _, val := range vals[1:] {
60			dst = strconv.AppendInt(append(dst, ','), int64(val), 10)
61		}
62	}
63	dst = append(dst, ']')
64	return dst
65}
66
67func AppendInt16(dst []byte, val int16) []byte {
68	return strconv.AppendInt(dst, int64(val), 10)
69}
70
71func AppendInts16(dst []byte, vals []int16) []byte {
72	if len(vals) == 0 {
73		return append(dst, '[', ']')
74	}
75	dst = append(dst, '[')
76	dst = strconv.AppendInt(dst, int64(vals[0]), 10)
77	if len(vals) > 1 {
78		for _, val := range vals[1:] {
79			dst = strconv.AppendInt(append(dst, ','), int64(val), 10)
80		}
81	}
82	dst = append(dst, ']')
83	return dst
84}
85
86func AppendInt32(dst []byte, val int32) []byte {
87	return strconv.AppendInt(dst, int64(val), 10)
88}
89
90func AppendInts32(dst []byte, vals []int32) []byte {
91	if len(vals) == 0 {
92		return append(dst, '[', ']')
93	}
94	dst = append(dst, '[')
95	dst = strconv.AppendInt(dst, int64(vals[0]), 10)
96	if len(vals) > 1 {
97		for _, val := range vals[1:] {
98			dst = strconv.AppendInt(append(dst, ','), int64(val), 10)
99		}
100	}
101	dst = append(dst, ']')
102	return dst
103}
104
105func AppendInt64(dst []byte, val int64) []byte {
106	return strconv.AppendInt(dst, val, 10)
107}
108
109func AppendInts64(dst []byte, vals []int64) []byte {
110	if len(vals) == 0 {
111		return append(dst, '[', ']')
112	}
113	dst = append(dst, '[')
114	dst = strconv.AppendInt(dst, vals[0], 10)
115	if len(vals) > 1 {
116		for _, val := range vals[1:] {
117			dst = strconv.AppendInt(append(dst, ','), val, 10)
118		}
119	}
120	dst = append(dst, ']')
121	return dst
122}
123
124func AppendUint(dst []byte, val uint) []byte {
125	return strconv.AppendUint(dst, uint64(val), 10)
126}
127
128func AppendUints(dst []byte, vals []uint) []byte {
129	if len(vals) == 0 {
130		return append(dst, '[', ']')
131	}
132	dst = append(dst, '[')
133	dst = strconv.AppendUint(dst, uint64(vals[0]), 10)
134	if len(vals) > 1 {
135		for _, val := range vals[1:] {
136			dst = strconv.AppendUint(append(dst, ','), uint64(val), 10)
137		}
138	}
139	dst = append(dst, ']')
140	return dst
141}
142
143func AppendUint8(dst []byte, val uint8) []byte {
144	return strconv.AppendUint(dst, uint64(val), 10)
145}
146
147func AppendUints8(dst []byte, vals []uint8) []byte {
148	if len(vals) == 0 {
149		return append(dst, '[', ']')
150	}
151	dst = append(dst, '[')
152	dst = strconv.AppendUint(dst, uint64(vals[0]), 10)
153	if len(vals) > 1 {
154		for _, val := range vals[1:] {
155			dst = strconv.AppendUint(append(dst, ','), uint64(val), 10)
156		}
157	}
158	dst = append(dst, ']')
159	return dst
160}
161
162func AppendUint16(dst []byte, val uint16) []byte {
163	return strconv.AppendUint(dst, uint64(val), 10)
164}
165
166func AppendUints16(dst []byte, vals []uint16) []byte {
167	if len(vals) == 0 {
168		return append(dst, '[', ']')
169	}
170	dst = append(dst, '[')
171	dst = strconv.AppendUint(dst, uint64(vals[0]), 10)
172	if len(vals) > 1 {
173		for _, val := range vals[1:] {
174			dst = strconv.AppendUint(append(dst, ','), uint64(val), 10)
175		}
176	}
177	dst = append(dst, ']')
178	return dst
179}
180
181func AppendUint32(dst []byte, val uint32) []byte {
182	return strconv.AppendUint(dst, uint64(val), 10)
183}
184
185func AppendUints32(dst []byte, vals []uint32) []byte {
186	if len(vals) == 0 {
187		return append(dst, '[', ']')
188	}
189	dst = append(dst, '[')
190	dst = strconv.AppendUint(dst, uint64(vals[0]), 10)
191	if len(vals) > 1 {
192		for _, val := range vals[1:] {
193			dst = strconv.AppendUint(append(dst, ','), uint64(val), 10)
194		}
195	}
196	dst = append(dst, ']')
197	return dst
198}
199
200func AppendUint64(dst []byte, val uint64) []byte {
201	return strconv.AppendUint(dst, uint64(val), 10)
202}
203
204func AppendUints64(dst []byte, vals []uint64) []byte {
205	if len(vals) == 0 {
206		return append(dst, '[', ']')
207	}
208	dst = append(dst, '[')
209	dst = strconv.AppendUint(dst, vals[0], 10)
210	if len(vals) > 1 {
211		for _, val := range vals[1:] {
212			dst = strconv.AppendUint(append(dst, ','), val, 10)
213		}
214	}
215	dst = append(dst, ']')
216	return dst
217}
218
219func AppendFloat(dst []byte, val float64, bitSize int) []byte {
220	// JSON does not permit NaN or Infinity. A typical JSON encoder would fail
221	// with an error, but a logging library wants the data to get thru so we
222	// make a tradeoff and store those types as string.
223	switch {
224	case math.IsNaN(val):
225		return append(dst, `"NaN"`...)
226	case math.IsInf(val, 1):
227		return append(dst, `"+Inf"`...)
228	case math.IsInf(val, -1):
229		return append(dst, `"-Inf"`...)
230	}
231	return strconv.AppendFloat(dst, val, 'f', -1, bitSize)
232}
233
234func AppendFloat32(dst []byte, val float32) []byte {
235	return AppendFloat(dst, float64(val), 32)
236}
237
238func AppendFloats32(dst []byte, vals []float32) []byte {
239	if len(vals) == 0 {
240		return append(dst, '[', ']')
241	}
242	dst = append(dst, '[')
243	dst = AppendFloat(dst, float64(vals[0]), 32)
244	if len(vals) > 1 {
245		for _, val := range vals[1:] {
246			dst = AppendFloat(append(dst, ','), float64(val), 32)
247		}
248	}
249	dst = append(dst, ']')
250	return dst
251}
252
253func AppendFloat64(dst []byte, val float64) []byte {
254	return AppendFloat(dst, val, 64)
255}
256
257func AppendFloats64(dst []byte, vals []float64) []byte {
258	if len(vals) == 0 {
259		return append(dst, '[', ']')
260	}
261	dst = append(dst, '[')
262	dst = AppendFloat(dst, vals[0], 32)
263	if len(vals) > 1 {
264		for _, val := range vals[1:] {
265			dst = AppendFloat(append(dst, ','), val, 64)
266		}
267	}
268	dst = append(dst, ']')
269	return dst
270}
271
272func AppendInterface(dst []byte, i interface{}) []byte {
273	marshaled, err := json.Marshal(i)
274	if err != nil {
275		return AppendString(dst, fmt.Sprintf("marshaling error: %v", err))
276	}
277	return append(dst, marshaled...)
278}
279