Source file src/mime/grammar.go

     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 string) 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  

View as plain text