1/** 2 * Copyright 2014 Paul Querna 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 * 16 */ 17 18/* Portions of this file are on Go stdlib's encoding/json/fold.go */ 19// Copyright 2009 The Go Authors. All rights reserved. 20// Use of this source code is governed by a BSD-style 21// license that can be found in the LICENSE file. 22 23package v1 24 25import ( 26 "unicode/utf8" 27) 28 29const ( 30 caseMask = ^byte(0x20) // Mask to ignore case in ASCII. 31 kelvin = '\u212a' 32 smallLongEss = '\u017f' 33) 34 35// equalFoldRight is a specialization of bytes.EqualFold when s is 36// known to be all ASCII (including punctuation), but contains an 's', 37// 'S', 'k', or 'K', requiring a Unicode fold on the bytes in t. 38// See comments on foldFunc. 39func EqualFoldRight(s, t []byte) bool { 40 for _, sb := range s { 41 if len(t) == 0 { 42 return false 43 } 44 tb := t[0] 45 if tb < utf8.RuneSelf { 46 if sb != tb { 47 sbUpper := sb & caseMask 48 if 'A' <= sbUpper && sbUpper <= 'Z' { 49 if sbUpper != tb&caseMask { 50 return false 51 } 52 } else { 53 return false 54 } 55 } 56 t = t[1:] 57 continue 58 } 59 // sb is ASCII and t is not. t must be either kelvin 60 // sign or long s; sb must be s, S, k, or K. 61 tr, size := utf8.DecodeRune(t) 62 switch sb { 63 case 's', 'S': 64 if tr != smallLongEss { 65 return false 66 } 67 case 'k', 'K': 68 if tr != kelvin { 69 return false 70 } 71 default: 72 return false 73 } 74 t = t[size:] 75 76 } 77 if len(t) > 0 { 78 return false 79 } 80 return true 81} 82 83// asciiEqualFold is a specialization of bytes.EqualFold for use when 84// s is all ASCII (but may contain non-letters) and contains no 85// special-folding letters. 86// See comments on foldFunc. 87func AsciiEqualFold(s, t []byte) bool { 88 if len(s) != len(t) { 89 return false 90 } 91 for i, sb := range s { 92 tb := t[i] 93 if sb == tb { 94 continue 95 } 96 if ('a' <= sb && sb <= 'z') || ('A' <= sb && sb <= 'Z') { 97 if sb&caseMask != tb&caseMask { 98 return false 99 } 100 } else { 101 return false 102 } 103 } 104 return true 105} 106 107// simpleLetterEqualFold is a specialization of bytes.EqualFold for 108// use when s is all ASCII letters (no underscores, etc) and also 109// doesn't contain 'k', 'K', 's', or 'S'. 110// See comments on foldFunc. 111func SimpleLetterEqualFold(s, t []byte) bool { 112 if len(s) != len(t) { 113 return false 114 } 115 for i, b := range s { 116 if b&caseMask != t[i]&caseMask { 117 return false 118 } 119 } 120 return true 121} 122