1 /* 2 * Copyright (C) 2003 Lars Knoll (knoll (at) kde.org) 3 * Copyright (C) 2004, 2005, 2006, 2008, 2009, 2010 Apple Inc. All rights reserved. 4 * Copyright (C) 2008 Eric Seidel <eric (at) webkit.org> 5 * Copyright (C) 2009 - 2010 Torch Mobile (Beijing) Co. Ltd. All rights reserved. 6 * 7 * This library is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Library General Public 9 * License as published by the Free Software Foundation; either 10 * version 2 of the License, or (at your option) any later version. 11 * 12 * This library is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Library General Public License for more details. 16 * 17 * You should have received a copy of the GNU Library General Public License 18 * along with this library; see the file COPYING.LIB. If not, write to 19 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 20 * Boston, MA 02110-1301, USA. 21 */ 22 23 #ifndef CSSTokenizer_h 24 #define CSSTokenizer_h 25 26 #include "wtf/Noncopyable.h" 27 #include "wtf/OwnPtr.h" 28 #include "wtf/text/WTFString.h" 29 30 namespace WebCore { 31 32 class CSSParser; 33 struct CSSParserLocation; 34 struct CSSParserString; 35 36 class CSSTokenizer { 37 WTF_MAKE_NONCOPYABLE(CSSTokenizer); 38 public: 39 // FIXME: This should not be needed but there are still some ties between the 2 classes. 40 friend class CSSParser; 41 42 CSSTokenizer(CSSParser& parser) 43 : m_parser(parser) 44 , m_parsedTextPrefixLength(0) 45 , m_parsedTextSuffixLength(0) 46 , m_parsingMode(NormalMode) 47 , m_is8BitSource(false) 48 , m_length(0) 49 , m_token(0) 50 , m_lineNumber(0) 51 , m_tokenStartLineNumber(0) 52 , m_internal(true) 53 { 54 m_tokenStart.ptr8 = 0; 55 } 56 57 void setupTokenizer(const char* prefix, unsigned prefixLength, const String&, const char* suffix, unsigned suffixLength); 58 59 CSSParserLocation currentLocation(); 60 61 inline int lex(void* yylval) { return (this->*m_lexFunc)(yylval); } 62 63 inline unsigned safeUserStringTokenOffset() 64 { 65 return std::min(tokenStartOffset(), static_cast<unsigned>(m_length - 1 - m_parsedTextSuffixLength)) - m_parsedTextPrefixLength; 66 } 67 68 bool is8BitSource() const { return m_is8BitSource; } 69 70 // FIXME: These 2 functions should be private so that we don't need the definitions below. 71 template <typename CharacterType> 72 inline CharacterType* tokenStart(); 73 74 inline unsigned tokenStartOffset(); 75 76 private: 77 UChar*& currentCharacter16(); 78 79 template <typename CharacterType> 80 inline CharacterType*& currentCharacter(); 81 82 template <typename CharacterType> 83 inline CharacterType* dataStart(); 84 85 template <typename CharacterType> 86 inline void setTokenStart(CharacterType*); 87 88 template <typename CharacterType> 89 inline bool isIdentifierStart(); 90 91 template <typename CharacterType> 92 inline CSSParserLocation tokenLocation(); 93 94 template <typename CharacterType> 95 unsigned parseEscape(CharacterType*&); 96 template <typename DestCharacterType> 97 inline void UnicodeToChars(DestCharacterType*&, unsigned); 98 template <typename SrcCharacterType, typename DestCharacterType> 99 inline bool parseIdentifierInternal(SrcCharacterType*&, DestCharacterType*&, bool&); 100 101 template <typename CharacterType> 102 inline void parseIdentifier(CharacterType*&, CSSParserString&, bool&); 103 104 template <typename SrcCharacterType, typename DestCharacterType> 105 inline bool parseStringInternal(SrcCharacterType*&, DestCharacterType*&, UChar); 106 107 template <typename CharacterType> 108 inline void parseString(CharacterType*&, CSSParserString& resultString, UChar); 109 110 template <typename CharacterType> 111 inline bool findURI(CharacterType*& start, CharacterType*& end, UChar& quote); 112 113 template <typename SrcCharacterType, typename DestCharacterType> 114 inline bool parseURIInternal(SrcCharacterType*&, DestCharacterType*&, UChar quote); 115 116 template <typename CharacterType> 117 inline void parseURI(CSSParserString&); 118 template <typename CharacterType> 119 inline bool parseUnicodeRange(); 120 template <typename CharacterType> 121 bool parseNthChild(); 122 template <typename CharacterType> 123 bool parseNthChildExtra(); 124 template <typename CharacterType> 125 inline bool detectFunctionTypeToken(int); 126 template <typename CharacterType> 127 inline void detectMediaQueryToken(int); 128 template <typename CharacterType> 129 inline void detectNumberToken(CharacterType*, int); 130 template <typename CharacterType> 131 inline void detectDashToken(int); 132 template <typename CharacterType> 133 inline void detectAtToken(int, bool); 134 template <typename CharacterType> 135 inline void detectSupportsToken(int); 136 template <typename CharacterType> 137 inline void detectCSSVariableDefinitionToken(int); 138 139 template <typename SourceCharacterType> 140 int realLex(void* yylval); 141 142 CSSParser& m_parser; 143 144 size_t m_parsedTextPrefixLength; 145 size_t m_parsedTextSuffixLength; 146 147 enum ParsingMode { 148 NormalMode, 149 MediaQueryMode, 150 SupportsMode, 151 NthChildMode 152 }; 153 154 ParsingMode m_parsingMode; 155 bool m_is8BitSource; 156 OwnPtr<LChar[]> m_dataStart8; 157 OwnPtr<UChar[]> m_dataStart16; 158 LChar* m_currentCharacter8; 159 UChar* m_currentCharacter16; 160 union { 161 LChar* ptr8; 162 UChar* ptr16; 163 } m_tokenStart; 164 unsigned m_length; 165 int m_token; 166 int m_lineNumber; 167 int m_tokenStartLineNumber; 168 169 // FIXME: This boolean is misnamed. Also it would be nice if we could consolidate it 170 // with the CSSParserMode logic to determine if internal properties are allowed. 171 bool m_internal; 172 173 int (CSSTokenizer::*m_lexFunc)(void*); 174 }; 175 176 inline unsigned CSSTokenizer::tokenStartOffset() 177 { 178 if (is8BitSource()) 179 return m_tokenStart.ptr8 - m_dataStart8.get(); 180 return m_tokenStart.ptr16 - m_dataStart16.get(); 181 } 182 183 template <> 184 inline LChar* CSSTokenizer::tokenStart<LChar>() 185 { 186 return m_tokenStart.ptr8; 187 } 188 189 template <> 190 inline UChar* CSSTokenizer::tokenStart<UChar>() 191 { 192 return m_tokenStart.ptr16; 193 } 194 195 } // namespace WebCore 196 197 #endif // CSSTokenizer_h 198