Reviewed by Dave.
[WebKit-https.git] / WebCore / khtml / misc / stringit.h
1 /*
2     This file is part of the KDE libraries
3
4     Copyright (C) 1999 Lars Knoll (knoll@mpi-hd.mpg.de)
5
6     This library is free software; you can redistribute it and/or
7     modify it under the terms of the GNU Library General Public
8     License as published by the Free Software Foundation; either
9     version 2 of the License, or (at your option) any later version.
10
11     This library is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14     Library General Public License for more details.
15
16     You should have received a copy of the GNU Library General Public License
17     along with this library; see the file COPYING.LIB.  If not, write to
18     the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19     Boston, MA 02111-1307, USA.
20 */
21 //----------------------------------------------------------------------------
22 //
23 // KDE HTML Widget -- String class
24
25 #ifndef KHTMLSTRING_H
26 #define KHTMLSTRING_H
27
28 #include "dom/dom_string.h"
29
30 #include <qstring.h>
31 #include <qvaluelist.h>
32
33 #include <assert.h>
34
35 namespace khtml
36 {
37
38 class TokenizerString;
39
40 class TokenizerSubstring
41 {
42 private:
43     friend class TokenizerString;
44     
45     TokenizerSubstring() : m_length(0), m_current(0) {}
46     TokenizerSubstring(const QString &str) : m_string(str), m_length(str.length()), m_current(m_length == 0 ? 0 : str.unicode()) {}
47     TokenizerSubstring(const QChar *str, int length) : m_length(length), m_current(length == 0 ? 0 : str) {}
48
49     void clear() { m_length = 0; m_current = 0; }
50     
51     void appendTo(QString &str) const {
52         if (m_string.unicode() == m_current) {
53             if (str.isEmpty())
54                 str = m_string;
55             else
56                 str.append(m_string);
57         } else {
58             str.insert(str.length(), m_current, m_length);
59         }
60     }
61
62     QString m_string;
63     int m_length;
64     const QChar *m_current;
65 };
66
67 class TokenizerString
68 {
69 public:
70     TokenizerString() : m_currentChar(0), m_lines(0), m_composite(false) {}
71     TokenizerString(const QChar *str, int length) : m_currentString(str, length), m_currentChar(m_currentString.m_current), m_lines(0), m_composite(false) {}
72     TokenizerString(const QString &str) : m_currentString(str), m_currentChar(m_currentString.m_current), m_lines(0), m_composite(false) {}
73
74     void clear();
75
76     void append(const TokenizerString &);
77     void prepend(const TokenizerString &);
78     
79     void push(QChar c) {
80         if (m_pushedChar1.isNull()) {
81             m_pushedChar1 = c;
82             m_currentChar = m_pushedChar1.isNull() ? m_currentString.m_current : &m_pushedChar1;
83         } else {
84             assert(m_pushedChar2.isNull());
85             m_pushedChar2 = c;
86         }
87     }
88     
89     bool isEmpty() const { return !current(); }
90     uint length() const;
91
92     void advance() {
93         if (!m_pushedChar1.isNull()) {
94             m_pushedChar1 = m_pushedChar2;
95             m_pushedChar2 = 0;
96         } else if (m_currentString.m_current) {
97             m_lines += *m_currentString.m_current++ == '\n';
98             if (--m_currentString.m_length == 0)
99                 advanceSubstring();
100         }
101         m_currentChar = m_pushedChar1.isNull() ? m_currentString.m_current: &m_pushedChar1;
102     }
103     
104     bool escaped() const { return !m_pushedChar1.isNull(); }
105
106     int lineCount() const { return m_lines; }
107     void resetLineCount() { m_lines = 0; }
108     
109     QString toString() const;
110
111     void operator++() { advance(); }
112     const QChar &operator*() const { return *current(); }
113     const QChar *operator->() const { return current(); }
114     
115 private:
116     void append(const TokenizerSubstring &);
117     void prepend(const TokenizerSubstring &);
118
119     void advanceSubstring();
120     const QChar *current() const { return m_currentChar; }
121
122     QChar m_pushedChar1;
123     QChar m_pushedChar2;
124     TokenizerSubstring m_currentString;
125     const QChar *m_currentChar;
126     QValueList<TokenizerSubstring> m_substrings;
127     int m_lines;
128     bool m_composite;
129 };
130
131 }
132
133 #endif