[SCM] WebKit Debian packaging branch, debian/unstable, updated. debian/1.1.15-1-40151-g37bb677

mjs mjs at 268f45cc-cd09-0410-ab3c-d52691b4dbfc
Sat Sep 26 05:58:40 UTC 2009


The following commit has been merged in the debian/unstable branch:
commit ee07229c8cb55a5adc62b24fad19faeaa3567c3d
Author: mjs <mjs at 268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Mon Mar 25 12:18:48 2002 +0000

    	Improved KURL performance:
    
    	* src/kwq/kdecore/kurl.h, src/kwq/KWQKURL.mm:
    	(KURL::normalizeURLString): New function to cache rewritten URL
    	strings.
    	(RelativeURLKeyRetainCallBack, RelativeURLKeyReleaseCallBack,
    	RelativeURLKeyCopyDescriptionCallBack,
    	RelativeURLKeyEqualCallBack, RelativeURLKeyHashCallBack,
    	KURL::normalizeRelativeURLString): Cache results of relative URL
    	resolution.
    	(KURL::clearCaches): function to clear the caches so they don't
    	grow forever.
    	(KURL::KURL): Set nothing but the string at construction time.
    	(KURL::isEmpty, KURL::isMalformed, KURL::hasPath, KURL::url,
    	KURL::protocol, KURL::host, KURL::port, KURL::pass, KURL::user,
    	KURL::ref, KURL::query, KURL::path, KURL::setProtocol,
    	KURL::setHost, KURL::setPort, KURL::setRef, KURL::setQuery,
    	KURL::setPath, KURL::prettyURL, KURL::copyOnWrite, KURL::parse,
    	KURL::assemble): Parse into parts on demand instead.
    	(KURL::swap, KURL::operator=): Handle KURL's new urlString field.
    
    	* src/kwq/KWQKloader.mm: (Cache::requestImage, Cache::requestStyleSheet,
    	Cache::requestScript): Don't redundantly check if KURL isMalformed.
    
    	* src/kwq/KWQKHTMLPart.mm (KHTMLPart::end): Clear KURL caches at
    	the end of each page load.
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@839 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/WebCore/ChangeLog-2002-12-03 b/WebCore/ChangeLog-2002-12-03
index f9331be..a13b9f8 100644
--- a/WebCore/ChangeLog-2002-12-03
+++ b/WebCore/ChangeLog-2002-12-03
@@ -1,3 +1,32 @@
+2002-03-25  Maciej Stachowiak  <mjs at apple.com>
+
+	Improved KURL performance:
+
+	* src/kwq/kdecore/kurl.h, src/kwq/KWQKURL.mm: 
+	(KURL::normalizeURLString): New function to cache rewritten URL
+	strings.
+	(RelativeURLKeyRetainCallBack, RelativeURLKeyReleaseCallBack,
+	RelativeURLKeyCopyDescriptionCallBack,
+	RelativeURLKeyEqualCallBack, RelativeURLKeyHashCallBack,
+	KURL::normalizeRelativeURLString): Cache results of relative URL
+	resolution.
+	(KURL::clearCaches): function to clear the caches so they don't
+	grow forever.
+	(KURL::KURL): Set nothing but the string at construction time.
+	(KURL::isEmpty, KURL::isMalformed, KURL::hasPath, KURL::url,
+	KURL::protocol, KURL::host, KURL::port, KURL::pass, KURL::user,
+	KURL::ref, KURL::query, KURL::path, KURL::setProtocol,
+	KURL::setHost, KURL::setPort, KURL::setRef, KURL::setQuery,
+	KURL::setPath, KURL::prettyURL, KURL::copyOnWrite, KURL::parse,
+	KURL::assemble): Parse into parts on demand instead.
+	(KURL::swap, KURL::operator=): Handle KURL's new urlString field.
+	
+	* src/kwq/KWQKloader.mm: (Cache::requestImage, Cache::requestStyleSheet,
+	Cache::requestScript): Don't redundantly check if KURL isMalformed.
+
+	* src/kwq/KWQKHTMLPart.mm (KHTMLPart::end): Clear KURL caches at
+	the end of each page load.
+
 2002-03-24  Darin Adler  <darin at apple.com>
 
 	* src/kwq/KWQListImpl.mm: (KWQListImpl::getFirst), (KWQListImpl::getLast):
diff --git a/WebCore/ChangeLog-2003-10-25 b/WebCore/ChangeLog-2003-10-25
index f9331be..a13b9f8 100644
--- a/WebCore/ChangeLog-2003-10-25
+++ b/WebCore/ChangeLog-2003-10-25
@@ -1,3 +1,32 @@
+2002-03-25  Maciej Stachowiak  <mjs at apple.com>
+
+	Improved KURL performance:
+
+	* src/kwq/kdecore/kurl.h, src/kwq/KWQKURL.mm: 
+	(KURL::normalizeURLString): New function to cache rewritten URL
+	strings.
+	(RelativeURLKeyRetainCallBack, RelativeURLKeyReleaseCallBack,
+	RelativeURLKeyCopyDescriptionCallBack,
+	RelativeURLKeyEqualCallBack, RelativeURLKeyHashCallBack,
+	KURL::normalizeRelativeURLString): Cache results of relative URL
+	resolution.
+	(KURL::clearCaches): function to clear the caches so they don't
+	grow forever.
+	(KURL::KURL): Set nothing but the string at construction time.
+	(KURL::isEmpty, KURL::isMalformed, KURL::hasPath, KURL::url,
+	KURL::protocol, KURL::host, KURL::port, KURL::pass, KURL::user,
+	KURL::ref, KURL::query, KURL::path, KURL::setProtocol,
+	KURL::setHost, KURL::setPort, KURL::setRef, KURL::setQuery,
+	KURL::setPath, KURL::prettyURL, KURL::copyOnWrite, KURL::parse,
+	KURL::assemble): Parse into parts on demand instead.
+	(KURL::swap, KURL::operator=): Handle KURL's new urlString field.
+	
+	* src/kwq/KWQKloader.mm: (Cache::requestImage, Cache::requestStyleSheet,
+	Cache::requestScript): Don't redundantly check if KURL isMalformed.
+
+	* src/kwq/KWQKHTMLPart.mm (KHTMLPart::end): Clear KURL caches at
+	the end of each page load.
+
 2002-03-24  Darin Adler  <darin at apple.com>
 
 	* src/kwq/KWQListImpl.mm: (KWQListImpl::getFirst), (KWQListImpl::getLast):
diff --git a/WebCore/ChangeLog-2005-08-23 b/WebCore/ChangeLog-2005-08-23
index f9331be..a13b9f8 100644
--- a/WebCore/ChangeLog-2005-08-23
+++ b/WebCore/ChangeLog-2005-08-23
@@ -1,3 +1,32 @@
+2002-03-25  Maciej Stachowiak  <mjs at apple.com>
+
+	Improved KURL performance:
+
+	* src/kwq/kdecore/kurl.h, src/kwq/KWQKURL.mm: 
+	(KURL::normalizeURLString): New function to cache rewritten URL
+	strings.
+	(RelativeURLKeyRetainCallBack, RelativeURLKeyReleaseCallBack,
+	RelativeURLKeyCopyDescriptionCallBack,
+	RelativeURLKeyEqualCallBack, RelativeURLKeyHashCallBack,
+	KURL::normalizeRelativeURLString): Cache results of relative URL
+	resolution.
+	(KURL::clearCaches): function to clear the caches so they don't
+	grow forever.
+	(KURL::KURL): Set nothing but the string at construction time.
+	(KURL::isEmpty, KURL::isMalformed, KURL::hasPath, KURL::url,
+	KURL::protocol, KURL::host, KURL::port, KURL::pass, KURL::user,
+	KURL::ref, KURL::query, KURL::path, KURL::setProtocol,
+	KURL::setHost, KURL::setPort, KURL::setRef, KURL::setQuery,
+	KURL::setPath, KURL::prettyURL, KURL::copyOnWrite, KURL::parse,
+	KURL::assemble): Parse into parts on demand instead.
+	(KURL::swap, KURL::operator=): Handle KURL's new urlString field.
+	
+	* src/kwq/KWQKloader.mm: (Cache::requestImage, Cache::requestStyleSheet,
+	Cache::requestScript): Don't redundantly check if KURL isMalformed.
+
+	* src/kwq/KWQKHTMLPart.mm (KHTMLPart::end): Clear KURL caches at
+	the end of each page load.
+
 2002-03-24  Darin Adler  <darin at apple.com>
 
 	* src/kwq/KWQListImpl.mm: (KWQListImpl::getFirst), (KWQListImpl::getLast):
diff --git a/WebCore/kwq/KWQKHTMLPart.mm b/WebCore/kwq/KWQKHTMLPart.mm
index 7b30c60..b45d01e 100644
--- a/WebCore/kwq/KWQKHTMLPart.mm
+++ b/WebCore/kwq/KWQKHTMLPart.mm
@@ -653,6 +653,7 @@ void KHTMLPart::end()
     //QString str = d->m_doc->recursive_toHTML(1);
     
     d->m_doc->close();
+    KURL::clearCaches();
 }
 
 KHTMLSettings *KHTMLPart::settings()
diff --git a/WebCore/kwq/KWQKHTMLPartImpl.mm b/WebCore/kwq/KWQKHTMLPartImpl.mm
index 7b30c60..b45d01e 100644
--- a/WebCore/kwq/KWQKHTMLPartImpl.mm
+++ b/WebCore/kwq/KWQKHTMLPartImpl.mm
@@ -653,6 +653,7 @@ void KHTMLPart::end()
     //QString str = d->m_doc->recursive_toHTML(1);
     
     d->m_doc->close();
+    KURL::clearCaches();
 }
 
 KHTMLSettings *KHTMLPart::settings()
diff --git a/WebCore/kwq/KWQKURL.h b/WebCore/kwq/KWQKURL.h
index c3aec6b..ba74ee6 100644
--- a/WebCore/kwq/KWQKURL.h
+++ b/WebCore/kwq/KWQKURL.h
@@ -62,6 +62,7 @@ public:
     // static member functions -------------------------------------------------
 
     static QString decode_string(const QString &urlString);
+    static void clearCaches();
 
     // constructors, copy constructors, and destructors ------------------------
 
@@ -106,11 +107,17 @@ public:
 // private ---------------------------------------------------------------------
 
 private:
+    void swap(KURL &other);
     void copyOnWrite();
+    void parse() const;
+    void assemble();
+    QString normalizeURLString(const QString &s);
+    QString normalizeRelativeURLString(const KURL &base, const QString &relative);
 
     class KWQKURLPrivate;
 
-    KWQRefPtr<KWQKURLPrivate> d;
+    mutable KWQRefPtr<KWQKURLPrivate> d;
+    QString urlString;
 }; // class KURL ===============================================================
 
 #endif
diff --git a/WebCore/kwq/KWQKURL.mm b/WebCore/kwq/KWQKURL.mm
index c9445c1..d79f967 100644
--- a/WebCore/kwq/KWQKURL.mm
+++ b/WebCore/kwq/KWQKURL.mm
@@ -29,6 +29,7 @@
 #ifndef USING_BORROWED_KURL
 
 #import <Foundation/NSURLPathUtilities.h>
+#include <CoreFoundation/CoreFoundation.h>
 
 class KURL::KWQKURLPrivate
 {
@@ -277,44 +278,179 @@ void KURL::KWQKURLPrivate::compose()
     }
 }
 
-// KURL
+struct RelativeURLKey {
+    CFStringRef base;
+    CFStringRef relative;
+};
 
-KURL::KURL() : 
-    d(new KURL::KWQKURLPrivate(QString()))
+static const void *RelativeURLKeyRetainCallBack(CFAllocatorRef allocator, const void *value)
 {
+    RelativeURLKey *key = value;
+    CFRetain(key->base);
+    CFRetain(key->relative);
+    return key;
 }
 
-KURL::KURL(const char *url, int encoding_hint=0) :
-    d(new KURL::KWQKURLPrivate(url))
+static void RelativeURLKeyReleaseCallBack(CFAllocatorRef allocator, const void *value)
 {
+    RelativeURLKey *key = value;
+    CFRelease(key->base);
+    CFRelease(key->relative);
+    delete key;
 }
 
-KURL::KURL(const QString &url, int encoding_hint=0) :
-    d(new KURL::KWQKURLPrivate(url))
+static CFStringRef RelativeURLKeyCopyDescriptionCallBack(const void *value)
+{
+    return CFSTR("");
+}
+
+static unsigned char RelativeURLKeyEqualCallBack(const void *value1, const void *value2)
 {
+    RelativeURLKey *key1 = value1;
+    RelativeURLKey *key2 = value2;
+    
+    return CFEqual(key1->base, key2->base) && CFEqual(key1->relative, key2->relative);
 }
 
-KURL::KURL(const KURL &base, const QString &relative)
+static CFHashCode RelativeURLKeyHashCallBack(const void *value)
 {
-    if (relative.isEmpty()) {
-	d = base.d;
+    RelativeURLKey *key = value;
+    return CFHash(key->base) ^ CFHash(key->relative);
+}
+
+static const  CFDictionaryKeyCallBacks RelativeURLKeyCallBacks = {
+    0,
+    RelativeURLKeyRetainCallBack,
+    RelativeURLKeyReleaseCallBack,
+    RelativeURLKeyCopyDescriptionCallBack,
+    RelativeURLKeyEqualCallBack,
+    RelativeURLKeyHashCallBack,
+};
+
+
+static CFMutableDictionaryRef NormalizedURLCache = NULL;
+static CFMutableDictionaryRef NormalizedRelativeURLCache = NULL;
+
+void KURL::clearCaches()
+{
+    if (NormalizedURLCache != NULL) {
+	CFDictionaryRemoveAllValues(NormalizedURLCache);
+    }
+    if (NormalizedRelativeURLCache != NULL) {
+	CFDictionaryRemoveAllValues(NormalizedRelativeURLCache);
+    }
+}
+
+QString KURL::normalizeURLString(const QString &s)
+{
+    CFMutableStringRef result = NULL;
+
+    if (NormalizedURLCache == NULL) {
+	NormalizedURLCache = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); 
+    }
+
+    result = CFDictionaryGetValue(NormalizedURLCache, s.getCFMutableString());
+
+    if (result != NULL) {
+	return QString::fromCFMutableString(result);
+    } else {
+	// normalize the URL string as KURL would:
+
+	QString qurl = QString(s);
+
+	// Special handling for paths
+	if (!qurl.isEmpty() && qurl[0] == '/') {
+	    qurl = QString("file:") + qurl;
+	}
+
+	if (d.isNull()) {
+	    d = KWQRefPtr<KURL::KWQKURLPrivate>(new KURL::KWQKURLPrivate(qurl));
+	}
+
+	qurl = d->sURL;
+
+	if (qurl.startsWith("file:///")) {
+	    qurl = QString("file:/") + qurl.mid(8);
+	} else if (qurl == "file://localhost") {
+	    qurl = QString("file:");
+	} else if (qurl.startsWith("file://localhost/")) {
+	    qurl = QString("file:/") + qurl.mid(17);
+	}
+
+	CFDictionarySetValue(NormalizedURLCache, s.getCFMutableString(), qurl.getCFMutableString());
+
+	return qurl;
+    }
+}
+
+
+QString KURL::normalizeRelativeURLString(const KURL &base, const QString &relative)
+{
+    CFMutableStringRef result = NULL;
+    RelativeURLKey key = { base.urlString.getCFMutableString(), relative.getCFMutableString() };
+
+    if (NormalizedRelativeURLCache == NULL) {
+	NormalizedRelativeURLCache = CFDictionaryCreateMutable(NULL, 0, &RelativeURLKeyCallBacks, &kCFTypeDictionaryValueCallBacks); 
+    }
+
+    result = CFDictionaryGetValue(NormalizedRelativeURLCache, &key);
+
+    if (result != NULL) {
+	return QString::fromCFMutableString(result);
     } else {
-	CFURLRef relativeURL = CFURLCreateWithString(NULL, relative.getCFMutableString(), base.d->urlRef);
-	if (relativeURL == NULL) {
-	    d = KWQRefPtr<KURL::KWQKURLPrivate>(new KURL::KWQKURLPrivate(relative));
+	QString result;
+	if (relative.isEmpty()) {
+	    result = base.urlString;
 	} else {
-	    CFURLRef absoluteURL = CFURLCopyAbsoluteURL(relativeURL);
-	
-	    d = KWQRefPtr<KURL::KWQKURLPrivate>(new KURL::KWQKURLPrivate(QString::fromCFString(CFURLGetString(absoluteURL))));
-	    
-	    CFRelease (relativeURL);
-	    CFRelease (absoluteURL);
+	    base.parse();
+
+	    CFURLRef relativeURL = CFURLCreateWithString(NULL, relative.getCFMutableString(), base.d->urlRef);
+	    if (relativeURL == NULL) {
+		result = normalizeURLString(relative);
+	    } else {
+		CFURLRef absoluteURL = CFURLCopyAbsoluteURL(relativeURL);
+		result = normalizeURLString(QString::fromCFString(CFURLGetString(absoluteURL)));
+		CFRelease(relativeURL);
+		CFRelease(absoluteURL);
+	    }
 	}
+		
+	CFDictionarySetValue(NormalizedRelativeURLCache, 
+			     new RelativeURLKey(key), 
+			     result.getCFMutableString());
+	return result;
     }
 }
 
+// KURL
+
+KURL::KURL() : 
+    d(NULL),
+    urlString(normalizeURLString(QString()))
+{
+}
+
+KURL::KURL(const char *url, int encoding_hint=0) :
+    d(NULL),
+    urlString(normalizeURLString(url))
+{
+}
+
+KURL::KURL(const QString &url, int encoding_hint=0) :
+    d(NULL),
+    urlString(normalizeURLString(url))
+{
+}
+
+KURL::KURL(const KURL &base, const QString &relative) :
+    d(NULL),
+    urlString(normalizeRelativeURLString(base, relative))
+{
+}
+
 KURL::KURL(const KURL &other) : 
-    d(other.d)
+    d(other.d),
+    urlString(other.urlString)
 {
 }
 
@@ -324,80 +460,72 @@ KURL::~KURL()
 
 bool KURL::isEmpty() const
 {
+    parse();
     return d->sURL.isEmpty();
 }
 
 bool KURL::isMalformed() const
 {
+    parse();
     return (d->urlRef == NULL);
 }
 
 bool KURL::hasPath() const
 {
+    parse();
     return !d->sPath.isEmpty();
 }
 
 QString KURL::url() const
 {
-    if (d->urlRef == NULL) {
-        return d->sURL;
-    } 
-
-    QString qurl = QString::fromCFString(CFURLGetString(d->urlRef));
-
-    // Special handling for file: URLs
-    if (qurl.startsWith("file:///")) {
-        qurl = QString("file:/") + qurl.mid(8);
-    } else if (d->sURL == "file://localhost") {
-        qurl = QString("file:/");
-    } else if (qurl.startsWith("file://localhost/")) {
-        qurl = QString("file:/") + qurl.mid(17);
-    }
-
-    if (d->addedSlash) {
-	qurl = qurl.left(qurl.length()-1);
-    }
-
-    return qurl;
+    return urlString;
 }
 
 QString KURL::protocol() const
 {
+    parse();
     return d->sProtocol;
 }
 
 QString KURL::host() const
 {
+    parse();
     return d->sHost;
 }
 
 unsigned short int KURL::port() const
 {
+    parse();
     return d->iPort;
 }
 
 QString KURL::pass() const
 {
+    parse();
     return d->sPass;
 }
 
 QString KURL::user() const
 {
+    parse();
     return d->sUser;
 }
 
 QString KURL::ref() const
 {
+    parse();
     return d->sRef;
 }
 
 QString KURL::query() const
 {
+    parse();
     return d->sQuery;
 }
 
 QString KURL::path() const
 {
+    parse();
     return d->sPath;
 }
 
@@ -405,28 +533,28 @@ void KURL::setProtocol(const QString &s)
 {
     copyOnWrite();
     d->sProtocol = s;
-    d->compose();
+    assemble();
 }
 
 void KURL::setHost(const QString &s)
 {
     copyOnWrite();
     d->sHost = s;
-    d->compose();
+    assemble();
 }
 
 void KURL::setPort(unsigned short i)
 {
     copyOnWrite();
     d->iPort = i;
-    d->compose();
+    assemble();
 }
 
 void KURL::setRef(const QString &s)
 {
     copyOnWrite();
     d->sRef = s;
-    d->compose();
+    assemble();
 }
 
 void KURL::setQuery(const QString &query, int encoding_hint=0)
@@ -437,7 +565,7 @@ void KURL::setQuery(const QString &query, int encoding_hint=0)
     } else {
 	d->sQuery = "?" + query;
     }
-    d->compose();
+    assemble();
 }
 
 void KURL::setPath(const QString &s)
@@ -445,11 +573,12 @@ void KURL::setPath(const QString &s)
     copyOnWrite();
     d->sPath = s;
     d->escapedPath = escapeQString(s);
-    d->compose();
+    assemble();
 }
 
 QString KURL::prettyURL(int trailing=0) const
 {
+    parse();
     if (d->urlRef == NULL) {
         return d->sURL;
     }
@@ -492,18 +621,23 @@ QString KURL::prettyURL(int trailing=0) const
 }
 
 
-KURL &KURL::operator=(const KURL &other)
+void KURL::swap(KURL &other)
 {
-    KURL tmp(other);
-    KWQRefPtr<KURL::KWQKURLPrivate> tmpD = tmp.d;
+    KWQRefPtr<KURL::KWQKURLPrivate> tmpD = other.d;
+    QString tmpString = other.urlString;
     
-    tmp.d = d;
+    other.d = d;
     d = tmpD;
-    
-    return *this;
-}
+    other.urlString = urlString;
+    urlString = tmpString;
+}   
 
 
+KURL &KURL::operator=(const KURL &other)
+{
+    KURL(other).swap(*this);
+    return *this;
+}
 
 QString KURL::decode_string(const QString &urlString)
 {
@@ -514,14 +648,28 @@ QString KURL::decode_string(const QString &urlString)
     return qUnescaped;
 }
 
-
 void KURL::copyOnWrite()
 {
+    parse();
     if (d->refCount > 1) {
 	d = KWQRefPtr<KURL::KWQKURLPrivate>(new KURL::KWQKURLPrivate(*d));
     }
 }
 
+void KURL::parse() const
+{
+    if (d.isNull()) {
+	d = KWQRefPtr<KURL::KWQKURLPrivate>(new KURL::KWQKURLPrivate(urlString));
+    }
+}
+
+void KURL::assemble()
+{
+    if (!d.isNull()) {
+	d->compose();
+	urlString = d->sURL;
+    }
+}
 
 #endif
 
diff --git a/WebCore/kwq/KWQKloader.mm b/WebCore/kwq/KWQKloader.mm
index 5f1719f..b2cf3c9 100644
--- a/WebCore/kwq/KWQKloader.mm
+++ b/WebCore/kwq/KWQKloader.mm
@@ -1451,14 +1451,6 @@ CachedImage *Cache::requestImage( DocLoader* dl, const DOMString & url, bool rel
     else
         kurl = url.string();
 
-    if( kurl.isMalformed() )
-    {
-#ifdef CACHE_DEBUG
-      kdDebug( 6060 ) << "Cache: Malformed url: " << kurl.url() << endl;
-#endif
-      return 0;
-    }
-
     CachedObject *o = 0;
     if (!reload)
         o = cache->find(kurl.url());
@@ -1509,12 +1501,6 @@ CachedCSSStyleSheet *Cache::requestStyleSheet( DocLoader* dl, const DOMString &
     else
         kurl = url.string();
 
-    if( kurl.isMalformed() )
-    {
-      kdDebug( 6060 ) << "Cache: Malformed url: " << kurl.url() << endl;
-      return 0;
-    }
-
     CachedObject *o = cache->find(kurl.url());
     if(!o)
     {
@@ -1562,12 +1548,6 @@ CachedScript *Cache::requestScript( DocLoader* dl, const DOM::DOMString &url, bo
     else
         kurl = url.string();
 
-    if( kurl.isMalformed() )
-    {
-      kdDebug( 6060 ) << "Cache: Malformed url: " << kurl.url() << endl;
-      return 0;
-    }
-
     CachedObject *o = cache->find(kurl.url());
     if(!o)
     {
diff --git a/WebCore/kwq/KWQLoader.mm b/WebCore/kwq/KWQLoader.mm
index 5f1719f..b2cf3c9 100644
--- a/WebCore/kwq/KWQLoader.mm
+++ b/WebCore/kwq/KWQLoader.mm
@@ -1451,14 +1451,6 @@ CachedImage *Cache::requestImage( DocLoader* dl, const DOMString & url, bool rel
     else
         kurl = url.string();
 
-    if( kurl.isMalformed() )
-    {
-#ifdef CACHE_DEBUG
-      kdDebug( 6060 ) << "Cache: Malformed url: " << kurl.url() << endl;
-#endif
-      return 0;
-    }
-
     CachedObject *o = 0;
     if (!reload)
         o = cache->find(kurl.url());
@@ -1509,12 +1501,6 @@ CachedCSSStyleSheet *Cache::requestStyleSheet( DocLoader* dl, const DOMString &
     else
         kurl = url.string();
 
-    if( kurl.isMalformed() )
-    {
-      kdDebug( 6060 ) << "Cache: Malformed url: " << kurl.url() << endl;
-      return 0;
-    }
-
     CachedObject *o = cache->find(kurl.url());
     if(!o)
     {
@@ -1562,12 +1548,6 @@ CachedScript *Cache::requestScript( DocLoader* dl, const DOM::DOMString &url, bo
     else
         kurl = url.string();
 
-    if( kurl.isMalformed() )
-    {
-      kdDebug( 6060 ) << "Cache: Malformed url: " << kurl.url() << endl;
-      return 0;
-    }
-
     CachedObject *o = cache->find(kurl.url());
     if(!o)
     {
diff --git a/WebCore/kwq/KWQLoaderImpl.mm b/WebCore/kwq/KWQLoaderImpl.mm
index 5f1719f..b2cf3c9 100644
--- a/WebCore/kwq/KWQLoaderImpl.mm
+++ b/WebCore/kwq/KWQLoaderImpl.mm
@@ -1451,14 +1451,6 @@ CachedImage *Cache::requestImage( DocLoader* dl, const DOMString & url, bool rel
     else
         kurl = url.string();
 
-    if( kurl.isMalformed() )
-    {
-#ifdef CACHE_DEBUG
-      kdDebug( 6060 ) << "Cache: Malformed url: " << kurl.url() << endl;
-#endif
-      return 0;
-    }
-
     CachedObject *o = 0;
     if (!reload)
         o = cache->find(kurl.url());
@@ -1509,12 +1501,6 @@ CachedCSSStyleSheet *Cache::requestStyleSheet( DocLoader* dl, const DOMString &
     else
         kurl = url.string();
 
-    if( kurl.isMalformed() )
-    {
-      kdDebug( 6060 ) << "Cache: Malformed url: " << kurl.url() << endl;
-      return 0;
-    }
-
     CachedObject *o = cache->find(kurl.url());
     if(!o)
     {
@@ -1562,12 +1548,6 @@ CachedScript *Cache::requestScript( DocLoader* dl, const DOM::DOMString &url, bo
     else
         kurl = url.string();
 
-    if( kurl.isMalformed() )
-    {
-      kdDebug( 6060 ) << "Cache: Malformed url: " << kurl.url() << endl;
-      return 0;
-    }
-
     CachedObject *o = cache->find(kurl.url());
     if(!o)
     {
diff --git a/WebCore/kwq/kdecore/kurl.h b/WebCore/kwq/kdecore/kurl.h
index c3aec6b..ba74ee6 100644
--- a/WebCore/kwq/kdecore/kurl.h
+++ b/WebCore/kwq/kdecore/kurl.h
@@ -62,6 +62,7 @@ public:
     // static member functions -------------------------------------------------
 
     static QString decode_string(const QString &urlString);
+    static void clearCaches();
 
     // constructors, copy constructors, and destructors ------------------------
 
@@ -106,11 +107,17 @@ public:
 // private ---------------------------------------------------------------------
 
 private:
+    void swap(KURL &other);
     void copyOnWrite();
+    void parse() const;
+    void assemble();
+    QString normalizeURLString(const QString &s);
+    QString normalizeRelativeURLString(const KURL &base, const QString &relative);
 
     class KWQKURLPrivate;
 
-    KWQRefPtr<KWQKURLPrivate> d;
+    mutable KWQRefPtr<KWQKURLPrivate> d;
+    QString urlString;
 }; // class KURL ===============================================================
 
 #endif
diff --git a/WebCore/src/kwq/KWQKHTMLPart.mm b/WebCore/src/kwq/KWQKHTMLPart.mm
index 7b30c60..b45d01e 100644
--- a/WebCore/src/kwq/KWQKHTMLPart.mm
+++ b/WebCore/src/kwq/KWQKHTMLPart.mm
@@ -653,6 +653,7 @@ void KHTMLPart::end()
     //QString str = d->m_doc->recursive_toHTML(1);
     
     d->m_doc->close();
+    KURL::clearCaches();
 }
 
 KHTMLSettings *KHTMLPart::settings()
diff --git a/WebCore/src/kwq/KWQKURL.mm b/WebCore/src/kwq/KWQKURL.mm
index c9445c1..d79f967 100644
--- a/WebCore/src/kwq/KWQKURL.mm
+++ b/WebCore/src/kwq/KWQKURL.mm
@@ -29,6 +29,7 @@
 #ifndef USING_BORROWED_KURL
 
 #import <Foundation/NSURLPathUtilities.h>
+#include <CoreFoundation/CoreFoundation.h>
 
 class KURL::KWQKURLPrivate
 {
@@ -277,44 +278,179 @@ void KURL::KWQKURLPrivate::compose()
     }
 }
 
-// KURL
+struct RelativeURLKey {
+    CFStringRef base;
+    CFStringRef relative;
+};
 
-KURL::KURL() : 
-    d(new KURL::KWQKURLPrivate(QString()))
+static const void *RelativeURLKeyRetainCallBack(CFAllocatorRef allocator, const void *value)
 {
+    RelativeURLKey *key = value;
+    CFRetain(key->base);
+    CFRetain(key->relative);
+    return key;
 }
 
-KURL::KURL(const char *url, int encoding_hint=0) :
-    d(new KURL::KWQKURLPrivate(url))
+static void RelativeURLKeyReleaseCallBack(CFAllocatorRef allocator, const void *value)
 {
+    RelativeURLKey *key = value;
+    CFRelease(key->base);
+    CFRelease(key->relative);
+    delete key;
 }
 
-KURL::KURL(const QString &url, int encoding_hint=0) :
-    d(new KURL::KWQKURLPrivate(url))
+static CFStringRef RelativeURLKeyCopyDescriptionCallBack(const void *value)
+{
+    return CFSTR("");
+}
+
+static unsigned char RelativeURLKeyEqualCallBack(const void *value1, const void *value2)
 {
+    RelativeURLKey *key1 = value1;
+    RelativeURLKey *key2 = value2;
+    
+    return CFEqual(key1->base, key2->base) && CFEqual(key1->relative, key2->relative);
 }
 
-KURL::KURL(const KURL &base, const QString &relative)
+static CFHashCode RelativeURLKeyHashCallBack(const void *value)
 {
-    if (relative.isEmpty()) {
-	d = base.d;
+    RelativeURLKey *key = value;
+    return CFHash(key->base) ^ CFHash(key->relative);
+}
+
+static const  CFDictionaryKeyCallBacks RelativeURLKeyCallBacks = {
+    0,
+    RelativeURLKeyRetainCallBack,
+    RelativeURLKeyReleaseCallBack,
+    RelativeURLKeyCopyDescriptionCallBack,
+    RelativeURLKeyEqualCallBack,
+    RelativeURLKeyHashCallBack,
+};
+
+
+static CFMutableDictionaryRef NormalizedURLCache = NULL;
+static CFMutableDictionaryRef NormalizedRelativeURLCache = NULL;
+
+void KURL::clearCaches()
+{
+    if (NormalizedURLCache != NULL) {
+	CFDictionaryRemoveAllValues(NormalizedURLCache);
+    }
+    if (NormalizedRelativeURLCache != NULL) {
+	CFDictionaryRemoveAllValues(NormalizedRelativeURLCache);
+    }
+}
+
+QString KURL::normalizeURLString(const QString &s)
+{
+    CFMutableStringRef result = NULL;
+
+    if (NormalizedURLCache == NULL) {
+	NormalizedURLCache = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); 
+    }
+
+    result = CFDictionaryGetValue(NormalizedURLCache, s.getCFMutableString());
+
+    if (result != NULL) {
+	return QString::fromCFMutableString(result);
+    } else {
+	// normalize the URL string as KURL would:
+
+	QString qurl = QString(s);
+
+	// Special handling for paths
+	if (!qurl.isEmpty() && qurl[0] == '/') {
+	    qurl = QString("file:") + qurl;
+	}
+
+	if (d.isNull()) {
+	    d = KWQRefPtr<KURL::KWQKURLPrivate>(new KURL::KWQKURLPrivate(qurl));
+	}
+
+	qurl = d->sURL;
+
+	if (qurl.startsWith("file:///")) {
+	    qurl = QString("file:/") + qurl.mid(8);
+	} else if (qurl == "file://localhost") {
+	    qurl = QString("file:");
+	} else if (qurl.startsWith("file://localhost/")) {
+	    qurl = QString("file:/") + qurl.mid(17);
+	}
+
+	CFDictionarySetValue(NormalizedURLCache, s.getCFMutableString(), qurl.getCFMutableString());
+
+	return qurl;
+    }
+}
+
+
+QString KURL::normalizeRelativeURLString(const KURL &base, const QString &relative)
+{
+    CFMutableStringRef result = NULL;
+    RelativeURLKey key = { base.urlString.getCFMutableString(), relative.getCFMutableString() };
+
+    if (NormalizedRelativeURLCache == NULL) {
+	NormalizedRelativeURLCache = CFDictionaryCreateMutable(NULL, 0, &RelativeURLKeyCallBacks, &kCFTypeDictionaryValueCallBacks); 
+    }
+
+    result = CFDictionaryGetValue(NormalizedRelativeURLCache, &key);
+
+    if (result != NULL) {
+	return QString::fromCFMutableString(result);
     } else {
-	CFURLRef relativeURL = CFURLCreateWithString(NULL, relative.getCFMutableString(), base.d->urlRef);
-	if (relativeURL == NULL) {
-	    d = KWQRefPtr<KURL::KWQKURLPrivate>(new KURL::KWQKURLPrivate(relative));
+	QString result;
+	if (relative.isEmpty()) {
+	    result = base.urlString;
 	} else {
-	    CFURLRef absoluteURL = CFURLCopyAbsoluteURL(relativeURL);
-	
-	    d = KWQRefPtr<KURL::KWQKURLPrivate>(new KURL::KWQKURLPrivate(QString::fromCFString(CFURLGetString(absoluteURL))));
-	    
-	    CFRelease (relativeURL);
-	    CFRelease (absoluteURL);
+	    base.parse();
+
+	    CFURLRef relativeURL = CFURLCreateWithString(NULL, relative.getCFMutableString(), base.d->urlRef);
+	    if (relativeURL == NULL) {
+		result = normalizeURLString(relative);
+	    } else {
+		CFURLRef absoluteURL = CFURLCopyAbsoluteURL(relativeURL);
+		result = normalizeURLString(QString::fromCFString(CFURLGetString(absoluteURL)));
+		CFRelease(relativeURL);
+		CFRelease(absoluteURL);
+	    }
 	}
+		
+	CFDictionarySetValue(NormalizedRelativeURLCache, 
+			     new RelativeURLKey(key), 
+			     result.getCFMutableString());
+	return result;
     }
 }
 
+// KURL
+
+KURL::KURL() : 
+    d(NULL),
+    urlString(normalizeURLString(QString()))
+{
+}
+
+KURL::KURL(const char *url, int encoding_hint=0) :
+    d(NULL),
+    urlString(normalizeURLString(url))
+{
+}
+
+KURL::KURL(const QString &url, int encoding_hint=0) :
+    d(NULL),
+    urlString(normalizeURLString(url))
+{
+}
+
+KURL::KURL(const KURL &base, const QString &relative) :
+    d(NULL),
+    urlString(normalizeRelativeURLString(base, relative))
+{
+}
+
 KURL::KURL(const KURL &other) : 
-    d(other.d)
+    d(other.d),
+    urlString(other.urlString)
 {
 }
 
@@ -324,80 +460,72 @@ KURL::~KURL()
 
 bool KURL::isEmpty() const
 {
+    parse();
     return d->sURL.isEmpty();
 }
 
 bool KURL::isMalformed() const
 {
+    parse();
     return (d->urlRef == NULL);
 }
 
 bool KURL::hasPath() const
 {
+    parse();
     return !d->sPath.isEmpty();
 }
 
 QString KURL::url() const
 {
-    if (d->urlRef == NULL) {
-        return d->sURL;
-    } 
-
-    QString qurl = QString::fromCFString(CFURLGetString(d->urlRef));
-
-    // Special handling for file: URLs
-    if (qurl.startsWith("file:///")) {
-        qurl = QString("file:/") + qurl.mid(8);
-    } else if (d->sURL == "file://localhost") {
-        qurl = QString("file:/");
-    } else if (qurl.startsWith("file://localhost/")) {
-        qurl = QString("file:/") + qurl.mid(17);
-    }
-
-    if (d->addedSlash) {
-	qurl = qurl.left(qurl.length()-1);
-    }
-
-    return qurl;
+    return urlString;
 }
 
 QString KURL::protocol() const
 {
+    parse();
     return d->sProtocol;
 }
 
 QString KURL::host() const
 {
+    parse();
     return d->sHost;
 }
 
 unsigned short int KURL::port() const
 {
+    parse();
     return d->iPort;
 }
 
 QString KURL::pass() const
 {
+    parse();
     return d->sPass;
 }
 
 QString KURL::user() const
 {
+    parse();
     return d->sUser;
 }
 
 QString KURL::ref() const
 {
+    parse();
     return d->sRef;
 }
 
 QString KURL::query() const
 {
+    parse();
     return d->sQuery;
 }
 
 QString KURL::path() const
 {
+    parse();
     return d->sPath;
 }
 
@@ -405,28 +533,28 @@ void KURL::setProtocol(const QString &s)
 {
     copyOnWrite();
     d->sProtocol = s;
-    d->compose();
+    assemble();
 }
 
 void KURL::setHost(const QString &s)
 {
     copyOnWrite();
     d->sHost = s;
-    d->compose();
+    assemble();
 }
 
 void KURL::setPort(unsigned short i)
 {
     copyOnWrite();
     d->iPort = i;
-    d->compose();
+    assemble();
 }
 
 void KURL::setRef(const QString &s)
 {
     copyOnWrite();
     d->sRef = s;
-    d->compose();
+    assemble();
 }
 
 void KURL::setQuery(const QString &query, int encoding_hint=0)
@@ -437,7 +565,7 @@ void KURL::setQuery(const QString &query, int encoding_hint=0)
     } else {
 	d->sQuery = "?" + query;
     }
-    d->compose();
+    assemble();
 }
 
 void KURL::setPath(const QString &s)
@@ -445,11 +573,12 @@ void KURL::setPath(const QString &s)
     copyOnWrite();
     d->sPath = s;
     d->escapedPath = escapeQString(s);
-    d->compose();
+    assemble();
 }
 
 QString KURL::prettyURL(int trailing=0) const
 {
+    parse();
     if (d->urlRef == NULL) {
         return d->sURL;
     }
@@ -492,18 +621,23 @@ QString KURL::prettyURL(int trailing=0) const
 }
 
 
-KURL &KURL::operator=(const KURL &other)
+void KURL::swap(KURL &other)
 {
-    KURL tmp(other);
-    KWQRefPtr<KURL::KWQKURLPrivate> tmpD = tmp.d;
+    KWQRefPtr<KURL::KWQKURLPrivate> tmpD = other.d;
+    QString tmpString = other.urlString;
     
-    tmp.d = d;
+    other.d = d;
     d = tmpD;
-    
-    return *this;
-}
+    other.urlString = urlString;
+    urlString = tmpString;
+}   
 
 
+KURL &KURL::operator=(const KURL &other)
+{
+    KURL(other).swap(*this);
+    return *this;
+}
 
 QString KURL::decode_string(const QString &urlString)
 {
@@ -514,14 +648,28 @@ QString KURL::decode_string(const QString &urlString)
     return qUnescaped;
 }
 
-
 void KURL::copyOnWrite()
 {
+    parse();
     if (d->refCount > 1) {
 	d = KWQRefPtr<KURL::KWQKURLPrivate>(new KURL::KWQKURLPrivate(*d));
     }
 }
 
+void KURL::parse() const
+{
+    if (d.isNull()) {
+	d = KWQRefPtr<KURL::KWQKURLPrivate>(new KURL::KWQKURLPrivate(urlString));
+    }
+}
+
+void KURL::assemble()
+{
+    if (!d.isNull()) {
+	d->compose();
+	urlString = d->sURL;
+    }
+}
 
 #endif
 
diff --git a/WebCore/src/kwq/KWQKloader.mm b/WebCore/src/kwq/KWQKloader.mm
index 5f1719f..b2cf3c9 100644
--- a/WebCore/src/kwq/KWQKloader.mm
+++ b/WebCore/src/kwq/KWQKloader.mm
@@ -1451,14 +1451,6 @@ CachedImage *Cache::requestImage( DocLoader* dl, const DOMString & url, bool rel
     else
         kurl = url.string();
 
-    if( kurl.isMalformed() )
-    {
-#ifdef CACHE_DEBUG
-      kdDebug( 6060 ) << "Cache: Malformed url: " << kurl.url() << endl;
-#endif
-      return 0;
-    }
-
     CachedObject *o = 0;
     if (!reload)
         o = cache->find(kurl.url());
@@ -1509,12 +1501,6 @@ CachedCSSStyleSheet *Cache::requestStyleSheet( DocLoader* dl, const DOMString &
     else
         kurl = url.string();
 
-    if( kurl.isMalformed() )
-    {
-      kdDebug( 6060 ) << "Cache: Malformed url: " << kurl.url() << endl;
-      return 0;
-    }
-
     CachedObject *o = cache->find(kurl.url());
     if(!o)
     {
@@ -1562,12 +1548,6 @@ CachedScript *Cache::requestScript( DocLoader* dl, const DOM::DOMString &url, bo
     else
         kurl = url.string();
 
-    if( kurl.isMalformed() )
-    {
-      kdDebug( 6060 ) << "Cache: Malformed url: " << kurl.url() << endl;
-      return 0;
-    }
-
     CachedObject *o = cache->find(kurl.url());
     if(!o)
     {
diff --git a/WebCore/src/kwq/kdecore/kurl.h b/WebCore/src/kwq/kdecore/kurl.h
index c3aec6b..ba74ee6 100644
--- a/WebCore/src/kwq/kdecore/kurl.h
+++ b/WebCore/src/kwq/kdecore/kurl.h
@@ -62,6 +62,7 @@ public:
     // static member functions -------------------------------------------------
 
     static QString decode_string(const QString &urlString);
+    static void clearCaches();
 
     // constructors, copy constructors, and destructors ------------------------
 
@@ -106,11 +107,17 @@ public:
 // private ---------------------------------------------------------------------
 
 private:
+    void swap(KURL &other);
     void copyOnWrite();
+    void parse() const;
+    void assemble();
+    QString normalizeURLString(const QString &s);
+    QString normalizeRelativeURLString(const KURL &base, const QString &relative);
 
     class KWQKURLPrivate;
 
-    KWQRefPtr<KWQKURLPrivate> d;
+    mutable KWQRefPtr<KWQKURLPrivate> d;
+    QString urlString;
 }; // class KURL ===============================================================
 
 #endif

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list