Back to index

lightning-sunbird  0.9+nobinonly
nsDiskCacheEntry.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
00002  *
00003  * ***** BEGIN LICENSE BLOCK *****
00004  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00005  *
00006  * The contents of this file are subject to the Mozilla Public License Version
00007  * 1.1 (the "License"); you may not use this file except in compliance with
00008  * the License. You may obtain a copy of the License at
00009  * http://www.mozilla.org/MPL/
00010  *
00011  * Software distributed under the License is distributed on an "AS IS" basis,
00012  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00013  * for the specific language governing rights and limitations under the
00014  * License.
00015  *
00016  * The Original Code is nsDiskCacheEntry.cpp, released
00017  * May 10, 2001.
00018  *
00019  * The Initial Developer of the Original Code is
00020  * Netscape Communications Corporation.
00021  * Portions created by the Initial Developer are Copyright (C) 2001
00022  * the Initial Developer. All Rights Reserved.
00023  *
00024  * Contributor(s):
00025  *   Gordon Sheridan  <gordon@netscape.com>
00026  *   Patrick C. Beard <beard@netscape.com>
00027  *
00028  * Alternatively, the contents of this file may be used under the terms of
00029  * either the GNU General Public License Version 2 or later (the "GPL"), or
00030  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00031  * in which case the provisions of the GPL or the LGPL are applicable instead
00032  * of those above. If you wish to allow use of your version of this file only
00033  * under the terms of either the GPL or the LGPL, and not to allow others to
00034  * use your version of this file under the terms of the MPL, indicate your
00035  * decision by deleting the provisions above and replace them with the notice
00036  * and other provisions required by the GPL or the LGPL. If you do not delete
00037  * the provisions above, a recipient may use your version of this file under
00038  * the terms of any one of the MPL, the GPL or the LGPL.
00039  *
00040  * ***** END LICENSE BLOCK ***** */
00041 
00042 #include "nsDiskCache.h"
00043 #include "nsDiskCacheEntry.h"
00044 #include "nsDiskCacheBinding.h"
00045 #include "nsDiskCacheMap.h"
00046 #include "nsCRT.h"
00047 
00048 #include "nsCache.h"
00049 
00050 
00051 /******************************************************************************
00052  *  nsDiskCacheEntry
00053  *****************************************************************************/
00054 
00060 nsCacheEntry *
00061 nsDiskCacheEntry::CreateCacheEntry(nsCacheDevice *  device)
00062 {
00063     nsCacheEntry * entry = nsnull;
00064     nsresult       rv = nsCacheEntry::Create(mKeyStart,
00065                                              nsICache::STREAM_BASED,
00066                                              nsICache::STORE_ON_DISK,
00067                                              device,
00068                                              &entry);
00069     if (NS_FAILED(rv) || !entry) return nsnull;
00070     
00071     entry->SetFetchCount(mFetchCount);
00072     entry->SetLastFetched(mLastFetched);
00073     entry->SetLastModified(mLastModified);
00074     entry->SetExpirationTime(mExpirationTime);
00075     entry->SetCacheDevice(device);
00076     // XXX why does nsCacheService have to fill out device in BindEntry()?
00077     entry->SetDataSize(mDataSize);
00078     
00079     rv = entry->UnflattenMetaData(&mKeyStart[mKeySize], mMetaDataSize);
00080     if (NS_FAILED(rv)) {
00081         delete entry;
00082         return nsnull;
00083     }
00084     
00085     return entry;                      
00086 }
00087 
00088 
00094 PRBool
00095 nsDiskCacheEntry::CheckConsistency(PRUint32  size)
00096 {
00097     if ((mHeaderVersion != nsDiskCache::kCurrentVersion) ||
00098         (Size() > size) ||
00099         (mKeySize == 0) ||
00100         (mKeyStart[mKeySize - 1] != 0)) // key is null terminated
00101         return PR_FALSE;
00102     
00103     return PR_TRUE;
00104 }
00105 
00106 
00112 nsDiskCacheEntry *
00113 CreateDiskCacheEntry(nsDiskCacheBinding *  binding)
00114 {
00115     nsCacheEntry * entry = binding->mCacheEntry;
00116     if (!entry)  return nsnull;
00117     
00118     PRUint32  keySize  = entry->Key()->Length() + 1;
00119     PRUint32  metaSize = entry->MetaDataSize();
00120     PRUint32  size     = sizeof(nsDiskCacheEntry) + keySize + metaSize;
00121     
00122     // pad size so we can write to block files without overrunning buffer
00123     PRInt32 pad;
00124     if      (size <=  1024) pad = (((size-1)/ 256) + 1) *  256;
00125     else if (size <=  4096) pad = (((size-1)/1024) + 1) * 1024;
00126     else if (size <= 16384) pad = (((size-1)/4096) + 1) * 4096;
00127     else return nsnull; // unexpected size!
00128     
00129     nsDiskCacheEntry * diskEntry = (nsDiskCacheEntry *)new char[pad];
00130     if (!diskEntry)  return nsnull;
00131     
00132     diskEntry->mHeaderVersion   = nsDiskCache::kCurrentVersion;
00133     diskEntry->mMetaLocation    = binding->mRecord.MetaLocation();
00134     diskEntry->mFetchCount      = entry->FetchCount();
00135     diskEntry->mLastFetched     = entry->LastFetched();
00136     diskEntry->mLastModified    = entry->LastModified();
00137     diskEntry->mExpirationTime  = entry->ExpirationTime();
00138     diskEntry->mDataSize        = entry->DataSize();
00139     diskEntry->mKeySize         = keySize;
00140     diskEntry->mMetaDataSize    = metaSize;
00141     
00142     memcpy(diskEntry->mKeyStart, entry->Key()->get(),keySize);
00143     
00144     nsresult rv = entry->FlattenMetaData(&diskEntry->mKeyStart[keySize], metaSize);
00145     if (NS_FAILED(rv)) {
00146         delete [] (char *)diskEntry;
00147         return nsnull;
00148     }
00149         
00150     pad -= diskEntry->Size();
00151     NS_ASSERTION(pad >= 0, "under allocated buffer for diskEntry.");
00152     if (pad > 0)
00153         memset(&diskEntry->mKeyStart[keySize+metaSize], 0, pad);
00154     
00155     return  diskEntry;
00156 }
00157 
00158 
00159 /******************************************************************************
00160  *  nsDiskCacheEntryInfo
00161  *****************************************************************************/
00162 
00163 NS_IMPL_ISUPPORTS1(nsDiskCacheEntryInfo, nsICacheEntryInfo)
00164 
00165 NS_IMETHODIMP nsDiskCacheEntryInfo::GetClientID(char ** clientID)
00166 {
00167     NS_ENSURE_ARG_POINTER(clientID);
00168     return ClientIDFromCacheKey(nsDependentCString(mDiskEntry->mKeyStart), clientID);
00169 }
00170 
00171 extern const char DISK_CACHE_DEVICE_ID[];
00172 NS_IMETHODIMP nsDiskCacheEntryInfo::GetDeviceID(char ** deviceID)
00173 {
00174     NS_ENSURE_ARG_POINTER(deviceID);
00175     *deviceID = nsCRT::strdup(mDeviceID);
00176     return *deviceID ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
00177 }
00178 
00179 
00180 NS_IMETHODIMP nsDiskCacheEntryInfo::GetKey(nsACString &clientKey)
00181 {
00182     return ClientKeyFromCacheKey(nsDependentCString(mDiskEntry->mKeyStart), clientKey);
00183 }
00184 
00185 NS_IMETHODIMP nsDiskCacheEntryInfo::GetFetchCount(PRInt32 *aFetchCount)
00186 {
00187     NS_ENSURE_ARG_POINTER(aFetchCount);
00188     *aFetchCount = mDiskEntry->mFetchCount;
00189     return NS_OK;
00190 }
00191 
00192 NS_IMETHODIMP nsDiskCacheEntryInfo::GetLastFetched(PRUint32 *aLastFetched)
00193 {
00194     NS_ENSURE_ARG_POINTER(aLastFetched);
00195     *aLastFetched = mDiskEntry->mLastFetched;
00196     return NS_OK;
00197 }
00198 
00199 NS_IMETHODIMP nsDiskCacheEntryInfo::GetLastModified(PRUint32 *aLastModified)
00200 {
00201     NS_ENSURE_ARG_POINTER(aLastModified);
00202     *aLastModified = mDiskEntry->mLastModified;
00203     return NS_OK;
00204 }
00205 
00206 NS_IMETHODIMP nsDiskCacheEntryInfo::GetExpirationTime(PRUint32 *aExpirationTime)
00207 {
00208     NS_ENSURE_ARG_POINTER(aExpirationTime);
00209     *aExpirationTime = mDiskEntry->mExpirationTime;
00210     return NS_OK;
00211 }
00212 
00213 NS_IMETHODIMP nsDiskCacheEntryInfo::IsStreamBased(PRBool *aStreamBased)
00214 {
00215     NS_ENSURE_ARG_POINTER(aStreamBased);
00216     *aStreamBased = PR_TRUE;
00217     return NS_OK;
00218 }
00219 
00220 NS_IMETHODIMP nsDiskCacheEntryInfo::GetDataSize(PRUint32 *aDataSize)
00221 {
00222     NS_ENSURE_ARG_POINTER(aDataSize);
00223     *aDataSize = mDiskEntry->mDataSize;
00224     return NS_OK;
00225 }