variant.go 2.4 KB

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