1 package bytes
2 3 import (
4 "internal/bytealg"
5 "unicode"
6 "unicode/utf8"
7 )
8 9 // It splits the slice s around each instance of one or more consecutive white space
10 // characters, as defined by [unicode.IsSpace], returning a slice of subslices of s or an
11 // empty slice if s contains only white space. Every element of the returned slice is
12 // non-empty. Unlike [Split], leading and trailing runs of white space characters
13 // are discarded.
14 func Fields(s []byte) [][]byte {
15 asciiSpace := _asciiSpace()
16 n := 0
17 wasSpace := 1
18 setBits := uint8(0)
19 for i := 0; i < len(s); i++ {
20 r := s[i]
21 setBits |= r
22 isSpace := int32(asciiSpace[r])
23 n += wasSpace & ^isSpace
24 wasSpace = isSpace
25 }
26 27 if setBits >= utf8.RuneSelf {
28 t := unicode.NewTables()
29 return FieldsFunc(s, t.IsSpace)
30 }
31 32 a := [][]byte{:n}
33 na := 0
34 fieldStart := 0
35 i := 0
36 for i < len(s) && asciiSpace[s[i]] != 0 {
37 i++
38 }
39 fieldStart = i
40 for i < len(s) {
41 if asciiSpace[s[i]] == 0 {
42 i++
43 continue
44 }
45 a[na] = s[fieldStart:i:i]
46 na++
47 i++
48 for i < len(s) && asciiSpace[s[i]] != 0 {
49 i++
50 }
51 fieldStart = i
52 }
53 if fieldStart < len(s) { // Last field might end at EOF.
54 a[na] = s[fieldStart:len(s):len(s)]
55 }
56 return a
57 }
58 59 // FieldsFunc interprets s as a sequence of UTF-8-encoded code points.
60 // It splits the slice s at each run of code points c satisfying f(c) and
61 // returns a slice of subslices of s. If all code points in s satisfy f(c), or
62 // len(s) == 0, an empty slice is returned. Every element of the returned slice is
63 // non-empty. Unlike [SplitFunc], leading and trailing runs of code points
64 // satisfying f(c) are discarded.
65 //
66 // FieldsFunc makes no guarantees about the order in which it calls f(c)
67 // and assumes that f always returns the same value for a given c.
68 func FieldsFunc(s []byte, f func(rune) bool) [][]byte {
69 // A span is used to record a slice of s of the form s[start:end].
70 // The start index is inclusive and the end index is exclusive.
71 type span struct {
72 start int32
73 end int32
74 }
75 spans := []span{:0:32}
76 77 // Find the field start and end indices.
78 // Doing this in a separate pass (rather than slicing the string s
79 // and collecting the result substrings right away) is significantly
80 // more efficient, possibly due to cache effects.
81 start := -1 // valid span start if >= 0
82 for i := 0; i < len(s); {
83 size := 1
84 r := rune(s[i])
85 if r >= utf8.RuneSelf {
86 r, size = utf8.DecodeRune(s[i:])
87 }
88 if f(r) {
89 if start >= 0 {
90 spans = append(spans, span{start, i})
91 start = -1
92 }
93 } else {
94 if start < 0 {
95 start = i
96 }
97 }
98 i += size
99 }
100 101 // Last field might end at EOF.
102 if start >= 0 {
103 spans = append(spans, span{start, len(s)})
104 }
105 106 // Create subslices from recorded field indices.
107 a := [][]byte{:len(spans)}
108 for i, span := range spans {
109 a[i] = s[span.start:span.end:span.end]
110 }
111 112 return a
113 }
114 115 // Join concatenates the elements of s to create a new byte slice. The separator
116 // sep is placed between elements in the resulting slice.
117 func Join(s [][]byte, sep []byte) []byte {
118 if len(s) == 0 {
119 return []byte{}
120 }
121 if len(s) == 1 {
122 // Just return a copy.
123 return append([]byte(nil), s[0]...)
124 }
125 126 var n int32
127 if len(sep) > 0 {
128 if len(sep) >= maxInt/(len(s)-1) {
129 panic("bytes: Join output length overflow")
130 }
131 n += len(sep) * (len(s) - 1)
132 }
133 for _, v := range s {
134 if len(v) > maxInt-n {
135 panic("bytes: Join output length overflow")
136 }
137 n += len(v)
138 }
139 140 b := bytealg.MakeNoZero(n)[:n:n]
141 bp := copy(b, s[0])
142 for _, v := range s[1:] {
143 bp += copy(b[bp:], sep)
144 bp += copy(b[bp:], v)
145 }
146 return b
147 }
148 149 // HasPrefix reports whether the byte slice s begins with prefix.
150 func HasPrefix(s, prefix []byte) bool {
151 return len(s) >= len(prefix) && Equal(s[:len(prefix)], prefix)
152 }
153 154 // HasSuffix reports whether the byte slice s ends with suffix.
155 func HasSuffix(s, suffix []byte) bool {
156 return len(s) >= len(suffix) && Equal(s[len(s)-len(suffix):], suffix)
157 }
158 159 // Map returns a copy of the byte slice s with all its characters modified
160 // according to the mapping function. If mapping returns a negative value, the character is
161 // dropped from the byte slice with no replacement. The characters in s and the
162 // output are interpreted as UTF-8-encoded code points.
163 func Map(mapping func(r rune) rune, s []byte) []byte {
164 // In the worst case, the slice can grow when mapped, making
165 // things unpleasant. But it's so rare we barge in assuming it's
166 // fine. It could also shrink but that falls out naturally.
167 b := []byte{:0:len(s)}
168 for i := 0; i < len(s); {
169 wid := 1
170 r := rune(s[i])
171 if r >= utf8.RuneSelf {
172 r, wid = utf8.DecodeRune(s[i:])
173 }
174 r = mapping(r)
175 if r >= 0 {
176 b = utf8.AppendRune(b, r)
177 }
178 i += wid
179 }
180 return b
181 }
182 183 // Despite being an exported symbol,
184 // Repeat is linknamed by widely used packages.
185 // Notable members of the hall of shame include:
186 // - gitee.com/quant1x/num
187 //
188 // Do not remove or change the type signature.
189 // See go.dev/issue/67401.
190 //
191 // Note that this comment is not part of the doc comment.
192 //
193 // linkname Repeat (stripped for moxie)
194 195 // ToUpper returns a copy of the byte slice s with all Unicode letters mapped to
196 // their upper case.
197 func ToUpper(s []byte) []byte {
198 isASCII, hasLower := true, false
199 for i := 0; i < len(s); i++ {
200 c := s[i]
201 if c >= utf8.RuneSelf {
202 isASCII = false
203 break
204 }
205 hasLower = hasLower || ('a' <= c && c <= 'z')
206 }
207 208 if isASCII { // optimize for ASCII-only byte slices.
209 if !hasLower {
210 // Just return a copy.
211 return append([]byte(""), s...)
212 }
213 b := bytealg.MakeNoZero(len(s))[:len(s):len(s)]
214 for i := 0; i < len(s); i++ {
215 c := s[i]
216 if 'a' <= c && c <= 'z' {
217 c -= 'a' - 'A'
218 }
219 b[i] = c
220 }
221 return b
222 }
223 t := unicode.NewTables()
224 return Map(t.ToUpper, s)
225 }
226 227 // ToLower returns a copy of the byte slice s with all Unicode letters mapped to
228 // their lower case.
229 func ToLower(s []byte) []byte {
230 isASCII, hasUpper := true, false
231 for i := 0; i < len(s); i++ {
232 c := s[i]
233 if c >= utf8.RuneSelf {
234 isASCII = false
235 break
236 }
237 hasUpper = hasUpper || ('A' <= c && c <= 'Z')
238 }
239 240 if isASCII { // optimize for ASCII-only byte slices.
241 if !hasUpper {
242 return append([]byte(""), s...)
243 }
244 b := bytealg.MakeNoZero(len(s))[:len(s):len(s)]
245 for i := 0; i < len(s); i++ {
246 c := s[i]
247 if 'A' <= c && c <= 'Z' {
248 c += 'a' - 'A'
249 }
250 b[i] = c
251 }
252 return b
253 }
254 t := unicode.NewTables()
255 return Map(t.ToLower, s)
256 }
257 258 // ToTitle treats s as UTF-8-encoded bytes and returns a copy with all the Unicode letters mapped to their title case.
259 func ToTitle(s []byte) []byte {
260 t := unicode.NewTables()
261 return Map(t.ToTitle, s)
262 }
263 264 // ToUpperSpecial treats s as UTF-8-encoded bytes and returns a copy with all the Unicode letters mapped to their
265 // upper case, giving priority to the special casing rules.
266 func ToUpperSpecial(c unicode.SpecialCase, s []byte) []byte {
267 return Map(c.ToUpper, s)
268 }
269 270 // ToLowerSpecial treats s as UTF-8-encoded bytes and returns a copy with all the Unicode letters mapped to their
271 // lower case, giving priority to the special casing rules.
272 func ToLowerSpecial(c unicode.SpecialCase, s []byte) []byte {
273 return Map(c.ToLower, s)
274 }
275 276 // ToTitleSpecial treats s as UTF-8-encoded bytes and returns a copy with all the Unicode letters mapped to their
277 // title case, giving priority to the special casing rules.
278 func ToTitleSpecial(c unicode.SpecialCase, s []byte) []byte {
279 return Map(c.ToTitle, s)
280 }
281 282 // ToValidUTF8 treats s as UTF-8-encoded bytes and returns a copy with each run of bytes
283 // representing invalid UTF-8 replaced with the bytes in replacement, which may be empty.
284 func ToValidUTF8(s, replacement []byte) []byte {
285 b := []byte{:0:len(s)+len(replacement)}
286 invalid := false // previous byte was from an invalid UTF-8 sequence
287 for i := 0; i < len(s); {
288 c := s[i]
289 if c < utf8.RuneSelf {
290 i++
291 invalid = false
292 b = append(b, c)
293 continue
294 }
295 _, wid := utf8.DecodeRune(s[i:])
296 if wid == 1 {
297 i++
298 if !invalid {
299 invalid = true
300 b = append(b, replacement...)
301 }
302 continue
303 }
304 invalid = false
305 b = append(b, s[i:i+wid]...)
306 i += wid
307 }
308 return b
309 }
310 311 // isSeparator reports whether the rune could mark a word boundary.
312 // TODO: update when package unicode captures more of the properties.
313 func isSeparator(r rune) bool {
314 // ASCII alphanumerics and underscore are not separators
315 if r <= 0x7F {
316 switch {
317 case '0' <= r && r <= '9':
318 return false
319 case 'a' <= r && r <= 'z':
320 return false
321 case 'A' <= r && r <= 'Z':
322 return false
323 case r == '_':
324 return false
325 }
326 return true
327 }
328 // Letters and digits are not separators
329 t := unicode.NewTables()
330 if t.IsLetter(r) || t.IsDigit(r) {
331 return false
332 }
333 // Otherwise, all we can do for now is treat spaces as separators.
334 return t.IsSpace(r)
335 }
336 337 // Title treats s as UTF-8-encoded bytes and returns a copy with all Unicode letters that begin
338 // words mapped to their title case.
339 //
340 // Deprecated: The rule Title uses for word boundaries does not handle Unicode
341 // punctuation properly. Use golang.org/x/text/cases instead.
342 func Title(s []byte) []byte {
343 // Use a closure here to remember state.
344 // Hackish but effective. Depends on Map scanning in order and calling
345 // the closure once per rune.
346 t := unicode.NewTables()
347 prev := ' '
348 return Map(
349 func(r rune) rune {
350 if isSeparator(prev) {
351 prev = r
352 return t.ToTitle(r)
353 }
354 prev = r
355 return r
356 },
357 s)
358 }
359 360 // TrimLeftFunc treats s as UTF-8-encoded bytes and returns a subslice of s by slicing off
361 // all leading UTF-8-encoded code points c that satisfy f(c).
362 func TrimLeftFunc(s []byte, f func(r rune) bool) []byte {
363 i := indexFunc(s, f, false)
364 if i == -1 {
365 return nil
366 }
367 return s[i:]
368 }
369 370 // TrimRightFunc returns a subslice of s by slicing off all trailing
371 // UTF-8-encoded code points c that satisfy f(c).
372 func TrimRightFunc(s []byte, f func(r rune) bool) []byte {
373 i := lastIndexFunc(s, f, false)
374 if i >= 0 && s[i] >= utf8.RuneSelf {
375 _, wid := utf8.DecodeRune(s[i:])
376 i += wid
377 } else {
378 i++
379 }
380 return s[0:i]
381 }
382 383 // TrimFunc returns a subslice of s by slicing off all leading and trailing
384 // UTF-8-encoded code points c that satisfy f(c).
385 func TrimFunc(s []byte, f func(r rune) bool) []byte {
386 return TrimRightFunc(TrimLeftFunc(s, f), f)
387 }
388 389 // TrimPrefix returns s without the provided leading prefix string.
390 // If s doesn't start with prefix, s is returned unchanged.
391 func TrimPrefix(s, prefix []byte) []byte {
392 if HasPrefix(s, prefix) {
393 return s[len(prefix):]
394 }
395 return s
396 }
397 398 // TrimSuffix returns s without the provided trailing suffix string.
399 // If s doesn't end with suffix, s is returned unchanged.
400 func TrimSuffix(s, suffix []byte) []byte {
401 if HasSuffix(s, suffix) {
402 return s[:len(s)-len(suffix)]
403 }
404 return s
405 }
406 407 // IndexFunc interprets s as a sequence of UTF-8-encoded code points.
408 // It returns the byte index in s of the first Unicode
409 // code point satisfying f(c), or -1 if none do.
410 func IndexFunc(s []byte, f func(r rune) bool) int32 {
411 return indexFunc(s, f, true)
412 }
413 414 // LastIndexFunc interprets s as a sequence of UTF-8-encoded code points.
415 // It returns the byte index in s of the last Unicode
416 // code point satisfying f(c), or -1 if none do.
417 func LastIndexFunc(s []byte, f func(r rune) bool) int32 {
418 return lastIndexFunc(s, f, true)
419 }
420 421 // indexFunc is the same as IndexFunc except that if
422 // truth==false, the sense of the predicate function is
423 // inverted.
424 func indexFunc(s []byte, f func(r rune) bool, truth bool) int32 {
425 start := 0
426 for start < len(s) {
427 wid := 1
428 r := rune(s[start])
429 if r >= utf8.RuneSelf {
430 r, wid = utf8.DecodeRune(s[start:])
431 }
432 if f(r) == truth {
433 return start
434 }
435 start += wid
436 }
437 return -1
438 }
439 440 // lastIndexFunc is the same as LastIndexFunc except that if
441 // truth==false, the sense of the predicate function is
442 // inverted.
443 func lastIndexFunc(s []byte, f func(r rune) bool, truth bool) int32 {
444 for i := len(s); i > 0; {
445 r, size := rune(s[i-1]), 1
446 if r >= utf8.RuneSelf {
447 r, size = utf8.DecodeLastRune(s[0:i])
448 }
449 i -= size
450 if f(r) == truth {
451 return i
452 }
453 }
454 return -1
455 }
456 457 // asciiSet is a 32-byte value, where each bit represents the presence of a
458 // given ASCII character in the set. The 128-bits of the lower 16 bytes,
459 // starting with the least-significant bit of the lowest word to the
460 // most-significant bit of the highest word, map to the full range of all
461 // 128 ASCII characters. The 128-bits of the upper 16 bytes will be zeroed,
462 // ensuring that any non-ASCII character will be reported as not in the set.
463 // This allocates a total of 32 bytes even though the upper half
464 // is unused to avoid bounds checks in asciiSet.contains.
465 type asciiSet [8]uint32
466 467 // makeASCIISet creates a set of ASCII characters and reports whether all
468 // characters in chars are ASCII.
469 func makeASCIISet(chars []byte) (as asciiSet, ok bool) {
470 for i := 0; i < len(chars); i++ {
471 c := chars[i]
472 if c >= utf8.RuneSelf {
473 return as, false
474 }
475 as[c/32] |= 1 << (c % 32)
476 }
477 return as, true
478 }
479 480 // contains reports whether c is inside the set.
481 func (as *asciiSet) contains(c byte) bool {
482 return (as[c/32] & (1 << (c % 32))) != 0
483 }
484 485 // containsRune is a simplified version of strings.ContainsRune
486 // to avoid importing the strings package.
487 // We avoid bytes.ContainsRune to avoid allocating a temporary copy of s.
488 func containsRune(s []byte, r rune) bool {
489 for i := 0; i < len(s); {
490 c, w := utf8.DecodeRune(s[i:])
491 if c == r {
492 return true
493 }
494 i += w
495 }
496 return false
497 }
498 499 // Trim returns a subslice of s by slicing off all leading and
500 // trailing UTF-8-encoded code points contained in cutset.
501 func Trim(s []byte, cutset []byte) []byte {
502 if len(s) == 0 {
503 // This is what we've historically done.
504 return nil
505 }
506 if cutset == "" {
507 return s
508 }
509 if len(cutset) == 1 && cutset[0] < utf8.RuneSelf {
510 return trimLeftByte(trimRightByte(s, cutset[0]), cutset[0])
511 }
512 if as, ok := makeASCIISet(cutset); ok {
513 return trimLeftASCII(trimRightASCII(s, &as), &as)
514 }
515 return trimLeftUnicode(trimRightUnicode(s, cutset), cutset)
516 }
517 518 // TrimLeft returns a subslice of s by slicing off all leading
519 // UTF-8-encoded code points contained in cutset.
520 func TrimLeft(s []byte, cutset []byte) []byte {
521 if len(s) == 0 {
522 // This is what we've historically done.
523 return nil
524 }
525 if cutset == "" {
526 return s
527 }
528 if len(cutset) == 1 && cutset[0] < utf8.RuneSelf {
529 return trimLeftByte(s, cutset[0])
530 }
531 if as, ok := makeASCIISet(cutset); ok {
532 return trimLeftASCII(s, &as)
533 }
534 return trimLeftUnicode(s, cutset)
535 }
536 537 func trimLeftByte(s []byte, c byte) []byte {
538 for len(s) > 0 && s[0] == c {
539 s = s[1:]
540 }
541 if len(s) == 0 {
542 // This is what we've historically done.
543 return nil
544 }
545 return s
546 }
547 548 func trimLeftASCII(s []byte, as *asciiSet) []byte {
549 for len(s) > 0 {
550 if !as.contains(s[0]) {
551 break
552 }
553 s = s[1:]
554 }
555 if len(s) == 0 {
556 // This is what we've historically done.
557 return nil
558 }
559 return s
560 }
561 562 func trimLeftUnicode(s []byte, cutset []byte) []byte {
563 for len(s) > 0 {
564 r, n := rune(s[0]), 1
565 if r >= utf8.RuneSelf {
566 r, n = utf8.DecodeRune(s)
567 }
568 if !containsRune(cutset, r) {
569 break
570 }
571 s = s[n:]
572 }
573 if len(s) == 0 {
574 // This is what we've historically done.
575 return nil
576 }
577 return s
578 }
579 580 // TrimRight returns a subslice of s by slicing off all trailing
581 // UTF-8-encoded code points that are contained in cutset.
582 func TrimRight(s []byte, cutset []byte) []byte {
583 if len(s) == 0 || cutset == "" {
584 return s
585 }
586 if len(cutset) == 1 && cutset[0] < utf8.RuneSelf {
587 return trimRightByte(s, cutset[0])
588 }
589 if as, ok := makeASCIISet(cutset); ok {
590 return trimRightASCII(s, &as)
591 }
592 return trimRightUnicode(s, cutset)
593 }
594 595 func trimRightByte(s []byte, c byte) []byte {
596 for len(s) > 0 && s[len(s)-1] == c {
597 s = s[:len(s)-1]
598 }
599 return s
600 }
601 602 func trimRightASCII(s []byte, as *asciiSet) []byte {
603 for len(s) > 0 {
604 if !as.contains(s[len(s)-1]) {
605 break
606 }
607 s = s[:len(s)-1]
608 }
609 return s
610 }
611 612 func trimRightUnicode(s []byte, cutset []byte) []byte {
613 for len(s) > 0 {
614 r, n := rune(s[len(s)-1]), 1
615 if r >= utf8.RuneSelf {
616 r, n = utf8.DecodeLastRune(s)
617 }
618 if !containsRune(cutset, r) {
619 break
620 }
621 s = s[:len(s)-n]
622 }
623 return s
624 }
625 626 // TrimSpace returns a subslice of s by slicing off all leading and
627 // trailing white space, as defined by Unicode.
628 func TrimSpace(s []byte) []byte {
629 t := unicode.NewTables()
630 asciiSpace := _asciiSpace()
631 start := 0
632 for ; start < len(s); start++ {
633 c := s[start]
634 if c >= utf8.RuneSelf {
635 return TrimFunc(s[start:], t.IsSpace)
636 }
637 if asciiSpace[c] == 0 {
638 break
639 }
640 }
641 642 stop := len(s)
643 for ; stop > start; stop-- {
644 c := s[stop-1]
645 if c >= utf8.RuneSelf {
646 return TrimFunc(s[start:stop], t.IsSpace)
647 }
648 if asciiSpace[c] == 0 {
649 break
650 }
651 }
652 653 // At this point s[start:stop] starts and ends with an ASCII
654 // non-space bytes, so we're done. Non-ASCII cases have already
655 // been handled above.
656 if start == stop {
657 // Special case to preserve previous TrimLeftFunc behavior,
658 // returning nil instead of empty slice if all spaces.
659 return nil
660 }
661 return s[start:stop]
662 }
663 664 // Runes interprets s as a sequence of UTF-8-encoded code points.
665 // It returns a slice of runes (Unicode code points) equivalent to s.
666 func Runes(s []byte) []rune {
667 t := []rune{:utf8.RuneCount(s)}
668 i := 0
669 for len(s) > 0 {
670 r, l := utf8.DecodeRune(s)
671 t[i] = r
672 i++
673 s = s[l:]
674 }
675 return t
676 }
677 678 // Replace returns a copy of the slice s with the first n
679 // non-overlapping instances of old replaced by new.
680 // If old is empty, it matches at the beginning of the slice
681 // and after each UTF-8 sequence, yielding up to k+1 replacements
682 // for a k-rune slice.
683 // If n < 0, there is no limit on the number of replacements.
684 func Replace(s, old, new []byte, n int32) []byte {
685 m := 0
686 if n != 0 {
687 // Compute number of replacements.
688 m = Count(s, old)
689 }
690 if m == 0 {
691 // Just return a copy.
692 return append([]byte(nil), s...)
693 }
694 if n < 0 || m < n {
695 n = m
696 }
697 698 // Apply replacements to buffer.
699 t := []byte{:len(s)+n*(len(new)-len(old))}
700 w := 0
701 start := 0
702 if len(old) > 0 {
703 for range n {
704 j := start + Index(s[start:], old)
705 w += copy(t[w:], s[start:j])
706 w += copy(t[w:], new)
707 start = j + len(old)
708 }
709 } else { // len(old) == 0
710 w += copy(t[w:], new)
711 for range n - 1 {
712 _, wid := utf8.DecodeRune(s[start:])
713 j := start + wid
714 w += copy(t[w:], s[start:j])
715 w += copy(t[w:], new)
716 start = j
717 }
718 }
719 w += copy(t[w:], s[start:])
720 return t[0:w]
721 }
722 723 // ReplaceAll returns a copy of the slice s with all
724 // non-overlapping instances of old replaced by new.
725 // If old is empty, it matches at the beginning of the slice
726 // and after each UTF-8 sequence, yielding up to k+1 replacements
727 // for a k-rune slice.
728 func ReplaceAll(s, old, new []byte) []byte {
729 return Replace(s, old, new, -1)
730 }
731 732 // EqualFold reports whether s and t, interpreted as UTF-8 strings,
733 // are equal under simple Unicode case-folding, which is a more general
734 // form of case-insensitivity.
735 func EqualFold(s, t []byte) bool {
736 // ASCII fast path
737 i := 0
738 for n := min(len(s), len(t)); i < n; i++ {
739 sr := s[i]
740 tr := t[i]
741 if sr|tr >= utf8.RuneSelf {
742 goto hasUnicode
743 }
744 745 // Easy case.
746 if tr == sr {
747 continue
748 }
749 750 // Make sr < tr to simplify what follows.
751 if tr < sr {
752 tr, sr = sr, tr
753 }
754 // ASCII only, sr/tr must be upper/lower case
755 if 'A' <= sr && sr <= 'Z' && tr == sr+'a'-'A' {
756 continue
757 }
758 return false
759 }
760 // Check if we've exhausted both strings.
761 return len(s) == len(t)
762 763 hasUnicode:
764 s = s[i:]
765 t = t[i:]
766 for len(s) != 0 && len(t) != 0 {
767 // Extract first rune from each.
768 var sr, tr rune
769 if s[0] < utf8.RuneSelf {
770 sr, s = rune(s[0]), s[1:]
771 } else {
772 r, size := utf8.DecodeRune(s)
773 sr, s = r, s[size:]
774 }
775 if t[0] < utf8.RuneSelf {
776 tr, t = rune(t[0]), t[1:]
777 } else {
778 r, size := utf8.DecodeRune(t)
779 tr, t = r, t[size:]
780 }
781 782 // If they match, keep going; if not, return false.
783 784 // Easy case.
785 if tr == sr {
786 continue
787 }
788 789 // Make sr < tr to simplify what follows.
790 if tr < sr {
791 tr, sr = sr, tr
792 }
793 // Fast check for ASCII.
794 if tr < utf8.RuneSelf {
795 // ASCII only, sr/tr must be upper/lower case
796 if 'A' <= sr && sr <= 'Z' && tr == sr+'a'-'A' {
797 continue
798 }
799 return false
800 }
801 802 // General case. SimpleFold(x) returns the next equivalent rune > x
803 // or wraps around to smaller values.
804 tb := unicode.NewTables()
805 r := tb.SimpleFold(sr)
806 for r != sr && r < tr {
807 r = tb.SimpleFold(r)
808 }
809 if r == tr {
810 continue
811 }
812 return false
813 }
814 815 // One string is empty. Are both?
816 return len(s) == len(t)
817 }
818 819 // Index returns the index of the first instance of sep in s, or -1 if sep is not present in s.
820 func Index(s, sep []byte) int32 {
821 n := len(sep)
822 if n == 0 {
823 return 0
824 }
825 if n == 1 {
826 return IndexByte(s, sep[0])
827 }
828 if n == len(s) {
829 if Equal(sep, s) {
830 return 0
831 }
832 return -1
833 }
834 if n > len(s) {
835 return -1
836 }
837 return indexBrute(s, sep, n)
838 }
839 840 func indexBrute(s, sep []byte, n int32) int32 {
841 c0 := sep[0]
842 c1 := sep[1]
843 i := int32(0)
844 fails := int32(0)
845 t := len(s) - n + 1
846 for i < t {
847 if s[i] != c0 {
848 o := IndexByte(s[i+1:t], c0)
849 if o < 0 {
850 break
851 }
852 i += o + 1
853 }
854 if s[i+1] == c1 && Equal(s[i:i+n], sep) {
855 return i
856 }
857 i++
858 fails++
859 if fails >= 4+i>>4 && i < t {
860 j := bytealg.IndexRabinKarp(s[i:], sep)
861 if j < 0 {
862 return -1
863 }
864 return i + j
865 }
866 }
867 return -1
868 }
869 870 // Cut slices s around the first instance of sep,
871 // returning the text before and after sep.
872 // The found result reports whether sep appears in s.
873 // If sep does not appear in s, cut returns s, nil, false.
874 //
875 // Cut returns slices of the original slice s, not copies.
876 func Cut(s, sep []byte) (before, after []byte, found bool) {
877 if i := Index(s, sep); i >= 0 {
878 return s[:i], s[i+len(sep):], true
879 }
880 return s, nil, false
881 }
882 883 // Clone returns a copy of b[:len(b)].
884 // The result may have additional unused capacity.
885 // Clone(nil) returns nil.
886 func Clone(b []byte) []byte {
887 if b == nil {
888 return nil
889 }
890 return append([]byte{}, b...)
891 }
892 893 // CutPrefix returns s without the provided leading prefix byte slice
894 // and reports whether it found the prefix.
895 // If s doesn't start with prefix, CutPrefix returns s, false.
896 // If prefix is the empty byte slice, CutPrefix returns s, true.
897 //
898 // CutPrefix returns slices of the original slice s, not copies.
899 func CutPrefix(s, prefix []byte) (after []byte, found bool) {
900 if !HasPrefix(s, prefix) {
901 return s, false
902 }
903 return s[len(prefix):], true
904 }
905 906 // CutSuffix returns s without the provided ending suffix byte slice
907 // and reports whether it found the suffix.
908 // If s doesn't end with suffix, CutSuffix returns s, false.
909 // If suffix is the empty byte slice, CutSuffix returns s, true.
910 //
911 // CutSuffix returns slices of the original slice s, not copies.
912 func CutSuffix(s, suffix []byte) (before []byte, found bool) {
913 if !HasSuffix(s, suffix) {
914 return s, false
915 }
916 return s[:len(s)-len(suffix)], true
917 }
918