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