1199 lines · 30.9 KB · Go
RawDownload
// Copyright 2010 The Go Authors.  All rights reserved.// Use of this source code is governed by a BSD-style// license that can be found in the LICENSE file. // Package json implements encoding and decoding of JSON objects as defined in// RFC 4627. The mapping between JSON objects and Go values is described// in the documentation for the Marshal and Unmarshal functions.//// See "JSON and Go" for an introduction to this package:// https://golang.org/doc/articles/json_and_go.htmlpackage json import (	"bytes"	"encoding"	"encoding/base64"	"fmt"	"math"	"reflect"	"runtime"	"sort"	"strconv"	"strings"	"sync"	"unicode"	"unicode/utf8") // Marshal returns the JSON encoding of v.//// Marshal traverses the value v recursively.// If an encountered value implements the Marshaler interface// and is not a nil pointer, Marshal calls its MarshalJSON method// to produce JSON. If no MarshalJSON method is present but the// value implements encoding.TextMarshaler instead, Marshal calls// its MarshalText method.// The nil pointer exception is not strictly necessary// but mimics a similar, necessary exception in the behavior of// UnmarshalJSON.//// Otherwise, Marshal uses the following type-dependent default encodings://// Boolean values encode as JSON booleans.//// Floating point, integer, and Number values encode as JSON numbers.//// String values encode as JSON strings coerced to valid UTF-8,// replacing invalid bytes with the Unicode replacement rune.// The angle brackets "<" and ">" are escaped to "\u003c" and "\u003e"// to keep some browsers from misinterpreting JSON output as HTML.// Ampersand "&" is also escaped to "\u0026" for the same reason.//// Array and slice values encode as JSON arrays, except that// []byte encodes as a base64-encoded string, and a nil slice// encodes as the null JSON object.//// Struct values encode as JSON objects. Each exported struct field// becomes a member of the object unless//   - the field's tag is "-", or//   - the field is empty and its tag specifies the "omitempty" option.// The empty values are false, 0, any// nil pointer or interface value, and any array, slice, map, or string of// length zero. The object's default key string is the struct field name// but can be specified in the struct field's tag value. The "json" key in// the struct field's tag value is the key name, followed by an optional comma// and options. Examples:////   // Field is ignored by this package.//   Field int `json:"-"`////   // Field appears in JSON as key "myName".//   Field int `json:"myName"`////   // Field appears in JSON as key "myName" and//   // the field is omitted from the object if its value is empty,//   // as defined above.//   Field int `json:"myName,omitempty"`////   // Field appears in JSON as key "Field" (the default), but//   // the field is skipped if empty.//   // Note the leading comma.//   Field int `json:",omitempty"`//// The "string" option signals that a field is stored as JSON inside a// JSON-encoded string. It applies only to fields of string, floating point,// integer, or boolean types. This extra level of encoding is sometimes used// when communicating with JavaScript programs:////    Int64String int64 `json:",string"`//// The key name will be used if it's a non-empty string consisting of// only Unicode letters, digits, dollar signs, percent signs, hyphens,// underscores and slashes.//// Anonymous struct fields are usually marshaled as if their inner exported fields// were fields in the outer struct, subject to the usual Go visibility rules amended// as described in the next paragraph.// An anonymous struct field with a name given in its JSON tag is treated as// having that name, rather than being anonymous.// An anonymous struct field of interface type is treated the same as having// that type as its name, rather than being anonymous.//// The Go visibility rules for struct fields are amended for JSON when// deciding which field to marshal or unmarshal. If there are// multiple fields at the same level, and that level is the least// nested (and would therefore be the nesting level selected by the// usual Go rules), the following extra rules apply://// 1) Of those fields, if any are JSON-tagged, only tagged fields are considered,// even if there are multiple untagged fields that would otherwise conflict.// 2) If there is exactly one field (tagged or not according to the first rule), that is selected.// 3) Otherwise there are multiple fields, and all are ignored; no error occurs.//// Handling of anonymous struct fields is new in Go 1.1.// Prior to Go 1.1, anonymous struct fields were ignored. To force ignoring of// an anonymous struct field in both current and earlier versions, give the field// a JSON tag of "-".//// Map values encode as JSON objects.// The map's key type must be string; the map keys are used as JSON object// keys, subject to the UTF-8 coercion described for string values above.//// Pointer values encode as the value pointed to.// A nil pointer encodes as the null JSON object.//// Interface values encode as the value contained in the interface.// A nil interface value encodes as the null JSON object.//// Channel, complex, and function values cannot be encoded in JSON.// Attempting to encode such a value causes Marshal to return// an UnsupportedTypeError.//// JSON cannot represent cyclic data structures and Marshal does not// handle them.  Passing cyclic structures to Marshal will result in// an infinite recursion.//func Marshal(v interface{}) ([]byte, error) {	e := &encodeState{}	err := e.marshal(v)	if err != nil {		return nil, err	}	return e.Bytes(), nil} // MarshalIndent is like Marshal but applies Indent to format the output.func MarshalIndent(v interface{}, prefix, indent string) ([]byte, error) {	b, err := Marshal(v)	if err != nil {		return nil, err	}	var buf bytes.Buffer	err = Indent(&buf, b, prefix, indent)	if err != nil {		return nil, err	}	return buf.Bytes(), nil} // HTMLEscape appends to dst the JSON-encoded src with <, >, &, U+2028 and U+2029// characters inside string literals changed to \u003c, \u003e, \u0026, \u2028, \u2029// so that the JSON will be safe to embed inside HTML <script> tags.// For historical reasons, web browsers don't honor standard HTML// escaping within <script> tags, so an alternative JSON encoding must// be used.func HTMLEscape(dst *bytes.Buffer, src []byte) {	// The characters can only appear in string literals,	// so just scan the string one byte at a time.	start := 0	for i, c := range src {		if c == '<' || c == '>' || c == '&' {			if start < i {				dst.Write(src[start:i])			}			dst.WriteString(`\u00`)			dst.WriteByte(hex[c>>4])			dst.WriteByte(hex[c&0xF])			start = i + 1		}		// Convert U+2028 and U+2029 (E2 80 A8 and E2 80 A9).		if c == 0xE2 && i+2 < len(src) && src[i+1] == 0x80 && src[i+2]&^1 == 0xA8 {			if start < i {				dst.Write(src[start:i])			}			dst.WriteString(`\u202`)			dst.WriteByte(hex[src[i+2]&0xF])			start = i + 3		}	}	if start < len(src) {		dst.Write(src[start:])	}} // Marshaler is the interface implemented by objects that// can marshal themselves into valid JSON.type Marshaler interface {	MarshalJSON() ([]byte, error)} // An UnsupportedTypeError is returned by Marshal when attempting// to encode an unsupported value type.type UnsupportedTypeError struct {	Type reflect.Type} func (e *UnsupportedTypeError) Error() string {	return "json: unsupported type: " + e.Type.String()} type UnsupportedValueError struct {	Value reflect.Value	Str   string} func (e *UnsupportedValueError) Error() string {	return "json: unsupported value: " + e.Str} // Before Go 1.2, an InvalidUTF8Error was returned by Marshal when// attempting to encode a string value with invalid UTF-8 sequences.// As of Go 1.2, Marshal instead coerces the string to valid UTF-8 by// replacing invalid bytes with the Unicode replacement rune U+FFFD.// This error is no longer generated but is kept for backwards compatibility// with programs that might mention it.type InvalidUTF8Error struct {	S string // the whole string value that caused the error} func (e *InvalidUTF8Error) Error() string {	return "json: invalid UTF-8 in string: " + strconv.Quote(e.S)} type MarshalerError struct {	Type reflect.Type	Err  error} func (e *MarshalerError) Error() string {	return "json: error calling MarshalJSON for type " + e.Type.String() + ": " + e.Err.Error()} var hex = "0123456789abcdef" // An encodeState encodes JSON into a bytes.Buffer.type encodeState struct {	bytes.Buffer // accumulated output	scratch      [64]byte} var encodeStatePool sync.Pool func newEncodeState() *encodeState {	if v := encodeStatePool.Get(); v != nil {		e := v.(*encodeState)		e.Reset()		return e	}	return new(encodeState)} func (e *encodeState) marshal(v interface{}) (err error) {	defer func() {		if r := recover(); r != nil {			if _, ok := r.(runtime.Error); ok {				panic(r)			}			if s, ok := r.(string); ok {				panic(s)			}			err = r.(error)		}	}()	e.reflectValue(reflect.ValueOf(v))	return nil} func (e *encodeState) error(err error) {	panic(err)} func isEmptyValue(v reflect.Value) bool {	switch v.Kind() {	case reflect.Array, reflect.Map, reflect.Slice, reflect.String:		return v.Len() == 0	case reflect.Bool:		return !v.Bool()	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:		return v.Int() == 0	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:		return v.Uint() == 0	case reflect.Float32, reflect.Float64:		return v.Float() == 0	case reflect.Interface, reflect.Ptr:		return v.IsNil()	}	return false} func (e *encodeState) reflectValue(v reflect.Value) {	valueEncoder(v)(e, v, false)} type encoderFunc func(e *encodeState, v reflect.Value, quoted bool) var encoderCache struct {	sync.RWMutex	m map[reflect.Type]encoderFunc} func valueEncoder(v reflect.Value) encoderFunc {	if !v.IsValid() {		return invalidValueEncoder	}	return typeEncoder(v.Type())} func typeEncoder(t reflect.Type) encoderFunc {	encoderCache.RLock()	f := encoderCache.m[t]	encoderCache.RUnlock()	if f != nil {		return f	} 	// To deal with recursive types, populate the map with an	// indirect func before we build it. This type waits on the	// real func (f) to be ready and then calls it.  This indirect	// func is only used for recursive types.	encoderCache.Lock()	if encoderCache.m == nil {		encoderCache.m = make(map[reflect.Type]encoderFunc)	}	var wg sync.WaitGroup	wg.Add(1)	encoderCache.m[t] = func(e *encodeState, v reflect.Value, quoted bool) {		wg.Wait()		f(e, v, quoted)	}	encoderCache.Unlock() 	// Compute fields without lock.	// Might duplicate effort but won't hold other computations back.	f = newTypeEncoder(t, true)	wg.Done()	encoderCache.Lock()	encoderCache.m[t] = f	encoderCache.Unlock()	return f} var (	marshalerType     = reflect.TypeOf(new(Marshaler)).Elem()	textMarshalerType = reflect.TypeOf(new(encoding.TextMarshaler)).Elem()) // newTypeEncoder constructs an encoderFunc for a type.// The returned encoder only checks CanAddr when allowAddr is true.func newTypeEncoder(t reflect.Type, allowAddr bool) encoderFunc {	if t.Implements(marshalerType) {		return marshalerEncoder	}	if t.Kind() != reflect.Ptr && allowAddr {		if reflect.PtrTo(t).Implements(marshalerType) {			return newCondAddrEncoder(addrMarshalerEncoder, newTypeEncoder(t, false))		}	} 	if t.Implements(textMarshalerType) {		return textMarshalerEncoder	}	if t.Kind() != reflect.Ptr && allowAddr {		if reflect.PtrTo(t).Implements(textMarshalerType) {			return newCondAddrEncoder(addrTextMarshalerEncoder, newTypeEncoder(t, false))		}	} 	switch t.Kind() {	case reflect.Bool:		return boolEncoder	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:		return intEncoder	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:		return uintEncoder	case reflect.Float32:		return float32Encoder	case reflect.Float64:		return float64Encoder	case reflect.String:		return stringEncoder	case reflect.Interface:		return interfaceEncoder	case reflect.Struct:		return newStructEncoder(t)	case reflect.Map:		return newMapEncoder(t)	case reflect.Slice:		return newSliceEncoder(t)	case reflect.Array:		return newArrayEncoder(t)	case reflect.Ptr:		return newPtrEncoder(t)	default:		return unsupportedTypeEncoder	}} func invalidValueEncoder(e *encodeState, v reflect.Value, quoted bool) {	e.WriteString("null")} func marshalerEncoder(e *encodeState, v reflect.Value, quoted bool) {	if v.Kind() == reflect.Ptr && v.IsNil() {		e.WriteString("null")		return	}	m := v.Interface().(Marshaler)	b, err := m.MarshalJSON()	if err == nil {		// copy JSON into buffer, checking validity.		err = compact(&e.Buffer, b, true)	}	if err != nil {		e.error(&MarshalerError{v.Type(), err})	}} func addrMarshalerEncoder(e *encodeState, v reflect.Value, quoted bool) {	va := v.Addr()	if va.IsNil() {		e.WriteString("null")		return	}	m := va.Interface().(Marshaler)	b, err := m.MarshalJSON()	if err == nil {		// copy JSON into buffer, checking validity.		err = compact(&e.Buffer, b, true)	}	if err != nil {		e.error(&MarshalerError{v.Type(), err})	}} func textMarshalerEncoder(e *encodeState, v reflect.Value, quoted bool) {	if v.Kind() == reflect.Ptr && v.IsNil() {		e.WriteString("null")		return	}	m := v.Interface().(encoding.TextMarshaler)	b, err := m.MarshalText()	if err != nil {		e.error(&MarshalerError{v.Type(), err})	}	e.stringBytes(b)} func addrTextMarshalerEncoder(e *encodeState, v reflect.Value, quoted bool) {	va := v.Addr()	if va.IsNil() {		e.WriteString("null")		return	}	m := va.Interface().(encoding.TextMarshaler)	b, err := m.MarshalText()	if err != nil {		e.error(&MarshalerError{v.Type(), err})	}	e.stringBytes(b)} func boolEncoder(e *encodeState, v reflect.Value, quoted bool) {	if quoted {		e.WriteByte('"')	}	if v.Bool() {		e.WriteString("true")	} else {		e.WriteString("false")	}	if quoted {		e.WriteByte('"')	}} func intEncoder(e *encodeState, v reflect.Value, quoted bool) {	b := strconv.AppendInt(e.scratch[:0], v.Int(), 10)	if quoted {		e.WriteByte('"')	}	e.Write(b)	if quoted {		e.WriteByte('"')	}} func uintEncoder(e *encodeState, v reflect.Value, quoted bool) {	b := strconv.AppendUint(e.scratch[:0], v.Uint(), 10)	if quoted {		e.WriteByte('"')

Lines 1–500 of 1199.