1
2
3
4
5
6
7
8
9 package stringslite
10
11 import (
12 "internal/bytealg"
13 "unsafe"
14 )
15
16 func HasPrefix(s, prefix string) bool {
17 return len(s) >= len(prefix) && s[:len(prefix)] == prefix
18 }
19
20 func HasSuffix(s, suffix string) bool {
21 return len(s) >= len(suffix) && s[len(s)-len(suffix):] == suffix
22 }
23
24 func IndexByte(s string, c byte) int {
25 return bytealg.IndexByteString(s, c)
26 }
27
28 func Index(s, substr string) int {
29 n := len(substr)
30 switch {
31 case n == 0 || substr == s:
32 return 0
33 case n == 1:
34 return IndexByte(s, substr[0])
35 case n >= len(s):
36 return -1
37 case n <= bytealg.MaxLen && len(s) <= bytealg.MaxBruteForce:
38
39 return bytealg.IndexString(s, substr)
40 }
41 c0 := substr[0]
42 c1 := substr[1]
43 i := 0
44 t := len(s) - n + 1
45 fails := 0
46 for i < t {
47 if s[i] != c0 {
48
49
50 o := IndexByte(s[i+1:t], c0)
51 if o < 0 {
52 return -1
53 }
54 i += o + 1
55 }
56 if s[i+1] == c1 && s[i:i+n] == substr {
57 return i
58 }
59 i++
60 fails++
61 if n <= bytealg.MaxLen && fails > bytealg.Cutover(i) {
62
63 r := bytealg.IndexString(s[i:], substr)
64 if r >= 0 {
65 return r + i
66 }
67 return -1
68 } else if fails >= 4+i>>4 && i < t {
69
70 j := bytealg.IndexRabinKarp(s[i:], substr)
71 if j < 0 {
72 return -1
73 }
74 return i + j
75 }
76 }
77 return -1
78 }
79
80 func Cut(s, sep string) (before, after string, found bool) {
81 if i := Index(s, sep); i >= 0 {
82 return s[:i], s[i+len(sep):], true
83 }
84 return s, "", false
85 }
86
87 func CutPrefix(s, prefix string) (after string, found bool) {
88 if !HasPrefix(s, prefix) {
89 return s, false
90 }
91 return s[len(prefix):], true
92 }
93
94 func CutSuffix(s, suffix string) (before string, found bool) {
95 if !HasSuffix(s, suffix) {
96 return s, false
97 }
98 return s[:len(s)-len(suffix)], true
99 }
100
101 func TrimPrefix(s, prefix string) string {
102 if HasPrefix(s, prefix) {
103 return s[len(prefix):]
104 }
105 return s
106 }
107
108 func TrimSuffix(s, suffix string) string {
109 if HasSuffix(s, suffix) {
110 return s[:len(s)-len(suffix)]
111 }
112 return s
113 }
114
115 func Clone(s string) string {
116 if len(s) == 0 {
117 return ""
118 }
119 b := make([]byte, len(s))
120 copy(b, s)
121 return unsafe.String(&b[0], len(b))
122 }
123
View as plain text