b6e1cb16e5a471b198d6c620badfbbaf464dd23a
[platform/upstream/gcc48.git] / libgo / go / 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 UnsupportedTypeError.
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 // An UnsupportedTypeError is returned by Marshal when attempting
161 // to encode an unsupported value type.
162 type UnsupportedTypeError struct {
163         Type reflect.Type
164 }
165
166 func (e *UnsupportedTypeError) Error() string {
167         return "json: unsupported type: " + e.Type.String()
168 }
169
170 type UnsupportedValueError struct {
171         Value reflect.Value
172         Str   string
173 }
174
175 func (e *UnsupportedValueError) Error() string {
176         return "json: unsupported value: " + e.Str
177 }
178
179 type InvalidUTF8Error struct {
180         S string
181 }
182
183 func (e *InvalidUTF8Error) Error() string {
184         return "json: invalid UTF-8 in string: " + strconv.Quote(e.S)
185 }
186
187 type MarshalerError struct {
188         Type reflect.Type
189         Err  error
190 }
191
192 func (e *MarshalerError) Error() string {
193         return "json: error calling MarshalJSON for type " + e.Type.String() + ": " + e.Err.Error()
194 }
195
196 var hex = "0123456789abcdef"
197
198 // An encodeState encodes JSON into a bytes.Buffer.
199 type encodeState struct {
200         bytes.Buffer // accumulated output
201         scratch      [64]byte
202 }
203
204 func (e *encodeState) marshal(v interface{}) (err error) {
205         defer func() {
206                 if r := recover(); r != nil {
207                         if _, ok := r.(runtime.Error); ok {
208                                 panic(r)
209                         }
210                         err = r.(error)
211                 }
212         }()
213         e.reflectValue(reflect.ValueOf(v))
214         return nil
215 }
216
217 func (e *encodeState) error(err error) {
218         panic(err)
219 }
220
221 var byteSliceType = reflect.TypeOf([]byte(nil))
222
223 func isEmptyValue(v reflect.Value) bool {
224         switch v.Kind() {
225         case reflect.Array, reflect.Map, reflect.Slice, reflect.String:
226                 return v.Len() == 0
227         case reflect.Bool:
228                 return !v.Bool()
229         case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
230                 return v.Int() == 0
231         case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
232                 return v.Uint() == 0
233         case reflect.Float32, reflect.Float64:
234                 return v.Float() == 0
235         case reflect.Interface, reflect.Ptr:
236                 return v.IsNil()
237         }
238         return false
239 }
240
241 func (e *encodeState) reflectValue(v reflect.Value) {
242         e.reflectValueQuoted(v, false)
243 }
244
245 // reflectValueQuoted writes the value in v to the output.
246 // If quoted is true, the serialization is wrapped in a JSON string.
247 func (e *encodeState) reflectValueQuoted(v reflect.Value, quoted bool) {
248         if !v.IsValid() {
249                 e.WriteString("null")
250                 return
251         }
252
253         m, ok := v.Interface().(Marshaler)
254         if !ok {
255                 // T doesn't match the interface. Check against *T too.
256                 if v.Kind() != reflect.Ptr && v.CanAddr() {
257                         m, ok = v.Addr().Interface().(Marshaler)
258                         if ok {
259                                 v = v.Addr()
260                         }
261                 }
262         }
263         if ok && (v.Kind() != reflect.Ptr || !v.IsNil()) {
264                 b, err := m.MarshalJSON()
265                 if err == nil {
266                         // copy JSON into buffer, checking validity.
267                         err = compact(&e.Buffer, b, true)
268                 }
269                 if err != nil {
270                         e.error(&MarshalerError{v.Type(), err})
271                 }
272                 return
273         }
274
275         writeString := (*encodeState).WriteString
276         if quoted {
277                 writeString = (*encodeState).string
278         }
279
280         switch v.Kind() {
281         case reflect.Bool:
282                 x := v.Bool()
283                 if x {
284                         writeString(e, "true")
285                 } else {
286                         writeString(e, "false")
287                 }
288
289         case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
290                 b := strconv.AppendInt(e.scratch[:0], v.Int(), 10)
291                 if quoted {
292                         writeString(e, string(b))
293                 } else {
294                         e.Write(b)
295                 }
296         case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
297                 b := strconv.AppendUint(e.scratch[:0], v.Uint(), 10)
298                 if quoted {
299                         writeString(e, string(b))
300                 } else {
301                         e.Write(b)
302                 }
303         case reflect.Float32, reflect.Float64:
304                 f := v.Float()
305                 if math.IsInf(f, 0) || math.IsNaN(f) {
306                         e.error(&UnsupportedValueError{v, strconv.FormatFloat(f, 'g', -1, v.Type().Bits())})
307                 }
308                 b := strconv.AppendFloat(e.scratch[:0], f, 'g', -1, v.Type().Bits())
309                 if quoted {
310                         writeString(e, string(b))
311                 } else {
312                         e.Write(b)
313                 }
314         case reflect.String:
315                 if quoted {
316                         sb, err := Marshal(v.String())
317                         if err != nil {
318                                 e.error(err)
319                         }
320                         e.string(string(sb))
321                 } else {
322                         e.string(v.String())
323                 }
324
325         case reflect.Struct:
326                 e.WriteByte('{')
327                 first := true
328                 for _, ef := range encodeFields(v.Type()) {
329                         fieldValue := v.Field(ef.i)
330                         if ef.omitEmpty && isEmptyValue(fieldValue) {
331                                 continue
332                         }
333                         if first {
334                                 first = false
335                         } else {
336                                 e.WriteByte(',')
337                         }
338                         e.string(ef.tag)
339                         e.WriteByte(':')
340                         e.reflectValueQuoted(fieldValue, ef.quoted)
341                 }
342                 e.WriteByte('}')
343
344         case reflect.Map:
345                 if v.Type().Key().Kind() != reflect.String {
346                         e.error(&UnsupportedTypeError{v.Type()})
347                 }
348                 if v.IsNil() {
349                         e.WriteString("null")
350                         break
351                 }
352                 e.WriteByte('{')
353                 var sv stringValues = v.MapKeys()
354                 sort.Sort(sv)
355                 for i, k := range sv {
356                         if i > 0 {
357                                 e.WriteByte(',')
358                         }
359                         e.string(k.String())
360                         e.WriteByte(':')
361                         e.reflectValue(v.MapIndex(k))
362                 }
363                 e.WriteByte('}')
364
365         case reflect.Slice:
366                 if v.IsNil() {
367                         e.WriteString("null")
368                         break
369                 }
370                 if v.Type().Elem().Kind() == reflect.Uint8 {
371                         // Byte slices get special treatment; arrays don't.
372                         s := v.Bytes()
373                         e.WriteByte('"')
374                         if len(s) < 1024 {
375                                 // for small buffers, using Encode directly is much faster.
376                                 dst := make([]byte, base64.StdEncoding.EncodedLen(len(s)))
377                                 base64.StdEncoding.Encode(dst, s)
378                                 e.Write(dst)
379                         } else {
380                                 // for large buffers, avoid unnecessary extra temporary
381                                 // buffer space.
382                                 enc := base64.NewEncoder(base64.StdEncoding, e)
383                                 enc.Write(s)
384                                 enc.Close()
385                         }
386                         e.WriteByte('"')
387                         break
388                 }
389                 // Slices can be marshalled as nil, but otherwise are handled
390                 // as arrays.
391                 fallthrough
392         case reflect.Array:
393                 e.WriteByte('[')
394                 n := v.Len()
395                 for i := 0; i < n; i++ {
396                         if i > 0 {
397                                 e.WriteByte(',')
398                         }
399                         e.reflectValue(v.Index(i))
400                 }
401                 e.WriteByte(']')
402
403         case reflect.Interface, reflect.Ptr:
404                 if v.IsNil() {
405                         e.WriteString("null")
406                         return
407                 }
408                 e.reflectValue(v.Elem())
409
410         default:
411                 e.error(&UnsupportedTypeError{v.Type()})
412         }
413         return
414 }
415
416 func isValidTag(s string) bool {
417         if s == "" {
418                 return false
419         }
420         for _, c := range s {
421                 switch {
422                 case strings.ContainsRune("!#$%&()*+-./:<=>?@[]^_{|}~", c):
423                         // Backslash and quote chars are reserved, but
424                         // otherwise any punctuation chars are allowed
425                         // in a tag name.
426                 default:
427                         if !unicode.IsLetter(c) && !unicode.IsDigit(c) {
428                                 return false
429                         }
430                 }
431         }
432         return true
433 }
434
435 // stringValues is a slice of reflect.Value holding *reflect.StringValue.
436 // It implements the methods to sort by string.
437 type stringValues []reflect.Value
438
439 func (sv stringValues) Len() int           { return len(sv) }
440 func (sv stringValues) Swap(i, j int)      { sv[i], sv[j] = sv[j], sv[i] }
441 func (sv stringValues) Less(i, j int) bool { return sv.get(i) < sv.get(j) }
442 func (sv stringValues) get(i int) string   { return sv[i].String() }
443
444 func (e *encodeState) string(s string) (int, error) {
445         len0 := e.Len()
446         e.WriteByte('"')
447         start := 0
448         for i := 0; i < len(s); {
449                 if b := s[i]; b < utf8.RuneSelf {
450                         if 0x20 <= b && b != '\\' && b != '"' && b != '<' && b != '>' {
451                                 i++
452                                 continue
453                         }
454                         if start < i {
455                                 e.WriteString(s[start:i])
456                         }
457                         switch b {
458                         case '\\', '"':
459                                 e.WriteByte('\\')
460                                 e.WriteByte(b)
461                         case '\n':
462                                 e.WriteByte('\\')
463                                 e.WriteByte('n')
464                         case '\r':
465                                 e.WriteByte('\\')
466                                 e.WriteByte('r')
467                         default:
468                                 // This encodes bytes < 0x20 except for \n and \r,
469                                 // as well as < and >. The latter are escaped because they
470                                 // can lead to security holes when user-controlled strings
471                                 // are rendered into JSON and served to some browsers.
472                                 e.WriteString(`\u00`)
473                                 e.WriteByte(hex[b>>4])
474                                 e.WriteByte(hex[b&0xF])
475                         }
476                         i++
477                         start = i
478                         continue
479                 }
480                 c, size := utf8.DecodeRuneInString(s[i:])
481                 if c == utf8.RuneError && size == 1 {
482                         e.error(&InvalidUTF8Error{s})
483                 }
484                 i += size
485         }
486         if start < len(s) {
487                 e.WriteString(s[start:])
488         }
489         e.WriteByte('"')
490         return e.Len() - len0, nil
491 }
492
493 // encodeField contains information about how to encode a field of a
494 // struct.
495 type encodeField struct {
496         i         int // field index in struct
497         tag       string
498         quoted    bool
499         omitEmpty bool
500 }
501
502 var (
503         typeCacheLock     sync.RWMutex
504         encodeFieldsCache = make(map[reflect.Type][]encodeField)
505 )
506
507 // encodeFields returns a slice of encodeField for a given
508 // struct type.
509 func encodeFields(t reflect.Type) []encodeField {
510         typeCacheLock.RLock()
511         fs, ok := encodeFieldsCache[t]
512         typeCacheLock.RUnlock()
513         if ok {
514                 return fs
515         }
516
517         typeCacheLock.Lock()
518         defer typeCacheLock.Unlock()
519         fs, ok = encodeFieldsCache[t]
520         if ok {
521                 return fs
522         }
523
524         v := reflect.Zero(t)
525         n := v.NumField()
526         for i := 0; i < n; i++ {
527                 f := t.Field(i)
528                 if f.PkgPath != "" {
529                         continue
530                 }
531                 if f.Anonymous {
532                         // We want to do a better job with these later,
533                         // so for now pretend they don't exist.
534                         continue
535                 }
536                 var ef encodeField
537                 ef.i = i
538                 ef.tag = f.Name
539
540                 tv := f.Tag.Get("json")
541                 if tv != "" {
542                         if tv == "-" {
543                                 continue
544                         }
545                         name, opts := parseTag(tv)
546                         if isValidTag(name) {
547                                 ef.tag = name
548                         }
549                         ef.omitEmpty = opts.Contains("omitempty")
550                         ef.quoted = opts.Contains("string")
551                 }
552                 fs = append(fs, ef)
553         }
554         encodeFieldsCache[t] = fs
555         return fs
556 }