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