diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2008-10-21 07:00:00 -0700 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2008-10-21 07:00:00 -0700 |
commit | 9364f22aed35e1a1e9d07c121510f80be3ab0502 (patch) | |
tree | d49911209b132da58d838efa852daf28d516df21 /WebCore/platform/text | |
parent | 87eb0cb35bad8784770ebc807e6c982432e47107 (diff) | |
download | external_webkit-9364f22aed35e1a1e9d07c121510f80be3ab0502.zip external_webkit-9364f22aed35e1a1e9d07c121510f80be3ab0502.tar.gz external_webkit-9364f22aed35e1a1e9d07c121510f80be3ab0502.tar.bz2 |
Initial Contribution
Diffstat (limited to 'WebCore/platform/text')
23 files changed, 517 insertions, 649 deletions
diff --git a/WebCore/platform/text/AtomicString.cpp b/WebCore/platform/text/AtomicString.cpp index f7b3c91..c584e6c 100644 --- a/WebCore/platform/text/AtomicString.cpp +++ b/WebCore/platform/text/AtomicString.cpp @@ -26,6 +26,7 @@ #include "AtomicString.h" +#include "DeprecatedString.h" #include "StaticConstructors.h" #include "StringHash.h" #include <kjs/identifier.h> @@ -73,16 +74,13 @@ bool operator==(const AtomicString& a, const char* b) return CStringTranslator::equal(impl, b); } -PassRefPtr<StringImpl> AtomicString::add(const char* c) +StringImpl* AtomicString::add(const char* c) { if (!c) return 0; if (!*c) return StringImpl::empty(); - pair<HashSet<StringImpl*>::iterator, bool> addResult = stringTable->add<const char*, CStringTranslator>(c); - if (!addResult.second) - return *addResult.first; - return adoptRef(*addResult.first); + return *stringTable->add<const char*, CStringTranslator>(c).first; } struct UCharBuffer { @@ -137,7 +135,7 @@ struct UCharBufferTranslator { } }; -PassRefPtr<StringImpl> AtomicString::add(const UChar* s, int length) +StringImpl* AtomicString::add(const UChar* s, int length) { if (!s) return 0; @@ -145,14 +143,11 @@ PassRefPtr<StringImpl> AtomicString::add(const UChar* s, int length) if (length == 0) return StringImpl::empty(); - UCharBuffer buf = { s, length }; - pair<HashSet<StringImpl*>::iterator, bool> addResult = stringTable->add<UCharBuffer, UCharBufferTranslator>(buf); - if (!addResult.second) - return *addResult.first; - return adoptRef(*addResult.first); + UCharBuffer buf = {s, length}; + return *stringTable->add<UCharBuffer, UCharBufferTranslator>(buf).first; } -PassRefPtr<StringImpl> AtomicString::add(const UChar* s) +StringImpl* AtomicString::add(const UChar* s) { if (!s) return 0; @@ -165,13 +160,10 @@ PassRefPtr<StringImpl> AtomicString::add(const UChar* s) return StringImpl::empty(); UCharBuffer buf = {s, length}; - pair<HashSet<StringImpl*>::iterator, bool> addResult = stringTable->add<UCharBuffer, UCharBufferTranslator>(buf); - if (!addResult.second) - return *addResult.first; - return adoptRef(*addResult.first); + return *stringTable->add<UCharBuffer, UCharBufferTranslator>(buf).first; } -PassRefPtr<StringImpl> AtomicString::add(StringImpl* r) +StringImpl* AtomicString::add(StringImpl* r) { if (!r || r->m_inTable) return r; @@ -190,12 +182,12 @@ void AtomicString::remove(StringImpl* r) stringTable->remove(r); } -PassRefPtr<StringImpl> AtomicString::add(const KJS::Identifier& str) +StringImpl* AtomicString::add(const KJS::Identifier& str) { return add(reinterpret_cast<const UChar*>(str.data()), str.size()); } -PassRefPtr<StringImpl> AtomicString::add(const KJS::UString& str) +StringImpl* AtomicString::add(const KJS::UString& str) { return add(reinterpret_cast<const UChar*>(str.data()), str.size()); } @@ -210,6 +202,16 @@ AtomicString::operator UString() const return m_string; } +AtomicString::AtomicString(const DeprecatedString& s) + : m_string(add(reinterpret_cast<const UChar*>(s.unicode()), s.length())) +{ +} + +DeprecatedString AtomicString::deprecatedString() const +{ + return m_string.deprecatedString(); +} + DEFINE_GLOBAL(AtomicString, nullAtom) DEFINE_GLOBAL(AtomicString, emptyAtom, "") DEFINE_GLOBAL(AtomicString, textAtom, "#text") diff --git a/WebCore/platform/text/AtomicString.h b/WebCore/platform/text/AtomicString.h index 2a2ac97..4a0bb5b 100644 --- a/WebCore/platform/text/AtomicString.h +++ b/WebCore/platform/text/AtomicString.h @@ -43,7 +43,7 @@ public: AtomicString(const String& s) : m_string(add(s.impl())) { } operator const String&() const { return m_string; } - const String& string() const { return m_string; }; + const String& domString() const { return m_string; }; operator KJS::Identifier() const; operator KJS::UString() const; @@ -57,16 +57,16 @@ public: bool contains(UChar c) const { return m_string.contains(c); } bool contains(const AtomicString& s, bool caseSensitive = true) const - { return m_string.contains(s.string(), caseSensitive); } + { return m_string.contains(s.domString(), caseSensitive); } int find(UChar c, int start = 0) const { return m_string.find(c, start); } int find(const AtomicString& s, int start = 0, bool caseSentitive = true) const - { return m_string.find(s.string(), start, caseSentitive); } + { return m_string.find(s.domString(), start, caseSentitive); } bool startsWith(const AtomicString& s, bool caseSensitive = true) const - { return m_string.startsWith(s.string(), caseSensitive); } + { return m_string.startsWith(s.domString(), caseSensitive); } bool endsWith(const AtomicString& s, bool caseSensitive = true) const - { return m_string.endsWith(s.string(), caseSensitive); } + { return m_string.endsWith(s.domString(), caseSensitive); } int toInt(bool* ok = 0) const { return m_string.toInt(ok); } double toDouble(bool* ok = 0) const { return m_string.toDouble(ok); } @@ -93,15 +93,18 @@ public: operator QString() const { return m_string; } #endif + AtomicString(const DeprecatedString&); + DeprecatedString deprecatedString() const; + private: String m_string; - static PassRefPtr<StringImpl> add(const char*); - static PassRefPtr<StringImpl> add(const UChar*, int length); - static PassRefPtr<StringImpl> add(const UChar*); - static PassRefPtr<StringImpl> add(StringImpl*); - static PassRefPtr<StringImpl> add(const KJS::UString&); - static PassRefPtr<StringImpl> add(const KJS::Identifier&); + static StringImpl* add(const char*); + static StringImpl* add(const UChar*, int length); + static StringImpl* add(const UChar*); + static StringImpl* add(StringImpl*); + static StringImpl* add(const KJS::UString&); + static StringImpl* add(const KJS::Identifier&); }; inline bool operator==(const AtomicString& a, const AtomicString& b) { return a.impl() == b.impl(); } diff --git a/WebCore/platform/text/BidiResolver.h b/WebCore/platform/text/BidiResolver.h index 3e545d9..d2515a9 100644 --- a/WebCore/platform/text/BidiResolver.h +++ b/WebCore/platform/text/BidiResolver.h @@ -1,6 +1,6 @@ /* * Copyright (C) 2000 Lars Knoll (knoll@kde.org) - * Copyright (C) 2003, 2004, 2006, 2007, 2008 Apple Inc. All right reserved. + * Copyright (C) 2003, 2004, 2006, 2007 Apple Inc. All right reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -85,8 +85,6 @@ struct BidiCharacterRun { } } - void destroy() { delete this; } - int start() const { return m_start; } int stop() const { return m_stop; } unsigned char level() const { return m_level; } @@ -111,7 +109,6 @@ public : , emptyRun(true) , m_firstRun(0) , m_lastRun(0) - , m_logicallyLastRun(0) , m_runCount(0) { } @@ -137,15 +134,14 @@ public : Run* firstRun() const { return m_firstRun; } Run* lastRun() const { return m_lastRun; } - Run* logicallyLastRun() const { return m_logicallyLastRun; } - unsigned runCount() const { return m_runCount; } + int runCount() const { return m_runCount; } void addRun(Run*); void deleteRuns(); protected: void appendRun(); - void reverseRuns(unsigned start, unsigned end); + void reverseRuns(int start, int end); Iterator current; Iterator sor; @@ -161,28 +157,22 @@ protected: Run* m_firstRun; Run* m_lastRun; - Run* m_logicallyLastRun; - unsigned m_runCount; + int m_runCount; }; template <class Iterator, class Run> -inline void BidiResolver<Iterator, Run>::addRun(Run* run) -{ - if (!m_firstRun) - m_firstRun = run; - else - m_lastRun->m_next = run; - m_lastRun = run; - m_runCount++; -} - -template <class Iterator, class Run> void BidiResolver<Iterator, Run>::appendRun() { if (emptyRun || eor.atEnd()) return; - addRun(new Run(sor.offset(), eor.offset() + 1, context(), m_direction)); + Run* bidiRun = new Run(sor.offset(), eor.offset() + 1, context(), m_direction); + if (!m_firstRun) + m_firstRun = bidiRun; + else + m_lastRun->m_next = bidiRun; + m_lastRun = bidiRun; + m_runCount++; eor.increment(*this); sor = eor; @@ -322,8 +312,8 @@ void BidiResolver<Iterator, Run>::deleteRuns() Run* curr = m_firstRun; while (curr) { - Run* s = curr->next(); - curr->destroy(); + Run* s = curr->m_next; + delete curr; curr = s; } @@ -333,18 +323,18 @@ void BidiResolver<Iterator, Run>::deleteRuns() } template <class Iterator, class Run> -void BidiResolver<Iterator, Run>::reverseRuns(unsigned start, unsigned end) +void BidiResolver<Iterator, Run>::reverseRuns(int start, int end) { if (start >= end) return; - ASSERT(end < m_runCount); + ASSERT(start >= 0 && end < m_runCount); // Get the item before the start of the runs to reverse and put it in // |beforeStart|. |curr| should point to the first run to reverse. Run* curr = m_firstRun; Run* beforeStart = 0; - unsigned i = 0; + int i = 0; while (i < start) { i++; beforeStart = curr; @@ -782,8 +772,6 @@ void BidiResolver<Iterator, Run>::createBidiRunsForLine(const Iterator& start, c } } - m_logicallyLastRun = m_lastRun; - // reorder line according to run structure... // do not reverse for visually ordered web sites if (!visualOrder) { @@ -808,22 +796,22 @@ void BidiResolver<Iterator, Run>::createBidiRunsForLine(const Iterator& start, c if (!(levelLow % 2)) levelLow++; - unsigned count = runCount() - 1; + int count = runCount() - 1; while (levelHigh >= levelLow) { - unsigned i = 0; + int i = 0; Run* currRun = firstRun(); while (i < count) { while (i < count && currRun && currRun->m_level < levelHigh) { i++; currRun = currRun->next(); } - unsigned start = i; + int start = i; while (i <= count && currRun && currRun->m_level >= levelHigh) { i++; currRun = currRun->next(); } - unsigned end = i - 1; + int end = i-1; reverseRuns(start, end); } levelHigh--; diff --git a/WebCore/platform/text/CString.cpp b/WebCore/platform/text/CString.cpp index f1434ad..4300b29 100644 --- a/WebCore/platform/text/CString.cpp +++ b/WebCore/platform/text/CString.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003, 2006, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2003, 2006 Apple Computer, Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -26,8 +26,7 @@ #include "config.h" #include "CString.h" - -using std::min; +#include "DeprecatedCString.h" namespace WebCore { @@ -41,12 +40,17 @@ CString::CString(const char* str, unsigned length) init(str, length); } +CString::CString(const DeprecatedCString& str) +{ + init(str.data(), str.length()); +} + void CString::init(const char* str, unsigned length) { if (!str) return; - m_buffer = CStringBuffer::create(length + 1); + m_buffer = new CStringBuffer(length + 1); memcpy(m_buffer->data(), str, length); m_buffer->data()[length] = '\0'; } @@ -68,11 +72,16 @@ unsigned CString::length() const { return m_buffer ? m_buffer->length() - 1 : 0; } + +DeprecatedCString CString::deprecatedCString() const +{ + return DeprecatedCString(data(), length() + 1); +} CString CString::newUninitialized(size_t length, char*& characterBuffer) { CString result; - result.m_buffer = CStringBuffer::create(length + 1); + result.m_buffer = new CStringBuffer(length + 1); char* bytes = result.m_buffer->data(); bytes[length] = '\0'; characterBuffer = bytes; @@ -86,7 +95,7 @@ void CString::copyBufferIfNeeded() int len = m_buffer->length(); RefPtr<CStringBuffer> m_temp = m_buffer; - m_buffer = CStringBuffer::create(len); + m_buffer = new CStringBuffer(len); memcpy(m_buffer->data(), m_temp->data(), len); } diff --git a/WebCore/platform/text/CString.h b/WebCore/platform/text/CString.h index fcb4c8c..bd1e06c 100644 --- a/WebCore/platform/text/CString.h +++ b/WebCore/platform/text/CString.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003, 2006, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2003, 2006 Apple Computer, Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -26,22 +26,23 @@ #ifndef CString_h #define CString_h -#include <wtf/PassRefPtr.h> #include <wtf/RefCounted.h> #include <wtf/Vector.h> +using std::min; + namespace WebCore { + class DeprecatedCString; + class CStringBuffer : public RefCounted<CStringBuffer> { public: - static PassRefPtr<CStringBuffer> create(unsigned length) { return adoptRef(new CStringBuffer(length)); } + CStringBuffer(unsigned length) : m_vector(length) { } char* data() { return m_vector.data(); } - size_t length() const { return m_vector.size(); } + unsigned length() const { return m_vector.size(); } private: - CStringBuffer(unsigned length) : m_vector(length) { } - Vector<char> m_vector; }; @@ -60,6 +61,9 @@ namespace WebCore { bool isNull() const { return !m_buffer; } + CString(const DeprecatedCString&); + DeprecatedCString deprecatedCString() const; + private: void copyBufferIfNeeded(); void init(const char*, unsigned length); @@ -69,6 +73,6 @@ namespace WebCore { bool operator==(const CString& a, const CString& b); inline bool operator!=(const CString& a, const CString& b) { return !(a == b); } -} // namespace WebCore +} #endif // CString_h diff --git a/WebCore/platform/text/CharacterNames.h b/WebCore/platform/text/CharacterNames.h index bfbb5b0..5b52479 100644 --- a/WebCore/platform/text/CharacterNames.h +++ b/WebCore/platform/text/CharacterNames.h @@ -39,8 +39,6 @@ namespace WebCore { const UChar bullet = 0x2022; const UChar horizontalEllipsis = 0x2026; const UChar ideographicSpace = 0x3000; - const UChar ideographicComma = 0x3001; - const UChar ideographicFullStop = 0x3002; const UChar leftToRightMark = 0x200E; const UChar leftToRightEmbed = 0x202A; const UChar leftToRightOverride = 0x202D; diff --git a/WebCore/platform/text/PlatformString.h b/WebCore/platform/text/PlatformString.h index 9399fdd..f900513 100644 --- a/WebCore/platform/text/PlatformString.h +++ b/WebCore/platform/text/PlatformString.h @@ -43,6 +43,7 @@ class wxString; namespace WebCore { class CString; +class DeprecatedString; struct StringHash; class String { @@ -131,25 +132,17 @@ public: static String format(const char *, ...) WTF_ATTRIBUTE_PRINTF(1, 2); - void split(const String& separator, Vector<String>& result) const; - void split(const String& separator, bool allowEmptyEntries, Vector<String>& result) const; - void split(UChar separator, Vector<String>& result) const; - void split(UChar separator, bool allowEmptyEntries, Vector<String>& result) const; - - int toIntStrict(bool* ok = 0, int base = 10) const; - unsigned toUIntStrict(bool* ok = 0, int base = 10) const; - int64_t toInt64Strict(bool* ok = 0, int base = 10) const; - uint64_t toUInt64Strict(bool* ok = 0, int base = 10) const; + Vector<String> split(const String& separator, bool allowEmptyEntries = false) const; + Vector<String> split(UChar separator, bool allowEmptyEntries = false) const; int toInt(bool* ok = 0) const; - unsigned toUInt(bool* ok = 0) const; int64_t toInt64(bool* ok = 0) const; uint64_t toUInt64(bool* ok = 0) const; double toDouble(bool* ok = 0) const; float toFloat(bool* ok = 0) const; Length* toLengthArray(int& len) const; Length* toCoordsArray(int& len) const; - bool percentage(int& percentage) const; + bool percentage(int &_percentage) const; // Makes a deep copy. Helpful only if you need to use a String on another thread. // Since the underlying StringImpl objects are immutable, there's no other reason @@ -203,7 +196,10 @@ public: // Determines the writing direction using the Unicode Bidi Algorithm rules P2 and P3. WTF::Unicode::Direction defaultWritingDirection() const { return m_impl ? m_impl->defaultWritingDirection() : WTF::Unicode::LeftToRight; } - + + String(const DeprecatedString&); + DeprecatedString deprecatedString() const; + private: RefPtr<StringImpl> m_impl; }; @@ -226,30 +222,12 @@ inline bool equalIgnoringCase(const String& a, const String& b) { return equalIg inline bool equalIgnoringCase(const String& a, const char* b) { return equalIgnoringCase(a.impl(), b); } inline bool equalIgnoringCase(const char* a, const String& b) { return equalIgnoringCase(a, b.impl()); } -inline bool operator!(const String& str) { return str.isNull(); } - - -// String Operations - -bool charactersAreAllASCII(const UChar*, size_t); - -int charactersToIntStrict(const UChar*, size_t, bool* ok = 0, int base = 10); -unsigned charactersToUIntStrict(const UChar*, size_t, bool* ok = 0, int base = 10); -int64_t charactersToInt64Strict(const UChar*, size_t, bool* ok = 0, int base = 10); -uint64_t charactersToUInt64Strict(const UChar*, size_t, bool* ok = 0, int base = 10); - -int charactersToInt(const UChar*, size_t, bool* ok = 0); // ignores trailing garbage -unsigned charactersToUInt(const UChar*, size_t, bool* ok = 0); // ignores trailing garbage -int64_t charactersToInt64(const UChar*, size_t, bool* ok = 0); // ignores trailing garbage -uint64_t charactersToUInt64(const UChar*, size_t, bool* ok = 0); // ignores trailing garbage +bool operator==(const String& a, const DeprecatedString& b); +inline bool operator==(const DeprecatedString& b, const String& a) { return a == b; } +inline bool operator!=(const String& a, const DeprecatedString& b) { return !(a == b); } +inline bool operator!=(const DeprecatedString& b, const String& a ) { return !(a == b); } -double charactersToDouble(const UChar*, size_t, bool* ok = 0); -float charactersToFloat(const UChar*, size_t, bool* ok = 0); - -int find(const UChar*, size_t, UChar, int startPosition = 0); -int reverseFind(const UChar*, size_t, UChar, int startPosition = -1); - -void append(Vector<UChar>&, const String&); +inline bool operator!(const String& str) { return str.isNull(); } #ifdef __OBJC__ // This is for situations in WebKit where the long standing behavior has been @@ -258,49 +236,8 @@ void append(Vector<UChar>&, const String&); inline NSString* nsStringNilIfEmpty(const String& str) { return str.isEmpty() ? nil : (NSString*)str; } #endif -inline bool charactersAreAllASCII(const UChar* characters, size_t length) -{ - UChar ored = 0; - for (size_t i = 0; i < length; ++i) - ored |= characters[i]; - return !(ored & 0xFF80); -} - -inline int find(const UChar* characters, size_t length, UChar character, int startPosition) -{ - if (startPosition >= static_cast<int>(length)) - return -1; - for (size_t i = startPosition; i < length; ++i) { - if (characters[i] == character) - return static_cast<int>(i); - } - return -1; } -inline int reverseFind(const UChar* characters, size_t length, UChar character, int startPosition) -{ - if (startPosition >= static_cast<int>(length) || !length) - return -1; - if (startPosition < 0) - startPosition += static_cast<int>(length); - while (true) { - if (characters[startPosition] == character) - return startPosition; - if (!startPosition) - return -1; - startPosition--; - } - ASSERT_NOT_REACHED(); - return -1; -} - -inline void append(Vector<UChar>& vector, const String& string) -{ - vector.append(string.characters(), string.length()); -} - -} // namespace WebCore - namespace WTF { // StringHash is the default hash for String diff --git a/WebCore/platform/text/RegularExpression.cpp b/WebCore/platform/text/RegularExpression.cpp index 4213d75..0c26d33 100644 --- a/WebCore/platform/text/RegularExpression.cpp +++ b/WebCore/platform/text/RegularExpression.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2004 Apple Computer, Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -26,7 +26,6 @@ #include "config.h" #include "RegularExpression.h" -#include "PlatformString.h" #include "Logging.h" #include <wtf/RefCounted.h> #include <pcre/pcre.h> @@ -37,44 +36,73 @@ namespace WebCore { const size_t maxSubstrings = 10; const size_t maxOffsets = 3 * maxSubstrings; -class RegularExpression::Private : public RefCounted<Private> { +class RegularExpression::Private : public RefCounted<RegularExpression::Private> +{ public: Private(); - Private(const String& pattern, bool caseSensitive); + Private(DeprecatedString pattern, bool caseSensitive, bool glob); ~Private(); - void compile(bool caseSensitive); + void compile(bool caseSensitive, bool glob); - String pattern; + DeprecatedString pattern; JSRegExp* regex; - String lastMatchString; + DeprecatedString lastMatchString; int lastMatchOffsets[maxOffsets]; int lastMatchCount; int lastMatchPos; int lastMatchLength; }; -RegularExpression::Private::Private() - : RefCounted<Private>(0) - , pattern("") +RegularExpression::Private::Private() : pattern("") { - compile(true); + compile(true, false); } -RegularExpression::Private::Private(const String& p, bool caseSensitive) - : RefCounted<Private>(0) - , pattern(p) - , lastMatchPos(-1) - , lastMatchLength(-1) +RegularExpression::Private::Private(DeprecatedString p, bool caseSensitive, bool glob) : pattern(p), lastMatchPos(-1), lastMatchLength(-1) { - compile(caseSensitive); + compile(caseSensitive, glob); +} + +static DeprecatedString RegExpFromGlob(DeprecatedString glob) +{ + DeprecatedString result = glob; + + // escape regexp metacharacters which are NOT glob metacharacters + + result.replace(RegularExpression("\\\\"), "\\\\"); + result.replace(RegularExpression("\\."), "\\."); + result.replace(RegularExpression("\\+"), "\\+"); + result.replace(RegularExpression("\\$"), "\\$"); + // FIXME: incorrect for ^ inside bracket group + result.replace(RegularExpression("\\^"), "\\^"); + + // translate glob metacharacters into regexp metacharacters + result.replace(RegularExpression("\\*"), ".*"); + result.replace(RegularExpression("\\?"), "."); + + // Require the glob to match the whole string + result = "^" + result + "$"; + + return result; } -void RegularExpression::Private::compile(bool caseSensitive) +void RegularExpression::Private::compile(bool caseSensitive, bool glob) { + DeprecatedString p; + + if (glob) { + p = RegExpFromGlob(pattern); + } else { + p = pattern; + } + // Note we don't honor the Qt syntax for various character classes. If we convert + // to a different underlying engine, we may need to change client code that relies + // on the regex syntax (see FrameMac.mm for a couple examples). + const char* errorMessage; - regex = jsRegExpCompile(pattern.characters(), pattern.length(), + regex = jsRegExpCompile(reinterpret_cast<const UChar*>(p.unicode()), p.length(), caseSensitive ? JSRegExpDoNotIgnoreCase : JSRegExpIgnoreCase, JSRegExpSingleLine, 0, &errorMessage); if (!regex) @@ -87,24 +115,20 @@ RegularExpression::Private::~Private() } -RegularExpression::RegularExpression() - : d(new Private) +RegularExpression::RegularExpression() : d(new RegularExpression::Private()) { } -RegularExpression::RegularExpression(const String& pattern, bool caseSensitive) - : d(new Private(pattern, caseSensitive)) +RegularExpression::RegularExpression(const DeprecatedString &pattern, bool caseSensitive, bool glob) : d(new RegularExpression::Private(pattern, caseSensitive, glob)) { } -RegularExpression::RegularExpression(const char* pattern) - : d(new Private(pattern, true)) +RegularExpression::RegularExpression(const char *cpattern) : d(new RegularExpression::Private(cpattern, true, false)) { } -RegularExpression::RegularExpression(const RegularExpression& re) - : d(re.d) +RegularExpression::RegularExpression(const RegularExpression &re) : d (re.d) { } @@ -112,51 +136,57 @@ RegularExpression::~RegularExpression() { } -RegularExpression& RegularExpression::operator=(const RegularExpression& re) +RegularExpression &RegularExpression::operator=(const RegularExpression &re) { RegularExpression tmp(re); - tmp.d.swap(d); + RefPtr<RegularExpression::Private> tmpD = tmp.d; + + tmp.d = d; + d = tmpD; + return *this; } -String RegularExpression::pattern() const +DeprecatedString RegularExpression::pattern() const { return d->pattern; } -int RegularExpression::match(const String& str, int startFrom, int* matchLength) const +int RegularExpression::match(const DeprecatedString &str, int startFrom, int *matchLength) const { d->lastMatchString = str; // First 2 offsets are start and end offsets; 3rd entry is used internally by pcre - d->lastMatchCount = jsRegExpExecute(d->regex, d->lastMatchString.characters(), - d->lastMatchString.length(), startFrom, d->lastMatchOffsets, maxOffsets); + d->lastMatchCount = jsRegExpExecute(d->regex, reinterpret_cast<const UChar*>(d->lastMatchString.unicode()), d->lastMatchString.length(), startFrom, d->lastMatchOffsets, maxOffsets); if (d->lastMatchCount < 0) { if (d->lastMatchCount != JSRegExpErrorNoMatch) LOG_ERROR("RegularExpression: pcre_exec() failed with result %d", d->lastMatchCount); d->lastMatchPos = -1; d->lastMatchLength = -1; - d->lastMatchString = String(); + d->lastMatchString = DeprecatedString(); return -1; } // 1 means 1 match; 0 means more than one match. First match is recorded in offsets. + //ASSERT(d->lastMatchCount < 2); d->lastMatchPos = d->lastMatchOffsets[0]; d->lastMatchLength = d->lastMatchOffsets[1] - d->lastMatchOffsets[0]; - if (matchLength) + if (matchLength != NULL) { *matchLength = d->lastMatchLength; + } return d->lastMatchPos; } -int RegularExpression::search(const String& str, int startFrom) const +int RegularExpression::search(const DeprecatedString &str, int startFrom) const { - if (startFrom < 0) + if (startFrom < 0) { startFrom = str.length() - startFrom; - return match(str, startFrom, 0); + } + return match(str, startFrom, NULL); } -int RegularExpression::searchRev(const String& str) const +int RegularExpression::searchRev(const DeprecatedString &str) const { - // FIXME: Total hack for now. Search forward, return the last, greedy match + // FIXME: Total hack for now. Search forward, return the last, greedy match int start = 0; int pos; int lastPos = -1; @@ -165,7 +195,7 @@ int RegularExpression::searchRev(const String& str) const int matchLength; pos = match(str, start, &matchLength); if (pos >= 0) { - if (pos + matchLength > lastPos + lastMatchLength) { + if ((pos+matchLength) > (lastPos+lastMatchLength)) { // replace last match if this one is later and not a subset of the last match lastPos = pos; lastMatchLength = matchLength; @@ -189,19 +219,4 @@ int RegularExpression::matchedLength() const return d->lastMatchLength; } -void replace(String& string, const RegularExpression& target, const String& replacement) -{ - int index = 0; - while (index < static_cast<int>(string.length())) { - int matchLength; - index = target.match(string, index, &matchLength); - if (index < 0) - break; - string.replace(index, matchLength, replacement); - index += replacement.length(); - if (!matchLength) - break; // Avoid infinite loop on 0-length matches, e.g. [a-z]* - } } - -} // namespace WebCore diff --git a/WebCore/platform/text/RegularExpression.h b/WebCore/platform/text/RegularExpression.h index 5d1991e..ec1cdef 100644 --- a/WebCore/platform/text/RegularExpression.h +++ b/WebCore/platform/text/RegularExpression.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2003 Apple Computer, Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -26,38 +26,34 @@ #ifndef RegularExpression_h #define RegularExpression_h -#include <wtf/RefPtr.h> +#include "DeprecatedString.h" namespace WebCore { -class String; - class RegularExpression { public: RegularExpression(); - RegularExpression(const String&, bool caseSensitive = false); - RegularExpression(const char*); + RegularExpression(const DeprecatedString &, bool caseSensitive = false, bool glob = false); + RegularExpression(const char *); ~RegularExpression(); - RegularExpression(const RegularExpression&); - RegularExpression& operator=(const RegularExpression&); + RegularExpression(const RegularExpression &); + RegularExpression &operator=(const RegularExpression &); - String pattern() const; - int match(const String&, int startFrom = 0, int* matchLength = 0) const; + DeprecatedString pattern() const; + int match(const DeprecatedString &, int startFrom = 0, int *matchLength = 0) const; - int search(const String&, int startFrom = 0) const; - int searchRev(const String&) const; + int search(const DeprecatedString &, int startFrom = 0) const; + int searchRev(const DeprecatedString &) const; int pos(int n = 0); int matchedLength() const; - + private: class Private; RefPtr<Private> d; }; -void replace(String&, const RegularExpression&, const String&); - -} // namespace WebCore +} -#endif // RegularExpression_h +#endif diff --git a/WebCore/platform/text/SegmentedString.cpp b/WebCore/platform/text/SegmentedString.cpp index 9f5eb26..0b3c7e9 100644 --- a/WebCore/platform/text/SegmentedString.cpp +++ b/WebCore/platform/text/SegmentedString.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. + Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -59,10 +59,10 @@ unsigned SegmentedString::length() const ++length; } if (m_composite) { - Deque<SegmentedSubstring>::const_iterator it = m_substrings.begin(); - Deque<SegmentedSubstring>::const_iterator e = m_substrings.end(); - for (; it != e; ++it) - length += it->m_length; + DeprecatedValueListConstIterator<SegmentedSubstring> i = m_substrings.begin(); + DeprecatedValueListConstIterator<SegmentedSubstring> e = m_substrings.end(); + for (; i != e; ++i) + length += (*i).m_length; } return length; } @@ -70,10 +70,10 @@ unsigned SegmentedString::length() const void SegmentedString::setExcludeLineNumbers() { if (m_composite) { - Deque<SegmentedSubstring>::iterator it = m_substrings.begin(); - Deque<SegmentedSubstring>::iterator e = m_substrings.end(); - for (; it != e; ++it) - it->setExcludeLineNumbers(); + DeprecatedValueListIterator<SegmentedSubstring> i = m_substrings.begin(); + DeprecatedValueListIterator<SegmentedSubstring> e = m_substrings.end(); + for (; i != e; ++i) + (*i).setExcludeLineNumbers(); } else m_currentString.setExcludeLineNumbers(); } @@ -120,10 +120,10 @@ void SegmentedString::append(const SegmentedString &s) ASSERT(!s.escaped()); append(s.m_currentString); if (s.m_composite) { - Deque<SegmentedSubstring>::const_iterator it = s.m_substrings.begin(); - Deque<SegmentedSubstring>::const_iterator e = s.m_substrings.end(); - for (; it != e; ++it) - append(*it); + DeprecatedValueListConstIterator<SegmentedSubstring> i = s.m_substrings.begin(); + DeprecatedValueListConstIterator<SegmentedSubstring> e = s.m_substrings.end(); + for (; i != e; ++i) + append(*i); } m_currentChar = m_pushedChar1 ? &m_pushedChar1 : m_currentString.m_current; } @@ -133,10 +133,10 @@ void SegmentedString::prepend(const SegmentedString &s) ASSERT(!escaped()); ASSERT(!s.escaped()); if (s.m_composite) { - Deque<SegmentedSubstring>::const_reverse_iterator it = s.m_substrings.rbegin(); - Deque<SegmentedSubstring>::const_reverse_iterator e = s.m_substrings.rend(); - for (; it != e; ++it) - prepend(*it); + DeprecatedValueListConstIterator<SegmentedSubstring> i = s.m_substrings.fromLast(); + DeprecatedValueListConstIterator<SegmentedSubstring> e = s.m_substrings.end(); + for (; i != e; --i) + prepend(*i); } prepend(s.m_currentString); m_currentChar = m_pushedChar1 ? &m_pushedChar1 : m_currentString.m_current; @@ -146,7 +146,7 @@ void SegmentedString::advanceSubstring() { if (m_composite) { m_currentString = m_substrings.first(); - m_substrings.removeFirst(); + m_substrings.remove(m_substrings.begin()); if (m_substrings.isEmpty()) m_composite = false; } else { @@ -164,10 +164,10 @@ String SegmentedString::toString() const } m_currentString.appendTo(result); if (m_composite) { - Deque<SegmentedSubstring>::const_iterator it = m_substrings.begin(); - Deque<SegmentedSubstring>::const_iterator e = m_substrings.end(); - for (; it != e; ++it) - it->appendTo(result); + DeprecatedValueListConstIterator<SegmentedSubstring> i = m_substrings.begin(); + DeprecatedValueListConstIterator<SegmentedSubstring> e = m_substrings.end(); + for (; i != e; ++i) + (*i).appendTo(result); } return result; } diff --git a/WebCore/platform/text/SegmentedString.h b/WebCore/platform/text/SegmentedString.h index 79ed1f0..52178d3 100644 --- a/WebCore/platform/text/SegmentedString.h +++ b/WebCore/platform/text/SegmentedString.h @@ -20,22 +20,20 @@ #ifndef SegmentedString_h #define SegmentedString_h +#include "DeprecatedValueList.h" #include "PlatformString.h" -#include <wtf/Deque.h> namespace WebCore { class SegmentedString; class SegmentedSubstring { -public: +private: + friend class SegmentedString; + SegmentedSubstring() : m_length(0), m_current(0), m_doNotExcludeLineNumbers(true) {} - SegmentedSubstring(const String& str) - : m_length(str.length()) - , m_current(str.isEmpty() ? 0 : str.characters()) - , m_string(str) - , m_doNotExcludeLineNumbers(true) - { + SegmentedSubstring(const String& str) : m_string(str), m_length(str.length()), m_doNotExcludeLineNumbers(true) { + 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_doNotExcludeLineNumbers(true) {} @@ -47,8 +45,7 @@ public: void setExcludeLineNumbers() { m_doNotExcludeLineNumbers = false; } - void appendTo(String& str) const - { + void appendTo(String& str) const { if (m_string.characters() == m_current) { if (str.isEmpty()) str = m_string; @@ -59,12 +56,9 @@ public: } } -public: + String m_string; int m_length; const UChar* m_current; - -private: - String m_string; bool m_doNotExcludeLineNumbers; }; @@ -83,8 +77,8 @@ public: void clear(); - void append(const SegmentedString&); - void prepend(const SegmentedString&); + void append(const SegmentedString &); + void prepend(const SegmentedString &); bool excludeLineNumbers() const { return m_currentString.excludeLineNumbers(); } void setExcludeLineNumbers(); @@ -155,8 +149,8 @@ public: const UChar* operator->() const { return current(); } private: - void append(const SegmentedSubstring&); - void prepend(const SegmentedSubstring&); + void append(const SegmentedSubstring &); + void prepend(const SegmentedSubstring &); void advanceSlowCase(); void advanceSlowCase(int& lineNumber); @@ -167,7 +161,7 @@ private: UChar m_pushedChar2; SegmentedSubstring m_currentString; const UChar* m_currentChar; - Deque<SegmentedSubstring> m_substrings; + DeprecatedValueList<SegmentedSubstring> m_substrings; bool m_composite; }; diff --git a/WebCore/platform/text/String.cpp b/WebCore/platform/text/String.cpp index ee4cef4..967e7c8 100644 --- a/WebCore/platform/text/String.cpp +++ b/WebCore/platform/text/String.cpp @@ -22,23 +22,17 @@ #include "PlatformString.h" #include "CString.h" -#include "FloatConversion.h" +#include "DeprecatedString.h" #include "StringBuffer.h" #include "TextEncoding.h" -#include <kjs/dtoa.h> #include <kjs/identifier.h> -#include <limits> -#include <stdarg.h> -#include <wtf/ASCIICType.h> #include <wtf/StringExtras.h> #include <wtf/Vector.h> -#include <wtf/unicode/Unicode.h> +#include <stdarg.h> using KJS::Identifier; using KJS::UString; -using namespace WTF; - namespace WebCore { String::String(const UChar* str, unsigned len) @@ -60,6 +54,13 @@ String::String(const UChar* str) m_impl = StringImpl::create(str, len); } +String::String(const DeprecatedString& str) +{ + if (str.isNull()) + return; + m_impl = StringImpl::create(reinterpret_cast<const UChar*>(str.unicode()), str.length()); +} + String::String(const char* str) { if (!str) @@ -288,7 +289,7 @@ bool String::percentage(int& result) const if ((*m_impl)[m_impl->length() - 1] != '%') return false; - result = charactersToIntStrict(m_impl->characters(), m_impl->length() - 1); + result = DeprecatedConstString(reinterpret_cast<const DeprecatedChar*>(m_impl->characters()), m_impl->length() - 1).string().toInt(); return true; } @@ -309,6 +310,15 @@ const UChar* String::charactersWithNullTermination() return m_impl->characters(); } +DeprecatedString String::deprecatedString() const +{ + if (!m_impl) + return DeprecatedString::null; + if (!m_impl->characters()) + return DeprecatedString("", 0); + return DeprecatedString(reinterpret_cast<const DeprecatedChar*>(m_impl->characters()), m_impl->length()); +} + String String::format(const char *format, ...) { va_list args; @@ -390,46 +400,6 @@ String String::number(double n) return String::format("%.6lg", n); } -int String::toIntStrict(bool* ok, int base) const -{ - if (!m_impl) { - if (ok) - *ok = false; - return 0; - } - return m_impl->toIntStrict(ok, base); -} - -unsigned String::toUIntStrict(bool* ok, int base) const -{ - if (!m_impl) { - if (ok) - *ok = false; - return 0; - } - return m_impl->toUIntStrict(ok, base); -} - -int64_t String::toInt64Strict(bool* ok, int base) const -{ - if (!m_impl) { - if (ok) - *ok = false; - return 0; - } - return m_impl->toInt64Strict(ok, base); -} - -uint64_t String::toUInt64Strict(bool* ok, int base) const -{ - if (!m_impl) { - if (ok) - *ok = false; - return 0; - } - return m_impl->toUInt64Strict(ok, base); -} - int String::toInt(bool* ok) const { if (!m_impl) { @@ -440,16 +410,6 @@ int String::toInt(bool* ok) const return m_impl->toInt(ok); } -unsigned String::toUInt(bool* ok) const -{ - if (!m_impl) { - if (ok) - *ok = false; - return 0; - } - return m_impl->toUInt(ok); -} - int64_t String::toInt64(bool* ok) const { if (!m_impl) { @@ -475,7 +435,7 @@ double String::toDouble(bool* ok) const if (!m_impl) { if (ok) *ok = false; - return 0.0; + return 0; } return m_impl->toDouble(ok); } @@ -512,10 +472,10 @@ Length* String::toLengthArray(int& len) const return m_impl ? m_impl->toLengthArray(len) : 0; } -void String::split(const String& separator, bool allowEmptyEntries, Vector<String>& result) const +Vector<String> String::split(const String& separator, bool allowEmptyEntries) const { - result.clear(); - + Vector<String> result; + int startPos = 0; int endPos; while ((endPos = find(separator, startPos)) != -1) { @@ -523,33 +483,17 @@ void String::split(const String& separator, bool allowEmptyEntries, Vector<Strin result.append(substring(startPos, endPos - startPos)); startPos = endPos + separator.length(); } - if (allowEmptyEntries || startPos != static_cast<int>(length())) - result.append(substring(startPos)); -} - -void String::split(const String& separator, Vector<String>& result) const -{ - return split(separator, false, result); -} - -void String::split(UChar separator, bool allowEmptyEntries, Vector<String>& result) const -{ - result.clear(); - - int startPos = 0; - int endPos; - while ((endPos = find(separator, startPos)) != -1) { - if (allowEmptyEntries || startPos != endPos) - result.append(substring(startPos, endPos - startPos)); - startPos = endPos + 1; - } - if (allowEmptyEntries || startPos != static_cast<int>(length())) + if (allowEmptyEntries || startPos != (int)length()) result.append(substring(startPos)); + + return result; } -void String::split(UChar separator, Vector<String>& result) const +Vector<String> String::split(UChar separator, bool allowEmptyEntries) const { - return split(String(&separator, 1), false, result); + Vector<String> result; + + return split(String(&separator, 1), allowEmptyEntries); } #ifndef NDEBUG @@ -588,6 +532,17 @@ String String::fromUTF8(const char* string) return UTF8Encoding().decode(string, strlen(string)); } + +bool operator==(const String& a, const DeprecatedString& b) +{ + unsigned l = a.length(); + if (l != b.length()) + return false; + if (!memcmp(a.characters(), b.unicode(), l * sizeof(UChar))) + return true; + return false; +} + String::String(const Identifier& str) { if (str.isNull()) @@ -616,178 +571,6 @@ String::operator UString() const return UString(reinterpret_cast<const KJS::UChar*>(m_impl->characters()), m_impl->length()); } -// String Operations - -static bool isCharacterAllowedInBase(UChar c, int base) -{ - if (c > 0x7F) - return false; - if (isASCIIDigit(c)) - return c - '0' < base; - if (isASCIIAlpha(c)) { - if (base > 36) - base = 36; - return (c >= 'a' && c < 'a' + base - 10) - || (c >= 'A' && c < 'A' + base - 10); - } - return false; -} - -template <typename IntegralType> -static inline IntegralType toIntegralType(const UChar* data, size_t length, bool* ok, int base) -{ - static const IntegralType integralMax = std::numeric_limits<IntegralType>::max(); - static const bool isSigned = std::numeric_limits<IntegralType>::is_signed; - const IntegralType maxMultiplier = integralMax / base; - - IntegralType value = 0; - bool isOk = false; - bool isNegative = false; - - if (!data) - goto bye; - - // skip leading whitespace - while (length && isSpaceOrNewline(*data)) { - length--; - data++; - } - - if (isSigned && length && *data == '-') { - length--; - data++; - isNegative = true; - } else if (length && *data == '+') { - length--; - data++; - } - - if (!length || !isCharacterAllowedInBase(*data, base)) - goto bye; - - while (length && isCharacterAllowedInBase(*data, base)) { - length--; - IntegralType digitValue; - UChar c = *data; - if (isASCIIDigit(c)) - digitValue = c - '0'; - else if (c >= 'a') - digitValue = c - 'a' + 10; - else - digitValue = c - 'A' + 10; - - if (value > maxMultiplier || (value == maxMultiplier && digitValue > (integralMax % base) + isNegative)) - goto bye; - - value = base * value + digitValue; - data++; - } - - if (isNegative) - value = -value; - - // skip trailing space - while (length && isSpaceOrNewline(*data)) { - length--; - data++; - } - - if (!length) - isOk = true; -bye: - if (ok) - *ok = isOk; - return isOk ? value : 0; -} - -static unsigned lengthOfCharactersAsInteger(const UChar* data, size_t length) -{ - size_t i = 0; - - // Allow leading spaces. - for (; i != length; ++i) { - if (!isSpaceOrNewline(data[i])) - break; - } - - // Allow sign. - if (i != length && (data[i] == '+' || data[i] == '-')) - ++i; - - // Allow digits. - for (; i != length; ++i) { - if (!Unicode::isDigit(data[i])) - break; - } - - return i; -} - -int charactersToIntStrict(const UChar* data, size_t length, bool* ok, int base) -{ - return toIntegralType<int>(data, length, ok, base); -} - -unsigned charactersToUIntStrict(const UChar* data, size_t length, bool* ok, int base) -{ - return toIntegralType<unsigned>(data, length, ok, base); -} - -int64_t charactersToInt64Strict(const UChar* data, size_t length, bool* ok, int base) -{ - return toIntegralType<int64_t>(data, length, ok, base); -} - -uint64_t charactersToUInt64Strict(const UChar* data, size_t length, bool* ok, int base) -{ - return toIntegralType<uint64_t>(data, length, ok, base); -} - -int charactersToInt(const UChar* data, size_t length, bool* ok) -{ - return toIntegralType<int>(data, lengthOfCharactersAsInteger(data, length), ok, 10); -} - -unsigned charactersToUInt(const UChar* data, size_t length, bool* ok) -{ - return toIntegralType<unsigned>(data, lengthOfCharactersAsInteger(data, length), ok, 10); -} - -int64_t charactersToInt64(const UChar* data, size_t length, bool* ok) -{ - return toIntegralType<int64_t>(data, lengthOfCharactersAsInteger(data, length), ok, 10); -} - -uint64_t charactersToUInt64(const UChar* data, size_t length, bool* ok) -{ - return toIntegralType<uint64_t>(data, lengthOfCharactersAsInteger(data, length), ok, 10); -} - -double charactersToDouble(const UChar* data, size_t length, bool* ok) -{ - if (!length) { - if (ok) - *ok = false; - return 0.0; - } - - Vector<char, 256> bytes(length + 1); - for (unsigned i = 0; i < length; ++i) - bytes[i] = data[i] < 0x7F ? data[i] : '?'; - bytes[length] = '\0'; - char* end; - double val = kjs_strtod(bytes.data(), &end); - if (ok) - *ok = (end == 0 || *end == '\0'); - return val; -} - -float charactersToFloat(const UChar* data, size_t length, bool* ok) -{ - // FIXME: This will return ok even when the string fits into a double but not a float. - return narrowPrecisionToFloat(charactersToDouble(data, length, ok)); -} - } // namespace WebCore #ifndef NDEBUG diff --git a/WebCore/platform/text/StringImpl.cpp b/WebCore/platform/text/StringImpl.cpp index f9087b5..0643de6 100644 --- a/WebCore/platform/text/StringImpl.cpp +++ b/WebCore/platform/text/StringImpl.cpp @@ -28,6 +28,7 @@ #include "AtomicString.h" #include "CString.h" #include "CharacterNames.h" +#include "DeprecatedString.h" #include "FloatConversion.h" #include "Length.h" #include "StringBuffer.h" @@ -59,7 +60,8 @@ static inline void deleteUCharVector(const UChar* p) // This constructor is used only to create the empty string. StringImpl::StringImpl() - : m_length(0) + : RefCounted<StringImpl>(1) + , m_length(0) , m_data(0) , m_hash(0) , m_inTable(false) @@ -71,7 +73,8 @@ StringImpl::StringImpl() // operation. Because of that, it's the one constructor that doesn't assert the // length is non-zero, since we support copying the empty string. inline StringImpl::StringImpl(const UChar* characters, unsigned length) - : m_length(length) + : RefCounted<StringImpl>(1) + , m_length(length) , m_hash(0) , m_inTable(false) , m_hasTerminatingNullCharacter(false) @@ -82,7 +85,8 @@ inline StringImpl::StringImpl(const UChar* characters, unsigned length) } inline StringImpl::StringImpl(const StringImpl& str, WithTerminatingNullCharacter) - : m_length(str.m_length) + : RefCounted<StringImpl>(1) + , m_length(str.m_length) , m_hash(str.m_hash) , m_inTable(false) , m_hasTerminatingNullCharacter(true) @@ -94,7 +98,8 @@ inline StringImpl::StringImpl(const StringImpl& str, WithTerminatingNullCharacte } inline StringImpl::StringImpl(const char* characters, unsigned length) - : m_length(length) + : RefCounted<StringImpl>(1) + , m_length(length) , m_hash(0) , m_inTable(false) , m_hasTerminatingNullCharacter(false) @@ -111,7 +116,8 @@ inline StringImpl::StringImpl(const char* characters, unsigned length) } inline StringImpl::StringImpl(UChar* characters, unsigned length, AdoptBuffer) - : m_length(length) + : RefCounted<StringImpl>(1) + , m_length(length) , m_data(characters) , m_hash(0) , m_inTable(false) @@ -121,9 +127,15 @@ inline StringImpl::StringImpl(UChar* characters, unsigned length, AdoptBuffer) ASSERT(length); } +// FIXME: These AtomicString constructors return objects with a refCount of 0, +// even though the others return objects with a refCount of 1. That preserves +// the historical behavior for the hash map translator call sites inside the +// AtomicString code, but is it correct? + // This constructor is only for use by AtomicString. StringImpl::StringImpl(const UChar* characters, unsigned length, unsigned hash) - : m_length(length) + : RefCounted<StringImpl>(0) + , m_length(length) , m_hash(hash) , m_inTable(true) , m_hasTerminatingNullCharacter(false) @@ -139,7 +151,8 @@ StringImpl::StringImpl(const UChar* characters, unsigned length, unsigned hash) // This constructor is only for use by AtomicString. StringImpl::StringImpl(const char* characters, unsigned length, unsigned hash) - : m_length(length) + : RefCounted<StringImpl>(0) + , m_length(length) , m_hash(hash) , m_inTable(true) , m_hasTerminatingNullCharacter(false) @@ -212,7 +225,7 @@ static Length parseLength(const UChar* data, unsigned length) ++i; bool ok; - int r = charactersToIntStrict(data, i, &ok); + int r = DeprecatedConstString(reinterpret_cast<const DeprecatedChar*>(data), i).string().toInt(&ok); /* Skip over any remaining digits, we are not that accurate (5.5% => 5%) */ while (i < length && (Unicode::isDigit(data[i]) || data[i] == '.')) @@ -500,54 +513,84 @@ PassRefPtr<StringImpl> StringImpl::capitalize(UChar previous) return adopt(data); } -int StringImpl::toIntStrict(bool* ok, int base) -{ - return charactersToIntStrict(m_data, m_length, ok, base); -} - -unsigned StringImpl::toUIntStrict(bool* ok, int base) -{ - return charactersToUIntStrict(m_data, m_length, ok, base); -} - -int64_t StringImpl::toInt64Strict(bool* ok, int base) -{ - return charactersToInt64Strict(m_data, m_length, ok, base); -} - -uint64_t StringImpl::toUInt64Strict(bool* ok, int base) -{ - return charactersToUInt64Strict(m_data, m_length, ok, base); -} - int StringImpl::toInt(bool* ok) { - return charactersToInt(m_data, m_length, ok); -} + unsigned i = 0; -unsigned StringImpl::toUInt(bool* ok) -{ - return charactersToUInt(m_data, m_length, ok); + // Allow leading spaces. + for (; i != m_length; ++i) + if (!isSpaceOrNewline(m_data[i])) + break; + + // Allow sign. + if (i != m_length && (m_data[i] == '+' || m_data[i] == '-')) + ++i; + + // Allow digits. + for (; i != m_length; ++i) + if (!Unicode::isDigit(m_data[i])) + break; + + return DeprecatedConstString(reinterpret_cast<const DeprecatedChar*>(m_data), i).string().toInt(ok); } int64_t StringImpl::toInt64(bool* ok) { - return charactersToInt64(m_data, m_length, ok); + unsigned i = 0; + + // Allow leading spaces. + for (; i != m_length; ++i) + if (!isSpaceOrNewline(m_data[i])) + break; + + // Allow sign. + if (i != m_length && (m_data[i] == '+' || m_data[i] == '-')) + ++i; + + // Allow digits. + for (; i != m_length; ++i) + if (!Unicode::isDigit(m_data[i])) + break; + + return DeprecatedConstString(reinterpret_cast<const DeprecatedChar*>(m_data), i).string().toInt64(ok); } uint64_t StringImpl::toUInt64(bool* ok) { - return charactersToUInt64(m_data, m_length, ok); + unsigned i = 0; + + // Allow leading spaces. + for (; i != m_length; ++i) + if (!isSpaceOrNewline(m_data[i])) + break; + + // Allow digits. + for (; i != m_length; ++i) + if (!Unicode::isDigit(m_data[i])) + break; + + return DeprecatedConstString(reinterpret_cast<const DeprecatedChar*>(m_data), i).string().toUInt64(ok); } double StringImpl::toDouble(bool* ok) { - return charactersToDouble(m_data, m_length, ok); + if (!m_length) { + if (ok) + *ok = false; + return 0; + } + char *end; + CString latin1String = Latin1Encoding().encode(characters(), length()); + double val = kjs_strtod(latin1String.data(), &end); + if (ok) + *ok = end == 0 || *end == '\0'; + return val; } float StringImpl::toFloat(bool* ok) { - return charactersToFloat(m_data, m_length, ok); + // FIXME: This will return ok even when the string fits into a double but not a float. + return narrowPrecisionToFloat(toDouble(ok)); } static bool equal(const UChar* a, const char* b, int length) @@ -614,7 +657,15 @@ int StringImpl::find(const char* chs, int index, bool caseSensitive) int StringImpl::find(UChar c, int start) { - return WebCore::find(m_data, m_length, c, start); + unsigned index = start; + if (index >= m_length ) + return -1; + while(index < m_length) { + if (m_data[index] == c) + return index; + index++; + } + return -1; } int StringImpl::find(StringImpl* str, int index, bool caseSensitive) @@ -675,7 +726,18 @@ int StringImpl::find(StringImpl* str, int index, bool caseSensitive) int StringImpl::reverseFind(UChar c, int index) { - return WebCore::reverseFind(m_data, m_length, c, index); + if (index >= (int)m_length || m_length == 0) + return -1; + + if (index < 0) + index += m_length; + while (1) { + if (m_data[index] == c) + return index; + if (index == 0) + return -1; + index--; + } } int StringImpl::reverseFind(StringImpl* str, int index, bool caseSensitive) diff --git a/WebCore/platform/text/StringImpl.h b/WebCore/platform/text/StringImpl.h index 1fb1e95..dd50b2e 100644 --- a/WebCore/platform/text/StringImpl.h +++ b/WebCore/platform/text/StringImpl.h @@ -49,9 +49,6 @@ struct StringHash; struct UCharBufferTranslator; class StringImpl : public RefCounted<StringImpl> { - friend class AtomicString; - friend struct UCharBufferTranslator; - friend struct CStringTranslator; private: StringImpl(); StringImpl(const UChar*, unsigned length); @@ -102,16 +99,9 @@ public: bool containsOnlyWhitespace(); - int toIntStrict(bool* ok = 0, int base = 10); - unsigned toUIntStrict(bool* ok = 0, int base = 10); - int64_t toInt64Strict(bool* ok = 0, int base = 10); - uint64_t toUInt64Strict(bool* ok = 0, int base = 10); - - int toInt(bool* ok = 0); // ignores trailing garbage - unsigned toUInt(bool* ok = 0); // ignores trailing garbage - int64_t toInt64(bool* ok = 0); // ignores trailing garbage - uint64_t toUInt64(bool* ok = 0); // ignores trailing garbage - + int toInt(bool* ok = 0); // ignores trailing garbage, unlike DeprecatedString + int64_t toInt64(bool* ok = 0); // ignores trailing garbage, unlike DeprecatedString + uint64_t toUInt64(bool* ok = 0); // ignores trailing garbage, unlike DeprecatedString double toDouble(bool* ok = 0); float toFloat(bool* ok = 0); @@ -156,6 +146,10 @@ public: #endif private: + friend class AtomicString; + friend struct UCharBufferTranslator; + friend struct CStringTranslator; + unsigned m_length; const UChar* m_data; mutable unsigned m_hash; diff --git a/WebCore/platform/text/TextBreakIteratorICU.cpp b/WebCore/platform/text/TextBreakIteratorICU.cpp index 9941f58..9fd2d0b 100644 --- a/WebCore/platform/text/TextBreakIteratorICU.cpp +++ b/WebCore/platform/text/TextBreakIteratorICU.cpp @@ -25,7 +25,6 @@ #include "TextBreakIteratorInternalICU.h" #include <unicode/ubrk.h> -#include <wtf/Assertions.h> namespace WebCore { @@ -39,7 +38,6 @@ static TextBreakIterator* setUpIterator(bool& createdIterator, TextBreakIterator UErrorCode openStatus = U_ZERO_ERROR; iterator = static_cast<TextBreakIterator*>(ubrk_open(type, currentTextBreakLocaleID(), 0, 0, &openStatus)); createdIterator = true; - ASSERT_WITH_MESSAGE(U_SUCCESS(openStatus), "ICU could not open a break iterator: %s (%d)", u_errorName(openStatus), openStatus); } if (!iterator) return 0; diff --git a/WebCore/platform/text/TextCodecICU.cpp b/WebCore/platform/text/TextCodecICU.cpp index 0299b8f..a89a74e 100644 --- a/WebCore/platform/text/TextCodecICU.cpp +++ b/WebCore/platform/text/TextCodecICU.cpp @@ -33,6 +33,7 @@ #include <unicode/ucnv.h> #include <unicode/ucnv_cb.h> #include <wtf/Assertions.h> +#include <wtf/HashMap.h> using std::auto_ptr; using std::min; @@ -85,7 +86,9 @@ void TextCodecICU::registerExtendedEncodingNames(EncodingNameRegistrar registrar // for encoding GB_2312-80 and several others. So, we need to override this behavior, too. if (strcmp(standardName, "GB2312") == 0 || strcmp(standardName, "GB_2312-80") == 0) standardName = "GBK"; +#ifndef ANDROID else +#endif registrar(standardName, standardName); uint16_t numAliases = ucnv_countAliases(name, &error); @@ -262,27 +265,23 @@ String TextCodecICU::decode(const char* bytes, size_t length, bool flush) // We need to apply these fallbacks ourselves as they are not currently supported by ICU and // they were provided by the old TEC encoding path // Needed to fix <rdar://problem/4708689> -static UChar getGbkEscape(UChar32 codePoint) -{ - switch (codePoint) { - case 0x01F9: - return 0xE7C8; - case 0x1E3F: - return 0xE7C7; - case 0x22EF: - return 0x2026; - case 0x301C: - return 0xFF5E; - default: - return 0; +static HashMap<UChar32, UChar>& gbkEscapes() { + static HashMap<UChar32, UChar> escapes; + if (escapes.isEmpty()) { + escapes.add(0x01F9, 0xE7C8); + escapes.add(0x1E3F, 0xE7C7); + escapes.add(0x22EF, 0x2026); + escapes.add(0x301C, 0xFF5E); } + + return escapes; } static void gbkCallbackEscape(const void* context, UConverterFromUnicodeArgs* fromUArgs, const UChar* codeUnits, int32_t length, UChar32 codePoint, UConverterCallbackReason reason, UErrorCode* err) { - UChar outChar; - if (reason == UCNV_UNASSIGNED && (outChar = getGbkEscape(codePoint))) { + if (codePoint && gbkEscapes().contains(codePoint)) { + UChar outChar = gbkEscapes().get(codePoint); const UChar* source = &outChar; *err = U_ZERO_ERROR; ucnv_cbFromUWriteUChars(fromUArgs, &source, source + 1, 0, err); @@ -294,8 +293,8 @@ static void gbkCallbackEscape(const void* context, UConverterFromUnicodeArgs* fr static void gbkCallbackSubstitute(const void* context, UConverterFromUnicodeArgs* fromUArgs, const UChar* codeUnits, int32_t length, UChar32 codePoint, UConverterCallbackReason reason, UErrorCode* err) { - UChar outChar; - if (reason == UCNV_UNASSIGNED && (outChar = getGbkEscape(codePoint))) { + if (gbkEscapes().contains(codePoint)) { + UChar outChar = gbkEscapes().get(codePoint); const UChar* source = &outChar; *err = U_ZERO_ERROR; ucnv_cbFromUWriteUChars(fromUArgs, &source, source + 1, 0, err); diff --git a/WebCore/platform/text/TextCodecLatin1.cpp b/WebCore/platform/text/TextCodecLatin1.cpp index 2e9d116..a687235 100644 --- a/WebCore/platform/text/TextCodecLatin1.cpp +++ b/WebCore/platform/text/TextCodecLatin1.cpp @@ -29,7 +29,6 @@ #include "CString.h" #include "PlatformString.h" #include "StringBuffer.h" -#include <stdio.h> using std::auto_ptr; diff --git a/WebCore/platform/text/TextCodecUserDefined.cpp b/WebCore/platform/text/TextCodecUserDefined.cpp index 3ef1bc9..a420992 100644 --- a/WebCore/platform/text/TextCodecUserDefined.cpp +++ b/WebCore/platform/text/TextCodecUserDefined.cpp @@ -29,7 +29,6 @@ #include "CString.h" #include "PlatformString.h" #include "StringBuffer.h" -#include <stdio.h> using std::auto_ptr; diff --git a/WebCore/platform/text/TextStream.cpp b/WebCore/platform/text/TextStream.cpp index 5aafbc0..b23e769 100644 --- a/WebCore/platform/text/TextStream.cpp +++ b/WebCore/platform/text/TextStream.cpp @@ -26,74 +26,145 @@ #include "config.h" #include "TextStream.h" +#include "DeprecatedString.h" +#include "Logging.h" #include "PlatformString.h" -#include <wtf/StringExtras.h> +#include <wtf/Vector.h> namespace WebCore { -static const size_t printBufferSize = 100; // large enough for any integer or floating point value in string format, including trailing null character +const size_t integerOrPointerAsStringBufferSize = 100; // large enough for any integer or pointer in string format, including trailing null character +const char* const precisionFormats[7] = { "%.0f", "%.1f", "%.2f", "%.3f", "%.4f", "%.5f", "%.6f"}; +const int maxPrecision = 6; // must match size of precisionFormats +const int defaultPrecision = 6; // matches qt and sprintf(.., "%f", ...) behaviour + +TextStream::TextStream(DeprecatedString* s) + : m_hasByteArray(false), m_string(s), m_precision(defaultPrecision) +{ +} + +TextStream& TextStream::operator<<(char c) +{ + if (m_hasByteArray) + m_byteArray.append(c); + + if (m_string) + m_string->append(DeprecatedChar(c)); + return *this; +} + +TextStream& TextStream::operator<<(short i) +{ + char buffer[integerOrPointerAsStringBufferSize]; + sprintf(buffer, "%d", i); + return *this << buffer; +} + +TextStream& TextStream::operator<<(unsigned short i) +{ + char buffer[integerOrPointerAsStringBufferSize]; + sprintf(buffer, "%u", i); + return *this << buffer; +} TextStream& TextStream::operator<<(int i) { - char buffer[printBufferSize]; - snprintf(buffer, sizeof(buffer) - 1, "%d", i); + char buffer[integerOrPointerAsStringBufferSize]; + sprintf(buffer, "%d", i); return *this << buffer; } TextStream& TextStream::operator<<(unsigned i) { - char buffer[printBufferSize]; - snprintf(buffer, sizeof(buffer) - 1, "%u", i); + char buffer[integerOrPointerAsStringBufferSize]; + sprintf(buffer, "%u", i); return *this << buffer; } TextStream& TextStream::operator<<(long i) { - char buffer[printBufferSize]; - snprintf(buffer, sizeof(buffer) - 1, "%ld", i); + char buffer[integerOrPointerAsStringBufferSize]; + sprintf(buffer, "%ld", i); return *this << buffer; } TextStream& TextStream::operator<<(unsigned long i) { - char buffer[printBufferSize]; - snprintf(buffer, sizeof(buffer) - 1, "%lu", i); + char buffer[integerOrPointerAsStringBufferSize]; + sprintf(buffer, "%lu", i); return *this << buffer; } TextStream& TextStream::operator<<(float f) { - char buffer[printBufferSize]; - snprintf(buffer, sizeof(buffer) - 1, "%.2f", f); + char buffer[integerOrPointerAsStringBufferSize]; + sprintf(buffer, precisionFormats[m_precision], f); return *this << buffer; } TextStream& TextStream::operator<<(double d) { - char buffer[printBufferSize]; - snprintf(buffer, sizeof(buffer) - 1, "%.2f", d); + char buffer[integerOrPointerAsStringBufferSize]; + sprintf(buffer, precisionFormats[m_precision], d); return *this << buffer; } -TextStream& TextStream::operator<<(const char* string) +TextStream& TextStream::operator<<(const char* s) { - size_t stringLength = strlen(string); - size_t textLength = m_text.size(); - m_text.grow(textLength + stringLength); - for (size_t i = 0; i < stringLength; ++i) - m_text[textLength + i] = string[i]; + if (m_hasByteArray) { + unsigned length = strlen(s); + unsigned oldSize = m_byteArray.size(); + m_byteArray.grow(oldSize + length); + memcpy(m_byteArray.data() + oldSize, s, length); + } + if (m_string) + m_string->append(s); return *this; } -TextStream& TextStream::operator<<(const String& string) +TextStream& TextStream::operator<<(const DeprecatedString& s) { - append(m_text, string); + if (m_hasByteArray) { + unsigned length = s.length(); + unsigned oldSize = m_byteArray.size(); + m_byteArray.grow(oldSize + length); + memcpy(m_byteArray.data() + oldSize, s.latin1(), length); + } + if (m_string) + m_string->append(s); return *this; } -String TextStream::release() +TextStream& TextStream::operator<<(const String& s) +{ + return (*this) << s.deprecatedString(); +} + +TextStream& TextStream::operator<<(void* p) +{ + char buffer[integerOrPointerAsStringBufferSize]; + sprintf(buffer, "%p", p); + return *this << buffer; +} + +TextStream& TextStream::operator<<(const TextStreamManipulator& m) +{ + return m(*this); +} + +int TextStream::precision(int p) +{ + int oldPrecision = m_precision; + + if (p >= 0 && p <= maxPrecision) + m_precision = p; + + return oldPrecision; +} + +TextStream &endl(TextStream& stream) { - return String::adopt(m_text); + return stream << '\n'; } } diff --git a/WebCore/platform/text/TextStream.h b/WebCore/platform/text/TextStream.h index b4b801c..897c267 100644 --- a/WebCore/platform/text/TextStream.h +++ b/WebCore/platform/text/TextStream.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2004 Apple Computer, Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -27,14 +27,26 @@ #define TextStream_h #include <wtf/Vector.h> -#include <wtf/unicode/Unicode.h> namespace WebCore { +class DeprecatedChar; +class DeprecatedString; class String; +class TextStream; + +typedef TextStream& (*TextStreamManipulator)(TextStream&); + +TextStream& endl(TextStream&); class TextStream { public: + TextStream(DeprecatedString*); + + TextStream& operator<<(char); + TextStream& operator<<(const DeprecatedChar&); + TextStream& operator<<(short); + TextStream& operator<<(unsigned short); TextStream& operator<<(int); TextStream& operator<<(unsigned); TextStream& operator<<(long); @@ -43,11 +55,21 @@ public: TextStream& operator<<(double); TextStream& operator<<(const char*); TextStream& operator<<(const String&); + TextStream& operator<<(const DeprecatedString&); + TextStream& operator<<(void*); - String release(); + TextStream& operator<<(const TextStreamManipulator&); + + int precision(int); private: - Vector<UChar> m_text; + TextStream(const TextStream&); + TextStream& operator=(const TextStream&); + + bool m_hasByteArray; + Vector<char> m_byteArray; + DeprecatedString* m_string; + int m_precision; }; } diff --git a/WebCore/platform/text/mac/ShapeArabic.c b/WebCore/platform/text/mac/ShapeArabic.c index 43e149d..4706e7c 100644 --- a/WebCore/platform/text/mac/ShapeArabic.c +++ b/WebCore/platform/text/mac/ShapeArabic.c @@ -2,28 +2,8 @@ ****************************************************************************** * * Copyright (C) 2000-2004, International Business Machines -* Corporation and others. All Rights Reserved. -* Copyright (C) 2007 Apple Inc. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy of this -* software and associated documentation files (the "Software"), to deal in the Software -* without restriction, including without limitation the rights to use, copy, modify, -* merge, publish, distribute, and/or sell copies of the Software, and to permit persons -* to whom the Software is furnished to do so, provided that the above copyright notice(s) -* and this permission notice appear in all copies of the Software and that both the above -* copyright notice(s) and this permission notice appear in supporting documentation. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, -* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -* PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER -* OR HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR -* CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR -* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING -* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -* -* Except as contained in this notice, the name of a copyright holder shall not be used in -* advertising or otherwise to promote the sale, use or other dealings in this Software -* without prior written authorization of the copyright holder. +* Corporation and others. All Rights Reserved. +* Copyright (C) 2007 Apple Inc. All rights reserved. * ****************************************************************************** * diff --git a/WebCore/platform/text/qt/StringQt.cpp b/WebCore/platform/text/qt/StringQt.cpp index de9f527..23a684b 100644 --- a/WebCore/platform/text/qt/StringQt.cpp +++ b/WebCore/platform/text/qt/StringQt.cpp @@ -26,6 +26,7 @@ #include "config.h" #include "PlatformString.h" +#include "DeprecatedString.h" #include <QString> @@ -43,14 +44,21 @@ String::String(const QStringRef& ref) { if (!ref.string()) return; - m_impl = StringImpl::create(reinterpret_cast<const UChar*>(ref.unicode()), ref.length()); + m_impl = StringImpl::create(reinterpret_cast<const UChar *>(ref.unicode()), ref.length()); } + String::operator QString() const { return QString(reinterpret_cast<const QChar*>(characters()), length()); } +// DeprecatedString conversions +DeprecatedString::operator QString() const +{ + return QString(reinterpret_cast<const QChar*>(unicode()), length()); +} + } // vim: ts=4 sw=4 et diff --git a/WebCore/platform/text/wx/StringWx.cpp b/WebCore/platform/text/wx/StringWx.cpp index 50919c4..7f91dbf 100644 --- a/WebCore/platform/text/wx/StringWx.cpp +++ b/WebCore/platform/text/wx/StringWx.cpp @@ -27,6 +27,7 @@ #include "PlatformString.h" #include "CString.h" +#include "DeprecatedString.h" #include "unicode/ustring.h" #include <wx/defs.h> @@ -87,6 +88,12 @@ String::operator wxString() const return wxString(utf8().data(), wxConvUTF8); } +// DeprecatedString conversions +DeprecatedString::operator wxString() const +{ + return wxString(utf8().data(), wxConvUTF8); +} + } // vim: ts=4 sw=4 et |