...
1
2
3
4
5 package json
6
7 import (
8 "bytes"
9 "unicode/utf8"
10 )
11
12 const (
13 caseMask = ^byte(0x20)
14 kelvin = '\u212a'
15 smallLongEss = '\u017f'
16 )
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33 func foldFunc(s []byte) func(s, t []byte) bool {
34 nonLetter := false
35 special := false
36 for _, b := range s {
37 if b >= utf8.RuneSelf {
38 return bytes.EqualFold
39 }
40 upper := b & caseMask
41 if upper < 'A' || upper > 'Z' {
42 nonLetter = true
43 } else if upper == 'K' || upper == 'S' {
44
45 special = true
46 }
47 }
48 if special {
49 return equalFoldRight
50 }
51 if nonLetter {
52 return asciiEqualFold
53 }
54 return simpleLetterEqualFold
55 }
56
57
58
59
60
61 func equalFoldRight(s, t []byte) bool {
62 for _, sb := range s {
63 if len(t) == 0 {
64 return false
65 }
66 tb := t[0]
67 if tb < utf8.RuneSelf {
68 if sb != tb {
69 sbUpper := sb & caseMask
70 if 'A' <= sbUpper && sbUpper <= 'Z' {
71 if sbUpper != tb&caseMask {
72 return false
73 }
74 } else {
75 return false
76 }
77 }
78 t = t[1:]
79 continue
80 }
81
82
83 tr, size := utf8.DecodeRune(t)
84 switch sb {
85 case 's', 'S':
86 if tr != smallLongEss {
87 return false
88 }
89 case 'k', 'K':
90 if tr != kelvin {
91 return false
92 }
93 default:
94 return false
95 }
96 t = t[size:]
97
98 }
99 if len(t) > 0 {
100 return false
101 }
102 return true
103 }
104
105
106
107
108
109 func asciiEqualFold(s, t []byte) bool {
110 if len(s) != len(t) {
111 return false
112 }
113 for i, sb := range s {
114 tb := t[i]
115 if sb == tb {
116 continue
117 }
118 if ('a' <= sb && sb <= 'z') || ('A' <= sb && sb <= 'Z') {
119 if sb&caseMask != tb&caseMask {
120 return false
121 }
122 } else {
123 return false
124 }
125 }
126 return true
127 }
128
129
130
131
132
133 func simpleLetterEqualFold(s, t []byte) bool {
134 if len(s) != len(t) {
135 return false
136 }
137 for i, b := range s {
138 if b&caseMask != t[i]&caseMask {
139 return false
140 }
141 }
142 return true
143 }
144
View as plain text