File indexing completed on 2024-07-21 12:09:19

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