github.com/hspan/go-ole@v0.0.0/variant.go (about)

     1  package ole
     2  
     3  import "unsafe"
     4  
     5  // NewVariant returns new variant based on type and value.
     6  func NewVariant(vt VT, val int64) VARIANT {
     7  	return VARIANT{VT: vt, Val: val}
     8  }
     9  
    10  // ToIUnknown converts Variant to Unknown object.
    11  func (v *VARIANT) ToIUnknown() *IUnknown {
    12  	if v.VT != VT_UNKNOWN {
    13  		return nil
    14  	}
    15  	return (*IUnknown)(unsafe.Pointer(uintptr(v.Val)))
    16  }
    17  
    18  // ToIDispatch converts variant to dispatch object.
    19  func (v *VARIANT) ToIDispatch() *IDispatch {
    20  	if v.VT != VT_DISPATCH {
    21  		return nil
    22  	}
    23  	return (*IDispatch)(unsafe.Pointer(uintptr(v.Val)))
    24  }
    25  
    26  // ToArray converts variant to SafeArray helper.
    27  func (v *VARIANT) ToArray() *SafeArrayConversion {
    28  	if v.VT != VT_SAFEARRAY {
    29  		if v.VT&VT_ARRAY == 0 {
    30  			return nil
    31  		}
    32  	}
    33  	var safeArray *SafeArray = (*SafeArray)(unsafe.Pointer(uintptr(v.Val)))
    34  	return &SafeArrayConversion{safeArray}
    35  }
    36  
    37  // ToString converts variant to Go string.
    38  func (v *VARIANT) ToString() string {
    39  	if v.VT != VT_BSTR {
    40  		return ""
    41  	}
    42  	return BstrToString(*(**uint16)(unsafe.Pointer(&v.Val)))
    43  }
    44  
    45  // Clear the memory of variant object.
    46  func (v *VARIANT) Clear() error {
    47  	return VariantClear(v)
    48  }
    49  
    50  // Value returns variant value based on its type.
    51  //
    52  // Currently supported types: 2- and 4-byte integers, strings, bools.
    53  // Note that 64-bit integers, datetimes, and other types are stored as strings
    54  // and will be returned as strings.
    55  //
    56  // Needs to be further converted, because this returns an interface{}.
    57  func (v *VARIANT) Value() interface{} {
    58  	switch v.VT {
    59  	case VT_I1:
    60  		return int8(v.Val)
    61  	case VT_UI1:
    62  		return uint8(v.Val)
    63  	case VT_I2:
    64  		return int16(v.Val)
    65  	case VT_UI2:
    66  		return uint16(v.Val)
    67  	case VT_I4:
    68  		return int32(v.Val)
    69  	case VT_UI4:
    70  		return uint32(v.Val)
    71  	case VT_I8:
    72  		return int64(v.Val)
    73  	case VT_UI8:
    74  		return uint64(v.Val)
    75  	case VT_INT:
    76  		return int(v.Val)
    77  	case VT_UINT:
    78  		return uint(v.Val)
    79  	case VT_INT_PTR:
    80  		return uintptr(v.Val) // TODO
    81  	case VT_UINT_PTR:
    82  		return uintptr(v.Val)
    83  	case VT_R4:
    84  		return *(*float32)(unsafe.Pointer(&v.Val))
    85  	case VT_R8:
    86  		return *(*float64)(unsafe.Pointer(&v.Val))
    87  	case VT_BSTR:
    88  		return v.ToString()
    89  	case VT_DATE:
    90  		// VT_DATE type will either return float64 or time.Time.
    91  		d := uint64(v.Val)
    92  		date, err := GetVariantDate(d)
    93  		if err != nil {
    94  			return float64(v.Val)
    95  		}
    96  		return date
    97  	case VT_UNKNOWN:
    98  		return v.ToIUnknown()
    99  	case VT_DISPATCH:
   100  		return v.ToIDispatch()
   101  	case VT_BOOL:
   102  		return v.Val != 0
   103  	}
   104  	return nil
   105  }