bc9a787c339a6ce9dea54bffb23d5b004a8d9101
[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     ASSERT(m_frame->document());
68     if (!m_resourceLoader->start(m_frame->document()->docLoader())) {
69         LOG_ERROR("Failed to start load for icon at url %s", m_frame->iconURL().url().ascii());
70         m_resourceLoader = 0;
71     }
72 }
73
74 void IconLoader::stopLoading()
75 {
76     delete m_resourceLoader;
77     m_resourceLoader = 0;
78     m_data.clear();
79 }
80
81 void IconLoader::receivedData(ResourceLoader* resourceLoader, const char* data, int size)
82 {
83     ASSERT(resourceLoader = m_resourceLoader);
84     ASSERT(data);
85     ASSERT(size > -1);
86     
87     for (int i=0; i<size; ++i)
88         m_data.append(data[i]);
89 }
90
91 void IconLoader::receivedAllData(ResourceLoader* resourceLoader)
92 {
93     ASSERT(resourceLoader == m_resourceLoader);
94
95     const char* data;
96     int size;
97     
98     // If we logged an HTTP response, only set the icon data if it was a valid response
99     if (m_httpStatusCode && (m_httpStatusCode < 200 || m_httpStatusCode > 299)) {
100         data = 0;
101         size = 0;
102     } else {
103         data = m_data.data();
104         size = m_data.size();
105     }
106         
107     IconDatabase * iconDatabase = IconDatabase::sharedIconDatabase();
108     ASSERT(iconDatabase);
109     
110     KURL iconURL(resourceLoader->url());
111     
112     if (data)
113         iconDatabase->setIconDataForIconURL(data, size, iconURL.url());
114     else
115         iconDatabase->setHaveNoIconForIconURL(iconURL.url());
116         
117     // We set both the original request URL and the final URL as the PageURLs as different parts
118     // of the app tend to want to retain both
119     iconDatabase->setIconURLForPageURL(iconURL.url(), m_frame->url().url());
120
121     // FIXME - Need to be able to do the following platform independently
122 #if PLATFORM(MAC)
123     FrameMac* frameMac = Mac(m_frame);
124     iconDatabase->setIconURLForPageURL(iconURL.url(), frameMac->originalRequestURL().url());
125 #endif
126
127     notifyIconChanged(iconURL);
128
129     // ResourceLoaders delete themselves after they deliver their last data, so we can just forget about it
130     m_resourceLoader = 0;
131     m_data.clear();
132 }
133