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