1/* 2 * Copyright (C) 2006, 2007, 2013 Apple 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 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 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 "WebKitDLL.h" 28#include "WebDataSource.h" 29 30#include "WebKit.h" 31#include "MemoryStream.h" 32#include "WebDocumentLoader.h" 33#include "WebError.h" 34#include "WebFrame.h" 35#include "WebFrameLoaderClient.h" 36#include "WebKit.h" 37#include "WebHTMLRepresentation.h" 38#include "WebKitStatisticsPrivate.h" 39#include "WebMutableURLRequest.h" 40#include "WebResource.h" 41#include "WebURLResponse.h" 42#include <WebCore/BString.h> 43#include <WebCore/CachedResourceLoader.h> 44#include <WebCore/Document.h> 45#include <WebCore/Frame.h> 46#include <WebCore/FrameLoader.h> 47#include <WebCore/URL.h> 48#include <WebCore/ResourceBuffer.h> 49 50using namespace WebCore; 51 52// WebDataSource ---------------------------------------------------------------- 53 54// {F230854D-7091-428a-8DB5-37CABA44C105} 55const GUID IID_WebDataSource = 56{ 0x5c2f9099, 0xe65e, 0x4a0f, { 0x9c, 0xa0, 0x6a, 0xd6, 0x92, 0x52, 0xa6, 0x2a } }; 57 58WebDataSource::WebDataSource(WebDocumentLoader* loader) 59 : m_refCount(0) 60 , m_loader(loader) 61{ 62 WebDataSourceCount++; 63 gClassCount++; 64 gClassNameCount.add("WebDataSource"); 65} 66 67WebDataSource::~WebDataSource() 68{ 69 if (m_loader) 70 m_loader->detachDataSource(); 71 WebDataSourceCount--; 72 gClassCount--; 73 gClassNameCount.remove("WebDataSource"); 74} 75 76WebDataSource* WebDataSource::createInstance(WebDocumentLoader* loader) 77{ 78 WebDataSource* instance = new WebDataSource(loader); 79 instance->AddRef(); 80 return instance; 81} 82 83WebDocumentLoader* WebDataSource::documentLoader() const 84{ 85 return m_loader.get(); 86} 87 88// IWebDataSourcePrivate ------------------------------------------------------ 89 90HRESULT STDMETHODCALLTYPE WebDataSource::overrideEncoding( 91 /* [retval][out] */ BSTR* /*encoding*/) 92{ 93 ASSERT_NOT_REACHED(); 94 return E_NOTIMPL; 95} 96 97HRESULT STDMETHODCALLTYPE WebDataSource::setOverrideEncoding( 98 /* [in] */ BSTR /*encoding*/) 99{ 100 ASSERT_NOT_REACHED(); 101 return E_NOTIMPL; 102} 103 104HRESULT STDMETHODCALLTYPE WebDataSource::mainDocumentError( 105 /* [retval][out] */ IWebError** error) 106{ 107 if (!error) { 108 ASSERT_NOT_REACHED(); 109 return E_POINTER; 110 } 111 112 *error = 0; 113 114 if (!m_loader) 115 return E_FAIL; 116 117 if (m_loader->mainDocumentError().isNull()) 118 return S_OK; 119 120 *error = WebError::createInstance(m_loader->mainDocumentError()); 121 return S_OK; 122} 123 124HRESULT STDMETHODCALLTYPE WebDataSource::setDeferMainResourceDataLoad( 125 /* [in] */ BOOL flag) 126{ 127 if (!m_loader) 128 return E_FAIL; 129 130 m_loader->setDeferMainResourceDataLoad(flag); 131 return S_OK; 132} 133 134// IUnknown ------------------------------------------------------------------- 135 136HRESULT STDMETHODCALLTYPE WebDataSource::QueryInterface(REFIID riid, void** ppvObject) 137{ 138 *ppvObject = 0; 139 if (IsEqualGUID(riid, IID_WebDataSource)) 140 *ppvObject = this; 141 else if (IsEqualGUID(riid, IID_IUnknown)) 142 *ppvObject = static_cast<IWebDataSource*>(this); 143 else if (IsEqualGUID(riid, IID_IWebDataSource)) 144 *ppvObject = static_cast<IWebDataSource*>(this); 145 else if (IsEqualGUID(riid, IID_IWebDataSourcePrivate)) 146 *ppvObject = static_cast<IWebDataSourcePrivate*>(this); 147 else 148 return E_NOINTERFACE; 149 150 AddRef(); 151 return S_OK; 152} 153 154ULONG STDMETHODCALLTYPE WebDataSource::AddRef(void) 155{ 156 return ++m_refCount; 157} 158 159ULONG STDMETHODCALLTYPE WebDataSource::Release(void) 160{ 161 ULONG newRef = --m_refCount; 162 if (!newRef) 163 delete(this); 164 165 return newRef; 166} 167 168// IWebDataSource -------------------------------------------------------------- 169 170HRESULT STDMETHODCALLTYPE WebDataSource::initWithRequest( 171 /* [in] */ IWebURLRequest* /*request*/) 172{ 173 ASSERT_NOT_REACHED(); 174 return E_NOTIMPL; 175} 176 177HRESULT STDMETHODCALLTYPE WebDataSource::data( 178 /* [retval][out] */ IStream** stream) 179{ 180 *stream = 0; 181 if (!m_loader) 182 return E_FAIL; 183 184 RefPtr<ResourceBuffer> buffer = m_loader->mainResourceData(); 185 return MemoryStream::createInstance(buffer ? buffer->sharedBuffer() : 0).copyRefTo(stream); 186} 187 188HRESULT WebDataSource::representation(/* [retval][out] */ IWebDocumentRepresentation** rep) 189{ 190 HRESULT hr = S_OK; 191 if (!m_representation) { 192 WebHTMLRepresentation* htmlRep = WebHTMLRepresentation::createInstance(static_cast<WebFrameLoaderClient&>(m_loader->frameLoader()->client()).webFrame()); 193 hr = htmlRep->QueryInterface(IID_IWebDocumentRepresentation, (void**) &m_representation); 194 htmlRep->Release(); 195 } 196 197 return m_representation.copyRefTo(rep); 198} 199 200HRESULT WebDataSource::webFrame(/* [retval][out] */ IWebFrame** frame) 201{ 202 *frame = static_cast<WebFrameLoaderClient&>(m_loader->frameLoader()->client()).webFrame(); 203 (*frame)->AddRef(); 204 return S_OK; 205} 206 207HRESULT STDMETHODCALLTYPE WebDataSource::initialRequest( 208 /* [retval][out] */ IWebURLRequest** request) 209{ 210 *request = WebMutableURLRequest::createInstance(m_loader->originalRequest()); 211 return S_OK; 212} 213 214HRESULT STDMETHODCALLTYPE WebDataSource::request( 215 /* [retval][out] */ IWebMutableURLRequest** request) 216{ 217 *request = WebMutableURLRequest::createInstance(m_loader->request()); 218 return S_OK; 219} 220 221HRESULT STDMETHODCALLTYPE WebDataSource::response( 222 /* [retval][out] */ IWebURLResponse** response) 223{ 224 *response = WebURLResponse::createInstance(m_loader->response()); 225 return S_OK; 226} 227 228HRESULT STDMETHODCALLTYPE WebDataSource::textEncodingName( 229 /* [retval][out] */ BSTR* name) 230{ 231 String encoding = m_loader->overrideEncoding(); 232 if (encoding.isNull()) 233 encoding = m_loader->response().textEncodingName(); 234 235 *name = BString(encoding).release(); 236 237 return S_OK; 238} 239 240HRESULT STDMETHODCALLTYPE WebDataSource::isLoading( 241 /* [retval][out] */ BOOL* loading) 242{ 243 *loading = m_loader->isLoadingInAPISense(); 244 return S_OK; 245} 246 247HRESULT STDMETHODCALLTYPE WebDataSource::pageTitle( 248 /* [retval][out] */ BSTR* title) 249{ 250 *title = BString(m_loader->title().string()).release(); 251 return S_OK; 252} 253 254HRESULT STDMETHODCALLTYPE WebDataSource::unreachableURL( 255 /* [retval][out] */ BSTR* url) 256{ 257 URL unreachableURL = m_loader->unreachableURL(); 258 BString urlString(unreachableURL.string()); 259 260 *url = urlString.release(); 261 return S_OK; 262} 263 264HRESULT STDMETHODCALLTYPE WebDataSource::webArchive( 265 /* [retval][out] */ IWebArchive** /*archive*/) 266{ 267 ASSERT_NOT_REACHED(); 268 return E_NOTIMPL; 269} 270 271HRESULT STDMETHODCALLTYPE WebDataSource::mainResource( 272 /* [retval][out] */ IWebResource** /*resource*/) 273{ 274 ASSERT_NOT_REACHED(); 275 return E_NOTIMPL; 276} 277 278HRESULT STDMETHODCALLTYPE WebDataSource::subresources( 279 /* [retval][out] */ IEnumVARIANT** /*result*/) 280{ 281 ASSERT_NOT_REACHED(); 282 return E_NOTIMPL; 283} 284 285HRESULT STDMETHODCALLTYPE WebDataSource::subresourceForURL( 286 /* [in] */ BSTR url, 287 /* [retval][out] */ IWebResource** resource) 288{ 289 if (!resource) { 290 ASSERT_NOT_REACHED(); 291 return E_POINTER; 292 } 293 294 *resource = 0; 295 296 Document *doc = m_loader->frameLoader()->frame().document(); 297 298 if (!doc) 299 return E_FAIL; 300 301 CachedResource *cachedResource = doc->cachedResourceLoader()->cachedResource(String(url)); 302 303 if (!cachedResource) 304 return E_FAIL; 305 306 ResourceBuffer* buffer = cachedResource->resourceBuffer(); 307 *resource = WebResource::createInstance(buffer ? buffer->sharedBuffer() : 0, cachedResource->response()); 308 return S_OK; 309} 310 311HRESULT STDMETHODCALLTYPE WebDataSource::addSubresource( 312 /* [in] */ IWebResource* /*subresource*/) 313{ 314 ASSERT_NOT_REACHED(); 315 return E_NOTIMPL; 316} 317