| 1 | /* | 
| 2 |  * Copyright (C) 2007, 2008, 2009, 2011 Apple Inc. All rights reserved. | 
| 3 |  * | 
| 4 |  * Redistribution and use in source and binary forms, with or without | 
| 5 |  * modification, are permitted provided that the following conditions | 
| 6 |  * are met: | 
| 7 |  * | 
| 8 |  * 1.  Redistributions of source code must retain the above copyright | 
| 9 |  *     notice, this list of conditions and the following disclaimer.  | 
| 10 |  * 2.  Redistributions in binary form must reproduce the above copyright | 
| 11 |  *     notice, this list of conditions and the following disclaimer in the | 
| 12 |  *     documentation and/or other materials provided with the distribution.  | 
| 13 |  * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of | 
| 14 |  *     its contributors may be used to endorse or promote products derived | 
| 15 |  *     from this software without specific prior written permission.  | 
| 16 |  * | 
| 17 |  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY | 
| 18 |  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 
| 19 |  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 
| 20 |  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY | 
| 21 |  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 
| 22 |  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 
| 23 |  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | 
| 24 |  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 
| 25 |  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 
| 26 |  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 
| 27 |  */ | 
| 28 |  | 
| 29 | #ifndef WTF_ASCIICType_h | 
| 30 | #define WTF_ASCIICType_h | 
| 31 |  | 
| 32 | #include <wtf/Assertions.h> | 
| 33 |  | 
| 34 | // The behavior of many of the functions in the <ctype.h> header is dependent | 
| 35 | // on the current locale. But in the WebKit project, all uses of those functions | 
| 36 | // are in code processing something that's not locale-specific. These equivalents | 
| 37 | // for some of the <ctype.h> functions are named more explicitly, not dependent | 
| 38 | // on the C library locale, and we should also optimize them as needed. | 
| 39 |  | 
| 40 | // All functions return false or leave the character unchanged if passed a character | 
| 41 | // that is outside the range 0-7F. So they can be used on Unicode strings or | 
| 42 | // characters if the intent is to do processing only if the character is ASCII. | 
| 43 |  | 
| 44 | namespace WTF { | 
| 45 |  | 
| 46 | template<typename CharType> inline bool isASCII(CharType c) | 
| 47 | { | 
| 48 |     return !(c & ~0x7F); | 
| 49 | } | 
| 50 |  | 
| 51 | template<typename CharType> inline bool isASCIIAlpha(CharType c) | 
| 52 | { | 
| 53 |     return (c | 0x20) >= 'a' && (c | 0x20) <= 'z'; | 
| 54 | } | 
| 55 |  | 
| 56 | template<typename CharType> inline bool isASCIIDigit(CharType c) | 
| 57 | { | 
| 58 |     return c >= '0' && c <= '9'; | 
| 59 | } | 
| 60 |  | 
| 61 | template<typename CharType> inline bool isASCIIAlphanumeric(CharType c) | 
| 62 | { | 
| 63 |     return isASCIIDigit(c) || isASCIIAlpha(c); | 
| 64 | } | 
| 65 |  | 
| 66 | template<typename CharType> inline bool isASCIIHexDigit(CharType c) | 
| 67 | { | 
| 68 |     return isASCIIDigit(c) || ((c | 0x20) >= 'a' && (c | 0x20) <= 'f'); | 
| 69 | } | 
| 70 |  | 
| 71 | template<typename CharType> inline bool isASCIILower(CharType c) | 
| 72 | { | 
| 73 |     return c >= 'a' && c <= 'z'; | 
| 74 | } | 
| 75 |  | 
| 76 | template<typename CharType> inline bool isASCIIOctalDigit(CharType c) | 
| 77 | { | 
| 78 |     return (c >= '0') & (c <= '7'); | 
| 79 | } | 
| 80 |  | 
| 81 | template<typename CharType> inline bool isASCIIPrintable(CharType c) | 
| 82 | { | 
| 83 |     return c >= ' ' && c <= '~'; | 
| 84 | } | 
| 85 |  | 
| 86 | /* | 
| 87 |  Statistics from a run of Apple's page load test for callers of isASCIISpace: | 
| 88 |  | 
| 89 |  character          count | 
| 90 |  ---------          ----- | 
| 91 |  non-spaces         689383 | 
| 92 |  20  space          294720 | 
| 93 |  0A  \n             89059 | 
| 94 |  09  \t             28320 | 
| 95 |  0D  \r             0 | 
| 96 |  0C  \f             0 | 
| 97 |  0B  \v             0 | 
| 98 |  */ | 
| 99 | template<typename CharType> inline bool isASCIISpace(CharType c) | 
| 100 | { | 
| 101 |     return c <= ' ' && (c == ' ' || (c <= 0xD && c >= 0x9)); | 
| 102 | } | 
| 103 |  | 
| 104 | template<typename CharType> inline bool isASCIIUpper(CharType c) | 
| 105 | { | 
| 106 |     return c >= 'A' && c <= 'Z'; | 
| 107 | } | 
| 108 |  | 
| 109 | template<typename CharType> inline CharType toASCIILower(CharType c) | 
| 110 | { | 
| 111 |     return c | ((c >= 'A' && c <= 'Z') << 5); | 
| 112 | } | 
| 113 |  | 
| 114 | template<typename CharType> inline CharType toASCIILowerUnchecked(CharType character) | 
| 115 | { | 
| 116 |     // This function can be used for comparing any input character | 
| 117 |     // to a lowercase English character. The isASCIIAlphaCaselessEqual | 
| 118 |     // below should be used for regular comparison of ASCII alpha | 
| 119 |     // characters, but switch statements in CSS tokenizer require | 
| 120 |     // direct use of this function. | 
| 121 |     return character | 0x20; | 
| 122 | } | 
| 123 |  | 
| 124 | template<typename CharType> inline CharType toASCIIUpper(CharType c) | 
| 125 | { | 
| 126 |     return c & ~((c >= 'a' && c <= 'z') << 5); | 
| 127 | } | 
| 128 |  | 
| 129 | template<typename CharType> inline int toASCIIHexValue(CharType c) | 
| 130 | { | 
| 131 |     ASSERT(isASCIIHexDigit(c)); | 
| 132 |     return c < 'A' ? c - '0' : (c - 'A' + 10) & 0xF; | 
| 133 | } | 
| 134 |  | 
| 135 | template<typename CharType> inline int toASCIIHexValue(CharType upperValue, CharType lowerValue) | 
| 136 | { | 
| 137 |     ASSERT(isASCIIHexDigit(upperValue) && isASCIIHexDigit(lowerValue)); | 
| 138 |     return ((toASCIIHexValue(upperValue) << 4) & 0xF0) | toASCIIHexValue(lowerValue); | 
| 139 | } | 
| 140 |  | 
| 141 | inline char lowerNibbleToASCIIHexDigit(char c) | 
| 142 | { | 
| 143 |     char nibble = c & 0xF; | 
| 144 |     return nibble < 10 ? '0' + nibble : 'A' + nibble - 10; | 
| 145 | } | 
| 146 |  | 
| 147 | inline char upperNibbleToASCIIHexDigit(char c) | 
| 148 | { | 
| 149 |     char nibble = (c >> 4) & 0xF; | 
| 150 |     return nibble < 10 ? '0' + nibble : 'A' + nibble - 10; | 
| 151 | } | 
| 152 |  | 
| 153 | template<typename CharType> inline bool isASCIIAlphaCaselessEqual(CharType cssCharacter, char character) | 
| 154 | { | 
| 155 |     // This function compares a (preferrably) constant ASCII | 
| 156 |     // lowercase letter to any input character. | 
| 157 |     ASSERT(character >= 'a' && character <= 'z'); | 
| 158 |     return LIKELY(toASCIILowerUnchecked(cssCharacter) == character); | 
| 159 | } | 
| 160 |  | 
| 161 | } | 
| 162 |  | 
| 163 | using WTF::isASCII; | 
| 164 | using WTF::isASCIIAlpha; | 
| 165 | using WTF::isASCIIAlphanumeric; | 
| 166 | using WTF::isASCIIDigit; | 
| 167 | using WTF::isASCIIHexDigit; | 
| 168 | using WTF::isASCIILower; | 
| 169 | using WTF::isASCIIOctalDigit; | 
| 170 | using WTF::isASCIIPrintable; | 
| 171 | using WTF::isASCIISpace; | 
| 172 | using WTF::isASCIIUpper; | 
| 173 | using WTF::toASCIIHexValue; | 
| 174 | using WTF::toASCIILower; | 
| 175 | using WTF::toASCIILowerUnchecked; | 
| 176 | using WTF::toASCIIUpper; | 
| 177 | using WTF::lowerNibbleToASCIIHexDigit; | 
| 178 | using WTF::upperNibbleToASCIIHexDigit; | 
| 179 | using WTF::isASCIIAlphaCaselessEqual; | 
| 180 |  | 
| 181 | #endif | 
| 182 |  |