Fix for <rdar://problem/5108896>, make sure the assert for setEncodedSize
[WebKit-https.git] / WebCore / loader / CachedResource.cpp
1 /*
2     This file is part of the KDE libraries
3
4     Copyright (C) 1998 Lars Knoll (knoll@mpi-hd.mpg.de)
5     Copyright (C) 2001 Dirk Mueller (mueller@kde.org)
6     Copyright (C) 2002 Waldo Bastian (bastian@kde.org)
7     Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com)
8     Copyright (C) 2004, 2005, 2006 Apple Computer, Inc.
9
10     This library is free software; you can redistribute it and/or
11     modify it under the terms of the GNU Library General Public
12     License as published by the Free Software Foundation; either
13     version 2 of the License, or (at your option) any later version.
14
15     This library is distributed in the hope that it will be useful,
16     but WITHOUT ANY WARRANTY; without even the implied warranty of
17     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18     Library General Public License for more details.
19
20     You should have received a copy of the GNU Library General Public License
21     along with this library; see the file COPYING.LIB.  If not, write to
22     the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
23     Boston, MA 02111-1307, USA.
24
25     This class provides all functionality needed for loading images, style sheets and html
26     pages from the web. It has a memory cache for these objects.
27 */
28
29 #include "config.h"
30 #include "CachedResource.h"
31
32 #include "Cache.h"
33 #include "FrameLoader.h"
34 #include "Request.h"
35 #include <KURL.h>
36 #include <wtf/Vector.h>
37
38 namespace WebCore {
39
40 CachedResource::CachedResource(const String& URL, Type type)
41 {
42     m_url = URL;
43     m_type = type;
44     m_status = Pending;
45     m_encodedSize = 0;
46     m_inCache = false;
47     m_request = 0;
48
49     m_accessCount = 0;
50     m_liveAccessCount = 0;
51     
52     m_nextInAllResourcesList = 0;
53     m_prevInAllResourcesList = 0;
54     
55     m_nextInLiveResourcesList = 0;
56     m_prevInLiveResourcesList = 0;
57
58 #ifndef NDEBUG
59     m_deleted = false;
60     m_lruIndex = 0;
61     m_liveLRUIndex = 0;
62 #endif
63     m_errorOccurred = false;
64     m_shouldTreatAsLocal = FrameLoader::shouldTreatURLAsLocal(m_url);
65 }
66
67 CachedResource::~CachedResource()
68 {
69     ASSERT(!inCache());
70     ASSERT(!m_deleted);
71 #ifndef NDEBUG
72     m_deleted = true;
73 #endif
74 }
75
76 void CachedResource::finish()
77 {
78     m_status = Cached;
79 }
80
81 bool CachedResource::isExpired() const
82 {
83     if (!m_response.expirationDate())
84         return false;
85     time_t now = time(0);
86     return (difftime(now, m_response.expirationDate()) >= 0);
87 }
88
89 void CachedResource::setRequest(Request* request)
90 {
91     if (request && !m_request)
92         m_status = Pending;
93     m_request = request;
94     if (canDelete() && !inCache())
95         delete this;
96 }
97
98 void CachedResource::ref(CachedResourceClient *c)
99 {
100     if (!referenced() && inCache()) {
101         increaseLiveAccessCount();
102         cache()->addToLiveResourcesSize(this);
103         cache()->insertInLiveResourcesList(this);
104     }
105     m_clients.add(c);
106 }
107
108 void CachedResource::deref(CachedResourceClient *c)
109 {
110     ASSERT(m_clients.contains(c));
111     m_clients.remove(c);
112     if (canDelete() && !inCache())
113         delete this;
114     else if (!referenced() && inCache()) {
115         cache()->removeFromLiveResourcesSize(this);
116         cache()->removeFromLiveResourcesList(this);
117         resetLiveAccessCount();
118         allReferencesRemoved();
119         cache()->pruneAllResources();
120     }
121 }
122
123 void CachedResource::setEncodedSize(unsigned size)
124 {
125     if (size == m_encodedSize)
126         return;
127
128     // The size cannot ever shrink (unless it is being nulled out because of an error).  If it ever does, assert.
129     ASSERT(size == 0 || size >= m_encodedSize);
130     
131     unsigned oldSize = m_encodedSize;
132
133     // The object must now be moved to a different queue, since its size has been changed.
134     // We have to remove explicitly before updating m_encodedSize, so that we find the correct previous
135     // queue.
136     if (inCache())
137         cache()->removeFromLRUList(this);
138     
139     m_encodedSize = size;
140    
141     if (inCache()) { 
142         // Now insert into the new LRU list.
143         cache()->insertInLRUList(this);
144         
145         // Update the cache's size totals.
146         cache()->adjustSize(referenced(), size - oldSize, 0);
147     }
148 }
149
150 void CachedResource::liveResourceAccessed()
151 {
152     if (inCache()) {
153         cache()->removeFromLiveResourcesList(this);
154         increaseLiveAccessCount();
155         cache()->insertInLiveResourcesList(this);
156         cache()->pruneLiveResources();
157     }
158 }
159
160 }