[Win] Unreviewed build fix after r207218.
[WebKit-https.git] / Source / WebKit / win / WebCache.cpp
1 /*
2  * Copyright (C) 2006-2007, 2015 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 "WebKitDLL.h"
27 #include "WebCache.h"
28
29 #include "CFDictionaryPropertyBag.h"
30 #include "WebApplicationCache.h"
31 #include <WebCore/ApplicationCacheStorage.h>
32 #include <WebCore/BString.h>
33 #include <WebCore/MemoryCache.h>
34 #include <WebCore/CrossOriginPreflightResultCache.h>
35
36 #if USE(CURL)
37 #include <WebCore/CurlCacheManager.h>
38 #elif USE(CFURLCONNECTION)
39 #include <CFNetwork/CFURLCachePriv.h>
40 #include <WebKitSystemInterface/WebKitSystemInterface.h>
41 #endif
42
43 using namespace WebCore;
44
45 // WebCache ---------------------------------------------------------------------------
46
47 WebCache::WebCache()
48 {
49     gClassCount++;
50     gClassNameCount().add("WebCache");
51 }
52
53 WebCache::~WebCache()
54 {
55     gClassCount--;
56     gClassNameCount().remove("WebCache");
57 }
58
59 WebCache* WebCache::createInstance()
60 {
61     WebCache* instance = new WebCache();
62     instance->AddRef();
63     return instance;
64 }
65
66 // IUnknown -------------------------------------------------------------------
67
68 HRESULT WebCache::QueryInterface(_In_ REFIID riid, _COM_Outptr_ void** ppvObject)
69 {
70     if (!ppvObject)
71         return E_POINTER;
72     *ppvObject = nullptr;
73     if (IsEqualGUID(riid, IID_IUnknown))
74         *ppvObject = static_cast<WebCache*>(this);
75     else if (IsEqualGUID(riid, IID_IWebCache))
76         *ppvObject = static_cast<WebCache*>(this);
77     else
78         return E_NOINTERFACE;
79
80     AddRef();
81     return S_OK;
82 }
83
84 ULONG WebCache::AddRef()
85 {
86     return ++m_refCount;
87 }
88
89 ULONG WebCache::Release()
90 {
91     ULONG newRef = --m_refCount;
92     if (!newRef)
93         delete(this);
94
95     return newRef;
96 }
97
98 // IWebCache ------------------------------------------------------------------------------
99
100 HRESULT WebCache::statistics(_Inout_ int* count, _Inout_opt_ IPropertyBag** s)
101 {
102     if (!count || (s && *count < 6))
103         return E_FAIL;
104
105     *count = 6;
106     if (!s)
107         return S_OK;
108
109     WebCore::MemoryCache::Statistics stat = WebCore::MemoryCache::singleton().getStatistics();
110
111     static CFStringRef imagesKey = CFSTR("images");
112     static CFStringRef stylesheetsKey = CFSTR("style sheets");
113     static CFStringRef xslKey = CFSTR("xsl");
114     static CFStringRef scriptsKey = CFSTR("scripts");
115 #if !ENABLE(XSLT)
116     const int zero = 0;
117 #endif
118
119     // Object Counts.
120     RetainPtr<CFMutableDictionaryRef> dictionary = adoptCF(CFDictionaryCreateMutable(0, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
121
122     RetainPtr<CFNumberRef> value = adoptCF(CFNumberCreate(0, kCFNumberIntType, &stat.images.count));
123     CFDictionaryAddValue(dictionary.get(), imagesKey, value.get());
124     
125     value = adoptCF(CFNumberCreate(0, kCFNumberIntType, &stat.cssStyleSheets.count));
126     CFDictionaryAddValue(dictionary.get(), stylesheetsKey, value.get());
127     
128 #if ENABLE(XSLT)
129     value = adoptCF(CFNumberCreate(0, kCFNumberIntType, &stat.xslStyleSheets.count));
130 #else
131     value = adoptCF(CFNumberCreate(0, kCFNumberIntType, &zero));
132 #endif
133     CFDictionaryAddValue(dictionary.get(), xslKey, value.get());
134
135     value = adoptCF(CFNumberCreate(0, kCFNumberIntType, &stat.scripts.count));
136     CFDictionaryAddValue(dictionary.get(), scriptsKey, value.get());
137
138     COMPtr<CFDictionaryPropertyBag> propBag = CFDictionaryPropertyBag::createInstance();
139     propBag->setDictionary(dictionary.get());
140     s[0] = propBag.leakRef();
141
142     // Object Sizes.
143     dictionary = adoptCF(CFDictionaryCreateMutable(0, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
144
145     value = adoptCF(CFNumberCreate(0, kCFNumberIntType, &stat.images.size));
146     CFDictionaryAddValue(dictionary.get(), imagesKey, value.get());
147     
148     value = adoptCF(CFNumberCreate(0, kCFNumberIntType, &stat.cssStyleSheets.size));
149     CFDictionaryAddValue(dictionary.get(), stylesheetsKey, value.get());
150     
151 #if ENABLE(XSLT)
152     value = adoptCF(CFNumberCreate(0, kCFNumberIntType, &stat.xslStyleSheets.size));
153 #else
154     value = adoptCF(CFNumberCreate(0, kCFNumberIntType, &zero));
155 #endif
156     CFDictionaryAddValue(dictionary.get(), xslKey, value.get());
157
158     value = adoptCF(CFNumberCreate(0, kCFNumberIntType, &stat.scripts.size));
159     CFDictionaryAddValue(dictionary.get(), scriptsKey, value.get());
160
161     propBag = CFDictionaryPropertyBag::createInstance();
162     propBag->setDictionary(dictionary.get());
163     s[1] = propBag.leakRef();
164
165     // Live Sizes.
166     dictionary = adoptCF(CFDictionaryCreateMutable(0, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
167
168     value = adoptCF(CFNumberCreate(0, kCFNumberIntType, &stat.images.liveSize));
169     CFDictionaryAddValue(dictionary.get(), imagesKey, value.get());
170     
171     value = adoptCF(CFNumberCreate(0, kCFNumberIntType, &stat.cssStyleSheets.liveSize));
172     CFDictionaryAddValue(dictionary.get(), stylesheetsKey, value.get());
173     
174 #if ENABLE(XSLT)
175     value = adoptCF(CFNumberCreate(0, kCFNumberIntType, &stat.xslStyleSheets.liveSize));
176 #else
177     value = adoptCF(CFNumberCreate(0, kCFNumberIntType, &zero));
178 #endif
179     CFDictionaryAddValue(dictionary.get(), xslKey, value.get());
180
181     value = adoptCF(CFNumberCreate(0, kCFNumberIntType, &stat.scripts.liveSize));
182     CFDictionaryAddValue(dictionary.get(), scriptsKey, value.get());
183
184     propBag = CFDictionaryPropertyBag::createInstance();
185     propBag->setDictionary(dictionary.get());
186     s[2] = propBag.leakRef();
187
188     // Decoded Sizes.
189     dictionary = adoptCF(CFDictionaryCreateMutable(0, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
190
191     value = adoptCF(CFNumberCreate(0, kCFNumberIntType, &stat.images.decodedSize));
192     CFDictionaryAddValue(dictionary.get(), imagesKey, value.get());
193     
194     value = adoptCF(CFNumberCreate(0, kCFNumberIntType, &stat.cssStyleSheets.decodedSize));
195     CFDictionaryAddValue(dictionary.get(), stylesheetsKey, value.get());
196     
197 #if ENABLE(XSLT)
198     value = adoptCF(CFNumberCreate(0, kCFNumberIntType, &stat.xslStyleSheets.decodedSize));
199 #else
200     value = adoptCF(CFNumberCreate(0, kCFNumberIntType, &zero));
201 #endif
202     CFDictionaryAddValue(dictionary.get(), xslKey, value.get());
203
204     value = adoptCF(CFNumberCreate(0, kCFNumberIntType, &stat.scripts.decodedSize));
205     CFDictionaryAddValue(dictionary.get(), scriptsKey, value.get());
206
207     propBag = CFDictionaryPropertyBag::createInstance();
208     propBag->setDictionary(dictionary.get());
209     s[3] = propBag.leakRef();
210
211     return S_OK;
212 }
213
214 HRESULT WebCache::empty()
215 {
216     auto& memoryCache = WebCore::MemoryCache::singleton();
217     if (memoryCache.disabled())
218         return S_OK;
219     memoryCache.setDisabled(true);
220     memoryCache.setDisabled(false);
221
222     // Empty the application cache.
223     WebApplicationCache::storage().empty();
224
225     // Empty the Cross-Origin Preflight cache
226     WebCore::CrossOriginPreflightResultCache::singleton().empty();
227
228     return S_OK;
229 }
230
231 HRESULT WebCache::setDisabled(BOOL disabled)
232 {
233     WebCore::MemoryCache::singleton().setDisabled(!!disabled);
234     return S_OK;
235 }
236
237 HRESULT WebCache::disabled(_Out_ BOOL* disabled)
238 {
239     if (!disabled)
240         return E_POINTER;
241     *disabled = WebCore::MemoryCache::singleton().disabled();
242     return S_OK;
243 }
244
245 HRESULT WebCache::cacheFolder(__deref_out_opt BSTR* location)
246 {
247 #if USE(CURL)
248     String cacheFolder = WebCore::CurlCacheManager::getInstance().cacheDirectory();
249     *location = WebCore::BString(cacheFolder).release();
250     return S_OK;
251 #elif USE(CFURLCONNECTION)
252     RetainPtr<CFStringRef> cfurlCacheDirectory = adoptCF(wkCopyFoundationCacheDirectory(0));
253     *location = BString(cfurlCacheDirectory.get()).release();
254     return S_OK;
255 #else
256     return E_NOTIMPL;
257 #endif
258 }
259
260 HRESULT WebCache::setCacheFolder(_In_ BSTR location)
261 {
262 #if USE(CURL)
263     String cacheFolder(location, SysStringLen(location));
264     WebCore::CurlCacheManager::getInstance().setCacheDirectory(cacheFolder);
265     return S_OK;
266 #elif USE(CFURLCONNECTION)
267     RetainPtr<CFURLCacheRef> cache = adoptCF(CFURLCacheCopySharedURLCache());
268     CFIndex memoryCapacity = CFURLCacheMemoryCapacity(cache.get());
269     CFIndex diskCapacity = CFURLCacheDiskCapacity(cache.get());
270     RetainPtr<CFURLCacheRef> newCache = adoptCF(CFURLCacheCreate(kCFAllocatorDefault, memoryCapacity, diskCapacity, String(location).createCFString().get()));
271     CFURLCacheSetSharedURLCache(newCache.get());
272     return S_OK;
273 #else
274     return E_NOTIMPL;
275 #endif
276 }