1 // Copyright 2010 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4 5 package mime
6 7 // isTSpecial reports whether c is in 'tspecials' as defined by RFC
8 // 1521 and RFC 2045.
9 func isTSpecial(c byte) bool {
10 // tspecials := "(" / ")" / "<" / ">" / "@" /
11 // "," / ";" / ":" / "\" / <">
12 // "/" / "[" / "]" / "?" / "="
13 //
14 // mask is a 128-bit bitmap with 1s for allowed bytes,
15 // so that the byte c can be tested with a shift and an and.
16 // If c >= 128, then 1<<c and 1<<(c-64) will both be zero,
17 // and this function will return false.
18 const mask = 0 |
19 1<<'(' |
20 1<<')' |
21 1<<'<' |
22 1<<'>' |
23 1<<'@' |
24 1<<',' |
25 1<<';' |
26 1<<':' |
27 1<<'\\' |
28 1<<'"' |
29 1<<'/' |
30 1<<'[' |
31 1<<']' |
32 1<<'?' |
33 1<<'='
34 return ((uint64(1)<<c)&(mask&(1<<64-1)) |
35 (uint64(1)<<(c-64))&(mask>>64)) != 0
36 }
37 38 // isTokenChar reports whether c is in 'token' as defined by RFC
39 // 1521 and RFC 2045.
40 func isTokenChar(c byte) bool {
41 // token := 1*<any (US-ASCII) CHAR except SPACE, CTLs,
42 // or tspecials>
43 //
44 // mask is a 128-bit bitmap with 1s for allowed bytes,
45 // so that the byte c can be tested with a shift and an and.
46 // If c >= 128, then 1<<c and 1<<(c-64) will both be zero,
47 // and this function will return false.
48 const mask = 0 |
49 (1<<(10)-1)<<'0' |
50 (1<<(26)-1)<<'a' |
51 (1<<(26)-1)<<'A' |
52 1<<'!' |
53 1<<'#' |
54 1<<'$' |
55 1<<'%' |
56 1<<'&' |
57 1<<'\'' |
58 1<<'*' |
59 1<<'+' |
60 1<<'-' |
61 1<<'.' |
62 1<<'^' |
63 1<<'_' |
64 1<<'`' |
65 1<<'|' |
66 1<<'~'
67 return ((uint64(1)<<c)&(mask&(1<<64-1)) |
68 (uint64(1)<<(c-64))&(mask>>64)) != 0
69 }
70 71 // isToken reports whether s is a 'token' as defined by RFC 1521
72 // and RFC 2045.
73 func isToken(s []byte) bool {
74 if s == "" {
75 return false
76 }
77 for _, c := range []byte(s) {
78 if !isTokenChar(c) {
79 return false
80 }
81 }
82 return true
83 }
84