func (cdc *Codec) decodeReflectBinary(bz []byte, info *TypeInfo, rv reflect.Value, fopts FieldOptions, bare bool) (n int, err error) {
	if !rv.CanAddr() {
		panic("rv not addressable")
	}
	if info.Type.Kind() == reflect.Interface && rv.Kind() == reflect.Ptr {
		panic("should not happen")
	}
	if printLog {
		spew.Printf("(D) decodeReflectBinary(bz: %X, info: %v, rv: %#v (%v), fopts: %v)\n",
			bz, info, rv.Interface(), rv.Type(), fopts)
		defer func() {
			fmt.Printf("(D) -> n: %v, err: %v\n", n, err)
		}()
	}
	var _n int

	// TODO consider the binary equivalent of json.Unmarshaller.

	// Dereference-and-construct pointers all the way.
	// This works for pointer-pointers.
	for rv.Kind() == reflect.Ptr {
		if rv.IsNil() {
			newPtr := reflect.New(rv.Type().Elem())
			rv.Set(newPtr)
		}
		rv = rv.Elem()
	}

	// Handle override if a pointer to rv implements UnmarshalAmino.
	if info.IsAminoUnmarshaler {
		// First, decode repr instance from bytes.
		rrv, rinfo := reflect.New(info.AminoUnmarshalReprType).Elem(), (*TypeInfo)(nil)
		rinfo, err = cdc.getTypeInfo_wlock(info.AminoUnmarshalReprType)
		if err != nil {
			return
		}
		_n, err = cdc.decodeReflectBinary(bz, rinfo, rrv, fopts, bare)
		if slide(&bz, &n, _n) && err != nil {
			return
		}
		// Then, decode from repr instance.
		uwrm := rv.Addr().MethodByName("UnmarshalAmino")
		uwouts := uwrm.Call([]reflect.Value{rrv})
		erri := uwouts[0].Interface()
		if erri != nil {
			err = erri.(error)
		}
		return
	}

	switch info.Type.Kind() {

	//----------------------------------------
	// Complex

	case reflect.Interface:
		_n, err = cdc.decodeReflectBinaryInterface(bz, info, rv, fopts, bare)
		n += _n
		return

	case reflect.Array:
		ert := info.Type.Elem()
		if ert.Kind() == reflect.Uint8 {
			_n, err = cdc.decodeReflectBinaryByteArray(bz, info, rv, fopts)
			n += _n
		} else {
			_n, err = cdc.decodeReflectBinaryArray(bz, info, rv, fopts, bare)
			n += _n
		}
		return

	case reflect.Slice:
		ert := info.Type.Elem()
		if ert.Kind() == reflect.Uint8 {
			_n, err = cdc.decodeReflectBinaryByteSlice(bz, info, rv, fopts)
			n += _n
		} else {
			_n, err = cdc.decodeReflectBinarySlice(bz, info, rv, fopts, bare)
			n += _n
		}
		return

	case reflect.Struct:
		_n, err = cdc.decodeReflectBinaryStruct(bz, info, rv, fopts, bare)
		n += _n
		return

	//----------------------------------------
	// Signed

	case reflect.Int64:
		var num int64
		if fopts.BinFixed64 {
			num, _n, err = DecodeInt64(bz)
			if slide(&bz, &n, _n) && err != nil {
				return
			}
			rv.SetInt(num)
		} else {
			var u64 uint64
			u64, _n, err = DecodeUvarint(bz)
			if slide(&bz, &n, _n) && err != nil {
				return
			}
			rv.SetInt(int64(u64))
		}
		return

	case reflect.Int32:
		if fopts.BinFixed32 {
			var num int32
			num, _n, err = DecodeInt32(bz)
			if slide(&bz, &n, _n) && err != nil {
				return
			}
			rv.SetInt(int64(num))
		} else {
			var num uint64
			num, _n, err = DecodeUvarint(bz)
			if slide(&bz, &n, _n) && err != nil {
				return
			}
			if int64(num) > math.MaxInt32 || int64(num) < math.MinInt32 {
				err = ErrOverflowInt
				return
			}
			rv.SetInt(int64(num))
		}
		return

	case reflect.Int16:
		var num int16
		num, _n, err = DecodeInt16(bz)
		if slide(&bz, &n, _n) && err != nil {
			return
		}
		rv.SetInt(int64(num))
		return

	case reflect.Int8:
		var num int8
		num, _n, err = DecodeInt8(bz)
		if slide(&bz, &n, _n) && err != nil {
			return
		}
		rv.SetInt(int64(num))
		return

	case reflect.Int:
		var num uint64
		num, _n, err = DecodeUvarint(bz)
		if slide(&bz, &n, _n) && err != nil {
			return
		}
		if int64(num) > int64(maxInt) || int64(num) < int64(minInt) {
			err = ErrOverflowInt
			return
		}
		rv.SetInt(int64(num))
		return

	//----------------------------------------
	// Unsigned

	case reflect.Uint64:
		var num uint64
		if fopts.BinFixed64 {
			num, _n, err = DecodeUint64(bz)
			if slide(&bz, &n, _n) && err != nil {
				return
			}
			rv.SetUint(num)
		} else {
			num, _n, err = DecodeUvarint(bz)
			if slide(&bz, &n, _n) && err != nil {
				return
			}
			rv.SetUint(num)
		}
		return

	case reflect.Uint32:
		if fopts.BinFixed32 {
			var num uint32
			num, _n, err = DecodeUint32(bz)
			if slide(&bz, &n, _n) && err != nil {
				return
			}
			rv.SetUint(uint64(num))
		} else {
			var num uint64
			num, _n, err = DecodeUvarint(bz)
			if slide(&bz, &n, _n) && err != nil {
				return
			}
			rv.SetUint(uint64(num))
		}
		return

	case reflect.Uint16:
		var num uint16
		num, _n, err = DecodeUint16(bz)
		if slide(&bz, &n, _n) && err != nil {
			return
		}
		rv.SetUint(uint64(num))
		return

	case reflect.Uint8:
		var num uint8
		num, _n, err = DecodeUint8(bz)
		if slide(&bz, &n, _n) && err != nil {
			return
		}
		rv.SetUint(uint64(num))
		return

	case reflect.Uint:
		var num uint64
		num, _n, err = DecodeUvarint(bz)
		if slide(&bz, &n, _n) && err != nil {
			return
		}
		rv.SetUint(num)
		return

	//----------------------------------------
	// Misc.

	case reflect.Bool:
		var b bool
		b, _n, err = DecodeBool(bz)
		if slide(&bz, &n, _n) && err != nil {
			return
		}
		rv.SetBool(b)
		return

	case reflect.Float64:
		var f float64
		if !fopts.Unsafe {
			err = errors.New("Float support requires `amino:\"unsafe\"`.")
			return
		}
		f, _n, err = DecodeFloat64(bz)
		if slide(&bz, &n, _n) && err != nil {
			return
		}
		rv.SetFloat(f)
		return

	case reflect.Float32:
		var f float32
		if !fopts.Unsafe {
			err = errors.New("Float support requires `amino:\"unsafe\"`.")
			return
		}
		f, _n, err = DecodeFloat32(bz)
		if slide(&bz, &n, _n) && err != nil {
			return
		}
		rv.SetFloat(float64(f))
		return

	case reflect.String:
		var str string
		str, _n, err = DecodeString(bz)
		if slide(&bz, &n, _n) && err != nil {
			return
		}
		rv.SetString(str)
		return

	default:
		panic(fmt.Sprintf("unknown field type %v", info.Type.Kind()))
	}

}
func (cdc *Codec) decodeReflectBinary(bz []byte, info *TypeInfo, rv reflect.Value, fopts FieldOptions, bare bool) (n int, err error) {
	if !rv.CanAddr() {
		panic("rv not addressable")
	}
	if info.Type.Kind() == reflect.Interface && rv.Kind() == reflect.Ptr {
		panic("should not happen")
	}
	if printLog {
		spew.Printf("(D) decodeReflectBinary(bz: %X, info: %v, rv: %#v (%v), fopts: %v)\n",
			bz, info, rv.Interface(), rv.Type(), fopts)
		defer func() {
			fmt.Printf("(D) -> n: %v, err: %v\n", n, err)
		}()
	}
	var _n int

	

	
	
	for rv.Kind() == reflect.Ptr {
		if rv.IsNil() {
			newPtr := reflect.New(rv.Type().Elem())
			rv.Set(newPtr)
		}
		rv = rv.Elem()
	}

	
	if info.IsAminoUnmarshaler {
		
		rrv, rinfo := reflect.New(info.AminoUnmarshalReprType).Elem(), (*TypeInfo)(nil)
		rinfo, err = cdc.getTypeInfo_wlock(info.AminoUnmarshalReprType)
		if err != nil {
			return
		}
		_n, err = cdc.decodeReflectBinary(bz, rinfo, rrv, fopts, bare)
		if slide(&bz, &n, _n) && err != nil {
			return
		}
		
		uwrm := rv.Addr().MethodByName("UnmarshalAmino")
		uwouts := uwrm.Call([]reflect.Value{rrv})
		erri := uwouts[0].Interface()
		if erri != nil {
			err = erri.(error)
		}
		return
	}

	switch info.Type.Kind() {

	
	

	case reflect.Interface:
		_n, err = cdc.decodeReflectBinaryInterface(bz, info, rv, fopts, bare)
		n += _n
		return

	case reflect.Array:
		ert := info.Type.Elem()
		if ert.Kind() == reflect.Uint8 {
			_n, err = cdc.decodeReflectBinaryByteArray(bz, info, rv, fopts)
			n += _n
		} else {
			_n, err = cdc.decodeReflectBinaryArray(bz, info, rv, fopts, bare)
			n += _n
		}
		return

	case reflect.Slice:
		ert := info.Type.Elem()
		if ert.Kind() == reflect.Uint8 {
			_n, err = cdc.decodeReflectBinaryByteSlice(bz, info, rv, fopts)
			n += _n
		} else {
			_n, err = cdc.decodeReflectBinarySlice(bz, info, rv, fopts, bare)
			n += _n
		}
		return

	case reflect.Struct:
		_n, err = cdc.decodeReflectBinaryStruct(bz, info, rv, fopts, bare)
		n += _n
		return

	
	

	case reflect.Int64:
		var num int64
		if fopts.BinFixed64 {
			num, _n, err = DecodeInt64(bz)
			if slide(&bz, &n, _n) && err != nil {
				return
			}
			rv.SetInt(num)
		} else {
			var u64 uint64
			u64, _n, err = DecodeUvarint(bz)
			if slide(&bz, &n, _n) && err != nil {
				return
			}
			rv.SetInt(int64(u64))
		}
		return

	case reflect.Int32:
		if fopts.BinFixed32 {
			var num int32
			num, _n, err = DecodeInt32(bz)
			if slide(&bz, &n, _n) && err != nil {
				return
			}
			rv.SetInt(int64(num))
		} else {
			var num uint64
			num, _n, err = DecodeUvarint(bz)
			if slide(&bz, &n, _n) && err != nil {
				return
			}
			if int64(num) > math.MaxInt32 || int64(num) < math.MinInt32 {
				err = ErrOverflowInt
				return
			}
			rv.SetInt(int64(num))
		}
		return

	case reflect.Int16:
		var num int16
		num, _n, err = DecodeInt16(bz)
		if slide(&bz, &n, _n) && err != nil {
			return
		}
		rv.SetInt(int64(num))
		return

	case reflect.Int8:
		var num int8
		num, _n, err = DecodeInt8(bz)
		if slide(&bz, &n, _n) && err != nil {
			return
		}
		rv.SetInt(int64(num))
		return

	case reflect.Int:
		var num uint64
		num, _n, err = DecodeUvarint(bz)
		if slide(&bz, &n, _n) && err != nil {
			return
		}
		if int64(num) > int64(maxInt) || int64(num) < int64(minInt) {
			err = ErrOverflowInt
			return
		}
		rv.SetInt(int64(num))
		return

	
	

	case reflect.Uint64:
		var num uint64
		if fopts.BinFixed64 {
			num, _n, err = DecodeUint64(bz)
			if slide(&bz, &n, _n) && err != nil {
				return
			}
			rv.SetUint(num)
		} else {
			num, _n, err = DecodeUvarint(bz)
			if slide(&bz, &n, _n) && err != nil {
				return
			}
			rv.SetUint(num)
		}
		return

	case reflect.Uint32:
		if fopts.BinFixed32 {
			var num uint32
			num, _n, err = DecodeUint32(bz)
			if slide(&bz, &n, _n) && err != nil {
				return
			}
			rv.SetUint(uint64(num))
		} else {
			var num uint64
			num, _n, err = DecodeUvarint(bz)
			if slide(&bz, &n, _n) && err != nil {
				return
			}
			rv.SetUint(uint64(num))
		}
		return

	case reflect.Uint16:
		var num uint16
		num, _n, err = DecodeUint16(bz)
		if slide(&bz, &n, _n) && err != nil {
			return
		}
		rv.SetUint(uint64(num))
		return

	case reflect.Uint8:
		var num uint8
		num, _n, err = DecodeUint8(bz)
		if slide(&bz, &n, _n) && err != nil {
			return
		}
		rv.SetUint(uint64(num))
		return

	case reflect.Uint:
		var num uint64
		num, _n, err = DecodeUvarint(bz)
		if slide(&bz, &n, _n) && err != nil {
			return
		}
		rv.SetUint(num)
		return

	
	

	case reflect.Bool:
		var b bool
		b, _n, err = DecodeBool(bz)
		if slide(&bz, &n, _n) && err != nil {
			return
		}
		rv.SetBool(b)
		return

	case reflect.Float64:
		var f float64
		if !fopts.Unsafe {
			err = errors.New("Float support requires `amino:\"unsafe\"`.")
			return
		}
		f, _n, err = DecodeFloat64(bz)
		if slide(&bz, &n, _n) && err != nil {
			return
		}
		rv.SetFloat(f)
		return

	case reflect.Float32:
		var f float32
		if !fopts.Unsafe {
			err = errors.New("Float support requires `amino:\"unsafe\"`.")
			return
		}
		f, _n, err = DecodeFloat32(bz)
		if slide(&bz, &n, _n) && err != nil {
			return
		}
		rv.SetFloat(float64(f))
		return

	case reflect.String:
		var str string
		str, _n, err = DecodeString(bz)
		if slide(&bz, &n, _n) && err != nil {
			return
		}
		rv.SetString(str)
		return

	default:
		panic(fmt.Sprintf("unknown field type %v", info.Type.Kind()))
	}

}
func ( cdc * Codec ) decodeReflectBinary ( bz [ ] byte , info * TypeInfo , rv reflect . Value , fopts FieldOptions , bare bool ) ( n int , err error ) { if ! rv . CanAddr ( ) { panic ( " " ) } if info . Type . Kind ( ) == reflect . Interface && rv . Kind ( ) == reflect . Ptr { panic ( " " ) } if printLog { spew . Printf ( " \n " , bz , info , rv . Interface ( ) , rv . Type ( ) , fopts ) defer func ( ) { fmt . Printf ( " \n " , n , err ) } ( ) } var _n int // TODO consider the binary equivalent of json.Unmarshaller. // Dereference-and-construct pointers all the way. // This works for pointer-pointers. for rv . Kind ( ) == reflect . Ptr { if rv . IsNil ( ) { newPtr := reflect . New ( rv . Type ( ) . Elem ( ) ) rv . Set ( newPtr ) } rv = rv . Elem ( ) } // Handle override if a pointer to rv implements UnmarshalAmino. if info . IsAminoUnmarshaler { // First, decode repr instance from bytes. rrv , rinfo := reflect . New ( info . AminoUnmarshalReprType ) . Elem ( ) , ( * TypeInfo ) ( nil ) rinfo , err = cdc . getTypeInfo_wlock ( info . AminoUnmarshalReprType ) if err != nil { return } _n , err = cdc . decodeReflectBinary ( bz , rinfo , rrv , fopts , bare ) if slide ( & bz , & n , _n ) && err != nil { return } // Then, decode from repr instance. uwrm := rv . Addr ( ) . MethodByName ( " " ) uwouts := uwrm . Call ( [ ] reflect . Value { rrv } ) erri := uwouts [ 0 ] . Interface ( ) if erri != nil { err = erri . ( error ) } return } switch info . Type . Kind ( ) { //---------------------------------------- // Complex case reflect . Interface : _n , err = cdc . decodeReflectBinaryInterface ( bz , info , rv , fopts , bare ) n += _n return case reflect . Array : ert := info . Type . Elem ( ) if ert . Kind ( ) == reflect . Uint8 { _n , err = cdc . decodeReflectBinaryByteArray ( bz , info , rv , fopts ) n += _n } else { _n , err = cdc . decodeReflectBinaryArray ( bz , info , rv , fopts , bare ) n += _n } return case reflect . Slice : ert := info . Type . Elem ( ) if ert . Kind ( ) == reflect . Uint8 { _n , err = cdc . decodeReflectBinaryByteSlice ( bz , info , rv , fopts ) n += _n } else { _n , err = cdc . decodeReflectBinarySlice ( bz , info , rv , fopts , bare ) n += _n } return case reflect . Struct : _n , err = cdc . decodeReflectBinaryStruct ( bz , info , rv , fopts , bare ) n += _n return //---------------------------------------- // Signed case reflect . Int64 : var num int64 if fopts . BinFixed64 { num , _n , err = DecodeInt64 ( bz ) if slide ( & bz , & n , _n ) && err != nil { return } rv . SetInt ( num ) } else { var u64 uint64 u64 , _n , err = DecodeUvarint ( bz ) if slide ( & bz , & n , _n ) && err != nil { return } rv . SetInt ( int64 ( u64 ) ) } return case reflect . Int32 : if fopts . BinFixed32 { var num int32 num , _n , err = DecodeInt32 ( bz ) if slide ( & bz , & n , _n ) && err != nil { return } rv . SetInt ( int64 ( num ) ) } else { var num uint64 num , _n , err = DecodeUvarint ( bz ) if slide ( & bz , & n , _n ) && err != nil { return } if int64 ( num ) > math . MaxInt32 || int64 ( num ) < math . MinInt32 { err = ErrOverflowInt return } rv . SetInt ( int64 ( num ) ) } return case reflect . Int16 : var num int16 num , _n , err = DecodeInt16 ( bz ) if slide ( & bz , & n , _n ) && err != nil { return } rv . SetInt ( int64 ( num ) ) return case reflect . Int8 : var num int8 num , _n , err = DecodeInt8 ( bz ) if slide ( & bz , & n , _n ) && err != nil { return } rv . SetInt ( int64 ( num ) ) return case reflect . Int : var num uint64 num , _n , err = DecodeUvarint ( bz ) if slide ( & bz , & n , _n ) && err != nil { return } if int64 ( num ) > int64 ( maxInt ) || int64 ( num ) < int64 ( minInt ) { err = ErrOverflowInt return } rv . SetInt ( int64 ( num ) ) return //---------------------------------------- // Unsigned case reflect . Uint64 : var num uint64 if fopts . BinFixed64 { num , _n , err = DecodeUint64 ( bz ) if slide ( & bz , & n , _n ) && err != nil { return } rv . SetUint ( num ) } else { num , _n , err = DecodeUvarint ( bz ) if slide ( & bz , & n , _n ) && err != nil { return } rv . SetUint ( num ) } return case reflect . Uint32 : if fopts . BinFixed32 { var num uint32 num , _n , err = DecodeUint32 ( bz ) if slide ( & bz , & n , _n ) && err != nil { return } rv . SetUint ( uint64 ( num ) ) } else { var num uint64 num , _n , err = DecodeUvarint ( bz ) if slide ( & bz , & n , _n ) && err != nil { return } rv . SetUint ( uint64 ( num ) ) } return case reflect . Uint16 : var num uint16 num , _n , err = DecodeUint16 ( bz ) if slide ( & bz , & n , _n ) && err != nil { return } rv . SetUint ( uint64 ( num ) ) return case reflect . Uint8 : var num uint8 num , _n , err = DecodeUint8 ( bz ) if slide ( & bz , & n , _n ) && err != nil { return } rv . SetUint ( uint64 ( num ) ) return case reflect . Uint : var num uint64 num , _n , err = DecodeUvarint ( bz ) if slide ( & bz , & n , _n ) && err != nil { return } rv . SetUint ( num ) return //---------------------------------------- // Misc. case reflect . Bool : var b bool b , _n , err = DecodeBool ( bz ) if slide ( & bz , & n , _n ) && err != nil { return } rv . SetBool ( b ) return case reflect . Float64 : var f float64 if ! fopts . Unsafe { err = errors . New ( " \" \" " ) return } f , _n , err = DecodeFloat64 ( bz ) if slide ( & bz , & n , _n ) && err != nil { return } rv . SetFloat ( f ) return case reflect . Float32 : var f float32 if ! fopts . Unsafe { err = errors . New ( " \" \" " ) return } f , _n , err = DecodeFloat32 ( bz ) if slide ( & bz , & n , _n ) && err != nil { return } rv . SetFloat ( float64 ( f ) ) return case reflect . String : var str string str , _n , err = DecodeString ( bz ) if slide ( & bz , & n , _n ) && err != nil { return } rv . SetString ( str ) return default : panic ( fmt . Sprintf ( " " , info . Type . Kind ( ) ) ) } }
// This is the main entrypoint for decoding all types from binary form. This
// function calls decodeReflectBinary*, and generally those functions should
// only call this one, for the prefix bytes are consumed here when present.
// CONTRACT: rv.CanAddr() is true.
This is the main entrypoint for decoding all types from binary form . This function calls decodeReflectBinary * and generally those functions should only call this one for the prefix bytes are consumed here when present . CONTRACT : rv . CanAddr () is true .