123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263 |
- package misspell
- // ByteToUpper converts an ascii byte to upper cases
- // Uses a branchless algorithm
- func ByteToUpper(x byte) byte {
- b := byte(0x80) | x
- c := b - byte(0x61)
- d := ^(b - byte(0x7b))
- e := (c & d) & (^x & 0x7f)
- return x - (e >> 2)
- }
- // ByteToLower converts an ascii byte to lower case
- // uses a branchless algorithm
- func ByteToLower(eax byte) byte {
- ebx := eax&byte(0x7f) + byte(0x25)
- ebx = ebx&byte(0x7f) + byte(0x1a)
- ebx = ((ebx & ^eax) >> 2) & byte(0x20)
- return eax + ebx
- }
- // ByteEqualFold does ascii compare, case insensitive
- func ByteEqualFold(a, b byte) bool {
- return a == b || ByteToLower(a) == ByteToLower(b)
- }
- // StringEqualFold ASCII case-insensitive comparison
- // golang toUpper/toLower for both bytes and strings
- // appears to be Unicode based which is super slow
- // based from https://codereview.appspot.com/5180044/patch/14007/21002
- func StringEqualFold(s1, s2 string) bool {
- if len(s1) != len(s2) {
- return false
- }
- for i := 0; i < len(s1); i++ {
- c1 := s1[i]
- c2 := s2[i]
- // c1 & c2
- if c1 != c2 {
- c1 |= 'a' - 'A'
- c2 |= 'a' - 'A'
- if c1 != c2 || c1 < 'a' || c1 > 'z' {
- return false
- }
- }
- }
- return true
- }
- // StringHasPrefixFold is similar to strings.HasPrefix but comparison
- // is done ignoring ASCII case.
- // /
- func StringHasPrefixFold(s1, s2 string) bool {
- // prefix is bigger than input --> false
- if len(s1) < len(s2) {
- return false
- }
- if len(s1) == len(s2) {
- return StringEqualFold(s1, s2)
- }
- return StringEqualFold(s1[:len(s2)], s2)
- }
|