github.com/benhoyt/goawk@v1.8.1/internal/strutil/strutil.go (about)

     1  // Package strutil provides some miscellaneous string functions.
     2  //
     3  package strutil
     4  
     5  import (
     6  	"strings"
     7  	"unicode"
     8  	"unicode/utf8"
     9  )
    10  
    11  var asciiSpace = [256]uint8{'\t': 1, '\n': 1, '\v': 1, '\f': 1, '\r': 1, ' ': 1}
    12  
    13  // TrimSpace returns a slice of the string s, with all leading and
    14  // trailing white space removed, as defined by Unicode. (It behaves
    15  // the same as Go's strings.TrimSpace, but has a fast path for ASCII
    16  // strings so is much faster for common cases.)
    17  func TrimSpace(s string) string {
    18  	// Fast path for ASCII: look for the first ASCII non-space byte
    19  	start := 0
    20  	for ; start < len(s); start++ {
    21  		c := s[start]
    22  		if c >= utf8.RuneSelf {
    23  			// If we run into a non-ASCII byte, fall back to the
    24  			// slower unicode-aware method on the remaining bytes
    25  			return strings.TrimFunc(s[start:], unicode.IsSpace)
    26  		}
    27  		if asciiSpace[c] == 0 {
    28  			break
    29  		}
    30  	}
    31  
    32  	// Now look for the first ASCII non-space byte from the end
    33  	stop := len(s)
    34  	for ; stop > start; stop-- {
    35  		c := s[stop-1]
    36  		if c >= utf8.RuneSelf {
    37  			return strings.TrimFunc(s[start:stop], unicode.IsSpace)
    38  		}
    39  		if asciiSpace[c] == 0 {
    40  			break
    41  		}
    42  	}
    43  
    44  	// At this point s[start:stop] starts and ends with an ASCII
    45  	// non-space bytes, so we're done. Non-ASCII cases have already
    46  	// been handled above.
    47  	return s[start:stop]
    48  }
    49  
    50  // IsASCIISpace returns true if c represents an ASCII whitespace byte.
    51  func IsASCIISpace(c byte) bool {
    52  	return asciiSpace[c] != 0
    53  }