forked from vitaminwater/cgo.wchar
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathwchar.go
159 lines (129 loc) · 3.67 KB
/
wchar.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
package wchar
import (
"unsafe"
)
// return pointer to this Wchar
func (w Wchar) Pointer() *Wchar {
return &w
}
// convert Wchar to Go rune
// will return an error when conversion failed.
func (w Wchar) GoRune() (rune, error) {
r, err := convertWcharToGoRune(w)
if err != nil {
return '\000', err
}
return r, nil
}
func FromGoRune(r rune) (Wchar, error) {
return convertGoRuneToWchar(r)
}
// FromWcharPtr converts a *C.wchar_t to a Go Wchar
func FromWcharPtr(ptr unsafe.Pointer) Wchar {
// quick return for null pointer
if uintptr(ptr) == 0x0 {
return Wchar(0)
}
return *((*Wchar)(ptr))
}
// go representation of a wchar string (array)
type WcharString []Wchar
// NewWcharString creates a new WcharString with given length.
// This is required when the WcharString is being used as write buffer for a call to a C function.
func NewWcharString(length int) WcharString {
return make(WcharString, length)
}
// FromGoString creates a WcharString from a Go string
func FromGoString(s string) (WcharString, error) {
return convertGoStringToWcharString(s)
}
// FromWcharStringPtr creates a WcharString from a *C.wchar_t.
// It finds the end of the *C.wchar_t string by finding the null terminator.
func FromWcharStringPtr(first unsafe.Pointer) WcharString {
// quick return for null pointer
if uintptr(first) == 0x0 {
return NewWcharString(0)
}
// Get uintptr from first wchar_t
wcharPtr := uintptr(first)
// allocate new WcharString to fill with data. Cap is unknown
ws := make(WcharString, 0)
// append data using pointer arithmic
var w Wchar
for {
// get Wchar value
w = *((*Wchar)(unsafe.Pointer(wcharPtr)))
// check for null byte terminator
if w == 0 {
break
}
// append Wchar to WcharString
ws = append(ws, w)
// increment pointer 4 bytes
wcharPtr += 4
}
// all done
return ws
}
// convert a *C.wchar_t and length int to a WcharString
func FromWcharStringPtrN(first unsafe.Pointer, length int) WcharString {
if uintptr(first) == 0x0 {
return NewWcharString(0)
}
// Get uintptr from first wchar_t
wcharPtr := uintptr(first)
// allocate new WcharString to fill with data. Only set cap, later use append
ws := make(WcharString, 0, length)
// append data using pointer arithmic
var x Wchar
for i := 0; i < length; i++ {
// get Wchar
x = *((*Wchar)(unsafe.Pointer(wcharPtr)))
// check for null byte terminator
if x == 0 {
break
}
// append Wchar to WcharString
ws = append(ws, x)
// increment pointer 4 bytes
wcharPtr += 4
}
// all done
return ws
}
// return pointer to first element
func (ws WcharString) Pointer() *Wchar {
return &ws[0]
}
// convert WcharString to Go string
// will return an error when conversion failed.
func (ws WcharString) GoString() (string, error) {
str, err := convertWcharStringToGoString(ws)
if err != nil {
return "", err
}
return str, nil
}
// convert a null terminated *C.wchar_t to a Go string
// convenient wrapper for WcharPtrToWcharString(first).GoString()
func WcharStringPtrToGoString(first unsafe.Pointer) (string, error) {
if uintptr(first) == 0x0 {
return "", nil
}
return convertWcharStringToGoString(FromWcharStringPtr(first))
}
// convert a *C.wchar_t and length int to a Go string
// convenient wrapper for WcharPtrIntToWcharString(first, length).GoString()
func WcharStringPtrNToGoString(first unsafe.Pointer, length int) (string, error) {
if uintptr(first) == 0x0 {
return "", nil
}
return convertWcharStringToGoString(FromWcharStringPtrN(first, length))
}
// convenient wrapper for WcharPtrToWcharString(first).GoString()
func WcharPtrToGoRune(first unsafe.Pointer) (rune, error) {
if uintptr(first) == 0x0 {
return '\000', nil
}
return convertWcharToGoRune(FromWcharPtr(first))
}