1
2
3
4
5 package cases
6
7 import "golang.org/x/text/transform"
8
9
10
11
12
13
14
15
16
17
18
19 type context struct {
20 dst, src []byte
21 atEOF bool
22
23 pDst int
24 pSrc int
25
26
27 nDst, nSrc int
28 err error
29
30 sz int
31 info info
32
33
34 isMidWord bool
35 }
36
37 func (c *context) Reset() {
38 c.isMidWord = false
39 }
40
41
42
43
44 func (c *context) ret() (nDst, nSrc int, err error) {
45 if c.err != nil || c.nSrc == len(c.src) {
46 return c.nDst, c.nSrc, c.err
47 }
48
49
50
51 if c.atEOF && c.pSrc == len(c.src) {
52 return c.pDst, c.pSrc, nil
53 }
54 return c.nDst, c.nSrc, transform.ErrShortSrc
55 }
56
57
58
59
60 func (c *context) retSpan() (n int, err error) {
61 _, nSrc, err := c.ret()
62 return nSrc, err
63 }
64
65
66
67 func (c *context) checkpoint() {
68 if c.err == nil {
69 c.nDst, c.nSrc = c.pDst, c.pSrc+c.sz
70 }
71 }
72
73
74
75 func (c *context) unreadRune() {
76 c.sz = 0
77 }
78
79 func (c *context) next() bool {
80 c.pSrc += c.sz
81 if c.pSrc == len(c.src) || c.err != nil {
82 c.info, c.sz = 0, 0
83 return false
84 }
85 v, sz := trie.lookup(c.src[c.pSrc:])
86 c.info, c.sz = info(v), sz
87 if c.sz == 0 {
88 if c.atEOF {
89
90
91
92 c.sz = 1
93 } else {
94 c.err = transform.ErrShortSrc
95 return false
96 }
97 }
98 return true
99 }
100
101
102 func (c *context) writeBytes(b []byte) bool {
103 if len(c.dst)-c.pDst < len(b) {
104 c.err = transform.ErrShortDst
105 return false
106 }
107
108 for _, ch := range b {
109 c.dst[c.pDst] = ch
110 c.pDst++
111 }
112 return true
113 }
114
115
116 func (c *context) writeString(s string) bool {
117 if len(c.dst)-c.pDst < len(s) {
118 c.err = transform.ErrShortDst
119 return false
120 }
121
122 for i := 0; i < len(s); i++ {
123 c.dst[c.pDst] = s[i]
124 c.pDst++
125 }
126 return true
127 }
128
129
130 func (c *context) copy() bool {
131 return c.writeBytes(c.src[c.pSrc : c.pSrc+c.sz])
132 }
133
134
135
136
137 func (c *context) copyXOR() bool {
138 if !c.copy() {
139 return false
140 }
141 if c.info&xorIndexBit == 0 {
142
143 c.dst[c.pDst-1] ^= byte(c.info >> xorShift)
144 } else {
145
146
147
148 idx := c.info >> xorShift
149 for p := c.pDst - 1; ; p-- {
150 c.dst[p] ^= xorData[idx]
151 idx--
152 if xorData[idx] == 0 {
153 break
154 }
155 }
156 }
157 return true
158 }
159
160
161 func (c *context) hasPrefix(s string) bool {
162 b := c.src[c.pSrc:]
163 if len(b) < len(s) {
164 return false
165 }
166 for i, c := range b[:len(s)] {
167 if c != s[i] {
168 return false
169 }
170 }
171 return true
172 }
173
174
175
176 func (c *context) caseType() info {
177 cm := c.info & 0x7
178 if cm < 4 {
179 return cm
180 }
181 if cm >= cXORCase {
182
183 b := c.src[c.pSrc+c.sz-1]
184 return info(b&1) ^ cm&0x3
185 }
186 if cm == cIgnorableCased {
187 return cLower
188 }
189 return cUncased
190 }
191
192
193 func lower(c *context) bool {
194 ct := c.caseType()
195 if c.info&hasMappingMask == 0 || ct == cLower {
196 return c.copy()
197 }
198 if c.info&exceptionBit == 0 {
199 return c.copyXOR()
200 }
201 e := exceptions[c.info>>exceptionShift:]
202 offset := 2 + e[0]&lengthMask
203 if nLower := (e[1] >> lengthBits) & lengthMask; nLower != noChange {
204 return c.writeString(e[offset : offset+nLower])
205 }
206 return c.copy()
207 }
208
209 func isLower(c *context) bool {
210 ct := c.caseType()
211 if c.info&hasMappingMask == 0 || ct == cLower {
212 return true
213 }
214 if c.info&exceptionBit == 0 {
215 c.err = transform.ErrEndOfSpan
216 return false
217 }
218 e := exceptions[c.info>>exceptionShift:]
219 if nLower := (e[1] >> lengthBits) & lengthMask; nLower != noChange {
220 c.err = transform.ErrEndOfSpan
221 return false
222 }
223 return true
224 }
225
226
227 func upper(c *context) bool {
228 ct := c.caseType()
229 if c.info&hasMappingMask == 0 || ct == cUpper {
230 return c.copy()
231 }
232 if c.info&exceptionBit == 0 {
233 return c.copyXOR()
234 }
235 e := exceptions[c.info>>exceptionShift:]
236 offset := 2 + e[0]&lengthMask
237
238 n := (e[1] >> lengthBits) & lengthMask
239 if ct == cTitle {
240
241 if n == noChange {
242 n = 0
243 }
244 n, e = e[1]&lengthMask, e[n:]
245 }
246 if n != noChange {
247 return c.writeString(e[offset : offset+n])
248 }
249 return c.copy()
250 }
251
252
253 func isUpper(c *context) bool {
254 ct := c.caseType()
255 if c.info&hasMappingMask == 0 || ct == cUpper {
256 return true
257 }
258 if c.info&exceptionBit == 0 {
259 c.err = transform.ErrEndOfSpan
260 return false
261 }
262 e := exceptions[c.info>>exceptionShift:]
263
264 n := (e[1] >> lengthBits) & lengthMask
265 if ct == cTitle {
266 n = e[1] & lengthMask
267 }
268 if n != noChange {
269 c.err = transform.ErrEndOfSpan
270 return false
271 }
272 return true
273 }
274
275
276 func title(c *context) bool {
277 ct := c.caseType()
278 if c.info&hasMappingMask == 0 || ct == cTitle {
279 return c.copy()
280 }
281 if c.info&exceptionBit == 0 {
282 if ct == cLower {
283 return c.copyXOR()
284 }
285 return c.copy()
286 }
287
288 e := exceptions[c.info>>exceptionShift:]
289 offset := 2 + e[0]&lengthMask
290
291 nFirst := (e[1] >> lengthBits) & lengthMask
292 if nTitle := e[1] & lengthMask; nTitle != noChange {
293 if nFirst != noChange {
294 e = e[nFirst:]
295 }
296 return c.writeString(e[offset : offset+nTitle])
297 }
298 if ct == cLower && nFirst != noChange {
299
300 return c.writeString(e[offset : offset+nFirst])
301 }
302
303 return c.copy()
304 }
305
306
307 func isTitle(c *context) bool {
308 ct := c.caseType()
309 if c.info&hasMappingMask == 0 || ct == cTitle {
310 return true
311 }
312 if c.info&exceptionBit == 0 {
313 if ct == cLower {
314 c.err = transform.ErrEndOfSpan
315 return false
316 }
317 return true
318 }
319
320 e := exceptions[c.info>>exceptionShift:]
321 if nTitle := e[1] & lengthMask; nTitle != noChange {
322 c.err = transform.ErrEndOfSpan
323 return false
324 }
325 nFirst := (e[1] >> lengthBits) & lengthMask
326 if ct == cLower && nFirst != noChange {
327 c.err = transform.ErrEndOfSpan
328 return false
329 }
330 return true
331 }
332
333
334 func foldFull(c *context) bool {
335 if c.info&hasMappingMask == 0 {
336 return c.copy()
337 }
338 ct := c.caseType()
339 if c.info&exceptionBit == 0 {
340 if ct != cLower || c.info&inverseFoldBit != 0 {
341 return c.copyXOR()
342 }
343 return c.copy()
344 }
345 e := exceptions[c.info>>exceptionShift:]
346 n := e[0] & lengthMask
347 if n == 0 {
348 if ct == cLower {
349 return c.copy()
350 }
351 n = (e[1] >> lengthBits) & lengthMask
352 }
353 return c.writeString(e[2 : 2+n])
354 }
355
356
357 func isFoldFull(c *context) bool {
358 if c.info&hasMappingMask == 0 {
359 return true
360 }
361 ct := c.caseType()
362 if c.info&exceptionBit == 0 {
363 if ct != cLower || c.info&inverseFoldBit != 0 {
364 c.err = transform.ErrEndOfSpan
365 return false
366 }
367 return true
368 }
369 e := exceptions[c.info>>exceptionShift:]
370 n := e[0] & lengthMask
371 if n == 0 && ct == cLower {
372 return true
373 }
374 c.err = transform.ErrEndOfSpan
375 return false
376 }
377
View as plain text