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 if n > len(s)+1 {
384 n = len(s) + 1
385 }
386
387 a := make([][]byte, n)
388 n--
389 i := 0
390 for i < n {
391 m := Index(s, sep)
392 if m < 0 {
393 break
394 }
395 a[i] = s[: m+sepSave : m+sepSave]
396 s = s[m+len(sep):]
397 i++
398 }
399 a[i] = s
400 return a[:i+1]
401 }
402
403
404
405
406
407
408
409
410
411
412 func SplitN(s, sep []byte, n int) [][]byte { return genSplit(s, sep, 0, n) }
413
414
415
416
417
418
419
420
421 func SplitAfterN(s, sep []byte, n int) [][]byte {
422 return genSplit(s, sep, len(sep), n)
423 }
424
425
426
427
428
429
430
431 func Split(s, sep []byte) [][]byte { return genSplit(s, sep, 0, -1) }
432
433
434
435
436
437 func SplitAfter(s, sep []byte) [][]byte {
438 return genSplit(s, sep, len(sep), -1)
439 }
440
441 var asciiSpace = [256]uint8{'\t': 1, '\n': 1, '\v': 1, '\f': 1, '\r': 1, ' ': 1}
442
443
444
445
446
447
448
449 func Fields(s []byte) [][]byte {
450
451
452 n := 0
453 wasSpace := 1
454
455 setBits := uint8(0)
456 for i := 0; i < len(s); i++ {
457 r := s[i]
458 setBits |= r
459 isSpace := int(asciiSpace[r])
460 n += wasSpace & ^isSpace
461 wasSpace = isSpace
462 }
463
464 if setBits >= utf8.RuneSelf {
465
466 return FieldsFunc(s, unicode.IsSpace)
467 }
468
469
470 a := make([][]byte, n)
471 na := 0
472 fieldStart := 0
473 i := 0
474
475 for i < len(s) && asciiSpace[s[i]] != 0 {
476 i++
477 }
478 fieldStart = i
479 for i < len(s) {
480 if asciiSpace[s[i]] == 0 {
481 i++
482 continue
483 }
484 a[na] = s[fieldStart:i:i]
485 na++
486 i++
487
488 for i < len(s) && asciiSpace[s[i]] != 0 {
489 i++
490 }
491 fieldStart = i
492 }
493 if fieldStart < len(s) {
494 a[na] = s[fieldStart:len(s):len(s)]
495 }
496 return a
497 }
498
499
500
501
502
503
504
505
506
507
508 func FieldsFunc(s []byte, f func(rune) bool) [][]byte {
509
510
511 type span struct {
512 start int
513 end int
514 }
515 spans := make([]span, 0, 32)
516
517
518
519
520
521 start := -1
522 for i := 0; i < len(s); {
523 r, size := utf8.DecodeRune(s[i:])
524 if f(r) {
525 if start >= 0 {
526 spans = append(spans, span{start, i})
527 start = -1
528 }
529 } else {
530 if start < 0 {
531 start = i
532 }
533 }
534 i += size
535 }
536
537
538 if start >= 0 {
539 spans = append(spans, span{start, len(s)})
540 }
541
542
543 a := make([][]byte, len(spans))
544 for i, span := range spans {
545 a[i] = s[span.start:span.end:span.end]
546 }
547
548 return a
549 }
550
551
552
553 func Join(s [][]byte, sep []byte) []byte {
554 if len(s) == 0 {
555 return []byte{}
556 }
557 if len(s) == 1 {
558
559 return append([]byte(nil), s[0]...)
560 }
561
562 var n int
563 if len(sep) > 0 {
564 if len(sep) >= maxInt/(len(s)-1) {
565 panic("bytes: Join output length overflow")
566 }
567 n += len(sep) * (len(s) - 1)
568 }
569 for _, v := range s {
570 if len(v) > maxInt-n {
571 panic("bytes: Join output length overflow")
572 }
573 n += len(v)
574 }
575
576 b := bytealg.MakeNoZero(n)[:n:n]
577 bp := copy(b, s[0])
578 for _, v := range s[1:] {
579 bp += copy(b[bp:], sep)
580 bp += copy(b[bp:], v)
581 }
582 return b
583 }
584
585
586 func HasPrefix(s, prefix []byte) bool {
587 return len(s) >= len(prefix) && Equal(s[:len(prefix)], prefix)
588 }
589
590
591 func HasSuffix(s, suffix []byte) bool {
592 return len(s) >= len(suffix) && Equal(s[len(s)-len(suffix):], suffix)
593 }
594
595
596
597
598
599 func Map(mapping func(r rune) rune, s []byte) []byte {
600
601
602
603 b := make([]byte, 0, len(s))
604 for i := 0; i < len(s); {
605 r, wid := utf8.DecodeRune(s[i:])
606 r = mapping(r)
607 if r >= 0 {
608 b = utf8.AppendRune(b, r)
609 }
610 i += wid
611 }
612 return b
613 }
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631 func Repeat(b []byte, count int) []byte {
632 if count == 0 {
633 return []byte{}
634 }
635
636
637
638
639 if count < 0 {
640 panic("bytes: negative Repeat count")
641 }
642 hi, lo := bits.Mul(uint(len(b)), uint(count))
643 if hi > 0 || lo > uint(maxInt) {
644 panic("bytes: Repeat output length overflow")
645 }
646 n := int(lo)
647
648 if len(b) == 0 {
649 return []byte{}
650 }
651
652
653
654
655
656
657
658
659
660
661
662 const chunkLimit = 8 * 1024
663 chunkMax := n
664 if chunkMax > chunkLimit {
665 chunkMax = chunkLimit / len(b) * len(b)
666 if chunkMax == 0 {
667 chunkMax = len(b)
668 }
669 }
670 nb := bytealg.MakeNoZero(n)[:n:n]
671 bp := copy(nb, b)
672 for bp < n {
673 chunk := min(bp, chunkMax)
674 bp += copy(nb[bp:], nb[:chunk])
675 }
676 return nb
677 }
678
679
680
681 func ToUpper(s []byte) []byte {
682 isASCII, hasLower := true, false
683 for i := 0; i < len(s); i++ {
684 c := s[i]
685 if c >= utf8.RuneSelf {
686 isASCII = false
687 break
688 }
689 hasLower = hasLower || ('a' <= c && c <= 'z')
690 }
691
692 if isASCII {
693 if !hasLower {
694
695 return append([]byte(""), s...)
696 }
697 b := bytealg.MakeNoZero(len(s))[:len(s):len(s)]
698 for i := 0; i < len(s); i++ {
699 c := s[i]
700 if 'a' <= c && c <= 'z' {
701 c -= 'a' - 'A'
702 }
703 b[i] = c
704 }
705 return b
706 }
707 return Map(unicode.ToUpper, s)
708 }
709
710
711
712 func ToLower(s []byte) []byte {
713 isASCII, hasUpper := true, false
714 for i := 0; i < len(s); i++ {
715 c := s[i]
716 if c >= utf8.RuneSelf {
717 isASCII = false
718 break
719 }
720 hasUpper = hasUpper || ('A' <= c && c <= 'Z')
721 }
722
723 if isASCII {
724 if !hasUpper {
725 return append([]byte(""), s...)
726 }
727 b := bytealg.MakeNoZero(len(s))[:len(s):len(s)]
728 for i := 0; i < len(s); i++ {
729 c := s[i]
730 if 'A' <= c && c <= 'Z' {
731 c += 'a' - 'A'
732 }
733 b[i] = c
734 }
735 return b
736 }
737 return Map(unicode.ToLower, s)
738 }
739
740
741 func ToTitle(s []byte) []byte { return Map(unicode.ToTitle, s) }
742
743
744
745 func ToUpperSpecial(c unicode.SpecialCase, s []byte) []byte {
746 return Map(c.ToUpper, s)
747 }
748
749
750
751 func ToLowerSpecial(c unicode.SpecialCase, s []byte) []byte {
752 return Map(c.ToLower, s)
753 }
754
755
756
757 func ToTitleSpecial(c unicode.SpecialCase, s []byte) []byte {
758 return Map(c.ToTitle, s)
759 }
760
761
762
763 func ToValidUTF8(s, replacement []byte) []byte {
764 b := make([]byte, 0, len(s)+len(replacement))
765 invalid := false
766 for i := 0; i < len(s); {
767 c := s[i]
768 if c < utf8.RuneSelf {
769 i++
770 invalid = false
771 b = append(b, c)
772 continue
773 }
774 _, wid := utf8.DecodeRune(s[i:])
775 if wid == 1 {
776 i++
777 if !invalid {
778 invalid = true
779 b = append(b, replacement...)
780 }
781 continue
782 }
783 invalid = false
784 b = append(b, s[i:i+wid]...)
785 i += wid
786 }
787 return b
788 }
789
790
791
792 func isSeparator(r rune) bool {
793
794 if r <= 0x7F {
795 switch {
796 case '0' <= r && r <= '9':
797 return false
798 case 'a' <= r && r <= 'z':
799 return false
800 case 'A' <= r && r <= 'Z':
801 return false
802 case r == '_':
803 return false
804 }
805 return true
806 }
807
808 if unicode.IsLetter(r) || unicode.IsDigit(r) {
809 return false
810 }
811
812 return unicode.IsSpace(r)
813 }
814
815
816
817
818
819
820 func Title(s []byte) []byte {
821
822
823
824 prev := ' '
825 return Map(
826 func(r rune) rune {
827 if isSeparator(prev) {
828 prev = r
829 return unicode.ToTitle(r)
830 }
831 prev = r
832 return r
833 },
834 s)
835 }
836
837
838
839 func TrimLeftFunc(s []byte, f func(r rune) bool) []byte {
840 i := indexFunc(s, f, false)
841 if i == -1 {
842 return nil
843 }
844 return s[i:]
845 }
846
847
848
849 func TrimRightFunc(s []byte, f func(r rune) bool) []byte {
850 i := lastIndexFunc(s, f, false)
851 if i >= 0 && s[i] >= utf8.RuneSelf {
852 _, wid := utf8.DecodeRune(s[i:])
853 i += wid
854 } else {
855 i++
856 }
857 return s[0:i]
858 }
859
860
861
862 func TrimFunc(s []byte, f func(r rune) bool) []byte {
863 return TrimRightFunc(TrimLeftFunc(s, f), f)
864 }
865
866
867
868 func TrimPrefix(s, prefix []byte) []byte {
869 if HasPrefix(s, prefix) {
870 return s[len(prefix):]
871 }
872 return s
873 }
874
875
876
877 func TrimSuffix(s, suffix []byte) []byte {
878 if HasSuffix(s, suffix) {
879 return s[:len(s)-len(suffix)]
880 }
881 return s
882 }
883
884
885
886
887 func IndexFunc(s []byte, f func(r rune) bool) int {
888 return indexFunc(s, f, true)
889 }
890
891
892
893
894 func LastIndexFunc(s []byte, f func(r rune) bool) int {
895 return lastIndexFunc(s, f, true)
896 }
897
898
899
900
901 func indexFunc(s []byte, f func(r rune) bool, truth bool) int {
902 start := 0
903 for start < len(s) {
904 r, wid := utf8.DecodeRune(s[start:])
905 if f(r) == truth {
906 return start
907 }
908 start += wid
909 }
910 return -1
911 }
912
913
914
915
916 func lastIndexFunc(s []byte, f func(r rune) bool, truth bool) int {
917 for i := len(s); i > 0; {
918 r, size := rune(s[i-1]), 1
919 if r >= utf8.RuneSelf {
920 r, size = utf8.DecodeLastRune(s[0:i])
921 }
922 i -= size
923 if f(r) == truth {
924 return i
925 }
926 }
927 return -1
928 }
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945 type asciiSet [256]bool
946
947
948
949 func makeASCIISet(chars string) (as asciiSet, ok bool) {
950 for i := 0; i < len(chars); i++ {
951 c := chars[i]
952 if c >= utf8.RuneSelf {
953 return as, false
954 }
955 as[c] = true
956 }
957 return as, true
958 }
959
960
961 func (as *asciiSet) contains(c byte) bool {
962 return as[c]
963 }
964
965
966
967
968
969
970
971 func shouldUseASCIISet(bufLen int) bool {
972 return bufLen > 8
973 }
974
975
976
977
978 func containsRune(s string, r rune) bool {
979 for _, c := range s {
980 if c == r {
981 return true
982 }
983 }
984 return false
985 }
986
987
988
989 func Trim(s []byte, cutset string) []byte {
990 if len(s) == 0 {
991
992 return nil
993 }
994 if cutset == "" {
995 return s
996 }
997 if len(cutset) == 1 && cutset[0] < utf8.RuneSelf {
998 return trimLeftByte(trimRightByte(s, cutset[0]), cutset[0])
999 }
1000 if as, ok := makeASCIISet(cutset); ok {
1001 return trimLeftASCII(trimRightASCII(s, &as), &as)
1002 }
1003 return trimLeftUnicode(trimRightUnicode(s, cutset), cutset)
1004 }
1005
1006
1007
1008 func TrimLeft(s []byte, cutset string) []byte {
1009 if len(s) == 0 {
1010
1011 return nil
1012 }
1013 if cutset == "" {
1014 return s
1015 }
1016 if len(cutset) == 1 && cutset[0] < utf8.RuneSelf {
1017 return trimLeftByte(s, cutset[0])
1018 }
1019 if as, ok := makeASCIISet(cutset); ok {
1020 return trimLeftASCII(s, &as)
1021 }
1022 return trimLeftUnicode(s, cutset)
1023 }
1024
1025 func trimLeftByte(s []byte, c byte) []byte {
1026 for len(s) > 0 && s[0] == c {
1027 s = s[1:]
1028 }
1029 if len(s) == 0 {
1030
1031 return nil
1032 }
1033 return s
1034 }
1035
1036 func trimLeftASCII(s []byte, as *asciiSet) []byte {
1037 for len(s) > 0 {
1038 if !as.contains(s[0]) {
1039 break
1040 }
1041 s = s[1:]
1042 }
1043 if len(s) == 0 {
1044
1045 return nil
1046 }
1047 return s
1048 }
1049
1050 func trimLeftUnicode(s []byte, cutset string) []byte {
1051 for len(s) > 0 {
1052 r, n := utf8.DecodeRune(s)
1053 if !containsRune(cutset, r) {
1054 break
1055 }
1056 s = s[n:]
1057 }
1058 if len(s) == 0 {
1059
1060 return nil
1061 }
1062 return s
1063 }
1064
1065
1066
1067 func TrimRight(s []byte, cutset string) []byte {
1068 if len(s) == 0 || cutset == "" {
1069 return s
1070 }
1071 if len(cutset) == 1 && cutset[0] < utf8.RuneSelf {
1072 return trimRightByte(s, cutset[0])
1073 }
1074 if as, ok := makeASCIISet(cutset); ok {
1075 return trimRightASCII(s, &as)
1076 }
1077 return trimRightUnicode(s, cutset)
1078 }
1079
1080 func trimRightByte(s []byte, c byte) []byte {
1081 for len(s) > 0 && s[len(s)-1] == c {
1082 s = s[:len(s)-1]
1083 }
1084 return s
1085 }
1086
1087 func trimRightASCII(s []byte, as *asciiSet) []byte {
1088 for len(s) > 0 {
1089 if !as.contains(s[len(s)-1]) {
1090 break
1091 }
1092 s = s[:len(s)-1]
1093 }
1094 return s
1095 }
1096
1097 func trimRightUnicode(s []byte, cutset string) []byte {
1098 for len(s) > 0 {
1099 r, n := rune(s[len(s)-1]), 1
1100 if r >= utf8.RuneSelf {
1101 r, n = utf8.DecodeLastRune(s)
1102 }
1103 if !containsRune(cutset, r) {
1104 break
1105 }
1106 s = s[:len(s)-n]
1107 }
1108 return s
1109 }
1110
1111
1112
1113 func TrimSpace(s []byte) []byte {
1114
1115 for lo, c := range s {
1116 if c >= utf8.RuneSelf {
1117
1118
1119 return TrimFunc(s[lo:], unicode.IsSpace)
1120 }
1121 if asciiSpace[c] != 0 {
1122 continue
1123 }
1124 s = s[lo:]
1125
1126 for hi := len(s) - 1; hi >= 0; hi-- {
1127 c := s[hi]
1128 if c >= utf8.RuneSelf {
1129 return TrimFunc(s[:hi+1], unicode.IsSpace)
1130 }
1131 if asciiSpace[c] == 0 {
1132
1133
1134
1135 return s[:hi+1]
1136 }
1137 }
1138 }
1139
1140
1141 return nil
1142 }
1143
1144
1145
1146 func Runes(s []byte) []rune {
1147 t := make([]rune, utf8.RuneCount(s))
1148 i := 0
1149 for len(s) > 0 {
1150 r, l := utf8.DecodeRune(s)
1151 t[i] = r
1152 i++
1153 s = s[l:]
1154 }
1155 return t
1156 }
1157
1158
1159
1160
1161
1162
1163
1164 func Replace(s, old, new []byte, n int) []byte {
1165 m := 0
1166 if n != 0 {
1167
1168 m = Count(s, old)
1169 }
1170 if m == 0 {
1171
1172 return append([]byte(nil), s...)
1173 }
1174 if n < 0 || m < n {
1175 n = m
1176 }
1177
1178
1179 t := make([]byte, len(s)+n*(len(new)-len(old)))
1180 w := 0
1181 start := 0
1182 if len(old) > 0 {
1183 for range n {
1184 j := start + Index(s[start:], old)
1185 w += copy(t[w:], s[start:j])
1186 w += copy(t[w:], new)
1187 start = j + len(old)
1188 }
1189 } else {
1190 w += copy(t[w:], new)
1191 for range n - 1 {
1192 _, wid := utf8.DecodeRune(s[start:])
1193 j := start + wid
1194 w += copy(t[w:], s[start:j])
1195 w += copy(t[w:], new)
1196 start = j
1197 }
1198 }
1199 w += copy(t[w:], s[start:])
1200 return t[0:w]
1201 }
1202
1203
1204
1205
1206
1207
1208 func ReplaceAll(s, old, new []byte) []byte {
1209 return Replace(s, old, new, -1)
1210 }
1211
1212
1213
1214
1215 func EqualFold(s, t []byte) bool {
1216
1217 i := 0
1218 for n := min(len(s), len(t)); i < n; i++ {
1219 sr := s[i]
1220 tr := t[i]
1221 if sr|tr >= utf8.RuneSelf {
1222 goto hasUnicode
1223 }
1224
1225
1226 if tr == sr {
1227 continue
1228 }
1229
1230
1231 if tr < sr {
1232 tr, sr = sr, tr
1233 }
1234
1235 if 'A' <= sr && sr <= 'Z' && tr == sr+'a'-'A' {
1236 continue
1237 }
1238 return false
1239 }
1240
1241 return len(s) == len(t)
1242
1243 hasUnicode:
1244 s = s[i:]
1245 t = t[i:]
1246 for len(s) != 0 && len(t) != 0 {
1247
1248 sr, size := utf8.DecodeRune(s)
1249 s = s[size:]
1250 tr, size := utf8.DecodeRune(t)
1251 t = t[size:]
1252
1253
1254
1255
1256 if tr == sr {
1257 continue
1258 }
1259
1260
1261 if tr < sr {
1262 tr, sr = sr, tr
1263 }
1264
1265 if tr < utf8.RuneSelf {
1266
1267 if 'A' <= sr && sr <= 'Z' && tr == sr+'a'-'A' {
1268 continue
1269 }
1270 return false
1271 }
1272
1273
1274
1275 r := unicode.SimpleFold(sr)
1276 for r != sr && r < tr {
1277 r = unicode.SimpleFold(r)
1278 }
1279 if r == tr {
1280 continue
1281 }
1282 return false
1283 }
1284
1285
1286 return len(s) == len(t)
1287 }
1288
1289
1290 func Index(s, sep []byte) int {
1291 n := len(sep)
1292 switch {
1293 case n == 0:
1294 return 0
1295 case n == 1:
1296 return IndexByte(s, sep[0])
1297 case n == len(s):
1298 if Equal(sep, s) {
1299 return 0
1300 }
1301 return -1
1302 case n > len(s):
1303 return -1
1304 case n <= bytealg.MaxLen:
1305
1306 if len(s) <= bytealg.MaxBruteForce {
1307 return bytealg.Index(s, sep)
1308 }
1309 c0 := sep[0]
1310 c1 := sep[1]
1311 i := 0
1312 t := len(s) - n + 1
1313 fails := 0
1314 for i < t {
1315 if s[i] != c0 {
1316
1317
1318 o := IndexByte(s[i+1:t], c0)
1319 if o < 0 {
1320 return -1
1321 }
1322 i += o + 1
1323 }
1324 if s[i+1] == c1 && Equal(s[i:i+n], sep) {
1325 return i
1326 }
1327 fails++
1328 i++
1329
1330 if fails > bytealg.Cutover(i) {
1331 r := bytealg.Index(s[i:], sep)
1332 if r >= 0 {
1333 return r + i
1334 }
1335 return -1
1336 }
1337 }
1338 return -1
1339 }
1340 c0 := sep[0]
1341 c1 := sep[1]
1342 i := 0
1343 fails := 0
1344 t := len(s) - n + 1
1345 for i < t {
1346 if s[i] != c0 {
1347 o := IndexByte(s[i+1:t], c0)
1348 if o < 0 {
1349 break
1350 }
1351 i += o + 1
1352 }
1353 if s[i+1] == c1 && Equal(s[i:i+n], sep) {
1354 return i
1355 }
1356 i++
1357 fails++
1358 if fails >= 4+i>>4 && i < t {
1359
1360
1361
1362
1363
1364
1365
1366
1367 j := bytealg.IndexRabinKarp(s[i:], sep)
1368 if j < 0 {
1369 return -1
1370 }
1371 return i + j
1372 }
1373 }
1374 return -1
1375 }
1376
1377
1378
1379
1380
1381
1382
1383 func Cut(s, sep []byte) (before, after []byte, found bool) {
1384 if i := Index(s, sep); i >= 0 {
1385 return s[:i], s[i+len(sep):], true
1386 }
1387 return s, nil, false
1388 }
1389
1390
1391
1392
1393 func Clone(b []byte) []byte {
1394 if b == nil {
1395 return nil
1396 }
1397 return append([]byte{}, b...)
1398 }
1399
1400
1401
1402
1403
1404
1405
1406 func CutPrefix(s, prefix []byte) (after []byte, found bool) {
1407 if !HasPrefix(s, prefix) {
1408 return s, false
1409 }
1410 return s[len(prefix):], true
1411 }
1412
1413
1414
1415
1416
1417
1418
1419 func CutSuffix(s, suffix []byte) (before []byte, found bool) {
1420 if !HasSuffix(s, suffix) {
1421 return s, false
1422 }
1423 return s[:len(s)-len(suffix)], true
1424 }
1425
View as plain text