1
0

utility.go 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. package ole
  2. import (
  3. "unicode/utf16"
  4. "unsafe"
  5. )
  6. // ClassIDFrom retrieves class ID whether given is program ID or application string.
  7. //
  8. // Helper that provides check against both Class ID from Program ID and Class ID from string. It is
  9. // faster, if you know which you are using, to use the individual functions, but this will check
  10. // against available functions for you.
  11. func ClassIDFrom(programID string) (classID *GUID, err error) {
  12. classID, err = CLSIDFromProgID(programID)
  13. if err != nil {
  14. classID, err = CLSIDFromString(programID)
  15. if err != nil {
  16. return
  17. }
  18. }
  19. return
  20. }
  21. // BytePtrToString converts byte pointer to a Go string.
  22. func BytePtrToString(p *byte) string {
  23. a := (*[10000]uint8)(unsafe.Pointer(p))
  24. i := 0
  25. for a[i] != 0 {
  26. i++
  27. }
  28. return string(a[:i])
  29. }
  30. // UTF16PtrToString is alias for LpOleStrToString.
  31. //
  32. // Kept for compatibility reasons.
  33. func UTF16PtrToString(p *uint16) string {
  34. return LpOleStrToString(p)
  35. }
  36. // LpOleStrToString converts COM Unicode to Go string.
  37. func LpOleStrToString(p *uint16) string {
  38. if p == nil {
  39. return ""
  40. }
  41. length := lpOleStrLen(p)
  42. a := make([]uint16, length)
  43. ptr := unsafe.Pointer(p)
  44. for i := 0; i < int(length); i++ {
  45. a[i] = *(*uint16)(ptr)
  46. ptr = unsafe.Pointer(uintptr(ptr) + 2)
  47. }
  48. return string(utf16.Decode(a))
  49. }
  50. // BstrToString converts COM binary string to Go string.
  51. func BstrToString(p *uint16) string {
  52. if p == nil {
  53. return ""
  54. }
  55. length := SysStringLen((*int16)(unsafe.Pointer(p)))
  56. a := make([]uint16, length)
  57. ptr := unsafe.Pointer(p)
  58. for i := 0; i < int(length); i++ {
  59. a[i] = *(*uint16)(ptr)
  60. ptr = unsafe.Pointer(uintptr(ptr) + 2)
  61. }
  62. return string(utf16.Decode(a))
  63. }
  64. // lpOleStrLen returns the length of Unicode string.
  65. func lpOleStrLen(p *uint16) (length int64) {
  66. if p == nil {
  67. return 0
  68. }
  69. ptr := unsafe.Pointer(p)
  70. for i := 0; ; i++ {
  71. if 0 == *(*uint16)(ptr) {
  72. length = int64(i)
  73. break
  74. }
  75. ptr = unsafe.Pointer(uintptr(ptr) + 2)
  76. }
  77. return
  78. }
  79. // convertHresultToError converts syscall to error, if call is unsuccessful.
  80. func convertHresultToError(hr uintptr, r2 uintptr, ignore error) (err error) {
  81. if hr != 0 {
  82. err = NewError(hr)
  83. }
  84. return
  85. }