gopkg.in/alecthomas/gometalinter.v3@v3.0.0/_linters/src/github.com/client9/misspell/ascii.go (about) 1 package misspell 2 3 // ByteToUpper converts an ascii byte to upper cases 4 // Uses a branchless algorithm 5 func ByteToUpper(x byte) byte { 6 b := byte(0x80) | x 7 c := b - byte(0x61) 8 d := ^(b - byte(0x7b)) 9 e := (c & d) & (^x & 0x7f) 10 return x - (e >> 2) 11 } 12 13 // ByteToLower converts an ascii byte to lower case 14 // uses a branchless algorithm 15 func ByteToLower(eax byte) byte { 16 ebx := eax&byte(0x7f) + byte(0x25) 17 ebx = ebx&byte(0x7f) + byte(0x1a) 18 ebx = ((ebx & ^eax) >> 2) & byte(0x20) 19 return eax + ebx 20 } 21 22 // ByteEqualFold does ascii compare, case insensitive 23 func ByteEqualFold(a, b byte) bool { 24 return a == b || ByteToLower(a) == ByteToLower(b) 25 } 26 27 // StringEqualFold ASCII case-insensitive comparison 28 // golang toUpper/toLower for both bytes and strings 29 // appears to be Unicode based which is super slow 30 // based from https://codereview.appspot.com/5180044/patch/14007/21002 31 func StringEqualFold(s1, s2 string) bool { 32 if len(s1) != len(s2) { 33 return false 34 } 35 for i := 0; i < len(s1); i++ { 36 c1 := s1[i] 37 c2 := s2[i] 38 // c1 & c2 39 if c1 != c2 { 40 c1 |= 'a' - 'A' 41 c2 |= 'a' - 'A' 42 if c1 != c2 || c1 < 'a' || c1 > 'z' { 43 return false 44 } 45 } 46 } 47 return true 48 } 49 50 // StringHasPrefixFold is similar to strings.HasPrefix but comparison 51 // is done ignoring ASCII case. 52 // / 53 func StringHasPrefixFold(s1, s2 string) bool { 54 // prefix is bigger than input --> false 55 if len(s1) < len(s2) { 56 return false 57 } 58 if len(s1) == len(s2) { 59 return StringEqualFold(s1, s2) 60 } 61 return StringEqualFold(s1[:len(s2)], s2) 62 }