Reviewed by Sarge
[WebKit-https.git] / WebCore / loader / icon / IconLoader.cpp
1 /*
2  * Copyright (C) 2006 Apple Computer, Inc.  All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25  
26 #include "config.h"
27 #include "IconLoader.h"
28
29 #include "dom/Document.h"
30 #include "loader/icon/IconDatabase.h"
31 #include "Logging.h"
32 #include "page/Frame.h"
33
34 #if PLATFORM(MAC)
35 #include "FrameMac.h"
36 #endif
37
38 using namespace WebCore;
39
40 IconLoader::IconLoader(Frame* frame)
41     : m_resourceLoader(0)
42     , m_frame(frame)
43     , m_httpStatusCode(0)
44 {
45 }
46
47 IconLoader* IconLoader::createForFrame(Frame* frame)
48 {
49     if (frame)
50         return new IconLoader(frame);
51     return 0;
52 }
53
54 IconLoader::~IconLoader()
55 {
56     delete m_resourceLoader;
57 }
58
59 void IconLoader::startLoading()
60 {    
61     if (m_resourceLoader)
62         return;
63     
64     m_httpStatusCode = 0;
65     m_resourceLoader = new ResourceLoader(this, "GET", m_frame->iconURL());
66     
67     // A frame may be documentless - one example is viewing a PDF directly
68     if (!m_frame->document()) {
69         // FIXME - http://bugzilla.opendarwin.org/show_bug.cgi?id=10902
70         // Once the loader infrastructure will cleanly let us load an icon without a DocLoader, we can implement this
71         LOG(IconDatabase, "Documentless-frame - icon won't be loaded");
72     } else if (!m_resourceLoader->start(m_frame->document()->docLoader())) {
73         LOG_ERROR("Failed to start load for icon at url %s", m_frame->iconURL().url().ascii());
74         m_resourceLoader = 0;
75     }
76 }
77
78 void IconLoader::stopLoading()
79 {
80     delete m_resourceLoader;
81     m_resourceLoader = 0;
82     m_data.clear();
83 }
84
85 void IconLoader::receivedData(ResourceLoader* resourceLoader, const char* data, int size)
86 {
87     ASSERT(resourceLoader = m_resourceLoader);
88     ASSERT(data);
89     ASSERT(size > -1);
90     
91     for (int i=0; i<size; ++i)
92         m_data.append(data[i]);
93 }
94
95 void IconLoader::receivedAllData(ResourceLoader* resourceLoader)
96 {
97     ASSERT(resourceLoader == m_resourceLoader);
98
99     const char* data;
100     int size;
101     
102     // If we logged an HTTP response, only set the icon data if it was a valid response
103     if (m_httpStatusCode && (m_httpStatusCode < 200 || m_httpStatusCode > 299)) {
104         data = 0;
105         size = 0;
106     } else {
107         data = m_data.data();
108         size = m_data.size();
109     }
110         
111     IconDatabase * iconDatabase = IconDatabase::sharedIconDatabase();
112     ASSERT(iconDatabase);
113     
114     KURL iconURL(resourceLoader->url());
115     
116     if (data)
117         iconDatabase->setIconDataForIconURL(data, size, iconURL.url());
118     else
119         iconDatabase->setHaveNoIconForIconURL(iconURL.url());
120         
121     // We set both the original request URL and the final URL as the PageURLs as different parts
122     // of the app tend to want to retain both
123     iconDatabase->setIconURLForPageURL(iconURL.url(), m_frame->url().url());
124
125     // FIXME - Need to be able to do the following platform independently
126 #if PLATFORM(MAC)
127     FrameMac* frameMac = Mac(m_frame);
128     iconDatabase->setIconURLForPageURL(iconURL.url(), frameMac->originalRequestURL().url());
129 #endif
130
131     notifyIconChanged(iconURL);
132
133     // ResourceLoaders delete themselves after they deliver their last data, so we can just forget about it
134     m_resourceLoader = 0;
135     m_data.clear();
136 }
137