OSDN Git Service

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