Source file src/pkg/encoding/json/encode.go
1 // Copyright 2010 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 implements encoding and decoding of JSON objects as defined in
6 // RFC 4627.
7 //
8 // See "JSON and Go" for an introduction to this package:
9 // http://golang.org/doc/articles/json_and_go.html
10 package json
11
12 import (
13 "bytes"
14 "encoding/base64"
15 "math"
16 "reflect"
17 "runtime"
18 "sort"
19 "strconv"
20 "strings"
21 "sync"
22 "unicode"
23 "unicode/utf8"
24 )
25
26 // Marshal returns the JSON encoding of v.
27 //
28 // Marshal traverses the value v recursively.
29 // If an encountered value implements the Marshaler interface
30 // and is not a nil pointer, Marshal calls its MarshalJSON method
31 // to produce JSON. The nil pointer exception is not strictly necessary
32 // but mimics a similar, necessary exception in the behavior of
33 // UnmarshalJSON.
34 //
35 // Otherwise, Marshal uses the following type-dependent default encodings:
36 //
37 // Boolean values encode as JSON booleans.
38 //
39 // Floating point and integer values encode as JSON numbers.
40 //
41 // String values encode as JSON strings, with each invalid UTF-8 sequence
42 // replaced by the encoding of the Unicode replacement character U+FFFD.
43 // The angle brackets "<" and ">" are escaped to "\u003c" and "\u003e"
44 // to keep some browsers from misinterpreting JSON output as HTML.
45 //
46 // Array and slice values encode as JSON arrays, except that
47 // []byte encodes as a base64-encoded string, and a nil slice
48 // encodes as the null JSON object.
49 //
50 // Struct values encode as JSON objects. Each exported struct field
51 // becomes a member of the object unless
52 // - the field's tag is "-", or
53 // - the field is empty and its tag specifies the "omitempty" option.
54 // The empty values are false, 0, any
55 // nil pointer or interface value, and any array, slice, map, or string of
56 // length zero. The object's default key string is the struct field name
57 // but can be specified in the struct field's tag value. The "json" key in
58 // struct field's tag value is the key name, followed by an optional comma
59 // and options. Examples:
60 //
61 // // Field is ignored by this package.
62 // Field int `json:"-"`
63 //
64 // // Field appears in JSON as key "myName".
65 // Field int `json:"myName"`
66 //
67 // // Field appears in JSON as key "myName" and
68 // // the field is omitted from the object if its value is empty,
69 // // as defined above.
70 // Field int `json:"myName,omitempty"`
71 //
72 // // Field appears in JSON as key "Field" (the default), but
73 // // the field is skipped if empty.
74 // // Note the leading comma.
75 // Field int `json:",omitempty"`
76 //
77 // The "string" option signals that a field is stored as JSON inside a
78 // JSON-encoded string. This extra level of encoding is sometimes
79 // used when communicating with JavaScript programs:
80 //
81 // Int64String int64 `json:",string"`
82 //
83 // The key name will be used if it's a non-empty string consisting of
84 // only Unicode letters, digits, dollar signs, percent signs, hyphens,
85 // underscores and slashes.
86 //
87 // Map values encode as JSON objects.
88 // The map's key type must be string; the object keys are used directly
89 // as map keys.
90 //
91 // Pointer values encode as the value pointed to.
92 // A nil pointer encodes as the null JSON object.
93 //
94 // Interface values encode as the value contained in the interface.
95 // A nil interface value encodes as the null JSON object.
96 //
97 // Channel, complex, and function values cannot be encoded in JSON.
98 // Attempting to encode such a value causes Marshal to return
99 // an InvalidTypeError.
100 //
101 // JSON cannot represent cyclic data structures and Marshal does not
102 // handle them. Passing cyclic structures to Marshal will result in
103 // an infinite recursion.
104 //
105 func Marshal(v interface{}) ([]byte, error) {
106 e := &encodeState{}
107 err := e.marshal(v)
108 if err != nil {
109 return nil, err
110 }
111 return e.Bytes(), nil
112 }
113
114 // MarshalIndent is like Marshal but applies Indent to format the output.
115 func MarshalIndent(v interface{}, prefix, indent string) ([]byte, error) {
116 b, err := Marshal(v)
117 if err != nil {
118 return nil, err
119 }
120 var buf bytes.Buffer
121 err = Indent(&buf, b, prefix, indent)
122 if err != nil {
123 return nil, err
124 }
125 return buf.Bytes(), nil
126 }
127
128 // HTMLEscape appends to dst the JSON-encoded src with <, >, and &
129 // characters inside string literals changed to \u003c, \u003e, \u0026
130 // so that the JSON will be safe to embed inside HTML <script> tags.
131 // For historical reasons, web browsers don't honor standard HTML
132 // escaping within <script> tags, so an alternative JSON encoding must
133 // be used.
134 func HTMLEscape(dst *bytes.Buffer, src []byte) {
135 // < > & can only appear in string literals,
136 // so just scan the string one byte at a time.
137 start := 0
138 for i, c := range src {
139 if c == '<' || c == '>' || c == '&' {
140 if start < i {
141 dst.Write(src[start:i])
142 }
143 dst.WriteString(`\u00`)
144 dst.WriteByte(hex[c>>4])
145 dst.WriteByte(hex[c&0xF])
146 start = i + 1
147 }
148 }
149 if start < len(src) {
150 dst.Write(src[start:])
151 }
152 }
153
154 // Marshaler is the interface implemented by objects that
155 // can marshal themselves into valid JSON.
156 type Marshaler interface {
157 MarshalJSON() ([]byte, error)
158 }
159
160 type UnsupportedTypeError struct {
161 Type reflect.Type
162 }
163
164 func (e *UnsupportedTypeError) Error() string {
165 return "json: unsupported type: " + e.Type.String()
166 }
167
168 type UnsupportedValueError struct {
169 Value reflect.Value
170 Str string
171 }
172
173 func (e *UnsupportedValueError) Error() string {
174 return "json: unsupported value: " + e.Str
175 }
176
177 type InvalidUTF8Error struct {
178 S string
179 }
180
181 func (e *InvalidUTF8Error) Error() string {
182 return "json: invalid UTF-8 in string: " + strconv.Quote(e.S)
183 }
184
185 type MarshalerError struct {
186 Type reflect.Type
187 Err error
188 }
189
190 func (e *MarshalerError) Error() string {
191 return "json: error calling MarshalJSON for type " + e.Type.String() + ": " + e.Err.Error()
192 }
193
194 var hex = "0123456789abcdef"
195
196 // An encodeState encodes JSON into a bytes.Buffer.
197 type encodeState struct {
198 bytes.Buffer // accumulated output
199 scratch [64]byte
200 }
201
202 func (e *encodeState) marshal(v interface{}) (err error) {
203 defer func() {
204 if r := recover(); r != nil {
205 if _, ok := r.(runtime.Error); ok {
206 panic(r)
207 }
208 err = r.(error)
209 }
210 }()
211 e.reflectValue(reflect.ValueOf(v))
212 return nil
213 }
214
215 func (e *encodeState) error(err error) {
216 panic(err)
217 }
218
219 var byteSliceType = reflect.TypeOf([]byte(nil))
220
221 func isEmptyValue(v reflect.Value) bool {
222 switch v.Kind() {
223 case reflect.Array, reflect.Map, reflect.Slice, reflect.String:
224 return v.Len() == 0
225 case reflect.Bool:
226 return !v.Bool()
227 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
228 return v.Int() == 0
229 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
230 return v.Uint() == 0
231 case reflect.Float32, reflect.Float64:
232 return v.Float() == 0
233 case reflect.Interface, reflect.Ptr:
234 return v.IsNil()
235 }
236 return false
237 }
238
239 func (e *encodeState) reflectValue(v reflect.Value) {
240 e.reflectValueQuoted(v, false)
241 }
242
243 // reflectValueQuoted writes the value in v to the output.
244 // If quoted is true, the serialization is wrapped in a JSON string.
245 func (e *encodeState) reflectValueQuoted(v reflect.Value, quoted bool) {
246 if !v.IsValid() {
247 e.WriteString("null")
248 return
249 }
250
251 m, ok := v.Interface().(Marshaler)
252 if !ok {
253 // T doesn't match the interface. Check against *T too.
254 if v.Kind() != reflect.Ptr && v.CanAddr() {
255 m, ok = v.Addr().Interface().(Marshaler)
256 if ok {
257 v = v.Addr()
258 }
259 }
260 }
261 if ok && (v.Kind() != reflect.Ptr || !v.IsNil()) {
262 b, err := m.MarshalJSON()
263 if err == nil {
264 // copy JSON into buffer, checking validity.
265 err = compact(&e.Buffer, b, true)
266 }
267 if err != nil {
268 e.error(&MarshalerError{v.Type(), err})
269 }
270 return
271 }
272
273 writeString := (*encodeState).WriteString
274 if quoted {
275 writeString = (*encodeState).string
276 }
277
278 switch v.Kind() {
279 case reflect.Bool:
280 x := v.Bool()
281 if x {
282 writeString(e, "true")
283 } else {
284 writeString(e, "false")
285 }
286
287 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
288 b := strconv.AppendInt(e.scratch[:0], v.Int(), 10)
289 if quoted {
290 writeString(e, string(b))
291 } else {
292 e.Write(b)
293 }
294 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
295 b := strconv.AppendUint(e.scratch[:0], v.Uint(), 10)
296 if quoted {
297 writeString(e, string(b))
298 } else {
299 e.Write(b)
300 }
301 case reflect.Float32, reflect.Float64:
302 f := v.Float()
303 if math.IsInf(f, 0) || math.IsNaN(f) {
304 e.error(&UnsupportedValueError{v, strconv.FormatFloat(f, 'g', -1, v.Type().Bits())})
305 }
306 b := strconv.AppendFloat(e.scratch[:0], f, 'g', -1, v.Type().Bits())
307 if quoted {
308 writeString(e, string(b))
309 } else {
310 e.Write(b)
311 }
312 case reflect.String:
313 if quoted {
314 sb, err := Marshal(v.String())
315 if err != nil {
316 e.error(err)
317 }
318 e.string(string(sb))
319 } else {
320 e.string(v.String())
321 }
322
323 case reflect.Struct:
324 e.WriteByte('{')
325 first := true
326 for _, ef := range encodeFields(v.Type()) {
327 fieldValue := v.Field(ef.i)
328 if ef.omitEmpty && isEmptyValue(fieldValue) {
329 continue
330 }
331 if first {
332 first = false
333 } else {
334 e.WriteByte(',')
335 }
336 e.string(ef.tag)
337 e.WriteByte(':')
338 e.reflectValueQuoted(fieldValue, ef.quoted)
339 }
340 e.WriteByte('}')
341
342 case reflect.Map:
343 if v.Type().Key().Kind() != reflect.String {
344 e.error(&UnsupportedTypeError{v.Type()})
345 }
346 if v.IsNil() {
347 e.WriteString("null")
348 break
349 }
350 e.WriteByte('{')
351 var sv stringValues = v.MapKeys()
352 sort.Sort(sv)
353 for i, k := range sv {
354 if i > 0 {
355 e.WriteByte(',')
356 }
357 e.string(k.String())
358 e.WriteByte(':')
359 e.reflectValue(v.MapIndex(k))
360 }
361 e.WriteByte('}')
362
363 case reflect.Slice:
364 if v.IsNil() {
365 e.WriteString("null")
366 break
367 }
368 if v.Type().Elem().Kind() == reflect.Uint8 {
369 // Byte slices get special treatment; arrays don't.
370 s := v.Bytes()
371 e.WriteByte('"')
372 if len(s) < 1024 {
373 // for small buffers, using Encode directly is much faster.
374 dst := make([]byte, base64.StdEncoding.EncodedLen(len(s)))
375 base64.StdEncoding.Encode(dst, s)
376 e.Write(dst)
377 } else {
378 // for large buffers, avoid unnecessary extra temporary
379 // buffer space.
380 enc := base64.NewEncoder(base64.StdEncoding, e)
381 enc.Write(s)
382 enc.Close()
383 }
384 e.WriteByte('"')
385 break
386 }
387 // Slices can be marshalled as nil, but otherwise are handled
388 // as arrays.
389 fallthrough
390 case reflect.Array:
391 e.WriteByte('[')
392 n := v.Len()
393 for i := 0; i < n; i++ {
394 if i > 0 {
395 e.WriteByte(',')
396 }
397 e.reflectValue(v.Index(i))
398 }
399 e.WriteByte(']')
400
401 case reflect.Interface, reflect.Ptr:
402 if v.IsNil() {
403 e.WriteString("null")
404 return
405 }
406 e.reflectValue(v.Elem())
407
408 default:
409 e.error(&UnsupportedTypeError{v.Type()})
410 }
411 return
412 }
413
414 func isValidTag(s string) bool {
415 if s == "" {
416 return false
417 }
418 for _, c := range s {
419 switch {
420 case strings.ContainsRune("!#$%&()*+-./:<=>?@[]^_{|}~", c):
421 // Backslash and quote chars are reserved, but
422 // otherwise any punctuation chars are allowed
423 // in a tag name.
424 default:
425 if !unicode.IsLetter(c) && !unicode.IsDigit(c) {
426 return false
427 }
428 }
429 }
430 return true
431 }
432
433 // stringValues is a slice of reflect.Value holding *reflect.StringValue.
434 // It implements the methods to sort by string.
435 type stringValues []reflect.Value
436
437 func (sv stringValues) Len() int { return len(sv) }
438 func (sv stringValues) Swap(i, j int) { sv[i], sv[j] = sv[j], sv[i] }
439 func (sv stringValues) Less(i, j int) bool { return sv.get(i) < sv.get(j) }
440 func (sv stringValues) get(i int) string { return sv[i].String() }
441
442 func (e *encodeState) string(s string) (int, error) {
443 len0 := e.Len()
444 e.WriteByte('"')
445 start := 0
446 for i := 0; i < len(s); {
447 if b := s[i]; b < utf8.RuneSelf {
448 if 0x20 <= b && b != '\\' && b != '"' && b != '<' && b != '>' {
449 i++
450 continue
451 }
452 if start < i {
453 e.WriteString(s[start:i])
454 }
455 switch b {
456 case '\\', '"':
457 e.WriteByte('\\')
458 e.WriteByte(b)
459 case '\n':
460 e.WriteByte('\\')
461 e.WriteByte('n')
462 case '\r':
463 e.WriteByte('\\')
464 e.WriteByte('r')
465 default:
466 // This encodes bytes < 0x20 except for \n and \r,
467 // as well as < and >. The latter are escaped because they
468 // can lead to security holes when user-controlled strings
469 // are rendered into JSON and served to some browsers.
470 e.WriteString(`\u00`)
471 e.WriteByte(hex[b>>4])
472 e.WriteByte(hex[b&0xF])
473 }
474 i++
475 start = i
476 continue
477 }
478 c, size := utf8.DecodeRuneInString(s[i:])
479 if c == utf8.RuneError && size == 1 {
480 e.error(&InvalidUTF8Error{s})
481 }
482 i += size
483 }
484 if start < len(s) {
485 e.WriteString(s[start:])
486 }
487 e.WriteByte('"')
488 return e.Len() - len0, nil
489 }
490
491 // encodeField contains information about how to encode a field of a
492 // struct.
493 type encodeField struct {
494 i int // field index in struct
495 tag string
496 quoted bool
497 omitEmpty bool
498 }
499
500 var (
501 typeCacheLock sync.RWMutex
502 encodeFieldsCache = make(map[reflect.Type][]encodeField)
503 )
504
505 // encodeFields returns a slice of encodeField for a given
506 // struct type.
507 func encodeFields(t reflect.Type) []encodeField {
508 typeCacheLock.RLock()
509 fs, ok := encodeFieldsCache[t]
510 typeCacheLock.RUnlock()
511 if ok {
512 return fs
513 }
514
515 typeCacheLock.Lock()
516 defer typeCacheLock.Unlock()
517 fs, ok = encodeFieldsCache[t]
518 if ok {
519 return fs
520 }
521
522 v := reflect.Zero(t)
523 n := v.NumField()
524 for i := 0; i < n; i++ {
525 f := t.Field(i)
526 if f.PkgPath != "" {
527 continue
528 }
529 if f.Anonymous {
530 // We want to do a better job with these later,
531 // so for now pretend they don't exist.
532 continue
533 }
534 var ef encodeField
535 ef.i = i
536 ef.tag = f.Name
537
538 tv := f.Tag.Get("json")
539 if tv != "" {
540 if tv == "-" {
541 continue
542 }
543 name, opts := parseTag(tv)
544 if isValidTag(name) {
545 ef.tag = name
546 }
547 ef.omitEmpty = opts.Contains("omitempty")
548 ef.quoted = opts.Contains("string")
549 }
550 fs = append(fs, ef)
551 }
552 encodeFieldsCache[t] = fs
553 return fs
554 }