1package search 2 3import ( 4 "encoding/binary" 5 "errors" 6 "math" 7 "reflect" 8) 9 10type VariantValue []byte 11type VariantType byte 12 13const ( 14 // variant type 15 VT_INTEGER VariantType = 0x0 16 VT_DOUBLE VariantType = 0x1 17 VT_BOOLEAN VariantType = 0x2 18 VT_STRING VariantType = 0x3 19) 20 21func ToVariantValue(value interface{}) (VariantValue, error) { 22 t := reflect.TypeOf(value) 23 switch t.Kind() { 24 case reflect.String: 25 return VTString(value.(string)), nil 26 case reflect.Int: 27 return VTInteger(int64(value.(int))), nil 28 case reflect.Int64: 29 return VTInteger(value.(int64)), nil 30 case reflect.Float64: 31 return VTDouble(value.(float64)), nil 32 case reflect.Bool: 33 return VTBoolean(value.(bool)), nil 34 default: 35 return nil, errors.New("interface{} type must be string/int64/float64.") 36 } 37} 38 39func (v *VariantValue) GetType() VariantType { 40 return VariantType(([]byte)(*v)[0]) 41} 42 43func VTInteger(v int64) VariantValue { 44 buf := make([]byte, 9) 45 buf[0] = byte(VT_INTEGER) 46 binary.LittleEndian.PutUint64(buf[1:9], uint64(v)) 47 return (VariantValue)(buf) 48} 49 50func VTDouble(v float64) VariantValue { 51 buf := make([]byte, 9) 52 buf[0] = byte(VT_DOUBLE) 53 binary.LittleEndian.PutUint64(buf[1:9], math.Float64bits(v)) 54 return (VariantValue)(buf) 55} 56 57func VTString(v string) VariantValue { 58 buf := make([]byte, 5+len(v)) 59 buf[0] = byte(VT_STRING) 60 binary.LittleEndian.PutUint32(buf[1:5], uint32(len(v))) 61 copy(buf[5:], v) 62 return (VariantValue)(buf) 63} 64 65func VTBoolean(b bool) VariantValue { 66 buf := make([]byte, 2) 67 buf[0] = byte(VT_BOOLEAN) 68 if b { 69 buf[1] = 1 70 } else { 71 buf[1] = 0 72 } 73 return (VariantValue)(buf) 74} 75