OSDN Git Service

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