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