Source file
src/bytes/bytes.go
1
2
3
4
5
6
7 package bytes
8
9 import (
10 "internal/bytealg"
11 "internal/stringslite"
12 "math/bits"
13 "unicode"
14 "unicode/utf8"
15 _ "unsafe"
16 )
17
18
19
20
21 func Equal(a, b []byte) bool {
22
23 return string(a) == string(b)
24 }
25
26
27
28
29 func Compare(a, b []byte) int {
30 return bytealg.Compare(a, b)
31 }
32
33
34
35 func explode(s []byte, n int) [][]byte {
36 if n <= 0 || n > len(s) {
37 n = len(s)
38 }
39 a := make([][]byte, n)
40 var size int
41 na := 0
42 for len(s) > 0 {
43 if na+1 >= n {
44 a[na] = s
45 na++
46 break
47 }
48 _, size = utf8.DecodeRune(s)
49 a[na] = s[0:size:size]
50 s = s[size:]
51 na++
52 }
53 return a[0:na]
54 }
55
56
57
58 func Count(s, sep []byte) int {
59
60 if len(sep) == 0 {
61 return utf8.RuneCount(s) + 1
62 }
63 if len(sep) == 1 {
64 return bytealg.Count(s, sep[0])
65 }
66 n := 0
67 for {
68 i := Index(s, sep)
69 if i == -1 {
70 return n
71 }
72 n++
73 s = s[i+len(sep):]
74 }
75 }
76
77
78 func Contains(b, subslice []byte) bool {
79 return Index(b, subslice) != -1
80 }
81
82
83 func ContainsAny(b []byte, chars string) bool {
84 return IndexAny(b, chars) >= 0
85 }
86
87
88 func ContainsRune(b []byte, r rune) bool {
89 return IndexRune(b, r) >= 0
90 }
91
92
93
94 func ContainsFunc(b []byte, f func(rune) bool) bool {
95 return IndexFunc(b, f) >= 0
96 }
97
98
99 func IndexByte(b []byte, c byte) int {
100 return bytealg.IndexByte(b, c)
101 }
102
103
104 func LastIndex(s, sep []byte) int {
105 n := len(sep)
106 switch {
107 case n == 0:
108 return len(s)
109 case n == 1:
110 return bytealg.LastIndexByte(s, sep[0])
111 case n == len(s):
112 if Equal(s, sep) {
113 return 0
114 }
115 return -1
116 case n > len(s):
117 return -1
118 }
119 return bytealg.LastIndexRabinKarp(s, sep)
120 }
121
122
123 func LastIndexByte(s []byte, c byte) int {
124 return bytealg.LastIndexByte(s, c)
125 }
126
127
128
129
130
131
132 func IndexRune(s []byte, r rune) int {
133 const haveFastIndex = bytealg.MaxBruteForce > 0
134 switch {
135 case 0 <= r && r < utf8.RuneSelf:
136 return IndexByte(s, byte(r))
137 case r == utf8.RuneError:
138 for i := 0; i < len(s); {
139 r1, n := utf8.DecodeRune(s[i:])
140 if r1 == utf8.RuneError {
141 return i
142 }
143 i += n
144 }
145 return -1
146 case !utf8.ValidRune(r):
147 return -1
148 default:
149
150
151
152 var b [utf8.UTFMax]byte
153 n := utf8.EncodeRune(b[:], r)
154 last := n - 1
155 i := last
156 fails := 0
157 for i < len(s) {
158 if s[i] != b[last] {
159 o := IndexByte(s[i+1:], b[last])
160 if o < 0 {
161 return -1
162 }
163 i += o + 1
164 }
165
166 for j := 1; j < n; j++ {
167 if s[i-j] != b[last-j] {
168 goto next
169 }
170 }
171 return i - last
172 next:
173 fails++
174 i++
175 if (haveFastIndex && fails > bytealg.Cutover(i)) && i < len(s) ||
176 (!haveFastIndex && fails >= 4+i>>4 && i < len(s)) {
177 goto fallback
178 }
179 }
180 return -1
181
182 fallback:
183
184
185 if haveFastIndex {
186 if j := bytealg.Index(s[i-last:], b[:n]); j >= 0 {
187 return i + j - last
188 }
189 } else {
190
191
192 c0 := b[last]
193 c1 := b[last-1]
194 loop:
195 for ; i < len(s); i++ {
196 if s[i] == c0 && s[i-1] == c1 {
197 for k := 2; k < n; k++ {
198 if s[i-k] != b[last-k] {
199 continue loop
200 }
201 }
202 return i - last
203 }
204 }
205 }
206 return -1
207 }
208 }
209
210
211
212
213
214 func IndexAny(s []byte, chars string) int {
215 if chars == "" {
216
217 return -1
218 }
219 if len(s) == 1 {
220 r := rune(s[0])
221 if r >= utf8.RuneSelf {
222
223 for _, r = range chars {
224 if r == utf8.RuneError {
225 return 0
226 }
227 }
228 return -1
229 }
230 if bytealg.IndexByteString(chars, s[0]) >= 0 {
231 return 0
232 }
233 return -1
234 }
235 if len(chars) == 1 {
236 r := rune(chars[0])
237 if r >= utf8.RuneSelf {
238 r = utf8.RuneError
239 }
240 return IndexRune(s, r)
241 }
242 if shouldUseASCIISet(len(s)) {
243 if as, isASCII := makeASCIISet(chars); isASCII {
244 for i, c := range s {
245 if as.contains(c) {
246 return i
247 }
248 }
249 return -1
250 }
251 }
252 var width int
253 for i := 0; i < len(s); i += width {
254 r := rune(s[i])
255 if r < utf8.RuneSelf {
256 if bytealg.IndexByteString(chars, s[i]) >= 0 {
257 return i
258 }
259 width = 1
260 continue
261 }
262 r, width = utf8.DecodeRune(s[i:])
263 if r != utf8.RuneError {
264
265 if len(chars) == width {
266 if chars == string(r) {
267 return i
268 }
269 continue
270 }
271
272 if bytealg.MaxLen >= width {
273 if bytealg.IndexString(chars, string(r)) >= 0 {
274 return i
275 }
276 continue
277 }
278 }
279 for _, ch := range chars {
280 if r == ch {
281 return i
282 }
283 }
284 }
285 return -1
286 }
287
288
289
290
291
292 func LastIndexAny(s []byte, chars string) int {
293 if chars == "" {
294
295 return -1
296 }
297 if shouldUseASCIISet(len(s)) {
298 if as, isASCII := makeASCIISet(chars); isASCII {
299 for i := len(s) - 1; i >= 0; i-- {
300 if as.contains(s[i]) {
301 return i
302 }
303 }
304 return -1
305 }
306 }
307 if len(s) == 1 {
308 r := rune(s[0])
309 if r >= utf8.RuneSelf {
310 for _, r = range chars {
311 if r == utf8.RuneError {
312 return 0
313 }
314 }
315 return -1
316 }
317 if bytealg.IndexByteString(chars, s[0]) >= 0 {
318 return 0
319 }
320 return -1
321 }
322 if len(chars) == 1 {
323 cr := rune(chars[0])
324 if cr >= utf8.RuneSelf {
325 cr = utf8.RuneError
326 }
327 for i := len(s); i > 0; {
328 r, size := utf8.DecodeLastRune(s[:i])
329 i -= size
330 if r == cr {
331 return i
332 }
333 }
334 return -1
335 }
336 for i := len(s); i > 0; {
337 r := rune(s[i-1])
338 if r < utf8.RuneSelf {
339 if bytealg.IndexByteString(chars, s[i-1]) >= 0 {
340 return i - 1
341 }
342 i--
343 continue
344 }
345 r, size := utf8.DecodeLastRune(s[:i])
346 i -= size
347 if r != utf8.RuneError {
348
349 if len(chars) == size {
350 if chars == string(r) {
351 return i
352 }
353 continue
354 }
355
356 if bytealg.MaxLen >= size {
357 if bytealg.IndexString(chars, string(r)) >= 0 {
358 return i
359 }
360 continue
361 }
362 }
363 for _, ch := range chars {
364 if r == ch {
365 return i
366 }
367 }
368 }
369 return -1
370 }
371
372
373
374 func genSplit(s, sep []byte, sepSave, n int) [][]byte {
375 if n == 0 {
376 return nil
377 }
378 if len(sep) == 0 {
379 return explode(s, n)
380 }
381 if n < 0 {
382 n = Count(s, sep) + 1
383 }
384 n = min(n, len(s)+1)
385
386 a := make([][]byte, n)
387 n--
388 i := 0
389 for i < n {
390 m := Index(s, sep)
391 if m < 0 {
392 break
393 }
394 a[i] = s[: m+sepSave : m+sepSave]
395 s = s[m+len(sep):]
396 i++
397 }
398 a[i] = s
399 return a[:i+1]
400 }
401
402
403
404
405
406
407
408
409
410
411 func SplitN(s, sep []byte, n int) [][]byte { return genSplit(s, sep, 0, n) }
412
413
414
415
416
417
418
419
420 func SplitAfterN(s, sep []byte, n int) [][]byte {
421 return genSplit(s, sep, len(sep), n)
422 }
423
424
425
426
427
428
429
430 func Split(s, sep []byte) [][]byte { return genSplit(s, sep, 0, -1) }
431
432
433
434
435
436 func SplitAfter(s, sep []byte) [][]byte {
437 return genSplit(s, sep, len(sep), -1)
438 }
439
440 var asciiSpace = [256]uint8{'\t': 1, '\n': 1, '\v': 1, '\f': 1, '\r': 1, ' ': 1}
441
442
443
444
445
446
447
448 func Fields(s []byte) [][]byte {
449
450
451 n := 0
452 wasSpace := 1
453
454 setBits := uint8(0)
455 for i := 0; i < len(s); i++ {
456 r := s[i]
457 setBits |= r
458 isSpace := int(asciiSpace[r])
459 n += wasSpace & ^isSpace
460 wasSpace = isSpace
461 }
462
463 if setBits >= utf8.RuneSelf {
464
465 return FieldsFunc(s, unicode.IsSpace)
466 }
467
468
469 a := make([][]byte, n)
470 na := 0
471 fieldStart := 0
472 i := 0
473
474 for i < len(s) && asciiSpace[s[i]] != 0 {
475 i++
476 }
477 fieldStart = i
478 for i < len(s) {
479 if asciiSpace[s[i]] == 0 {
480 i++
481 continue
482 }
483 a[na] = s[fieldStart:i:i]
484 na++
485 i++
486
487 for i < len(s) && asciiSpace[s[i]] != 0 {
488 i++
489 }
490 fieldStart = i
491 }
492 if fieldStart < len(s) {
493 a[na] = s[fieldStart:len(s):len(s)]
494 }
495 return a
496 }
497
498
499
500
501
502
503
504
505
506
507 func FieldsFunc(s []byte, f func(rune) bool) [][]byte {
508
509
510 type span struct {
511 start int
512 end int
513 }
514 spans := make([]span, 0, 32)
515
516
517
518
519
520 start := -1
521 for i := 0; i < len(s); {
522 r, size := utf8.DecodeRune(s[i:])
523 if f(r) {
524 if start >= 0 {
525 spans = append(spans, span{start, i})
526 start = -1
527 }
528 } else {
529 if start < 0 {
530 start = i
531 }
532 }
533 i += size
534 }
535
536
537 if start >= 0 {
538 spans = append(spans, span{start, len(s)})
539 }
540
541
542 a := make([][]byte, len(spans))
543 for i, span := range spans {
544 a[i] = s[span.start:span.end:span.end]
545 }
546
547 return a
548 }
549
550
551
552 func Join(s [][]byte, sep []byte) []byte {
553 if len(s) == 0 {
554 return []byte{}
555 }
556 if len(s) == 1 {
557
558 return append([]byte(nil), s[0]...)
559 }
560
561 var n int
562 if len(sep) > 0 {
563 if len(sep) >= maxInt/(len(s)-1) {
564 panic("bytes: Join output length overflow")
565 }
566 n += len(sep) * (len(s) - 1)
567 }
568 for _, v := range s {
569 if len(v) > maxInt-n {
570 panic("bytes: Join output length overflow")
571 }
572 n += len(v)
573 }
574
575 b := bytealg.MakeNoZero(n)[:n:n]
576 bp := copy(b, s[0])
577 for _, v := range s[1:] {
578 bp += copy(b[bp:], sep)
579 bp += copy(b[bp:], v)
580 }
581 return b
582 }
583
584
585 func HasPrefix(s, prefix []byte) bool {
586 return len(s) >= len(prefix) && Equal(s[:len(prefix)], prefix)
587 }
588
589
590 func HasSuffix(s, suffix []byte) bool {
591 return len(s) >= len(suffix) && Equal(s[len(s)-len(suffix):], suffix)
592 }
593
594
595
596
597
598 func Map(mapping func(r rune) rune, s []byte) []byte {
599
600
601
602 b := make([]byte, 0, len(s))
603 for i := 0; i < len(s); {
604 r, wid := utf8.DecodeRune(s[i:])
605 r = mapping(r)
606 if r >= 0 {
607 b = utf8.AppendRune(b, r)
608 }
609 i += wid
610 }
611 return b
612 }
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630 func Repeat(b []byte, count int) []byte {
631 if count == 0 {
632 return []byte{}
633 }
634
635
636
637
638 if count < 0 {
639 panic("bytes: negative Repeat count")
640 }
641 hi, lo := bits.Mul(uint(len(b)), uint(count))
642 if hi > 0 || lo > uint(maxInt) {
643 panic("bytes: Repeat output length overflow")
644 }
645 n := int(lo)
646
647 if len(b) == 0 {
648 return []byte{}
649 }
650
651
652
653
654
655
656
657
658
659
660
661 const chunkLimit = 8 * 1024
662 chunkMax := n
663 if chunkMax > chunkLimit {
664 chunkMax = chunkLimit / len(b) * len(b)
665 if chunkMax == 0 {
666 chunkMax = len(b)
667 }
668 }
669 nb := bytealg.MakeNoZero(n)[:n:n]
670 bp := copy(nb, b)
671 for bp < n {
672 chunk := min(bp, chunkMax)
673 bp += copy(nb[bp:], nb[:chunk])
674 }
675 return nb
676 }
677
678
679
680 func ToUpper(s []byte) []byte {
681 isASCII, hasLower := true, false
682 for i := 0; i < len(s); i++ {
683 c := s[i]
684 if c >= utf8.RuneSelf {
685 isASCII = false
686 break
687 }
688 hasLower = hasLower || ('a' <= c && c <= 'z')
689 }
690
691 if isASCII {
692 if !hasLower {
693
694 return append([]byte(""), s...)
695 }
696 b := bytealg.MakeNoZero(len(s))[:len(s):len(s)]
697 for i := 0; i < len(s); i++ {
698 c := s[i]
699 if 'a' <= c && c <= 'z' {
700 c -= 'a' - 'A'
701 }
702 b[i] = c
703 }
704 return b
705 }
706 return Map(unicode.ToUpper, s)
707 }
708
709
710
711 func ToLower(s []byte) []byte {
712 isASCII, hasUpper := true, false
713 for i := 0; i < len(s); i++ {
714 c := s[i]
715 if c >= utf8.RuneSelf {
716 isASCII = false
717 break
718 }
719 hasUpper = hasUpper || ('A' <= c && c <= 'Z')
720 }
721
722 if isASCII {
723 if !hasUpper {
724 return append([]byte(""), s...)
725 }
726 b := bytealg.MakeNoZero(len(s))[:len(s):len(s)]
727 for i := 0; i < len(s); i++ {
728 c := s[i]
729 if 'A' <= c && c <= 'Z' {
730 c += 'a' - 'A'
731 }
732 b[i] = c
733 }
734 return b
735 }
736 return Map(unicode.ToLower, s)
737 }
738
739
740 func ToTitle(s []byte) []byte { return Map(unicode.ToTitle, s) }
741
742
743
744 func ToUpperSpecial(c unicode.SpecialCase, s []byte) []byte {
745 return Map(c.ToUpper, s)
746 }
747
748
749
750 func ToLowerSpecial(c unicode.SpecialCase, s []byte) []byte {
751 return Map(c.ToLower, s)
752 }
753
754
755
756 func ToTitleSpecial(c unicode.SpecialCase, s []byte) []byte {
757 return Map(c.ToTitle, s)
758 }
759
760
761
762 func ToValidUTF8(s, replacement []byte) []byte {
763 b := make([]byte, 0, len(s)+len(replacement))
764 invalid := false
765 for i := 0; i < len(s); {
766 c := s[i]
767 if c < utf8.RuneSelf {
768 i++
769 invalid = false
770 b = append(b, c)
771 continue
772 }
773 _, wid := utf8.DecodeRune(s[i:])
774 if wid == 1 {
775 i++
776 if !invalid {
777 invalid = true
778 b = append(b, replacement...)
779 }
780 continue
781 }
782 invalid = false
783 b = append(b, s[i:i+wid]...)
784 i += wid
785 }
786 return b
787 }
788
789
790
791 func isSeparator(r rune) bool {
792
793 if r <= 0x7F {
794 switch {
795 case '0' <= r && r <= '9':
796 return false
797 case 'a' <= r && r <= 'z':
798 return false
799 case 'A' <= r && r <= 'Z':
800 return false
801 case r == '_':
802 return false
803 }
804 return true
805 }
806
807 if unicode.IsLetter(r) || unicode.IsDigit(r) {
808 return false
809 }
810
811 return unicode.IsSpace(r)
812 }
813
814
815
816
817
818
819 func Title(s []byte) []byte {
820
821
822
823 prev := ' '
824 return Map(
825 func(r rune) rune {
826 if isSeparator(prev) {
827 prev = r
828 return unicode.ToTitle(r)
829 }
830 prev = r
831 return r
832 },
833 s)
834 }
835
836
837
838 func TrimLeftFunc(s []byte, f func(r rune) bool) []byte {
839 i := indexFunc(s, f, false)
840 if i == -1 {
841 return nil
842 }
843 return s[i:]
844 }
845
846
847
848 func TrimRightFunc(s []byte, f func(r rune) bool) []byte {
849 i := lastIndexFunc(s, f, false)
850 if i >= 0 && s[i] >= utf8.RuneSelf {
851 _, wid := utf8.DecodeRune(s[i:])
852 i += wid
853 } else {
854 i++
855 }
856 return s[0:i]
857 }
858
859
860
861 func TrimFunc(s []byte, f func(r rune) bool) []byte {
862 return TrimRightFunc(TrimLeftFunc(s, f), f)
863 }
864
865
866
867 func TrimPrefix(s, prefix []byte) []byte {
868 if HasPrefix(s, prefix) {
869 return s[len(prefix):]
870 }
871 return s
872 }
873
874
875
876 func TrimSuffix(s, suffix []byte) []byte {
877 if HasSuffix(s, suffix) {
878 return s[:len(s)-len(suffix)]
879 }
880 return s
881 }
882
883
884
885
886 func IndexFunc(s []byte, f func(r rune) bool) int {
887 return indexFunc(s, f, true)
888 }
889
890
891
892
893 func LastIndexFunc(s []byte, f func(r rune) bool) int {
894 return lastIndexFunc(s, f, true)
895 }
896
897
898
899
900 func indexFunc(s []byte, f func(r rune) bool, truth bool) int {
901 start := 0
902 for start < len(s) {
903 r, wid := utf8.DecodeRune(s[start:])
904 if f(r) == truth {
905 return start
906 }
907 start += wid
908 }
909 return -1
910 }
911
912
913
914
915 func lastIndexFunc(s []byte, f func(r rune) bool, truth bool) int {
916 for i := len(s); i > 0; {
917 r, size := rune(s[i-1]), 1
918 if r >= utf8.RuneSelf {
919 r, size = utf8.DecodeLastRune(s[0:i])
920 }
921 i -= size
922 if f(r) == truth {
923 return i
924 }
925 }
926 return -1
927 }
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944 type asciiSet [256]bool
945
946
947
948 func makeASCIISet(chars string) (as asciiSet, ok bool) {
949 for i := 0; i < len(chars); i++ {
950 c := chars[i]
951 if c >= utf8.RuneSelf {
952 return as, false
953 }
954 as[c] = true
955 }
956 return as, true
957 }
958
959
960 func (as *asciiSet) contains(c byte) bool {
961 return as[c]
962 }
963
964
965
966
967
968
969
970 func shouldUseASCIISet(bufLen int) bool {
971 return bufLen > 8
972 }
973
974
975
976
977 func containsRune(s string, r rune) bool {
978 for _, c := range s {
979 if c == r {
980 return true
981 }
982 }
983 return false
984 }
985
986
987
988 func Trim(s []byte, cutset string) []byte {
989 if len(s) == 0 {
990
991 return nil
992 }
993 if cutset == "" {
994 return s
995 }
996 if len(cutset) == 1 && cutset[0] < utf8.RuneSelf {
997 return trimLeftByte(trimRightByte(s, cutset[0]), cutset[0])
998 }
999 if as, ok := makeASCIISet(cutset); ok {
1000 return trimLeftASCII(trimRightASCII(s, &as), &as)
1001 }
1002 return trimLeftUnicode(trimRightUnicode(s, cutset), cutset)
1003 }
1004
1005
1006
1007 func TrimLeft(s []byte, cutset string) []byte {
1008 if len(s) == 0 {
1009
1010 return nil
1011 }
1012 if cutset == "" {
1013 return s
1014 }
1015 if len(cutset) == 1 && cutset[0] < utf8.RuneSelf {
1016 return trimLeftByte(s, cutset[0])
1017 }
1018 if as, ok := makeASCIISet(cutset); ok {
1019 return trimLeftASCII(s, &as)
1020 }
1021 return trimLeftUnicode(s, cutset)
1022 }
1023
1024 func trimLeftByte(s []byte, c byte) []byte {
1025 for len(s) > 0 && s[0] == c {
1026 s = s[1:]
1027 }
1028 if len(s) == 0 {
1029
1030 return nil
1031 }
1032 return s
1033 }
1034
1035 func trimLeftASCII(s []byte, as *asciiSet) []byte {
1036 for len(s) > 0 {
1037 if !as.contains(s[0]) {
1038 break
1039 }
1040 s = s[1:]
1041 }
1042 if len(s) == 0 {
1043
1044 return nil
1045 }
1046 return s
1047 }
1048
1049 func trimLeftUnicode(s []byte, cutset string) []byte {
1050 for len(s) > 0 {
1051 r, n := utf8.DecodeRune(s)
1052 if !containsRune(cutset, r) {
1053 break
1054 }
1055 s = s[n:]
1056 }
1057 if len(s) == 0 {
1058
1059 return nil
1060 }
1061 return s
1062 }
1063
1064
1065
1066 func TrimRight(s []byte, cutset string) []byte {
1067 if len(s) == 0 || cutset == "" {
1068 return s
1069 }
1070 if len(cutset) == 1 && cutset[0] < utf8.RuneSelf {
1071 return trimRightByte(s, cutset[0])
1072 }
1073 if as, ok := makeASCIISet(cutset); ok {
1074 return trimRightASCII(s, &as)
1075 }
1076 return trimRightUnicode(s, cutset)
1077 }
1078
1079 func trimRightByte(s []byte, c byte) []byte {
1080 for len(s) > 0 && s[len(s)-1] == c {
1081 s = s[:len(s)-1]
1082 }
1083 return s
1084 }
1085
1086 func trimRightASCII(s []byte, as *asciiSet) []byte {
1087 for len(s) > 0 {
1088 if !as.contains(s[len(s)-1]) {
1089 break
1090 }
1091 s = s[:len(s)-1]
1092 }
1093 return s
1094 }
1095
1096 func trimRightUnicode(s []byte, cutset string) []byte {
1097 for len(s) > 0 {
1098 r, n := rune(s[len(s)-1]), 1
1099 if r >= utf8.RuneSelf {
1100 r, n = utf8.DecodeLastRune(s)
1101 }
1102 if !containsRune(cutset, r) {
1103 break
1104 }
1105 s = s[:len(s)-n]
1106 }
1107 return s
1108 }
1109
1110 func trimSpaceUnicode(s []byte) []byte {
1111 for len(s) > 0 {
1112 r, n := utf8.DecodeRune(s)
1113 if !stringslite.IsSpace(r) {
1114 break
1115 }
1116 s = s[n:]
1117 }
1118 if len(s) == 0 {
1119
1120 return nil
1121 }
1122 return trimRightSpaceUnicode(s)
1123 }
1124
1125 func trimRightSpaceUnicode(s []byte) []byte {
1126 for len(s) > 0 {
1127 r, n := rune(s[len(s)-1]), 1
1128 if r >= utf8.RuneSelf {
1129 r, n = utf8.DecodeLastRune(s)
1130 }
1131 if !stringslite.IsSpace(r) {
1132 break
1133 }
1134 s = s[:len(s)-n]
1135 }
1136 return s
1137 }
1138
1139
1140
1141 func TrimSpace(s []byte) []byte {
1142
1143 for lo, c := range s {
1144 if c >= utf8.RuneSelf {
1145
1146
1147 return trimSpaceUnicode(s[lo:])
1148 }
1149 if asciiSpace[c] != 0 {
1150 continue
1151 }
1152 s = s[lo:]
1153
1154 for hi := len(s) - 1; hi >= 0; hi-- {
1155 c := s[hi]
1156 if c >= utf8.RuneSelf {
1157 return trimRightSpaceUnicode(s[:hi+1])
1158 }
1159 if asciiSpace[c] == 0 {
1160
1161
1162
1163 return s[:hi+1]
1164 }
1165 }
1166 }
1167
1168
1169 return nil
1170 }
1171
1172
1173
1174 func Runes(s []byte) []rune {
1175 t := make([]rune, utf8.RuneCount(s))
1176 i := 0
1177 for len(s) > 0 {
1178 r, l := utf8.DecodeRune(s)
1179 t[i] = r
1180 i++
1181 s = s[l:]
1182 }
1183 return t
1184 }
1185
1186
1187
1188
1189
1190
1191
1192 func Replace(s, old, new []byte, n int) []byte {
1193 m := 0
1194 if n != 0 {
1195
1196 m = Count(s, old)
1197 }
1198 if m == 0 {
1199
1200 return append([]byte(nil), s...)
1201 }
1202 if n < 0 || m < n {
1203 n = m
1204 }
1205
1206
1207 t := make([]byte, len(s)+n*(len(new)-len(old)))
1208 w := 0
1209 start := 0
1210 if len(old) > 0 {
1211 for range n {
1212 j := start + Index(s[start:], old)
1213 w += copy(t[w:], s[start:j])
1214 w += copy(t[w:], new)
1215 start = j + len(old)
1216 }
1217 } else {
1218 w += copy(t[w:], new)
1219 for range n - 1 {
1220 _, wid := utf8.DecodeRune(s[start:])
1221 j := start + wid
1222 w += copy(t[w:], s[start:j])
1223 w += copy(t[w:], new)
1224 start = j
1225 }
1226 }
1227 w += copy(t[w:], s[start:])
1228 return t[0:w]
1229 }
1230
1231
1232
1233
1234
1235
1236 func ReplaceAll(s, old, new []byte) []byte {
1237 return Replace(s, old, new, -1)
1238 }
1239
1240
1241
1242
1243 func EqualFold(s, t []byte) bool {
1244
1245 i := 0
1246 for n := min(len(s), len(t)); i < n; i++ {
1247 sr := s[i]
1248 tr := t[i]
1249 if sr|tr >= utf8.RuneSelf {
1250 goto hasUnicode
1251 }
1252
1253
1254 if tr == sr {
1255 continue
1256 }
1257
1258
1259 if tr < sr {
1260 tr, sr = sr, tr
1261 }
1262
1263 if 'A' <= sr && sr <= 'Z' && tr == sr+'a'-'A' {
1264 continue
1265 }
1266 return false
1267 }
1268
1269 return len(s) == len(t)
1270
1271 hasUnicode:
1272 s = s[i:]
1273 t = t[i:]
1274 for len(s) != 0 && len(t) != 0 {
1275
1276 sr, size := utf8.DecodeRune(s)
1277 s = s[size:]
1278 tr, size := utf8.DecodeRune(t)
1279 t = t[size:]
1280
1281
1282
1283
1284 if tr == sr {
1285 continue
1286 }
1287
1288
1289 if tr < sr {
1290 tr, sr = sr, tr
1291 }
1292
1293 if tr < utf8.RuneSelf {
1294
1295 if 'A' <= sr && sr <= 'Z' && tr == sr+'a'-'A' {
1296 continue
1297 }
1298 return false
1299 }
1300
1301
1302
1303 r := unicode.SimpleFold(sr)
1304 for r != sr && r < tr {
1305 r = unicode.SimpleFold(r)
1306 }
1307 if r == tr {
1308 continue
1309 }
1310 return false
1311 }
1312
1313
1314 return len(s) == len(t)
1315 }
1316
1317
1318 func Index(s, sep []byte) int {
1319 n := len(sep)
1320 switch {
1321 case n == 0:
1322 return 0
1323 case n == 1:
1324 return IndexByte(s, sep[0])
1325 case n == len(s):
1326 if Equal(sep, s) {
1327 return 0
1328 }
1329 return -1
1330 case n > len(s):
1331 return -1
1332 case n <= bytealg.MaxLen:
1333
1334 if len(s) <= bytealg.MaxBruteForce {
1335 return bytealg.Index(s, sep)
1336 }
1337 c0 := sep[0]
1338 c1 := sep[1]
1339 i := 0
1340 t := len(s) - n + 1
1341 fails := 0
1342 for i < t {
1343 if s[i] != c0 {
1344
1345
1346 o := IndexByte(s[i+1:t], c0)
1347 if o < 0 {
1348 return -1
1349 }
1350 i += o + 1
1351 }
1352 if s[i+1] == c1 && Equal(s[i:i+n], sep) {
1353 return i
1354 }
1355 fails++
1356 i++
1357
1358 if fails > bytealg.Cutover(i) {
1359 r := bytealg.Index(s[i:], sep)
1360 if r >= 0 {
1361 return r + i
1362 }
1363 return -1
1364 }
1365 }
1366 return -1
1367 }
1368 c0 := sep[0]
1369 c1 := sep[1]
1370 i := 0
1371 fails := 0
1372 t := len(s) - n + 1
1373 for i < t {
1374 if s[i] != c0 {
1375 o := IndexByte(s[i+1:t], c0)
1376 if o < 0 {
1377 break
1378 }
1379 i += o + 1
1380 }
1381 if s[i+1] == c1 && Equal(s[i:i+n], sep) {
1382 return i
1383 }
1384 i++
1385 fails++
1386 if fails >= 4+i>>4 && i < t {
1387
1388
1389
1390
1391
1392
1393
1394
1395 j := bytealg.IndexRabinKarp(s[i:], sep)
1396 if j < 0 {
1397 return -1
1398 }
1399 return i + j
1400 }
1401 }
1402 return -1
1403 }
1404
1405
1406
1407
1408
1409
1410
1411 func Cut(s, sep []byte) (before, after []byte, found bool) {
1412 if i := Index(s, sep); i >= 0 {
1413 return s[:i], s[i+len(sep):], true
1414 }
1415 return s, nil, false
1416 }
1417
1418
1419
1420
1421 func Clone(b []byte) []byte {
1422 if b == nil {
1423 return nil
1424 }
1425 return append([]byte{}, b...)
1426 }
1427
1428
1429
1430
1431
1432
1433
1434 func CutPrefix(s, prefix []byte) (after []byte, found bool) {
1435 if !HasPrefix(s, prefix) {
1436 return s, false
1437 }
1438 return s[len(prefix):], true
1439 }
1440
1441
1442
1443
1444
1445
1446
1447 func CutSuffix(s, suffix []byte) (before []byte, found bool) {
1448 if !HasSuffix(s, suffix) {
1449 return s, false
1450 }
1451 return s[:len(s)-len(suffix)], true
1452 }
1453
1454
1455
1456
1457
1458
1459
1460 func CutLast(s, sep []byte) (before, after []byte, found bool) {
1461 if i := LastIndex(s, sep); i >= 0 {
1462 return s[:i], s[i+len(sep):], true
1463 }
1464 return s, nil, false
1465 }
1466
View as plain text