text: package msgpack
  
  import (
  	"errors"
  	"fmt"
  	"reflect"
  )
  
  var interfaceType = reflect.TypeOf((*interface{})(nil)).Elem()
  var stringType = reflect.TypeOf((*string)(nil)).Elem()
  
  var valueDecoders []decoderFunc
  
  func init() {
  	valueDecoders = []decoderFunc{
  		reflect.Bool:          decodeBoolValue,
  		reflect.Int:           decodeInt64Value,
  		reflect.Int8:          decodeInt64Value,
  		reflect.Int16:         decodeInt64Value,
  		reflect.Int32:         decodeInt64Value,
  		reflect.Int64:         decodeInt64Value,
  		reflect.Uint:          decodeUint64Value,
  		reflect.Uint8:         decodeUint64Value,
  		reflect.Uint16:        decodeUint64Value,
  		reflect.Uint32:        decodeUint64Value,
  		reflect.Uint64:        decodeUint64Value,
  		reflect.Float32:       decodeFloat32Value,
  		reflect.Float64:       decodeFloat64Value,
  		reflect.Complex64:     decodeUnsupportedValue,
  		reflect.Complex128:    decodeUnsupportedValue,
  		reflect.Array:         decodeArrayValue,
  		reflect.Chan:          decodeUnsupportedValue,
  		reflect.Func:          decodeUnsupportedValue,
  		reflect.Interface:     decodeInterfaceValue,
  		reflect.Map:           decodeMapValue,
  		reflect.Ptr:           decodeUnsupportedValue,
  		reflect.Slice:         decodeSliceValue,
  		reflect.String:        decodeStringValue,
  		reflect.Struct:        decodeStructValue,
  		reflect.UnsafePointer: decodeUnsupportedValue,
  	}
  }
  
  func mustSet(v reflect.Value) error {
  	if !v.CanSet() {
  		return fmt.Errorf("msgpack: Decode(nonsettable %s)", v.Type())
  	}
  	return nil
  }
  
  func getDecoder(typ reflect.Type) decoderFunc {
  	kind := typ.Kind()
  
  	decoder, ok := typDecMap[typ]
  	if ok {
  		return decoder
  	}
  
  	if typ.Implements(customDecoderType) {
  		return decodeCustomValue
  	}
  	if typ.Implements(unmarshalerType) {
  		return unmarshalValue
  	}
  
  	// Addressable struct field value.
  	if kind != reflect.Ptr {
  		ptr := reflect.PtrTo(typ)
  		if ptr.Implements(customDecoderType) {
  			return decodeCustomValueAddr
  		}
  		if ptr.Implements(unmarshalerType) {
  			return unmarshalValueAddr
  		}
  	}
  
  	switch kind {
  	case reflect.Ptr:
  		return ptrDecoderFunc(typ)
  	case reflect.Slice:
  		elem := typ.Elem()
  		switch elem.Kind() {
  		case reflect.Uint8:
  			return decodeBytesValue
  		}
  		switch elem {
  		case stringType:
  			return decodeStringSliceValue
  		}
  	case reflect.Array:
  		if typ.Elem().Kind() == reflect.Uint8 {
  			return decodeByteArrayValue
  		}
  	case reflect.Map:
  		if typ.Key() == stringType {
  			switch typ.Elem() {
  			case stringType:
  				return decodeMapStringStringValue
  			case interfaceType:
  				return decodeMapStringInterfaceValue
  			}
  		}
  	}
  	return valueDecoders[kind]
  }
  
  func ptrDecoderFunc(typ reflect.Type) decoderFunc {
  	decoder := getDecoder(typ.Elem())
  	return func(d *Decoder, v reflect.Value) error {
  		if d.hasNilCode() {
  			if err := mustSet(v); err != nil {
  				return err
  			}
  			if !v.IsNil() {
  				v.Set(reflect.Zero(v.Type()))
  			}
  			return d.DecodeNil()
  		}
  		if v.IsNil() {
  			if err := mustSet(v); err != nil {
  				return err
  			}
  			v.Set(reflect.New(v.Type().Elem()))
  		}
  		return decoder(d, v.Elem())
  	}
  }
  
  func decodeCustomValueAddr(d *Decoder, v reflect.Value) error {
  	if !v.CanAddr() {
  		return fmt.Errorf("msgpack: Decode(nonaddressable %T)", v.Interface())
  	}
  	return decodeCustomValue(d, v.Addr())
  }
  
  func decodeCustomValue(d *Decoder, v reflect.Value) error {
  	if d.hasNilCode() {
  		return d.decodeNilValue(v)
  	}
  
  	if v.IsNil() {
  		v.Set(reflect.New(v.Type().Elem()))
  	}
  
  	decoder := v.Interface().(CustomDecoder)
  	return decoder.DecodeMsgpack(d)
  }
  
  func unmarshalValueAddr(d *Decoder, v reflect.Value) error {
  	if !v.CanAddr() {
  		return fmt.Errorf("msgpack: Decode(nonaddressable %T)", v.Interface())
  	}
  	return unmarshalValue(d, v.Addr())
  }
  
  func unmarshalValue(d *Decoder, v reflect.Value) error {
  	if d.hasNilCode() {
  		return d.decodeNilValue(v)
  	}
  
  	if v.IsNil() {
  		v.Set(reflect.New(v.Type().Elem()))
  	}
  
  	if d.extLen != 0 {
  		b, err := d.readN(d.extLen)
  		if err != nil {
  			return err
  		}
  		d.rec = b
  	} else {
  		d.rec = makeBuffer()
  		if err := d.Skip(); err != nil {
  			return err
  		}
  	}
  
  	unmarshaler := v.Interface().(Unmarshaler)
  	err := unmarshaler.UnmarshalMsgpack(d.rec)
  	d.rec = nil
  	return err
  }
  
  func decodeBoolValue(d *Decoder, v reflect.Value) error {
  	flag, err := d.DecodeBool()
  	if err != nil {
  		return err
  	}
  	if err = mustSet(v); err != nil {
  		return err
  	}
  	v.SetBool(flag)
  	return nil
  }
  
  func decodeInterfaceValue(d *Decoder, v reflect.Value) error {
  	if v.IsNil() {
  		return d.interfaceValue(v)
  	}
  
  	elem := v.Elem()
  	if !elem.CanAddr() {
  		if d.hasNilCode() {
  			v.Set(reflect.Zero(v.Type()))
  			return d.DecodeNil()
  		}
  	}
  
  	return d.DecodeValue(elem)
  }
  
  func (d *Decoder) interfaceValue(v reflect.Value) error {
  	vv, err := d.decodeInterfaceCond()
  	if err != nil {
  		return err
  	}
  
  	if vv != nil {
  		if v.Type() == errorType {
  			if vv, ok := vv.(string); ok {
  				v.Set(reflect.ValueOf(errors.New(vv)))
  				return nil
  			}
  		}
  
  		v.Set(reflect.ValueOf(vv))
  	}
  
  	return nil
  }
  
  func decodeUnsupportedValue(d *Decoder, v reflect.Value) error {
  	return fmt.Errorf("msgpack: Decode(unsupported %s)", v.Type())
  }
  