| package ole |
| |
| import "unsafe" |
| |
| // NewVariant returns new variant based on type and value. |
| func NewVariant(vt VT, val int64) VARIANT { |
| return VARIANT{VT: vt, Val: val} |
| } |
| |
| // ToIUnknown converts Variant to Unknown object. |
| func (v *VARIANT) ToIUnknown() *IUnknown { |
| if v.VT != VT_UNKNOWN { |
| return nil |
| } |
| return (*IUnknown)(unsafe.Pointer(uintptr(v.Val))) |
| } |
| |
| // ToIDispatch converts variant to dispatch object. |
| func (v *VARIANT) ToIDispatch() *IDispatch { |
| if v.VT != VT_DISPATCH { |
| return nil |
| } |
| return (*IDispatch)(unsafe.Pointer(uintptr(v.Val))) |
| } |
| |
| // ToArray converts variant to SafeArray helper. |
| func (v *VARIANT) ToArray() *SafeArrayConversion { |
| if v.VT != VT_SAFEARRAY { |
| if v.VT&VT_ARRAY == 0 { |
| return nil |
| } |
| } |
| var safeArray *SafeArray = (*SafeArray)(unsafe.Pointer(uintptr(v.Val))) |
| return &SafeArrayConversion{safeArray} |
| } |
| |
| // ToString converts variant to Go string. |
| func (v *VARIANT) ToString() string { |
| if v.VT != VT_BSTR { |
| return "" |
| } |
| return BstrToString(*(**uint16)(unsafe.Pointer(&v.Val))) |
| } |
| |
| // Clear the memory of variant object. |
| func (v *VARIANT) Clear() error { |
| return VariantClear(v) |
| } |
| |
| // Value returns variant value based on its type. |
| // |
| // Currently supported types: 2- and 4-byte integers, strings, bools. |
| // Note that 64-bit integers, datetimes, and other types are stored as strings |
| // and will be returned as strings. |
| // |
| // Needs to be further converted, because this returns an interface{}. |
| func (v *VARIANT) Value() interface{} { |
| switch v.VT { |
| case VT_I1: |
| return int8(v.Val) |
| case VT_UI1: |
| return uint8(v.Val) |
| case VT_I2: |
| return int16(v.Val) |
| case VT_UI2: |
| return uint16(v.Val) |
| case VT_I4: |
| return int32(v.Val) |
| case VT_UI4: |
| return uint32(v.Val) |
| case VT_I8: |
| return int64(v.Val) |
| case VT_UI8: |
| return uint64(v.Val) |
| case VT_INT: |
| return int(v.Val) |
| case VT_UINT: |
| return uint(v.Val) |
| case VT_INT_PTR: |
| return uintptr(v.Val) // TODO |
| case VT_UINT_PTR: |
| return uintptr(v.Val) |
| case VT_R4: |
| return *(*float32)(unsafe.Pointer(&v.Val)) |
| case VT_R8: |
| return *(*float64)(unsafe.Pointer(&v.Val)) |
| case VT_BSTR: |
| return v.ToString() |
| case VT_DATE: |
| // VT_DATE type will either return float64 or time.Time. |
| d := float64(v.Val) |
| date, err := GetVariantDate(d) |
| if err != nil { |
| return d |
| } |
| return date |
| case VT_UNKNOWN: |
| return v.ToIUnknown() |
| case VT_DISPATCH: |
| return v.ToIDispatch() |
| case VT_BOOL: |
| return v.Val != 0 |
| } |
| return nil |
| } |