/
common.go
179 lines (160 loc) · 3.99 KB
/
common.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
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
package 炫彩工具类
import (
"syscall"
"unicode/utf16"
"unsafe"
)
// Bytes2String byte切片到string.
//
// @param b
// @return string
func Bytes2String(b []byte) string {
return *(*string)(unsafe.Pointer(&b))
}
func String2Bytes(s string) []byte {
sh := (*stringHeader)(unsafe.Pointer(&s))
bh := sliceHeader{
Data: sh.Data,
Len: sh.Len,
Cap: sh.Len,
}
return *(*[]byte)(unsafe.Pointer(&bh))
}
// stringHeader is the runtime representation of a string.
// It cannot be used safely or portably and its representation may
// change in a later release.
// Moreover, the Data field is not sufficient to guarantee the data
// it references will not be garbage collected, so programs must keep
// a separate, correctly typed pointer to the underlying data.
type stringHeader struct {
Data uintptr
Len int
}
// sliceHeader is the runtime representation of a slice.
// It cannot be used safely or portably and its representation may
// change in a later release.
// Moreover, the Data field is not sufficient to guarantee the data
// it references will not be garbage collected, so programs must keep
// a separate, correctly typed pointer to the underlying data.
type sliceHeader struct {
Data uintptr
Len int
Cap int
}
// StrPtr 将string转换到uintptr.
//
// @param s
// @return uintptr
func StrPtr(s string) uintptr {
if len(s) == 0 {
return uintptr(0)
}
p, _ := syscall.UTF16PtrFromString(s)
return uintptr(unsafe.Pointer(p))
}
// UintPtrToString 将uintptr转换到string.
//
// @param ptr
// @return string
func UintPtrToString(ptr uintptr) string {
if ptr == 0 {
return ""
}
s := *(*[]uint16)(unsafe.Pointer(&ptr)) // uintptr转换到[]uint16
for i := 0; i < len(s); i++ {
if s[i] == 0 {
(*sliceHeader)(unsafe.Pointer(&s)).Cap = i // 修改切片的cap
s = s[0:i]
break
}
}
return string(utf16.Decode(s))
}
// Uint16SliceDataPtr 将uint16[0]指针转换到uintptr.
//
// @param p
// @return uintptr
func Uint16SliceDataPtr(p *[]uint16) uintptr {
if len(*p) == 0 {
return uintptr(0)
}
return uintptr(unsafe.Pointer(&(*p)[0]))
}
// BoolPtr 将bool转换到uintptr.
//
// @param b
// @return uintptr
func BoolPtr(b bool) uintptr {
if b {
return uintptr(1)
}
return uintptr(0)
}
// Float32Ptr 将float32转换到uintptr.
//
// @param f
// @return uintptr
func Float32Ptr(f float32) uintptr {
return uintptr(*(*uint32)(unsafe.Pointer(&f)))
}
// UintPtrToFloat32 将uintptr转换到float32.
//
// @param ptr
// @return float32
func UintPtrToFloat32(ptr uintptr) float32 {
if ptr == 0 {
return 0
}
u := uint32(ptr)
return *(*float32)(unsafe.Pointer(&u))
}
// ByteSliceDataPtr 将byte[0]指针转换到uintptr.
//
// @param b
// @return uintptr
func ByteSliceDataPtr(b *[]byte) uintptr {
if len(*b) == 0 {
return uintptr(0)
}
return uintptr(unsafe.Pointer(&(*b)[0]))
}
/* // byte指针到uintptr.
func bytePtr(p *byte) uintptr {
return uintptr(unsafe.Pointer(p))
} */
/* func UintPtrToString2(r uintptr) string {
p := (*uint16)(unsafe.Pointer(r))
if p == nil {
return ""
}
n, end, add := 0, unsafe.Pointer(p), unsafe.Sizeof(*p)
for *(*uint16)(end) != 0 {
end = unsafe.Add(end, add)
n++
}
return string(utf16.Decode(unsafe.Slice(p, n)))
} */
/*// RuneToUint16Ptr 返回指向 UTF-8 字符串 r 的 UTF-16 编码的指针.
func RuneToUint16Ptr(r []rune) *uint16 {
return &utf16.Encode(r)[0]
}*/
// StringToUint16Ptr 返回指向 UTF-8 字符串 s 的 UTF-16 编码的指针,与 syscall.UTF16PtrFromString 不同的是末尾没有添加终止 NUL。
func StringToUint16Ptr(s string) *uint16 {
return &utf16.Encode([]rune(s))[0]
}
// Uint16SliceToStringSlice 按null字符分割, 把 []uint16 转换到 []string.
func Uint16SliceToStringSlice(s []uint16) []string {
strSlice := make([]string, 0)
start := 0
for i := 0; i < len(s); i++ {
if s[i] == 0 {
strSlice = append(strSlice, string(utf16.Decode(s[start:i])))
start = i + 1
// 连续null字符, 所以跳出
if s[start] == 0 {
break
}
}
}
return strSlice
}