-
Notifications
You must be signed in to change notification settings - Fork 315
/
string.go
127 lines (115 loc) · 2.51 KB
/
string.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
package utils
import (
"math/rand"
"strconv"
"strings"
"unicode/utf8"
"unsafe"
)
func RandomString(len int) string {
return RandomStringRange(len, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890")
}
func RandomStringRange(length int, str string) string {
sb := strings.Builder{}
sb.Grow(length)
for i := 0; i < length; i++ {
sb.WriteByte(str[rand.Intn(len(str))])
}
return sb.String()
}
func ChunkString(s string, chunkSize int) []string {
runes := []rune(s)
if len(runes) == 0 || len(runes) <= chunkSize {
return []string{s}
}
chunkLen := len(runes) / chunkSize
if len(runes)%chunkSize != 0 {
chunkLen++
}
chunks := make([]string, 0, chunkLen)
for i := 0; i < len(runes); i += chunkSize {
nn := i + chunkSize
if nn > len(runes) {
nn = len(runes)
}
chunks = append(chunks, string(runes[i:nn]))
}
return chunks
}
func ConvertSubVersionToInt(str string) int32 {
i, _ := strconv.ParseInt(strings.Join(strings.Split(str, "."), ""), 10, 32)
return int32(i) * 10
}
// B2S converts byte slice to a string without memory allocation.
func B2S(b []byte) string {
size := len(b)
if size == 0 {
return ""
}
return unsafe.String(&b[0], size)
}
// S2B converts string to a byte slice without memory allocation.
//
// Note it may break if string and/or slice header will change
// in the future go versions.
func S2B(s string) (b []byte) {
return unsafe.Slice(unsafe.StringData(s), len(s))
}
const (
escQuot = """ // shorter than """
escApos = "'" // shorter than "'"
escAmp = "&"
escLT = "<"
escGT = ">"
escTab = "	"
escNL = "
"
escCR = "
"
escFFFD = "\uFFFD" // Unicode replacement character
)
func isInCharacterRange(r rune) (inrange bool) {
return r == 0x09 ||
r == 0x0A ||
r == 0x0D ||
r >= 0x20 && r <= 0xD7FF ||
r >= 0xE000 && r <= 0xFFFD ||
r >= 0x10000 && r <= 0x10FFFF
}
// XmlEscape xml escape string
func XmlEscape(s string) string {
var esc string
var sb strings.Builder
sb.Grow(len(s))
last := 0
for i, r := range s {
width := utf8.RuneLen(r)
switch r {
case '"':
esc = escQuot
case '\'':
esc = escApos
case '&':
esc = escAmp
case '<':
esc = escLT
case '>':
esc = escGT
case '\t':
esc = escTab
case '\n':
esc = escNL
case '\r':
esc = escCR
default:
if !isInCharacterRange(r) || (r == 0xFFFD && width == 1) {
esc = escFFFD
break
}
continue
}
sb.WriteString(s[last:i])
sb.WriteString(esc)
last = i + width
}
sb.WriteString(s[last:])
return sb.String()
}