gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

encode_value.go (5934B)


      1 package msgpack
      2 
      3 import (
      4 	"encoding"
      5 	"fmt"
      6 	"reflect"
      7 )
      8 
      9 var valueEncoders []encoderFunc
     10 
     11 //nolint:gochecknoinits
     12 func init() {
     13 	valueEncoders = []encoderFunc{
     14 		reflect.Bool:          encodeBoolValue,
     15 		reflect.Int:           encodeIntValue,
     16 		reflect.Int8:          encodeInt8CondValue,
     17 		reflect.Int16:         encodeInt16CondValue,
     18 		reflect.Int32:         encodeInt32CondValue,
     19 		reflect.Int64:         encodeInt64CondValue,
     20 		reflect.Uint:          encodeUintValue,
     21 		reflect.Uint8:         encodeUint8CondValue,
     22 		reflect.Uint16:        encodeUint16CondValue,
     23 		reflect.Uint32:        encodeUint32CondValue,
     24 		reflect.Uint64:        encodeUint64CondValue,
     25 		reflect.Float32:       encodeFloat32Value,
     26 		reflect.Float64:       encodeFloat64Value,
     27 		reflect.Complex64:     encodeUnsupportedValue,
     28 		reflect.Complex128:    encodeUnsupportedValue,
     29 		reflect.Array:         encodeArrayValue,
     30 		reflect.Chan:          encodeUnsupportedValue,
     31 		reflect.Func:          encodeUnsupportedValue,
     32 		reflect.Interface:     encodeInterfaceValue,
     33 		reflect.Map:           encodeMapValue,
     34 		reflect.Ptr:           encodeUnsupportedValue,
     35 		reflect.Slice:         encodeSliceValue,
     36 		reflect.String:        encodeStringValue,
     37 		reflect.Struct:        encodeStructValue,
     38 		reflect.UnsafePointer: encodeUnsupportedValue,
     39 	}
     40 }
     41 
     42 func getEncoder(typ reflect.Type) encoderFunc {
     43 	if v, ok := typeEncMap.Load(typ); ok {
     44 		return v.(encoderFunc)
     45 	}
     46 	fn := _getEncoder(typ)
     47 	typeEncMap.Store(typ, fn)
     48 	return fn
     49 }
     50 
     51 func _getEncoder(typ reflect.Type) encoderFunc {
     52 	kind := typ.Kind()
     53 
     54 	if kind == reflect.Ptr {
     55 		if _, ok := typeEncMap.Load(typ.Elem()); ok {
     56 			return ptrEncoderFunc(typ)
     57 		}
     58 	}
     59 
     60 	if typ.Implements(customEncoderType) {
     61 		return encodeCustomValue
     62 	}
     63 	if typ.Implements(marshalerType) {
     64 		return marshalValue
     65 	}
     66 	if typ.Implements(binaryMarshalerType) {
     67 		return marshalBinaryValue
     68 	}
     69 	if typ.Implements(textMarshalerType) {
     70 		return marshalTextValue
     71 	}
     72 
     73 	// Addressable struct field value.
     74 	if kind != reflect.Ptr {
     75 		ptr := reflect.PtrTo(typ)
     76 		if ptr.Implements(customEncoderType) {
     77 			return encodeCustomValuePtr
     78 		}
     79 		if ptr.Implements(marshalerType) {
     80 			return marshalValuePtr
     81 		}
     82 		if ptr.Implements(binaryMarshalerType) {
     83 			return marshalBinaryValueAddr
     84 		}
     85 		if ptr.Implements(textMarshalerType) {
     86 			return marshalTextValueAddr
     87 		}
     88 	}
     89 
     90 	if typ == errorType {
     91 		return encodeErrorValue
     92 	}
     93 
     94 	switch kind {
     95 	case reflect.Ptr:
     96 		return ptrEncoderFunc(typ)
     97 	case reflect.Slice:
     98 		elem := typ.Elem()
     99 		if elem.Kind() == reflect.Uint8 {
    100 			return encodeByteSliceValue
    101 		}
    102 		if elem == stringType {
    103 			return encodeStringSliceValue
    104 		}
    105 	case reflect.Array:
    106 		if typ.Elem().Kind() == reflect.Uint8 {
    107 			return encodeByteArrayValue
    108 		}
    109 	case reflect.Map:
    110 		if typ.Key() == stringType {
    111 			switch typ.Elem() {
    112 			case stringType:
    113 				return encodeMapStringStringValue
    114 			case interfaceType:
    115 				return encodeMapStringInterfaceValue
    116 			}
    117 		}
    118 	}
    119 
    120 	return valueEncoders[kind]
    121 }
    122 
    123 func ptrEncoderFunc(typ reflect.Type) encoderFunc {
    124 	encoder := getEncoder(typ.Elem())
    125 	return func(e *Encoder, v reflect.Value) error {
    126 		if v.IsNil() {
    127 			return e.EncodeNil()
    128 		}
    129 		return encoder(e, v.Elem())
    130 	}
    131 }
    132 
    133 func encodeCustomValuePtr(e *Encoder, v reflect.Value) error {
    134 	if !v.CanAddr() {
    135 		return fmt.Errorf("msgpack: Encode(non-addressable %T)", v.Interface())
    136 	}
    137 	encoder := v.Addr().Interface().(CustomEncoder)
    138 	return encoder.EncodeMsgpack(e)
    139 }
    140 
    141 func encodeCustomValue(e *Encoder, v reflect.Value) error {
    142 	if nilable(v.Kind()) && v.IsNil() {
    143 		return e.EncodeNil()
    144 	}
    145 
    146 	encoder := v.Interface().(CustomEncoder)
    147 	return encoder.EncodeMsgpack(e)
    148 }
    149 
    150 func marshalValuePtr(e *Encoder, v reflect.Value) error {
    151 	if !v.CanAddr() {
    152 		return fmt.Errorf("msgpack: Encode(non-addressable %T)", v.Interface())
    153 	}
    154 	return marshalValue(e, v.Addr())
    155 }
    156 
    157 func marshalValue(e *Encoder, v reflect.Value) error {
    158 	if nilable(v.Kind()) && v.IsNil() {
    159 		return e.EncodeNil()
    160 	}
    161 
    162 	marshaler := v.Interface().(Marshaler)
    163 	b, err := marshaler.MarshalMsgpack()
    164 	if err != nil {
    165 		return err
    166 	}
    167 	_, err = e.w.Write(b)
    168 	return err
    169 }
    170 
    171 func encodeBoolValue(e *Encoder, v reflect.Value) error {
    172 	return e.EncodeBool(v.Bool())
    173 }
    174 
    175 func encodeInterfaceValue(e *Encoder, v reflect.Value) error {
    176 	if v.IsNil() {
    177 		return e.EncodeNil()
    178 	}
    179 	return e.EncodeValue(v.Elem())
    180 }
    181 
    182 func encodeErrorValue(e *Encoder, v reflect.Value) error {
    183 	if v.IsNil() {
    184 		return e.EncodeNil()
    185 	}
    186 	return e.EncodeString(v.Interface().(error).Error())
    187 }
    188 
    189 func encodeUnsupportedValue(e *Encoder, v reflect.Value) error {
    190 	return fmt.Errorf("msgpack: Encode(unsupported %s)", v.Type())
    191 }
    192 
    193 func nilable(kind reflect.Kind) bool {
    194 	switch kind {
    195 	case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice:
    196 		return true
    197 	}
    198 	return false
    199 }
    200 
    201 //------------------------------------------------------------------------------
    202 
    203 func marshalBinaryValueAddr(e *Encoder, v reflect.Value) error {
    204 	if !v.CanAddr() {
    205 		return fmt.Errorf("msgpack: Encode(non-addressable %T)", v.Interface())
    206 	}
    207 	return marshalBinaryValue(e, v.Addr())
    208 }
    209 
    210 func marshalBinaryValue(e *Encoder, v reflect.Value) error {
    211 	if nilable(v.Kind()) && v.IsNil() {
    212 		return e.EncodeNil()
    213 	}
    214 
    215 	marshaler := v.Interface().(encoding.BinaryMarshaler)
    216 	data, err := marshaler.MarshalBinary()
    217 	if err != nil {
    218 		return err
    219 	}
    220 
    221 	return e.EncodeBytes(data)
    222 }
    223 
    224 //------------------------------------------------------------------------------
    225 
    226 func marshalTextValueAddr(e *Encoder, v reflect.Value) error {
    227 	if !v.CanAddr() {
    228 		return fmt.Errorf("msgpack: Encode(non-addressable %T)", v.Interface())
    229 	}
    230 	return marshalTextValue(e, v.Addr())
    231 }
    232 
    233 func marshalTextValue(e *Encoder, v reflect.Value) error {
    234 	if nilable(v.Kind()) && v.IsNil() {
    235 		return e.EncodeNil()
    236 	}
    237 
    238 	marshaler := v.Interface().(encoding.TextMarshaler)
    239 	data, err := marshaler.MarshalText()
    240 	if err != nil {
    241 		return err
    242 	}
    243 
    244 	return e.EncodeBytes(data)
    245 }