...
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
34 func foldFunc(s []byte) func(s, t []byte) bool {
35 nonLetter := false
36 special := false
37 for _, b := range s {
38 if b >= utf8.RuneSelf {
39 return bytes.EqualFold
40 }
41 upper := b & caseMask
42 if upper < 'A' || upper > 'Z' {
43 nonLetter = true
44 } else if upper == 'K' || upper == 'S' {
45
46 special = true
47 }
48 }
49 if special {
50 return equalFoldRight
51 }
52 if nonLetter {
53 return asciiEqualFold
54 }
55 return simpleLetterEqualFold
56 }
57
58
59
60
61
62 func equalFoldRight(s, t []byte) bool {
63 for _, sb := range s {
64 if len(t) == 0 {
65 return false
66 }
67 tb := t[0]
68 if tb < utf8.RuneSelf {
69 if sb != tb {
70 sbUpper := sb & caseMask
71 if 'A' <= sbUpper && sbUpper <= 'Z' {
72 if sbUpper != tb&caseMask {
73 return false
74 }
75 } else {
76 return false
77 }
78 }
79 t = t[1:]
80 continue
81 }
82
83
84 tr, size := utf8.DecodeRune(t)
85 switch sb {
86 case 's', 'S':
87 if tr != smallLongEss {
88 return false
89 }
90 case 'k', 'K':
91 if tr != kelvin {
92 return false
93 }
94 default:
95 return false
96 }
97 t = t[size:]
98
99 }
100 if len(t) > 0 {
101 return false
102 }
103 return true
104 }
105
106
107
108
109
110 func asciiEqualFold(s, t []byte) bool {
111 if len(s) != len(t) {
112 return false
113 }
114 for i, sb := range s {
115 tb := t[i]
116 if sb == tb {
117 continue
118 }
119 if ('a' <= sb && sb <= 'z') || ('A' <= sb && sb <= 'Z') {
120 if sb&caseMask != tb&caseMask {
121 return false
122 }
123 } else {
124 return false
125 }
126 }
127 return true
128 }
129
130
131
132
133
134 func simpleLetterEqualFold(s, t []byte) bool {
135 if len(s) != len(t) {
136 return false
137 }
138 for i, b := range s {
139 if b&caseMask != t[i]&caseMask {
140 return false
141 }
142 }
143 return true
144 }
145
View as plain text