OSDN Git Service

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