URL
https://opencores.org/ocsvn/openrisc/openrisc/trunk
Subversion Repositories openrisc
[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libgo/] [go/] [encoding/] [json/] [decode.go] - Rev 747
Compare with Previous | Blame | View Log
// 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.// Represents JSON data structure using native Go types: booleans, floats,// strings, arrays, and maps.package jsonimport ("encoding/base64""errors""fmt""reflect""runtime""strconv""strings""unicode""unicode/utf16""unicode/utf8")// Unmarshal parses the JSON-encoded data and stores the result// in the value pointed to by v.//// Unmarshal uses the inverse of the encodings that// Marshal uses, allocating maps, slices, and pointers as necessary,// with the following additional rules://// To unmarshal JSON into a pointer, Unmarshal first handles the case of// the JSON being the JSON literal null. In that case, Unmarshal sets// the pointer to nil. Otherwise, Unmarshal unmarshals the JSON into// the value pointed at by the pointer. If the pointer is nil, Unmarshal// allocates a new value for it to point to.//// To unmarshal JSON into an interface value, Unmarshal unmarshals// the JSON into the concrete value contained in the interface value.// If the interface value is nil, that is, has no concrete value stored in it,// Unmarshal stores one of these in the interface value://// bool, for JSON booleans// float64, for JSON numbers// string, for JSON strings// []interface{}, for JSON arrays// map[string]interface{}, for JSON objects// nil for JSON null//// If a JSON value is not appropriate for a given target type,// or if a JSON number overflows the target type, Unmarshal// skips that field and completes the unmarshalling as best it can.// If no more serious errors are encountered, Unmarshal returns// an UnmarshalTypeError describing the earliest such error.//func Unmarshal(data []byte, v interface{}) error {d := new(decodeState).init(data)// Quick check for well-formedness.// Avoids filling out half a data structure// before discovering a JSON syntax error.err := checkValid(data, &d.scan)if err != nil {return err}return d.unmarshal(v)}// Unmarshaler is the interface implemented by objects// that can unmarshal a JSON description of themselves.// The input can be assumed to be a valid JSON object// encoding. UnmarshalJSON must copy the JSON data// if it wishes to retain the data after returning.type Unmarshaler interface {UnmarshalJSON([]byte) error}// An UnmarshalTypeError describes a JSON value that was// not appropriate for a value of a specific Go type.type UnmarshalTypeError struct {Value string // description of JSON value - "bool", "array", "number -5"Type reflect.Type // type of Go value it could not be assigned to}func (e *UnmarshalTypeError) Error() string {return "json: cannot unmarshal " + e.Value + " into Go value of type " + e.Type.String()}// An UnmarshalFieldError describes a JSON object key that// led to an unexported (and therefore unwritable) struct field.type UnmarshalFieldError struct {Key stringType reflect.TypeField reflect.StructField}func (e *UnmarshalFieldError) Error() string {return "json: cannot unmarshal object key " + strconv.Quote(e.Key) + " into unexported field " + e.Field.Name + " of type " + e.Type.String()}// An InvalidUnmarshalError describes an invalid argument passed to Unmarshal.// (The argument to Unmarshal must be a non-nil pointer.)type InvalidUnmarshalError struct {Type reflect.Type}func (e *InvalidUnmarshalError) Error() string {if e.Type == nil {return "json: Unmarshal(nil)"}if e.Type.Kind() != reflect.Ptr {return "json: Unmarshal(non-pointer " + e.Type.String() + ")"}return "json: Unmarshal(nil " + e.Type.String() + ")"}func (d *decodeState) unmarshal(v interface{}) (err error) {defer func() {if r := recover(); r != nil {if _, ok := r.(runtime.Error); ok {panic(r)}err = r.(error)}}()rv := reflect.ValueOf(v)pv := rvif pv.Kind() != reflect.Ptr || pv.IsNil() {return &InvalidUnmarshalError{reflect.TypeOf(v)}}d.scan.reset()// We decode rv not pv.Elem because the Unmarshaler interface// test must be applied at the top level of the value.d.value(rv)return d.savedError}// decodeState represents the state while decoding a JSON value.type decodeState struct {data []byteoff int // read offset in datascan scannernextscan scanner // for calls to nextValuesavedError errortempstr string // scratch space to avoid some allocations}// errPhase is used for errors that should not happen unless// there is a bug in the JSON decoder or something is editing// the data slice while the decoder executes.var errPhase = errors.New("JSON decoder out of sync - data changing underfoot?")func (d *decodeState) init(data []byte) *decodeState {d.data = datad.off = 0d.savedError = nilreturn d}// error aborts the decoding by panicking with err.func (d *decodeState) error(err error) {panic(err)}// saveError saves the first err it is called with,// for reporting at the end of the unmarshal.func (d *decodeState) saveError(err error) {if d.savedError == nil {d.savedError = err}}// next cuts off and returns the next full JSON value in d.data[d.off:].// The next value is known to be an object or array, not a literal.func (d *decodeState) next() []byte {c := d.data[d.off]item, rest, err := nextValue(d.data[d.off:], &d.nextscan)if err != nil {d.error(err)}d.off = len(d.data) - len(rest)// Our scanner has seen the opening brace/bracket// and thinks we're still in the middle of the object.// invent a closing brace/bracket to get it out.if c == '{' {d.scan.step(&d.scan, '}')} else {d.scan.step(&d.scan, ']')}return item}// scanWhile processes bytes in d.data[d.off:] until it// receives a scan code not equal to op.// It updates d.off and returns the new scan code.func (d *decodeState) scanWhile(op int) int {var newOp intfor {if d.off >= len(d.data) {newOp = d.scan.eof()d.off = len(d.data) + 1 // mark processed EOF with len+1} else {c := int(d.data[d.off])d.off++newOp = d.scan.step(&d.scan, c)}if newOp != op {break}}return newOp}// value decodes a JSON value from d.data[d.off:] into the value.// it updates d.off to point past the decoded value.func (d *decodeState) value(v reflect.Value) {if !v.IsValid() {_, rest, err := nextValue(d.data[d.off:], &d.nextscan)if err != nil {d.error(err)}d.off = len(d.data) - len(rest)// d.scan thinks we're still at the beginning of the item.// Feed in an empty string - the shortest, simplest value -// so that it knows we got to the end of the value.if d.scan.redo {// rewind.d.scan.redo = falsed.scan.step = stateBeginValue}d.scan.step(&d.scan, '"')d.scan.step(&d.scan, '"')return}switch op := d.scanWhile(scanSkipSpace); op {default:d.error(errPhase)case scanBeginArray:d.array(v)case scanBeginObject:d.object(v)case scanBeginLiteral:d.literal(v)}}// indirect walks down v allocating pointers as needed,// until it gets to a non-pointer.// if it encounters an Unmarshaler, indirect stops and returns that.// if decodingNull is true, indirect stops at the last pointer so it can be set to nil.func (d *decodeState) indirect(v reflect.Value, decodingNull bool) (Unmarshaler, reflect.Value) {// If v is a named type and is addressable,// start with its address, so that if the type has pointer methods,// we find them.if v.Kind() != reflect.Ptr && v.Type().Name() != "" && v.CanAddr() {v = v.Addr()}for {var isUnmarshaler boolif v.Type().NumMethod() > 0 {// Remember that this is an unmarshaler,// but wait to return it until after allocating// the pointer (if necessary)._, isUnmarshaler = v.Interface().(Unmarshaler)}if iv := v; iv.Kind() == reflect.Interface && !iv.IsNil() {v = iv.Elem()continue}pv := vif pv.Kind() != reflect.Ptr {break}if pv.Elem().Kind() != reflect.Ptr && decodingNull && pv.CanSet() {return nil, pv}if pv.IsNil() {pv.Set(reflect.New(pv.Type().Elem()))}if isUnmarshaler {// Using v.Interface().(Unmarshaler)// here means that we have to use a pointer// as the struct field. We cannot use a value inside// a pointer to a struct, because in that case// v.Interface() is the value (x.f) not the pointer (&x.f).// This is an unfortunate consequence of reflect.// An alternative would be to look up the// UnmarshalJSON method and return a FuncValue.return v.Interface().(Unmarshaler), reflect.Value{}}v = pv.Elem()}return nil, v}// array consumes an array from d.data[d.off-1:], decoding into the value v.// the first byte of the array ('[') has been read already.func (d *decodeState) array(v reflect.Value) {// Check for unmarshaler.unmarshaler, pv := d.indirect(v, false)if unmarshaler != nil {d.off--err := unmarshaler.UnmarshalJSON(d.next())if err != nil {d.error(err)}return}v = pv// Check type of target.switch v.Kind() {default:d.saveError(&UnmarshalTypeError{"array", v.Type()})d.off--d.next()returncase reflect.Interface:// Decoding into nil interface? Switch to non-reflect code.v.Set(reflect.ValueOf(d.arrayInterface()))returncase reflect.Array:case reflect.Slice:break}i := 0for {// Look ahead for ] - can only happen on first iteration.op := d.scanWhile(scanSkipSpace)if op == scanEndArray {break}// Back up so d.value can have the byte we just read.d.off--d.scan.undo(op)// Get element of array, growing if necessary.if v.Kind() == reflect.Slice {// Grow slice if necessaryif i >= v.Cap() {newcap := v.Cap() + v.Cap()/2if newcap < 4 {newcap = 4}newv := reflect.MakeSlice(v.Type(), v.Len(), newcap)reflect.Copy(newv, v)v.Set(newv)}if i >= v.Len() {v.SetLen(i + 1)}}if i < v.Len() {// Decode into element.d.value(v.Index(i))} else {// Ran out of fixed array: skip.d.value(reflect.Value{})}i++// Next token must be , or ].op = d.scanWhile(scanSkipSpace)if op == scanEndArray {break}if op != scanArrayValue {d.error(errPhase)}}if i < v.Len() {if v.Kind() == reflect.Array {// Array. Zero the rest.z := reflect.Zero(v.Type().Elem())for ; i < v.Len(); i++ {v.Index(i).Set(z)}} else {v.SetLen(i)}}if i == 0 && v.Kind() == reflect.Slice {v.Set(reflect.MakeSlice(v.Type(), 0, 0))}}// object consumes an object from d.data[d.off-1:], decoding into the value v.// the first byte of the object ('{') has been read already.func (d *decodeState) object(v reflect.Value) {// Check for unmarshaler.unmarshaler, pv := d.indirect(v, false)if unmarshaler != nil {d.off--err := unmarshaler.UnmarshalJSON(d.next())if err != nil {d.error(err)}return}v = pv// Decoding into nil interface? Switch to non-reflect code.iv := vif iv.Kind() == reflect.Interface {iv.Set(reflect.ValueOf(d.objectInterface()))return}// Check type of target: struct or map[string]Tvar (mv reflect.Valuesv reflect.Value)switch v.Kind() {case reflect.Map:// map must have string typet := v.Type()if t.Key() != reflect.TypeOf("") {d.saveError(&UnmarshalTypeError{"object", v.Type()})break}mv = vif mv.IsNil() {mv.Set(reflect.MakeMap(t))}case reflect.Struct:sv = vdefault:d.saveError(&UnmarshalTypeError{"object", v.Type()})}if !mv.IsValid() && !sv.IsValid() {d.off--d.next() // skip over { } in inputreturn}var mapElem reflect.Valuefor {// Read opening " of string key or closing }.op := d.scanWhile(scanSkipSpace)if op == scanEndObject {// closing } - can only happen on first iteration.break}if op != scanBeginLiteral {d.error(errPhase)}// Read string key.start := d.off - 1op = d.scanWhile(scanContinue)item := d.data[start : d.off-1]key, ok := unquote(item)if !ok {d.error(errPhase)}// Figure out field corresponding to key.var subv reflect.Valuedestring := false // whether the value is wrapped in a string to be decoded firstif mv.IsValid() {elemType := mv.Type().Elem()if !mapElem.IsValid() {mapElem = reflect.New(elemType).Elem()} else {mapElem.Set(reflect.Zero(elemType))}subv = mapElem} else {var f reflect.StructFieldvar ok boolst := sv.Type()for i := 0; i < sv.NumField(); i++ {sf := st.Field(i)tag := sf.Tag.Get("json")if tag == "-" {// Pretend this field doesn't exist.continue}// First, tag matchtagName, _ := parseTag(tag)if tagName == key {f = sfok = truebreak // no better match possible}// Second, exact field name matchif sf.Name == key {f = sfok = true}// Third, case-insensitive field name match,// but only if a better match hasn't already been seenif !ok && strings.EqualFold(sf.Name, key) {f = sfok = true}}// Extract value; name must be exported.if ok {if f.PkgPath != "" {d.saveError(&UnmarshalFieldError{key, st, f})} else {subv = sv.FieldByIndex(f.Index)}_, opts := parseTag(f.Tag.Get("json"))destring = opts.Contains("string")}}// Read : before value.if op == scanSkipSpace {op = d.scanWhile(scanSkipSpace)}if op != scanObjectKey {d.error(errPhase)}// Read value.if destring {d.value(reflect.ValueOf(&d.tempstr))d.literalStore([]byte(d.tempstr), subv, true)} else {d.value(subv)}// Write value back to map;// if using struct, subv points into struct already.if mv.IsValid() {mv.SetMapIndex(reflect.ValueOf(key), subv)}// Next token must be , or }.op = d.scanWhile(scanSkipSpace)if op == scanEndObject {break}if op != scanObjectValue {d.error(errPhase)}}}// literal consumes a literal from d.data[d.off-1:], decoding into the value v.// The first byte of the literal has been read already// (that's how the caller knows it's a literal).func (d *decodeState) literal(v reflect.Value) {// All bytes inside literal return scanContinue op code.start := d.off - 1op := d.scanWhile(scanContinue)// Scan read one byte too far; back up.d.off--d.scan.undo(op)d.literalStore(d.data[start:d.off], v, false)}// literalStore decodes a literal stored in item into v.//// fromQuoted indicates whether this literal came from unwrapping a// string from the ",string" struct tag option. this is used only to// produce more helpful error messages.func (d *decodeState) literalStore(item []byte, v reflect.Value, fromQuoted bool) {// Check for unmarshaler.wantptr := item[0] == 'n' // nullunmarshaler, pv := d.indirect(v, wantptr)if unmarshaler != nil {err := unmarshaler.UnmarshalJSON(item)if err != nil {d.error(err)}return}v = pvswitch c := item[0]; c {case 'n': // nullswitch v.Kind() {default:d.saveError(&UnmarshalTypeError{"null", v.Type()})case reflect.Interface, reflect.Ptr, reflect.Map, reflect.Slice:v.Set(reflect.Zero(v.Type()))}case 't', 'f': // true, falsevalue := c == 't'switch v.Kind() {default:if fromQuoted {d.saveError(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type()))} else {d.saveError(&UnmarshalTypeError{"bool", v.Type()})}case reflect.Bool:v.SetBool(value)case reflect.Interface:v.Set(reflect.ValueOf(value))}case '"': // strings, ok := unquoteBytes(item)if !ok {if fromQuoted {d.error(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type()))} else {d.error(errPhase)}}switch v.Kind() {default:d.saveError(&UnmarshalTypeError{"string", v.Type()})case reflect.Slice:if v.Type() != byteSliceType {d.saveError(&UnmarshalTypeError{"string", v.Type()})break}b := make([]byte, base64.StdEncoding.DecodedLen(len(s)))n, err := base64.StdEncoding.Decode(b, s)if err != nil {d.saveError(err)break}v.Set(reflect.ValueOf(b[0:n]))case reflect.String:v.SetString(string(s))case reflect.Interface:v.Set(reflect.ValueOf(string(s)))}default: // numberif c != '-' && (c < '0' || c > '9') {if fromQuoted {d.error(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type()))} else {d.error(errPhase)}}s := string(item)switch v.Kind() {default:if fromQuoted {d.error(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type()))} else {d.error(&UnmarshalTypeError{"number", v.Type()})}case reflect.Interface:n, err := strconv.ParseFloat(s, 64)if err != nil {d.saveError(&UnmarshalTypeError{"number " + s, v.Type()})break}v.Set(reflect.ValueOf(n))case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:n, err := strconv.ParseInt(s, 10, 64)if err != nil || v.OverflowInt(n) {d.saveError(&UnmarshalTypeError{"number " + s, v.Type()})break}v.SetInt(n)case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:n, err := strconv.ParseUint(s, 10, 64)if err != nil || v.OverflowUint(n) {d.saveError(&UnmarshalTypeError{"number " + s, v.Type()})break}v.SetUint(n)case reflect.Float32, reflect.Float64:n, err := strconv.ParseFloat(s, v.Type().Bits())if err != nil || v.OverflowFloat(n) {d.saveError(&UnmarshalTypeError{"number " + s, v.Type()})break}v.SetFloat(n)}}}// The xxxInterface routines build up a value to be stored// in an empty interface. They are not strictly necessary,// but they avoid the weight of reflection in this common case.// valueInterface is like value but returns interface{}func (d *decodeState) valueInterface() interface{} {switch d.scanWhile(scanSkipSpace) {default:d.error(errPhase)case scanBeginArray:return d.arrayInterface()case scanBeginObject:return d.objectInterface()case scanBeginLiteral:return d.literalInterface()}panic("unreachable")}// arrayInterface is like array but returns []interface{}.func (d *decodeState) arrayInterface() []interface{} {var v []interface{}for {// Look ahead for ] - can only happen on first iteration.op := d.scanWhile(scanSkipSpace)if op == scanEndArray {break}// Back up so d.value can have the byte we just read.d.off--d.scan.undo(op)v = append(v, d.valueInterface())// Next token must be , or ].op = d.scanWhile(scanSkipSpace)if op == scanEndArray {break}if op != scanArrayValue {d.error(errPhase)}}return v}// objectInterface is like object but returns map[string]interface{}.func (d *decodeState) objectInterface() map[string]interface{} {m := make(map[string]interface{})for {// Read opening " of string key or closing }.op := d.scanWhile(scanSkipSpace)if op == scanEndObject {// closing } - can only happen on first iteration.break}if op != scanBeginLiteral {d.error(errPhase)}// Read string key.start := d.off - 1op = d.scanWhile(scanContinue)item := d.data[start : d.off-1]key, ok := unquote(item)if !ok {d.error(errPhase)}// Read : before value.if op == scanSkipSpace {op = d.scanWhile(scanSkipSpace)}if op != scanObjectKey {d.error(errPhase)}// Read value.m[key] = d.valueInterface()// Next token must be , or }.op = d.scanWhile(scanSkipSpace)if op == scanEndObject {break}if op != scanObjectValue {d.error(errPhase)}}return m}// literalInterface is like literal but returns an interface value.func (d *decodeState) literalInterface() interface{} {// All bytes inside literal return scanContinue op code.start := d.off - 1op := d.scanWhile(scanContinue)// Scan read one byte too far; back up.d.off--d.scan.undo(op)item := d.data[start:d.off]switch c := item[0]; c {case 'n': // nullreturn nilcase 't', 'f': // true, falsereturn c == 't'case '"': // strings, ok := unquote(item)if !ok {d.error(errPhase)}return sdefault: // numberif c != '-' && (c < '0' || c > '9') {d.error(errPhase)}n, err := strconv.ParseFloat(string(item), 64)if err != nil {d.saveError(&UnmarshalTypeError{"number " + string(item), reflect.TypeOf(0.0)})}return n}panic("unreachable")}// getu4 decodes \uXXXX from the beginning of s, returning the hex value,// or it returns -1.func getu4(s []byte) rune {if len(s) < 6 || s[0] != '\\' || s[1] != 'u' {return -1}r, err := strconv.ParseUint(string(s[2:6]), 16, 64)if err != nil {return -1}return rune(r)}// unquote converts a quoted JSON string literal s into an actual string t.// The rules are different than for Go, so cannot use strconv.Unquote.func unquote(s []byte) (t string, ok bool) {s, ok = unquoteBytes(s)t = string(s)return}func unquoteBytes(s []byte) (t []byte, ok bool) {if len(s) < 2 || s[0] != '"' || s[len(s)-1] != '"' {return}s = s[1 : len(s)-1]// Check for unusual characters. If there are none,// then no unquoting is needed, so return a slice of the// original bytes.r := 0for r < len(s) {c := s[r]if c == '\\' || c == '"' || c < ' ' {break}if c < utf8.RuneSelf {r++continue}rr, size := utf8.DecodeRune(s[r:])if rr == utf8.RuneError && size == 1 {break}r += size}if r == len(s) {return s, true}b := make([]byte, len(s)+2*utf8.UTFMax)w := copy(b, s[0:r])for r < len(s) {// Out of room? Can only happen if s is full of// malformed UTF-8 and we're replacing each// byte with RuneError.if w >= len(b)-2*utf8.UTFMax {nb := make([]byte, (len(b)+utf8.UTFMax)*2)copy(nb, b[0:w])b = nb}switch c := s[r]; {case c == '\\':r++if r >= len(s) {return}switch s[r] {default:returncase '"', '\\', '/', '\'':b[w] = s[r]r++w++case 'b':b[w] = '\b'r++w++case 'f':b[w] = '\f'r++w++case 'n':b[w] = '\n'r++w++case 'r':b[w] = '\r'r++w++case 't':b[w] = '\t'r++w++case 'u':r--rr := getu4(s[r:])if rr < 0 {return}r += 6if utf16.IsSurrogate(rr) {rr1 := getu4(s[r:])if dec := utf16.DecodeRune(rr, rr1); dec != unicode.ReplacementChar {// A valid pair; consume.r += 6w += utf8.EncodeRune(b[w:], dec)break}// Invalid surrogate; fall back to replacement rune.rr = unicode.ReplacementChar}w += utf8.EncodeRune(b[w:], rr)}// Quote, control characters are invalid.case c == '"', c < ' ':return// ASCIIcase c < utf8.RuneSelf:b[w] = cr++w++// Coerce to well-formed UTF-8.default:rr, size := utf8.DecodeRune(s[r:])r += sizew += utf8.EncodeRune(b[w:], rr)}}return b[0:w], true}
