blob: 26d8c1dea6024619a7736d0623d758ae239685e8 [file] [log] [blame]
/*
This file is part of the KDE libraries
Copyright (C) 2004, 2005, 2006 Apple Computer
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#ifndef SegmentedString_h
#define SegmentedString_h
#include "DeprecatedValueList.h"
#include "PlatformString.h"
namespace WebCore {
class SegmentedString;
class SegmentedSubstring {
private:
friend class SegmentedString;
SegmentedSubstring() : m_length(0), m_current(0), m_excludeLineNumbers(false) {}
SegmentedSubstring(const String& str) : m_string(str), m_length(str.length()), m_excludeLineNumbers(false) {
m_current = m_length == 0 ? 0 : m_string.characters();
}
SegmentedSubstring(const UChar* str, int length) : m_length(length), m_current(length == 0 ? 0 : str), m_excludeLineNumbers(false) {}
void clear() { m_length = 0; m_current = 0; }
bool excludeLineNumbers() const { return m_excludeLineNumbers; }
void setExcludeLineNumbers() { m_excludeLineNumbers = true; }
void appendTo(String& str) const {
if (m_string.characters() == m_current) {
if (str.isEmpty())
str = m_string;
else
str.append(m_string);
} else {
str.append(String(m_current, m_length));
}
}
String m_string;
int m_length;
const UChar* m_current;
bool m_excludeLineNumbers;
};
class SegmentedString {
public:
SegmentedString()
: m_pushedChar1(0), m_pushedChar2(0), m_currentChar(0), m_composite(false) {}
SegmentedString(const UChar* str, int length) : m_pushedChar1(0), m_pushedChar2(0)
, m_currentString(str, length), m_currentChar(m_currentString.m_current), m_composite(false) {}
SegmentedString(const String& str)
: m_pushedChar1(0), m_pushedChar2(0), m_currentString(str)
, m_currentChar(m_currentString.m_current), m_composite(false) {}
SegmentedString(const SegmentedString&);
const SegmentedString& operator=(const SegmentedString&);
void clear();
void append(const SegmentedString &);
void prepend(const SegmentedString &);
bool excludeLineNumbers() const { return m_currentString.excludeLineNumbers(); }
void setExcludeLineNumbers();
void push(UChar c) {
if (!m_pushedChar1) {
m_pushedChar1 = c;
m_currentChar = m_pushedChar1 ? &m_pushedChar1 : m_currentString.m_current;
} else {
ASSERT(!m_pushedChar2);
m_pushedChar2 = c;
}
}
bool isEmpty() const { return !current(); }
unsigned length() const;
void advance(int* lineNumber = 0) {
if (m_pushedChar1) {
m_pushedChar1 = m_pushedChar2;
m_pushedChar2 = 0;
} else if (m_currentString.m_current) {
if (*m_currentString.m_current++ == '\n' && lineNumber && !m_currentString.excludeLineNumbers())
*lineNumber = *lineNumber + 1;
if (--m_currentString.m_length == 0)
advanceSubstring();
}
m_currentChar = m_pushedChar1 ? &m_pushedChar1 : m_currentString.m_current;
}
bool escaped() const { return m_pushedChar1; }
String toString() const;
const UChar& operator*() const { return *current(); }
const UChar* operator->() const { return current(); }
private:
void append(const SegmentedSubstring &);
void prepend(const SegmentedSubstring &);
void advanceSubstring();
const UChar* current() const { return m_currentChar; }
UChar m_pushedChar1;
UChar m_pushedChar2;
SegmentedSubstring m_currentString;
const UChar* m_currentChar;
DeprecatedValueList<SegmentedSubstring> m_substrings;
bool m_composite;
};
}
#endif