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.
5 // Package json implements encoding and decoding of JSON objects as defined in
8 // See "JSON and Go" for an introduction to this package:
9 // http://blog.golang.org/2011/01/json-and-go.html
23 // Marshal returns the JSON encoding of v.
25 // Marshal traverses the value v recursively.
26 // If an encountered value implements the Marshaler interface
27 // and is not a nil pointer, Marshal calls its MarshalJSON method
28 // to produce JSON. The nil pointer exception is not strictly necessary
29 // but mimics a similar, necessary exception in the behavior of
32 // Otherwise, Marshal uses the following type-dependent default encodings:
34 // Boolean values encode as JSON booleans.
36 // Floating point and integer values encode as JSON numbers.
38 // String values encode as JSON strings, with each invalid UTF-8 sequence
39 // replaced by the encoding of the Unicode replacement character U+FFFD.
41 // Array and slice values encode as JSON arrays, except that
42 // []byte encodes as a base64-encoded string.
44 // Struct values encode as JSON objects. Each exported struct field
45 // becomes a member of the object unless
46 // - the field's tag is "-", or
47 // - the field is empty and its tag specifies the "omitempty" option.
48 // The empty values are false, 0, any
49 // nil pointer or interface value, and any array, slice, map, or string of
50 // length zero. The object's default key string is the struct field name
51 // but can be specified in the struct field's tag value. The "json" key in
52 // struct field's tag value is the key name, followed by an optional comma
53 // and options. Examples:
55 // // Field is ignored by this package.
56 // Field int `json:"-"`
58 // // Field appears in JSON as key "myName".
59 // Field int `json:"myName"`
61 // // Field appears in JSON as key "myName" and
62 // // the field is omitted from the object if its value is empty,
63 // // as defined above.
64 // Field int `json:"myName,omitempty"`
66 // // Field appears in JSON as key "Field" (the default), but
67 // // the field is skipped if empty.
68 // // Note the leading comma.
69 // Field int `json:",omitempty"`
71 // The "string" option signals that a field is stored as JSON inside a
72 // JSON-encoded string. This extra level of encoding is sometimes
73 // used when communicating with JavaScript programs:
75 // Int64String int64 `json:",string"`
77 // The key name will be used if it's a non-empty string consisting of
78 // only Unicode letters, digits, dollar signs, hyphens, and underscores.
80 // Map values encode as JSON objects.
81 // The map's key type must be string; the object keys are used directly
84 // Pointer values encode as the value pointed to.
85 // A nil pointer encodes as the null JSON object.
87 // Interface values encode as the value contained in the interface.
88 // A nil interface value encodes as the null JSON object.
90 // Channel, complex, and function values cannot be encoded in JSON.
91 // Attempting to encode such a value causes Marshal to return
92 // an InvalidTypeError.
94 // JSON cannot represent cyclic data structures and Marshal does not
95 // handle them. Passing cyclic structures to Marshal will result in
96 // an infinite recursion.
98 func Marshal(v interface{}) ([]byte, error) {
104 return e.Bytes(), nil
107 // MarshalIndent is like Marshal but applies Indent to format the output.
108 func MarshalIndent(v interface{}, prefix, indent string) ([]byte, error) {
114 err = Indent(&buf, b, prefix, indent)
118 return buf.Bytes(), nil
121 // MarshalForHTML is like Marshal but applies HTMLEscape to the output.
122 func MarshalForHTML(v interface{}) ([]byte, error) {
129 return buf.Bytes(), nil
132 // HTMLEscape appends to dst the JSON-encoded src with <, >, and &
133 // characters inside string literals changed to \u003c, \u003e, \u0026
134 // so that the JSON will be safe to embed inside HTML <script> tags.
135 // For historical reasons, web browsers don't honor standard HTML
136 // escaping within <script> tags, so an alternative JSON encoding must
138 func HTMLEscape(dst *bytes.Buffer, src []byte) {
139 // < > & can only appear in string literals,
140 // so just scan the string one byte at a time.
142 for i, c := range src {
143 if c == '<' || c == '>' || c == '&' {
145 dst.Write(src[start:i])
147 dst.WriteString(`\u00`)
148 dst.WriteByte(hex[c>>4])
149 dst.WriteByte(hex[c&0xF])
153 if start < len(src) {
154 dst.Write(src[start:])
158 // Marshaler is the interface implemented by objects that
159 // can marshal themselves into valid JSON.
160 type Marshaler interface {
161 MarshalJSON() ([]byte, error)
164 type UnsupportedTypeError struct {
168 func (e *UnsupportedTypeError) Error() string {
169 return "json: unsupported type: " + e.Type.String()
172 type InvalidUTF8Error struct {
176 func (e *InvalidUTF8Error) Error() string {
177 return "json: invalid UTF-8 in string: " + strconv.Quote(e.S)
180 type MarshalerError struct {
185 func (e *MarshalerError) Error() string {
186 return "json: error calling MarshalJSON for type " + e.Type.String() + ": " + e.Err.Error()
189 type interfaceOrPtrValue interface {
194 var hex = "0123456789abcdef"
196 // An encodeState encodes JSON into a bytes.Buffer.
197 type encodeState struct {
198 bytes.Buffer // accumulated output
201 func (e *encodeState) marshal(v interface{}) (err error) {
203 if r := recover(); r != nil {
204 if _, ok := r.(runtime.Error); ok {
210 e.reflectValue(reflect.ValueOf(v))
214 func (e *encodeState) error(err error) {
218 var byteSliceType = reflect.TypeOf([]byte(nil))
220 func isEmptyValue(v reflect.Value) bool {
222 case reflect.Array, reflect.Map, reflect.Slice, reflect.String:
226 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
228 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
230 case reflect.Float32, reflect.Float64:
231 return v.Float() == 0
232 case reflect.Interface, reflect.Ptr:
238 func (e *encodeState) reflectValue(v reflect.Value) {
239 e.reflectValueQuoted(v, false)
242 // reflectValueQuoted writes the value in v to the output.
243 // If quoted is true, the serialization is wrapped in a JSON string.
244 func (e *encodeState) reflectValueQuoted(v reflect.Value, quoted bool) {
246 e.WriteString("null")
250 if j, ok := v.Interface().(Marshaler); ok && (v.Kind() != reflect.Ptr || !v.IsNil()) {
251 b, err := j.MarshalJSON()
253 // copy JSON into buffer, checking validity.
254 err = Compact(&e.Buffer, b)
257 e.error(&MarshalerError{v.Type(), err})
262 writeString := (*encodeState).WriteString
264 writeString = (*encodeState).string
271 writeString(e, "true")
273 writeString(e, "false")
276 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
277 writeString(e, strconv.Itoa64(v.Int()))
279 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
280 writeString(e, strconv.Uitoa64(v.Uint()))
282 case reflect.Float32, reflect.Float64:
283 writeString(e, strconv.FtoaN(v.Float(), 'g', -1, v.Type().Bits()))
287 sb, err := Marshal(v.String())
301 for i := 0; i < n; i++ {
306 tag, omitEmpty, quoted := f.Name, false, false
307 if tv := f.Tag.Get("json"); tv != "" {
311 name, opts := parseTag(tv)
312 if isValidTag(name) {
315 omitEmpty = opts.Contains("omitempty")
316 quoted = opts.Contains("string")
318 fieldValue := v.Field(i)
319 if omitEmpty && isEmptyValue(fieldValue) {
329 e.reflectValueQuoted(fieldValue, quoted)
334 if v.Type().Key().Kind() != reflect.String {
335 e.error(&UnsupportedTypeError{v.Type()})
338 e.WriteString("null")
342 var sv stringValues = v.MapKeys()
344 for i, k := range sv {
350 e.reflectValue(v.MapIndex(k))
356 e.WriteString("null")
359 // Slices can be marshalled as nil, but otherwise are handled
363 if v.Type() == byteSliceType {
365 s := v.Interface().([]byte)
367 // for small buffers, using Encode directly is much faster.
368 dst := make([]byte, base64.StdEncoding.EncodedLen(len(s)))
369 base64.StdEncoding.Encode(dst, s)
372 // for large buffers, avoid unnecessary extra temporary
374 enc := base64.NewEncoder(base64.StdEncoding, e)
383 for i := 0; i < n; i++ {
387 e.reflectValue(v.Index(i))
391 case reflect.Interface, reflect.Ptr:
393 e.WriteString("null")
396 e.reflectValue(v.Elem())
399 e.error(&UnsupportedTypeError{v.Type()})
404 func isValidTag(s string) bool {
408 for _, c := range s {
409 if c != '$' && c != '-' && c != '_' && !unicode.IsLetter(c) && !unicode.IsDigit(c) {
416 // stringValues is a slice of reflect.Value holding *reflect.StringValue.
417 // It implements the methods to sort by string.
418 type stringValues []reflect.Value
420 func (sv stringValues) Len() int { return len(sv) }
421 func (sv stringValues) Swap(i, j int) { sv[i], sv[j] = sv[j], sv[i] }
422 func (sv stringValues) Less(i, j int) bool { return sv.get(i) < sv.get(j) }
423 func (sv stringValues) get(i int) string { return sv[i].String() }
425 func (e *encodeState) string(s string) (int, error) {
429 for i := 0; i < len(s); {
430 if b := s[i]; b < utf8.RuneSelf {
431 if 0x20 <= b && b != '\\' && b != '"' && b != '<' && b != '>' {
436 e.WriteString(s[start:i])
449 // This encodes bytes < 0x20 except for \n and \r,
450 // as well as < and >. The latter are escaped because they
451 // can lead to security holes when user-controlled strings
452 // are rendered into JSON and served to some browsers.
453 e.WriteString(`\u00`)
454 e.WriteByte(hex[b>>4])
455 e.WriteByte(hex[b&0xF])
461 c, size := utf8.DecodeRuneInString(s[i:])
462 if c == utf8.RuneError && size == 1 {
463 e.error(&InvalidUTF8Error{s})
468 e.WriteString(s[start:])
471 return e.Len() - len0, nil