[SCM] WebKit Debian packaging branch, debian/unstable, updated. debian/1.1.15-1-40151-g37bb677
hyatt
hyatt at 268f45cc-cd09-0410-ab3c-d52691b4dbfc
Sat Sep 26 08:24:29 UTC 2009
The following commit has been merged in the debian/unstable branch:
commit 746ed3362ed76c202eec08754b535f859289e7c4
Author: hyatt <hyatt at 268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date: Wed Jan 28 21:19:39 2004 +0000
Make AtomicString a new class that owns DOMStrings, instead of using KJS::Identifier. One day when we
convert DOMString and UString to have the same underlying rep, then these classes could possibly re-merge.
For now this provides an easy migration path for all the code that is using DOMStringImpl*.
Also fixed a bug with float clearing in the style cascade.
Reviewed by darin
* khtml/css/cssparser.h:
(DOM::atomicString):
* khtml/css/cssstyleselector.cpp:
(khtml::CSSStyleSelector::checkOneSelector):
(khtml::CSSStyleSelector::applyRule):
* khtml/dom/dom_string.cpp:
(DOMString::DOMString):
* khtml/xml/dom_nameimpl.cpp:
(DOM::AtomicStringStatisticsExitLogger::~AtomicStringStatisticsExitLogger):
(DOM::AtomicString::equal):
(DOM::AtomicString::add):
(DOM::AtomicString::insert):
(DOM::AtomicString::remove):
(DOM::AtomicString::expand):
(DOM::AtomicString::shrink):
(DOM::AtomicString::rehash):
(DOM::AtomicString::null):
(DOM::AtomicString::init):
(DOM::operator==):
(DOM::equalsIgnoreCase):
* khtml/xml/dom_nameimpl.h:
(DOM::AtomicString::AtomicString):
(DOM::AtomicString:::m_string):
(DOM::AtomicString::string):
(DOM::AtomicString::qstring):
(DOM::AtomicString::implementation):
(DOM::AtomicString::unicode):
(DOM::AtomicString::length):
(DOM::AtomicString::ascii):
(DOM::AtomicString::find):
(DOM::AtomicString::isNull):
(DOM::AtomicString::isEmpty):
(DOM::AtomicString::equal):
(DOM::operator==):
(DOM::operator!=):
* khtml/xml/dom_stringimpl.cpp:
(DOM::DOMStringImpl::empty):
(DOM::DOMStringImpl::DOMStringImpl):
(DOM::DOMStringImpl::~DOMStringImpl):
(DOM::DOMStringImpl::append):
(DOM::DOMStringImpl::insert):
(DOM::DOMStringImpl::truncate):
(DOM::DOMStringImpl::remove):
(DOM::DOMStringImpl::split):
(DOM::DOMStringImpl::substring):
(DOM::DOMStringImpl::replace):
(DOM::DOMStringImpl::computeHash):
* khtml/xml/dom_stringimpl.h:
(DOM::DOMStringImpl::DOMStringImpl):
(DOM::DOMStringImpl::hash):
* khtml/xml/dom_textimpl.cpp:
(CharacterDataImpl::CharacterDataImpl):
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@5999 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/WebCore/ChangeLog-2005-08-23 b/WebCore/ChangeLog-2005-08-23
index dba1cf3..b8ab7bf 100644
--- a/WebCore/ChangeLog-2005-08-23
+++ b/WebCore/ChangeLog-2005-08-23
@@ -1,3 +1,66 @@
+2004-01-28 David Hyatt <hyatt at apple.com>
+
+ Make AtomicString a new class that owns DOMStrings, instead of using KJS::Identifier. One day when we
+ convert DOMString and UString to have the same underlying rep, then these classes could possibly re-merge.
+ For now this provides an easy migration path for all the code that is using DOMStringImpl*.
+
+ Also fixed a bug with float clearing in the style cascade.
+
+ Reviewed by darin
+
+ * khtml/css/cssparser.h:
+ (DOM::atomicString):
+ * khtml/css/cssstyleselector.cpp:
+ (khtml::CSSStyleSelector::checkOneSelector):
+ (khtml::CSSStyleSelector::applyRule):
+ * khtml/dom/dom_string.cpp:
+ (DOMString::DOMString):
+ * khtml/xml/dom_nameimpl.cpp:
+ (DOM::AtomicStringStatisticsExitLogger::~AtomicStringStatisticsExitLogger):
+ (DOM::AtomicString::equal):
+ (DOM::AtomicString::add):
+ (DOM::AtomicString::insert):
+ (DOM::AtomicString::remove):
+ (DOM::AtomicString::expand):
+ (DOM::AtomicString::shrink):
+ (DOM::AtomicString::rehash):
+ (DOM::AtomicString::null):
+ (DOM::AtomicString::init):
+ (DOM::operator==):
+ (DOM::equalsIgnoreCase):
+ * khtml/xml/dom_nameimpl.h:
+ (DOM::AtomicString::AtomicString):
+ (DOM::AtomicString:::m_string):
+ (DOM::AtomicString::string):
+ (DOM::AtomicString::qstring):
+ (DOM::AtomicString::implementation):
+ (DOM::AtomicString::unicode):
+ (DOM::AtomicString::length):
+ (DOM::AtomicString::ascii):
+ (DOM::AtomicString::find):
+ (DOM::AtomicString::isNull):
+ (DOM::AtomicString::isEmpty):
+ (DOM::AtomicString::equal):
+ (DOM::operator==):
+ (DOM::operator!=):
+ * khtml/xml/dom_stringimpl.cpp:
+ (DOM::DOMStringImpl::empty):
+ (DOM::DOMStringImpl::DOMStringImpl):
+ (DOM::DOMStringImpl::~DOMStringImpl):
+ (DOM::DOMStringImpl::append):
+ (DOM::DOMStringImpl::insert):
+ (DOM::DOMStringImpl::truncate):
+ (DOM::DOMStringImpl::remove):
+ (DOM::DOMStringImpl::split):
+ (DOM::DOMStringImpl::substring):
+ (DOM::DOMStringImpl::replace):
+ (DOM::DOMStringImpl::computeHash):
+ * khtml/xml/dom_stringimpl.h:
+ (DOM::DOMStringImpl::DOMStringImpl):
+ (DOM::DOMStringImpl::hash):
+ * khtml/xml/dom_textimpl.cpp:
+ (CharacterDataImpl::CharacterDataImpl):
+
2004-01-27 Chris Blumenberg <cblu at apple.com>
Fixed:
diff --git a/WebCore/khtml/css/cssparser.h b/WebCore/khtml/css/cssparser.h
index 0774a27..c516500 100644
--- a/WebCore/khtml/css/cssparser.h
+++ b/WebCore/khtml/css/cssparser.h
@@ -76,7 +76,7 @@ namespace DOM {
return DOMString( (QChar *)ps.string, ps.length );
}
static inline AtomicString atomicString( const ParseString &ps ) {
- return AtomicString( (AtomicChar*)ps.string, ps.length );
+ return AtomicString( ps.string, ps.length );
}
class ValueList {
diff --git a/WebCore/khtml/css/cssstyleselector.cpp b/WebCore/khtml/css/cssstyleselector.cpp
index e4f8ca5..d94598b 100644
--- a/WebCore/khtml/css/cssstyleselector.cpp
+++ b/WebCore/khtml/css/cssstyleselector.cpp
@@ -901,7 +901,7 @@ bool CSSStyleSelector::checkOneSelector(DOM::CSSSelector *sel, DOM::ElementImpl
}
// The selector's value can't contain a space, or it's totally bogus.
- spacePos = sel->value.ustring().find(' ');
+ spacePos = sel->value.find(' ');
if (spacePos != -1)
return false;
@@ -1716,9 +1716,11 @@ void CSSStyleSelector::applyRule( int id, DOM::CSSValueImpl *value )
{
HANDLE_INHERIT_AND_INITIAL(clear, Clear)
if(!primitiveValue) break;
- EClear c = CNONE;
+ EClear c;
switch(primitiveValue->getIdent())
{
+ case CSS_VAL_NONE:
+ c = CNONE; break;
case CSS_VAL_LEFT:
c = CLEFT; break;
case CSS_VAL_RIGHT:
diff --git a/WebCore/khtml/dom/dom_string.cpp b/WebCore/khtml/dom/dom_string.cpp
index cf3c07b..5f6f822 100644
--- a/WebCore/khtml/dom/dom_string.cpp
+++ b/WebCore/khtml/dom/dom_string.cpp
@@ -29,7 +29,15 @@ using namespace DOM;
DOMString::DOMString(const QChar *str, uint len)
{
- impl = new DOMStringImpl( str, len );
+ if (!str) {
+ impl = 0;
+ return;
+ }
+
+ if (len == 0)
+ impl = DOMStringImpl::empty();
+ else
+ impl = new DOMStringImpl(str, len);
impl->ref();
}
@@ -39,8 +47,11 @@ DOMString::DOMString(const QString &str)
impl = 0;
return;
}
-
- impl = new DOMStringImpl( str.unicode(), str.length() );
+
+ if (str.isEmpty())
+ impl = DOMStringImpl::empty();
+ else
+ impl = new DOMStringImpl(str.unicode(), str.length());
impl->ref();
}
@@ -51,7 +62,11 @@ DOMString::DOMString(const char *str)
return;
}
- impl = new DOMStringImpl( str );
+ int l = strlen(str);
+ if (l == 0)
+ impl = DOMStringImpl::empty();
+ else
+ impl = new DOMStringImpl(str, l);
impl->ref();
}
diff --git a/WebCore/khtml/xml/dom_nameimpl.cpp b/WebCore/khtml/xml/dom_nameimpl.cpp
index e19ac63..6f86a7b 100644
--- a/WebCore/khtml/xml/dom_nameimpl.cpp
+++ b/WebCore/khtml/xml/dom_nameimpl.cpp
@@ -21,10 +21,323 @@
*/
#include "dom/dom_string.h"
+#include "xml/dom_stringimpl.h"
#include "dom_nameimpl.h"
namespace DOM {
+// For KHTML we need to avoid having static constructors.
+// Our strategy is to declare the global objects with a different type (initialized to 0)
+// and then use placement new to initialize the global objects later. This is not completely
+// portable, and it would be good to figure out a 100% clean way that still avoids code that
+// runs at init time.
+
+#if APPLE_CHANGES
+#define AVOID_STATIC_CONSTRUCTORS 1
+#endif
+
+#if AVOID_STATIC_CONSTRUCTORS
+#define KHTML_ATOMICSTRING_HIDE_GLOBALS 1
+#endif
+
+#include "dom_nameimpl.h"
+
+#define DUMP_STATISTICS 0
+
+#if DUMP_STATISTICS
+
+static int numProbes;
+static int numCollisions;
+
+struct AtomicStringStatisticsExitLogger { ~AtomicStringStatisticsExitLogger(); };
+
+static AtomicStringStatisticsExitLogger logger;
+
+AtomicStringStatisticsExitLogger::~AtomicStringStatisticsExitLogger()
+{
+ printf("\nDOM::AtomicString statistics\n\n");
+ printf("%d probes\n", numProbes);
+ printf("%d collisions (%.1f%%)\n", numCollisions, 100.0 * numCollisions / numProbes);
+}
+
+#endif
+
+const int _minTableSize = 64;
+
+DOMStringImpl **AtomicString::_table;
+int AtomicString::_tableSize;
+int AtomicString::_tableSizeMask;
+int AtomicString::_keyCount;
+
+bool AtomicString::equal(DOMStringImpl *r, const char *s)
+{
+ if (!r && !s) return true;
+ if (!r || !s) return false;
+
+ int length = r->l;
+ const QChar *d = r->s;
+ for (int i = 0; i != length; ++i)
+ if (d[i] != s[i])
+ return false;
+ return s[length] == 0;
+}
+
+bool AtomicString::equal(DOMStringImpl *r, const QChar *s, uint length)
+{
+ if (!r && !s) return true;
+ if (!r || !s) return false;
+
+ if (r->l != length)
+ return false;
+ const QChar *d = r->s;
+ for (uint i = 0; i != length; ++i)
+ if (d[i] != s[i])
+ return false;
+ return true;
+}
+
+bool AtomicString::equal(DOMStringImpl *r, DOMStringImpl *b)
+{
+ if (r == b) return true;
+ if (!r || !b) return false;
+ uint length = r->l;
+ if (length != b->l)
+ return false;
+ const QChar *d = r->s;
+ const QChar *s = b->s;
+ for (uint i = 0; i != length; ++i)
+ if (d[i] != s[i])
+ return false;
+ return true;
+}
+
+DOMStringImpl *AtomicString::add(const char *c)
+{
+ if (!c)
+ return 0;
+ int length = strlen(c);
+ if (length == 0)
+ return DOMStringImpl::empty();
+
+ if (!_table)
+ expand();
+
+ unsigned hash = DOMStringImpl::computeHash(c);
+
+ int i = hash & _tableSizeMask;
+#if DUMP_STATISTICS
+ ++numProbes;
+ numCollisions += _table[i] && !equal(_table[i], c);
+#endif
+ while (DOMStringImpl *key = _table[i]) {
+ if (equal(key, c))
+ return key;
+ i = (i + 1) & _tableSizeMask;
+ }
+
+ QChar *d = new QChar[length];
+ for (int j = 0; j != length; j++)
+ d[j] = c[j];
+
+ DOMStringImpl *r = new DOMStringImpl(d, length);
+ r->_hash = hash;
+
+ _table[i] = r;
+ ++_keyCount;
+
+ if (_keyCount * 2 >= _tableSize)
+ expand();
+
+ return r;
+}
+
+DOMStringImpl *AtomicString::add(const QChar *s, int length)
+{
+ if (!s)
+ return 0;
+
+ if (length == 0)
+ return DOMStringImpl::empty();
+
+ if (!_table)
+ expand();
+
+ unsigned hash = DOMStringImpl::computeHash(s, length);
+
+ int i = hash & _tableSizeMask;
+#if DUMP_STATISTICS
+ ++numProbes;
+ numCollisions += _table[i] && !equal(_table[i], s, length);
+#endif
+ while (DOMStringImpl *key = _table[i]) {
+ if (equal(key, s, length))
+ return key;
+ i = (i + 1) & _tableSizeMask;
+ }
+
+ QChar *d = new QChar[length];
+ for (int j = 0; j != length; j++)
+ d[j] = s[j];
+
+ DOMStringImpl *r = new DOMStringImpl(d, length);
+ r->_hash = hash;
+
+ _table[i] = r;
+ ++_keyCount;
+
+ if (_keyCount * 2 >= _tableSize)
+ expand();
+
+ return r;
+}
+
+DOMStringImpl *AtomicString::add(DOMStringImpl *r)
+{
+ if (!r)
+ return 0;
+
+ if (r->l == 0)
+ return DOMStringImpl::empty();
+
+ if (!_table)
+ expand();
+
+ unsigned hash = r->hash();
+
+ int i = hash & _tableSizeMask;
+#if DUMP_STATISTICS
+ ++numProbes;
+ numCollisions += _table[i] && !equal(_table[i], r);
+#endif
+ while (DOMStringImpl *key = _table[i]) {
+ if (equal(key, r))
+ return key;
+ i = (i + 1) & _tableSizeMask;
+ }
+
+ _table[i] = r;
+ ++_keyCount;
+
+ if (_keyCount * 2 >= _tableSize)
+ expand();
+
+ return r;
+}
+
+inline void AtomicString::insert(DOMStringImpl *key)
+{
+ unsigned hash = key->hash();
+
+ int i = hash & _tableSizeMask;
+#if DUMP_STATISTICS
+ ++numProbes;
+ numCollisions += _table[i] != 0;
+#endif
+ while (_table[i])
+ i = (i + 1) & _tableSizeMask;
+
+ _table[i] = key;
+}
+
+void AtomicString::remove(DOMStringImpl *r)
+{
+ unsigned hash = r->hash();
+
+ DOMStringImpl *key;
+
+ int i = hash & _tableSizeMask;
+#if DUMP_STATISTICS
+ ++numProbes;
+ numCollisions += _table[i] && equal(_table[i], r);
+#endif
+ while ((key = _table[i])) {
+ if (equal(key, r))
+ break;
+ i = (i + 1) & _tableSizeMask;
+ }
+ if (!key)
+ return;
+
+ _table[i] = 0;
+ --_keyCount;
+
+ if (_keyCount * 6 < _tableSize && _tableSize > _minTableSize) {
+ shrink();
+ return;
+ }
+
+ // Reinsert all the items to the right in the same cluster.
+ while (1) {
+ i = (i + 1) & _tableSizeMask;
+ key = _table[i];
+ if (!key)
+ break;
+ _table[i] = 0;
+ insert(key);
+ }
+}
+
+void AtomicString::expand()
+{
+ rehash(_tableSize == 0 ? _minTableSize : _tableSize * 2);
+}
+
+void AtomicString::shrink()
+{
+ rehash(_tableSize / 2);
+}
+
+void AtomicString::rehash(int newTableSize)
+{
+ int oldTableSize = _tableSize;
+ DOMStringImpl **oldTable = _table;
+
+ _tableSize = newTableSize;
+ _tableSizeMask = newTableSize - 1;
+ _table = (DOMStringImpl **)calloc(newTableSize, sizeof(DOMStringImpl *));
+
+ for (int i = 0; i != oldTableSize; ++i)
+ if (DOMStringImpl *key = oldTable[i])
+ insert(key);
+
+ free(oldTable);
+}
+
+const AtomicString &AtomicString::null()
+{
+ static AtomicString null;
+ return null;
+}
+
+// Global constants for property name strings.
+
+#if !AVOID_STATIC_CONSTRUCTORS
+ // Define an AtomicString in the normal way.
+ #define DEFINE_GLOBAL(name, string) extern const AtomicString name ## PropertyName(string);
+#else
+ // Define an AtomicString-sized array of pointers to avoid static initialization.
+ // Use an array of pointers instead of an array of char in case there is some alignment issue.
+ #define DEFINE_GLOBAL(name, string) \
+ void * name ## PropertyName[(sizeof(AtomicString) + sizeof(void *) - 1) / sizeof(void *)];
+#endif
+
+#define CALL_DEFINE_GLOBAL(name) DEFINE_GLOBAL(name, #name)
+KHTML_ATOMICSTRING_EACH_GLOBAL(CALL_DEFINE_GLOBAL)
+
+void AtomicString::init()
+{
+#if AVOID_STATIC_CONSTRUCTORS
+ static bool initialized;
+ if (!initialized) {
+ // Use placement new to initialize the globals.
+ #define PLACEMENT_NEW_GLOBAL(name, string) new (&name ## PropertyName) AtomicString(string);
+ #define CALL_PLACEMENT_NEW_GLOBAL(name) PLACEMENT_NEW_GLOBAL(name, #name)
+ KHTML_ATOMICSTRING_EACH_GLOBAL(CALL_PLACEMENT_NEW_GLOBAL)
+ initialized = true;
+ }
+#endif
+}
+
AtomicStringList* AtomicStringList::clone()
{
return new AtomicStringList(m_string, m_next ? m_next->clone() : 0);
@@ -32,47 +345,21 @@ AtomicStringList* AtomicStringList::clone()
bool operator==(const AtomicString &a, const DOMString &b)
{
- unsigned l = a.size();
- if (l != b.length()) return false;
-
- if (!memcmp(a.ustring().data(), b.unicode(), l*sizeof(unsigned short)))
- return true;
- return false;
-
+ return a.string() == b;
}
bool equalsIgnoreCase(const AtomicString &as, const DOMString &bs)
{
// returns true when equal, false otherwise (ignoring case)
- unsigned l = as.size();
- if (l != bs.length()) return false;
-
- const QChar *a = reinterpret_cast<const QChar*>(as.ustring().data());
- const QChar *b = bs.unicode();
- if (a == b) return true;
- if (!(a && b)) return false;
- while (l--) {
- if (*a != *b && a->lower() != b->lower()) return false;
- a++,b++;
- }
- return true;
+ return !strcasecmp(as.string(), bs);
}
bool equalsIgnoreCase(const AtomicString &as, const AtomicString &bs)
{
// returns true when equal, false otherwise (ignoring case)
- int l = as.size();
- if (l != bs.size()) return false;
-
- const QChar *a = reinterpret_cast<const QChar*>(as.ustring().data());
- const QChar *b = reinterpret_cast<const QChar*>(bs.ustring().data());
- if ( a == b ) return true;
- if ( !( a && b ) ) return false;
- while ( l-- ) {
- if ( *a != *b && a->lower() != b->lower() ) return false;
- a++,b++;
- }
- return true;
+ if (as == bs)
+ return true;
+ return !strcasecmp(as.string(), bs.string());
}
}
diff --git a/WebCore/khtml/xml/dom_nameimpl.h b/WebCore/khtml/xml/dom_nameimpl.h
index 3b6f47d..e11e5bd 100644
--- a/WebCore/khtml/xml/dom_nameimpl.h
+++ b/WebCore/khtml/xml/dom_nameimpl.h
@@ -22,13 +22,94 @@
#ifndef _DOM_NameImpl_h_
#define _DOM_NameImpl_h_
-#include <kjs/identifier.h>
+#include "dom/dom_string.h"
namespace DOM {
-typedef KJS::Identifier AtomicString;
-typedef KJS::UChar AtomicChar;
+class AtomicString {
+public:
+ static void init();
+
+ AtomicString() { }
+ AtomicString(const char *s) : m_string(add(s)) { }
+ AtomicString(const QChar *s, int length) : m_string(add(s, length)) { }
+ AtomicString(const unsigned short* s, int length) : m_string(add((QChar*)s, length)) { }
+ AtomicString(DOMStringImpl* imp) :m_string(add(imp)) { }
+ explicit AtomicString(const DOMString &s) : m_string(add(s.implementation())) { }
+
+ const DOMString& string() const { return m_string; };
+ QString qstring() const { return m_string.string(); };
+
+ const DOMStringImpl* implementation() { return m_string.implementation(); }
+
+ const QChar *unicode() const { return m_string.unicode(); }
+ int length() const { return m_string.length(); }
+
+ const char *ascii() const { return m_string.string().ascii(); }
+
+ int find(const QChar c, int start = 0) const { return m_string.find(c, start); }
+
+ bool isNull() const { return m_string.isNull(); }
+ bool isEmpty() const { return m_string.isEmpty(); }
+
+ static const AtomicString &null();
+
+ friend bool operator==(const AtomicString &, const AtomicString &);
+ friend bool operator!=(const AtomicString &, const AtomicString &);
+
+ friend bool operator==(const AtomicString &, const char *);
+
+ static void remove(DOMStringImpl *);
+
+private:
+ DOMString m_string;
+
+ static bool equal(DOMStringImpl *, const char *);
+ static bool equal(DOMStringImpl *, const QChar *, uint length);
+ static bool equal(DOMStringImpl *, DOMStringImpl *);
+
+ static bool equal(const AtomicString &a, const AtomicString &b)
+ { return a.m_string.implementation() == b.m_string.implementation(); }
+ static bool equal(const AtomicString &a, const char *b)
+ { return equal(a.m_string.implementation(), b); }
+
+ static DOMStringImpl *add(const char *);
+ static DOMStringImpl *add(const QChar *, int length);
+ static DOMStringImpl *add(DOMStringImpl *);
+
+ static void insert(DOMStringImpl *);
+
+ static void rehash(int newTableSize);
+ static void expand();
+ static void shrink();
+
+ static DOMStringImpl **_table;
+ static int _tableSize;
+ static int _tableSizeMask;
+ static int _keyCount;
+};
+
+inline bool operator==(const AtomicString &a, const AtomicString &b)
+{ return AtomicString::equal(a, b); }
+
+inline bool operator!=(const AtomicString &a, const AtomicString &b)
+{ return !AtomicString::equal(a, b); }
+inline bool operator==(const AtomicString &a, const char *b)
+{ return AtomicString::equal(a, b); }
+
+// List of property names, passed to a macro so we can do set them up various
+// ways without repeating the list.
+#define KHTML_ATOMICSTRING_EACH_GLOBAL(macro)
+
+ // Define external global variables for all property names above (and one more).
+#if !KHTML_ATOMICSTRING_HIDE_GLOBALS
+#define KHTML_ATOMICSTRING_DECLARE_GLOBAL(name) extern const AtomicString name ## PropertyName;
+ KHTML_ATOMICSTRING_EACH_GLOBAL(KHTML_ATOMICSTRING_DECLARE_GLOBAL)
+ KHTML_ATOMICSTRING_DECLARE_GLOBAL(specialPrototype)
+#undef KHTML_ATOMICSTRING_DECLARE_GLOBAL
+#endif
+
class AtomicStringList {
public:
AtomicStringList() :m_next(0) {}
diff --git a/WebCore/khtml/xml/dom_stringimpl.cpp b/WebCore/khtml/xml/dom_stringimpl.cpp
index f47d553..9e6edad 100644
--- a/WebCore/khtml/xml/dom_stringimpl.cpp
+++ b/WebCore/khtml/xml/dom_stringimpl.cpp
@@ -28,16 +28,37 @@
#include <kdebug.h>
#include <string.h>
+#include "dom_nameimpl.h"
-using namespace DOM;
using namespace khtml;
namespace DOM {
using khtml::Fixed;
+DOMStringImpl* DOMStringImpl::empty()
+{
+ static DOMStringImpl e = WithOneRef();
+ return &e;
+}
+
+DOMStringImpl::DOMStringImpl(const QChar *str, unsigned int len) {
+ _hash = 0;
+ bool havestr = str && len;
+ s = QT_ALLOC_QCHAR_VEC( havestr ? len : 1 );
+ if(str && len) {
+ memcpy( s, str, len * sizeof(QChar) );
+ l = len;
+ } else {
+ // crash protection
+ s[0] = 0x0;
+ l = 0;
+ }
+}
+
DOMStringImpl::DOMStringImpl(const char *str)
{
+ _hash = 0;
if(str && *str)
{
l = strlen(str);
@@ -55,8 +76,36 @@ DOMStringImpl::DOMStringImpl(const char *str)
}
}
+DOMStringImpl::DOMStringImpl(const char *str, unsigned int len)
+{
+ _hash = 0;
+ l = len;
+ if (!l || !str)
+ return;
+
+ s = QT_ALLOC_QCHAR_VEC(l);
+ int i = l;
+ QChar* ptr = s;
+ while( i-- )
+ *ptr++ = *str++;
+}
+
+DOMStringImpl::DOMStringImpl(const QChar &ch) {
+ _hash = 0;
+ s = QT_ALLOC_QCHAR_VEC( 1 );
+ s[0] = ch;
+ l = 1;
+}
+
+DOMStringImpl::~DOMStringImpl()
+{
+ if (_hash) AtomicString::remove(this);
+ if(s) QT_DELETE_QCHAR_VEC(s);
+}
+
void DOMStringImpl::append(DOMStringImpl *str)
{
+ assert(_hash == 0);
if(str && str->l != 0)
{
int newlen = l+str->l;
@@ -71,6 +120,7 @@ void DOMStringImpl::append(DOMStringImpl *str)
void DOMStringImpl::insert(DOMStringImpl *str, uint pos)
{
+ assert(_hash == 0);
if(pos > l)
{
append(str);
@@ -91,6 +141,7 @@ void DOMStringImpl::insert(DOMStringImpl *str, uint pos)
void DOMStringImpl::truncate(int len)
{
+ assert(_hash == 0);
if(len > (int)l) return;
int nl = len < 1 ? 1 : len;
@@ -103,31 +154,33 @@ void DOMStringImpl::truncate(int len)
void DOMStringImpl::remove(uint pos, int len)
{
- if(len <= 0) return;
- if(pos >= l ) return;
- if((unsigned)len > l - pos)
+ assert(_hash == 0);
+ if(len <= 0) return;
+ if(pos >= l ) return;
+ if((unsigned)len > l - pos)
len = l - pos;
- uint newLen = l-len;
- QChar *c = QT_ALLOC_QCHAR_VEC(newLen);
- memcpy(c, s, pos*sizeof(QChar));
- memcpy(c+pos, s+pos+len, (l-len-pos)*sizeof(QChar));
- if(s) QT_DELETE_QCHAR_VEC(s);
- s = c;
- l = newLen;
+ uint newLen = l-len;
+ QChar *c = QT_ALLOC_QCHAR_VEC(newLen);
+ memcpy(c, s, pos*sizeof(QChar));
+ memcpy(c+pos, s+pos+len, (l-len-pos)*sizeof(QChar));
+ if(s) QT_DELETE_QCHAR_VEC(s);
+ s = c;
+ l = newLen;
}
DOMStringImpl *DOMStringImpl::split(uint pos)
{
- if( pos >=l ) return new DOMStringImpl();
+ assert(_hash == 0);
+ if( pos >=l ) return new DOMStringImpl();
- uint newLen = l-pos;
- QChar *c = QT_ALLOC_QCHAR_VEC(newLen);
- memcpy(c, s+pos, newLen*sizeof(QChar));
+ uint newLen = l-pos;
+ QChar *c = QT_ALLOC_QCHAR_VEC(newLen);
+ memcpy(c, s+pos, newLen*sizeof(QChar));
- DOMStringImpl *str = new DOMStringImpl(s + pos, newLen);
- truncate(pos);
- return str;
+ DOMStringImpl *str = new DOMStringImpl(s + pos, newLen);
+ truncate(pos);
+ return str;
}
bool DOMStringImpl::containsOnlyWhitespace() const
@@ -149,11 +202,10 @@ bool DOMStringImpl::containsOnlyWhitespace() const
DOMStringImpl *DOMStringImpl::substring(uint pos, uint len)
{
- if( pos >=l ) return new DOMStringImpl();
- if(len > l - pos)
+ if (pos >=l) return new DOMStringImpl();
+ if (len > l - pos)
len = l - pos;
-
- return new DOMStringImpl(s + pos, len);
+ return new DOMStringImpl(s + pos, len);
}
static Length parseLength(QChar *s, unsigned int l)
@@ -350,4 +402,77 @@ DOMStringImpl *DOMStringImpl::replace(QChar oldC, QChar newC)
return c;
}
+// Golden ratio - arbitrary start value to avoid mapping all 0's to all 0's
+// or anything like that.
+const unsigned PHI = 0x9e3779b9U;
+
+// This hash algorithm comes from:
+// http://burtleburtle.net/bob/hash/hashfaq.html
+// http://burtleburtle.net/bob/hash/doobs.html
+unsigned DOMStringImpl::computeHash(const QChar *s, int length)
+{
+ int prefixLength = length < 8 ? length : 8;
+ int suffixPosition = length < 16 ? 8 : length - 8;
+
+ unsigned h = PHI;
+ h += length;
+ h += (h << 10);
+ h ^= (h << 6);
+
+ for (int i = 0; i < prefixLength; i++) {
+ h += s[i].unicode();
+ h += (h << 10);
+ h ^= (h << 6);
+ }
+ for (int i = suffixPosition; i < length; i++){
+ h += s[i].unicode();
+ h += (h << 10);
+ h ^= (h << 6);
+ }
+
+ h += (h << 3);
+ h ^= (h >> 11);
+ h += (h << 15);
+
+ if (h == 0)
+ h = 0x80000000;
+
+ return h;
+}
+
+// This hash algorithm comes from:
+// http://burtleburtle.net/bob/hash/hashfaq.html
+// http://burtleburtle.net/bob/hash/doobs.html
+unsigned DOMStringImpl::computeHash(const char *s)
+{
+ int length = strlen(s);
+ int prefixLength = length < 8 ? length : 8;
+ int suffixPosition = length < 16 ? 8 : length - 8;
+
+ unsigned h = PHI;
+ h += length;
+ h += (h << 10);
+ h ^= (h << 6);
+
+ for (int i = 0; i < prefixLength; i++) {
+ h += (unsigned char)s[i];
+ h += (h << 10);
+ h ^= (h << 6);
+ }
+ for (int i = suffixPosition; i < length; i++) {
+ h += (unsigned char)s[i];
+ h += (h << 10);
+ h ^= (h << 6);
+ }
+
+ h += (h << 3);
+ h ^= (h >> 11);
+ h += (h << 15);
+
+ if (h == 0)
+ h = 0x80000000;
+
+ return h;
+}
+
} // namespace DOM
diff --git a/WebCore/khtml/xml/dom_stringimpl.h b/WebCore/khtml/xml/dom_stringimpl.h
index d5c073e..d590c1a 100644
--- a/WebCore/khtml/xml/dom_stringimpl.h
+++ b/WebCore/khtml/xml/dom_stringimpl.h
@@ -35,32 +35,23 @@ namespace DOM {
class DOMStringImpl : public khtml::Shared<DOMStringImpl>
{
+private:
+ struct WithOneRef { };
+ DOMStringImpl(WithOneRef) { s = 0; l = 0; _hash = 0; ref(); }
+
protected:
- DOMStringImpl() { s = 0, l = 0; }
+ DOMStringImpl() { s = 0, l = 0; _hash = 0; }
public:
- DOMStringImpl(const QChar *str, unsigned int len) {
- bool havestr = str && len;
- s = QT_ALLOC_QCHAR_VEC( havestr ? len : 1 );
- if(str && len) {
- memcpy( s, str, len * sizeof(QChar) );
- l = len;
- } else {
- // crash protection
- s[0] = 0x0;
- l = 0;
- }
- }
-
+ DOMStringImpl(const QChar *str, unsigned int len);
DOMStringImpl(const char *str);
- DOMStringImpl(const QChar &ch) {
- s = QT_ALLOC_QCHAR_VEC( 1 );
- s[0] = ch;
- l = 1;
- }
- ~DOMStringImpl() {
- if(s) QT_DELETE_QCHAR_VEC(s);
- }
-
+ DOMStringImpl(const char *str, unsigned int len);
+ DOMStringImpl(const QChar &ch);
+ ~DOMStringImpl();
+
+ unsigned hash() const { if (_hash == 0) _hash = computeHash(s, l); return _hash; }
+ static unsigned computeHash(const QChar *, int length);
+ static unsigned computeHash(const char *);
+
void append(DOMStringImpl *str);
void insert(DOMStringImpl *str, unsigned int pos);
void truncate(int len);
@@ -91,8 +82,11 @@ public:
// This modifies the string in place if there is only one ref, makes a new string otherwise.
DOMStringImpl *replace(QChar, QChar);
+ static DOMStringImpl* empty();
+
unsigned int l;
QChar *s;
+ mutable unsigned _hash;
};
};
diff --git a/WebCore/khtml/xml/dom_textimpl.cpp b/WebCore/khtml/xml/dom_textimpl.cpp
index aa9ff47..4f7a9ab 100644
--- a/WebCore/khtml/xml/dom_textimpl.cpp
+++ b/WebCore/khtml/xml/dom_textimpl.cpp
@@ -45,7 +45,7 @@ CharacterDataImpl::CharacterDataImpl(DocumentPtr *doc)
CharacterDataImpl::CharacterDataImpl(DocumentPtr *doc, const DOMString &_text)
: NodeImpl(doc)
{
- str = _text.impl ? _text.impl : new DOMStringImpl(0, 0);
+ str = _text.impl ? _text.impl : new DOMStringImpl((QChar*)0, 0);
str->ref();
}
--
WebKit Debian packaging
More information about the Pkg-webkit-commits
mailing list