...
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 return len(t) == 0
101 }
102
103
104
105
106
107 func asciiEqualFold(s, t []byte) bool {
108 if len(s) != len(t) {
109 return false
110 }
111 for i, sb := range s {
112 tb := t[i]
113 if sb == tb {
114 continue
115 }
116 if ('a' <= sb && sb <= 'z') || ('A' <= sb && sb <= 'Z') {
117 if sb&caseMask != tb&caseMask {
118 return false
119 }
120 } else {
121 return false
122 }
123 }
124 return true
125 }
126
127
128
129
130
131 func simpleLetterEqualFold(s, t []byte) bool {
132 if len(s) != len(t) {
133 return false
134 }
135 for i, b := range s {
136 if b&caseMask != t[i]&caseMask {
137 return false
138 }
139 }
140 return true
141 }
142
View as plain text