File indexing completed on 2023-09-24 04:06:36
0001 /* 0002 This file is part of the KDE libraries 0003 0004 Copyright (C) 1999 Lars Knoll (knoll@mpi-hd.mpg.de) 0005 Copyright (C) 2004 Apple Computer, Inc. 0006 0007 This library is free software; you can redistribute it and/or 0008 modify it under the terms of the GNU Library General Public 0009 License as published by the Free Software Foundation; either 0010 version 2 of the License, or (at your option) any later version. 0011 0012 This library is distributed in the hope that it will be useful, 0013 but WITHOUT ANY WARRANTY; without even the implied warranty of 0014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0015 Library General Public License for more details. 0016 0017 You should have received a copy of the GNU Library General Public License 0018 along with this library; see the file COPYING.LIB. If not, write to 0019 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0020 Boston, MA 02110-1301, USA. 0021 */ 0022 //---------------------------------------------------------------------------- 0023 // 0024 // KDE HTML Widget -- String class 0025 0026 #ifndef KHTMLSTRING_H 0027 #define KHTMLSTRING_H 0028 0029 #include "dom/dom_string.h" 0030 0031 #include <QList> 0032 #include <QString> 0033 0034 #include <assert.h> 0035 0036 using namespace DOM; 0037 0038 namespace khtml 0039 { 0040 0041 class DOMStringIt 0042 { 0043 public: 0044 DOMStringIt() 0045 { 0046 s = nullptr, l = 0; 0047 lines = 0; 0048 } 0049 DOMStringIt(QChar *str, uint len) 0050 { 0051 s = str, l = len; 0052 lines = 0; 0053 } 0054 DOMStringIt(const QString &str) 0055 { 0056 s = str.unicode(); 0057 l = str.length(); 0058 lines = 0; 0059 } 0060 0061 DOMStringIt *operator++() 0062 { 0063 if (!pushedChar.isNull()) { 0064 pushedChar = 0; 0065 } else if (l > 0) { 0066 if (*s == QLatin1Char('\n')) { 0067 lines++; 0068 } 0069 s++, l--; 0070 } 0071 return this; 0072 } 0073 public: 0074 void push(const QChar &c) 0075 { 0076 /* assert(pushedChar.isNull());*/ pushedChar = c; 0077 } 0078 0079 const QChar &operator*() const 0080 { 0081 return pushedChar.isNull() ? *s : pushedChar; 0082 } 0083 const QChar *operator->() const 0084 { 0085 return pushedChar.isNull() ? s : &pushedChar; 0086 } 0087 0088 bool escaped() const 0089 { 0090 return !pushedChar.isNull(); 0091 } 0092 uint length() const 0093 { 0094 return l + (!pushedChar.isNull()); 0095 } 0096 0097 const QChar *current() const 0098 { 0099 return pushedChar.isNull() ? s : &pushedChar; 0100 } 0101 int lineCount() const 0102 { 0103 return lines; 0104 } 0105 0106 protected: 0107 QChar pushedChar; 0108 const QChar *s; 0109 int l; 0110 int lines; 0111 }; 0112 0113 class TokenizerString; 0114 0115 class TokenizerSubstring 0116 { 0117 friend class TokenizerString; 0118 public: 0119 TokenizerSubstring() : m_length(0), m_current(nullptr) {} 0120 TokenizerSubstring(const QString &str) : m_string(str), m_length(str.length()), m_current(m_length == 0 ? nullptr : str.unicode()) {} 0121 TokenizerSubstring(const QChar *str, int length) : m_length(length), m_current(length == 0 ? nullptr : str) {} 0122 0123 void clear() 0124 { 0125 m_length = 0; 0126 m_current = nullptr; 0127 } 0128 0129 void appendTo(QString &str) const 0130 { 0131 if (m_string.unicode() == m_current) { 0132 if (str.isEmpty()) { 0133 str = m_string; 0134 } else { 0135 str.append(m_string); 0136 } 0137 } else { 0138 str.insert(str.length(), m_current, m_length); 0139 } 0140 } 0141 private: 0142 QString m_string; 0143 int m_length; 0144 const QChar *m_current; 0145 }; 0146 0147 class TokenizerString 0148 { 0149 0150 public: 0151 TokenizerString() : m_currentChar(nullptr), m_lines(0), m_composite(false) {} 0152 TokenizerString(const QChar *str, int length) : m_currentString(str, length), m_currentChar(m_currentString.m_current), m_lines(0), m_composite(false) {} 0153 TokenizerString(const QString &str) : m_currentString(str), m_currentChar(m_currentString.m_current), m_lines(0), m_composite(false) {} 0154 TokenizerString(const TokenizerString &o) : m_pushedChar1(o.m_pushedChar1), m_pushedChar2(o.m_pushedChar2), 0155 m_currentString(o.m_currentString), m_substrings(o.m_substrings), 0156 m_lines(o.m_lines), m_composite(o.m_composite) 0157 { 0158 m_currentChar = m_pushedChar1.isNull() ? m_currentString.m_current : &m_pushedChar1; 0159 } 0160 0161 void clear(); 0162 0163 void append(const TokenizerString &); 0164 void prepend(const TokenizerString &); 0165 0166 void push(QChar c) 0167 { 0168 if (m_pushedChar1.isNull()) { 0169 m_pushedChar1 = c; 0170 m_currentChar = m_pushedChar1.isNull() ? m_currentString.m_current : &m_pushedChar1; 0171 } else { 0172 assert(m_pushedChar2.isNull()); 0173 m_pushedChar2 = c; 0174 } 0175 } 0176 0177 bool isEmpty() const 0178 { 0179 return !current(); 0180 } 0181 uint length() const; 0182 0183 void advance() 0184 { 0185 if (!m_pushedChar1.isNull()) { 0186 m_pushedChar1 = m_pushedChar2; 0187 m_pushedChar2 = 0; 0188 } else if (m_currentString.m_current) { 0189 m_lines += *m_currentString.m_current++ == QLatin1Char('\n'); 0190 if (--m_currentString.m_length == 0) { 0191 advanceSubstring(); 0192 } 0193 } 0194 m_currentChar = m_pushedChar1.isNull() ? m_currentString.m_current : &m_pushedChar1; 0195 } 0196 uint count() const 0197 { 0198 return m_substrings.count(); 0199 } 0200 0201 bool escaped() const 0202 { 0203 return !m_pushedChar1.isNull(); 0204 } 0205 0206 int lineCount() const 0207 { 0208 return m_lines; 0209 } 0210 void resetLineCount() 0211 { 0212 m_lines = 0; 0213 } 0214 0215 QString toString() const; 0216 0217 void operator++() 0218 { 0219 advance(); 0220 } 0221 const QChar &operator*() const 0222 { 0223 return *current(); 0224 } 0225 const QChar *operator->() const 0226 { 0227 return current(); 0228 } 0229 0230 private: 0231 void append(const TokenizerSubstring &); 0232 void prepend(const TokenizerSubstring &); 0233 0234 void advanceSubstring(); 0235 const QChar *current() const 0236 { 0237 return m_currentChar; 0238 } 0239 0240 QChar m_pushedChar1; 0241 QChar m_pushedChar2; 0242 TokenizerSubstring m_currentString; 0243 const QChar *m_currentChar; 0244 QList<TokenizerSubstring> m_substrings; 0245 int m_lines; 0246 bool m_composite; 0247 0248 }; 0249 0250 class TokenizerQueue : public QList<TokenizerString> 0251 { 0252 0253 public: 0254 TokenizerQueue() {} 0255 ~TokenizerQueue() {} 0256 void push(const TokenizerString &t) 0257 { 0258 prepend(t); 0259 } 0260 TokenizerString pop() 0261 { 0262 if (isEmpty()) { 0263 return TokenizerString(); 0264 } 0265 TokenizerString t(first()); 0266 erase(begin()); 0267 return t; 0268 } 0269 TokenizerString &top() 0270 { 0271 return first(); 0272 } 0273 TokenizerString &bottom() 0274 { 0275 return last(); 0276 } 0277 }; 0278 0279 } 0280 0281 #endif 0282