1 /* 2 This file is part of the KDE libraries 3 4 Copyright (C) 1999 Lars Knoll (knoll@mpi-hd.mpg.de) 5 Copyright (C) 2004 Apple Computer, Inc. 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 // 24 // KDE HTML Widget -- String class 25 26 #ifndef KHTMLSTRING_H 27 #define KHTMLSTRING_H 28 29 #include "dom/dom_string.h" 30 31 #include <QList> 32 #include <QString> 33 34 #include <assert.h> 35 36 using namespace DOM; 37 38 namespace khtml 39 { 40 41 class DOMStringIt 42 { 43 public: DOMStringIt()44 DOMStringIt() 45 { 46 s = nullptr, l = 0; 47 lines = 0; 48 } DOMStringIt(QChar * str,uint len)49 DOMStringIt(QChar *str, uint len) 50 { 51 s = str, l = len; 52 lines = 0; 53 } DOMStringIt(const QString & str)54 DOMStringIt(const QString &str) 55 { 56 s = str.unicode(); 57 l = str.length(); 58 lines = 0; 59 } 60 61 DOMStringIt *operator++() 62 { 63 if (!pushedChar.isNull()) { 64 pushedChar = 0; 65 } else if (l > 0) { 66 if (*s == QLatin1Char('\n')) { 67 lines++; 68 } 69 s++, l--; 70 } 71 return this; 72 } 73 public: push(const QChar & c)74 void push(const QChar &c) 75 { 76 /* assert(pushedChar.isNull());*/ pushedChar = c; 77 } 78 79 const QChar &operator*() const 80 { 81 return pushedChar.isNull() ? *s : pushedChar; 82 } 83 const QChar *operator->() const 84 { 85 return pushedChar.isNull() ? s : &pushedChar; 86 } 87 escaped()88 bool escaped() const 89 { 90 return !pushedChar.isNull(); 91 } length()92 uint length() const 93 { 94 return l + (!pushedChar.isNull()); 95 } 96 current()97 const QChar *current() const 98 { 99 return pushedChar.isNull() ? s : &pushedChar; 100 } lineCount()101 int lineCount() const 102 { 103 return lines; 104 } 105 106 protected: 107 QChar pushedChar; 108 const QChar *s; 109 int l; 110 int lines; 111 }; 112 113 class TokenizerString; 114 115 class TokenizerSubstring 116 { 117 friend class TokenizerString; 118 public: TokenizerSubstring()119 TokenizerSubstring() : m_length(0), m_current(nullptr) {} TokenizerSubstring(const QString & str)120 TokenizerSubstring(const QString &str) : m_string(str), m_length(str.length()), m_current(m_length == 0 ? nullptr : str.unicode()) {} TokenizerSubstring(const QChar * str,int length)121 TokenizerSubstring(const QChar *str, int length) : m_length(length), m_current(length == 0 ? nullptr : str) {} 122 clear()123 void clear() 124 { 125 m_length = 0; 126 m_current = nullptr; 127 } 128 appendTo(QString & str)129 void appendTo(QString &str) const 130 { 131 if (m_string.unicode() == m_current) { 132 if (str.isEmpty()) { 133 str = m_string; 134 } else { 135 str.append(m_string); 136 } 137 } else { 138 str.insert(str.length(), m_current, m_length); 139 } 140 } 141 private: 142 QString m_string; 143 int m_length; 144 const QChar *m_current; 145 }; 146 147 class TokenizerString 148 { 149 150 public: TokenizerString()151 TokenizerString() : m_currentChar(nullptr), m_lines(0), m_composite(false) {} TokenizerString(const QChar * str,int length)152 TokenizerString(const QChar *str, int length) : m_currentString(str, length), m_currentChar(m_currentString.m_current), m_lines(0), m_composite(false) {} TokenizerString(const QString & str)153 TokenizerString(const QString &str) : m_currentString(str), m_currentChar(m_currentString.m_current), m_lines(0), m_composite(false) {} TokenizerString(const TokenizerString & o)154 TokenizerString(const TokenizerString &o) : m_pushedChar1(o.m_pushedChar1), m_pushedChar2(o.m_pushedChar2), 155 m_currentString(o.m_currentString), m_substrings(o.m_substrings), 156 m_lines(o.m_lines), m_composite(o.m_composite) 157 { 158 m_currentChar = m_pushedChar1.isNull() ? m_currentString.m_current : &m_pushedChar1; 159 } 160 161 void clear(); 162 163 void append(const TokenizerString &); 164 void prepend(const TokenizerString &); 165 push(QChar c)166 void push(QChar c) 167 { 168 if (m_pushedChar1.isNull()) { 169 m_pushedChar1 = c; 170 m_currentChar = m_pushedChar1.isNull() ? m_currentString.m_current : &m_pushedChar1; 171 } else { 172 assert(m_pushedChar2.isNull()); 173 m_pushedChar2 = c; 174 } 175 } 176 isEmpty()177 bool isEmpty() const 178 { 179 return !current(); 180 } 181 uint length() const; 182 advance()183 void advance() 184 { 185 if (!m_pushedChar1.isNull()) { 186 m_pushedChar1 = m_pushedChar2; 187 m_pushedChar2 = 0; 188 } else if (m_currentString.m_current) { 189 m_lines += *m_currentString.m_current++ == QLatin1Char('\n'); 190 if (--m_currentString.m_length == 0) { 191 advanceSubstring(); 192 } 193 } 194 m_currentChar = m_pushedChar1.isNull() ? m_currentString.m_current : &m_pushedChar1; 195 } count()196 uint count() const 197 { 198 return m_substrings.count(); 199 } 200 escaped()201 bool escaped() const 202 { 203 return !m_pushedChar1.isNull(); 204 } 205 lineCount()206 int lineCount() const 207 { 208 return m_lines; 209 } resetLineCount()210 void resetLineCount() 211 { 212 m_lines = 0; 213 } 214 215 QString toString() const; 216 217 void operator++() 218 { 219 advance(); 220 } 221 const QChar &operator*() const 222 { 223 return *current(); 224 } 225 const QChar *operator->() const 226 { 227 return current(); 228 } 229 230 private: 231 void append(const TokenizerSubstring &); 232 void prepend(const TokenizerSubstring &); 233 234 void advanceSubstring(); current()235 const QChar *current() const 236 { 237 return m_currentChar; 238 } 239 240 QChar m_pushedChar1; 241 QChar m_pushedChar2; 242 TokenizerSubstring m_currentString; 243 const QChar *m_currentChar; 244 QList<TokenizerSubstring> m_substrings; 245 int m_lines; 246 bool m_composite; 247 248 }; 249 250 class TokenizerQueue : public QList<TokenizerString> 251 { 252 253 public: TokenizerQueue()254 TokenizerQueue() {} ~TokenizerQueue()255 ~TokenizerQueue() {} push(const TokenizerString & t)256 void push(const TokenizerString &t) 257 { 258 prepend(t); 259 } pop()260 TokenizerString pop() 261 { 262 if (isEmpty()) { 263 return TokenizerString(); 264 } 265 TokenizerString t(first()); 266 erase(begin()); 267 return t; 268 } top()269 TokenizerString &top() 270 { 271 return first(); 272 } bottom()273 TokenizerString &bottom() 274 { 275 return last(); 276 } 277 }; 278 279 } 280 281 #endif 282 283