nsCacheEntryDescriptor::RequestDataSizeChange(). r=gagan, sr=darin. git-svn-id: svn://10.0.0.236/trunk@103250 18797224-902f-48f8-a5cc-f745e15eee43
658 lines
18 KiB
C++
658 lines
18 KiB
C++
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
|
*
|
|
* The contents of this file are subject to the Mozilla Public
|
|
* License Version 1.1 (the "License"); you may not use this file
|
|
* except in compliance with the License. You may obtain a copy of
|
|
* the License at http://www.mozilla.org/MPL/
|
|
*
|
|
* Software distributed under the License is distributed on an "AS
|
|
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
|
* implied. See the License for the specific language governing
|
|
* rights and limitations under the License.
|
|
*
|
|
* The Original Code is nsCacheEntryDescriptor.cpp, released February 22, 2001.
|
|
*
|
|
* The Initial Developer of the Original Code is Netscape Communications
|
|
* Corporation. Portions created by Netscape are
|
|
* Copyright (C) 2001 Netscape Communications Corporation. All
|
|
* Rights Reserved.
|
|
*
|
|
* Contributor(s):
|
|
* Gordon Sheridan, 22-February-2001
|
|
*/
|
|
|
|
#include "nsICache.h"
|
|
#include "nsCache.h"
|
|
#include "nsCacheService.h"
|
|
#include "nsCacheEntryDescriptor.h"
|
|
#include "nsCacheEntry.h"
|
|
#include "nsReadableUtils.h"
|
|
#include "nsIOutputStream.h"
|
|
|
|
NS_IMPL_THREADSAFE_ISUPPORTS1(nsCacheEntryDescriptor, nsICacheEntryDescriptor)
|
|
|
|
|
|
nsCacheEntryDescriptor::nsCacheEntryDescriptor(nsCacheEntry * entry,
|
|
nsCacheAccessMode accessGranted)
|
|
: mCacheEntry(entry),
|
|
mAccessGranted(accessGranted)
|
|
{
|
|
NS_INIT_ISUPPORTS();
|
|
PR_INIT_CLIST(this);
|
|
}
|
|
|
|
|
|
nsCacheEntryDescriptor::~nsCacheEntryDescriptor()
|
|
{
|
|
if (mCacheEntry)
|
|
Close();
|
|
}
|
|
|
|
|
|
nsresult
|
|
nsCacheEntryDescriptor::Create(nsCacheEntry * entry, nsCacheAccessMode accessGranted,
|
|
nsICacheEntryDescriptor ** result)
|
|
{
|
|
NS_ENSURE_ARG_POINTER(result);
|
|
nsresult rv = nsnull;
|
|
|
|
nsCacheEntryDescriptor * descriptor =
|
|
new nsCacheEntryDescriptor(entry, accessGranted);
|
|
|
|
if (descriptor == nsnull)
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
NS_ADDREF(descriptor);
|
|
rv = descriptor->QueryInterface(NS_GET_IID(nsICacheEntryDescriptor), (void**)result);
|
|
NS_RELEASE(descriptor);
|
|
return rv;
|
|
}
|
|
|
|
|
|
NS_IMETHODIMP
|
|
nsCacheEntryDescriptor::GetClientID(char ** result)
|
|
{
|
|
NS_ENSURE_ARG_POINTER(result);
|
|
if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
|
|
|
|
return ClientIDFromCacheKey(*(mCacheEntry->Key()), result);
|
|
}
|
|
|
|
|
|
NS_IMETHODIMP
|
|
nsCacheEntryDescriptor::GetDeviceID(char ** result)
|
|
{
|
|
NS_ENSURE_ARG_POINTER(result);
|
|
if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
|
|
|
|
*result = nsCRT::strdup(mCacheEntry->GetDeviceID());
|
|
return *result ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
|
|
}
|
|
|
|
|
|
NS_IMETHODIMP
|
|
nsCacheEntryDescriptor::GetKey(char ** result)
|
|
{
|
|
NS_ENSURE_ARG_POINTER(result);
|
|
if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
|
|
|
|
return ClientKeyFromCacheKey(*(mCacheEntry->Key()), result);
|
|
}
|
|
|
|
|
|
NS_IMETHODIMP
|
|
nsCacheEntryDescriptor::GetFetchCount(PRInt32 *result)
|
|
{
|
|
NS_ENSURE_ARG_POINTER(result);
|
|
if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
|
|
|
|
*result = mCacheEntry->FetchCount();
|
|
return NS_OK;
|
|
}
|
|
|
|
|
|
NS_IMETHODIMP
|
|
nsCacheEntryDescriptor::GetLastFetched(PRUint32 *result)
|
|
{
|
|
NS_ENSURE_ARG_POINTER(result);
|
|
if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
|
|
|
|
*result = mCacheEntry->LastFetched();
|
|
return NS_OK;
|
|
}
|
|
|
|
|
|
NS_IMETHODIMP
|
|
nsCacheEntryDescriptor::GetLastModified(PRUint32 *result)
|
|
{
|
|
NS_ENSURE_ARG_POINTER(result);
|
|
if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
|
|
|
|
*result = mCacheEntry->LastModified();
|
|
return NS_OK;
|
|
}
|
|
|
|
|
|
NS_IMETHODIMP
|
|
nsCacheEntryDescriptor::GetExpirationTime(PRUint32 *result)
|
|
{
|
|
NS_ENSURE_ARG_POINTER(result);
|
|
if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
|
|
|
|
*result = mCacheEntry->ExpirationTime();
|
|
return NS_OK;
|
|
}
|
|
|
|
|
|
NS_IMETHODIMP
|
|
nsCacheEntryDescriptor::SetExpirationTime(PRUint32 expirationTime)
|
|
{
|
|
if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
|
|
|
|
mCacheEntry->SetExpirationTime(expirationTime);
|
|
mCacheEntry->MarkEntryDirty();
|
|
return NS_OK;
|
|
}
|
|
|
|
|
|
NS_IMETHODIMP nsCacheEntryDescriptor::IsStreamBased(PRBool *result)
|
|
{
|
|
NS_ENSURE_ARG_POINTER(result);
|
|
if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
|
|
|
|
*result = mCacheEntry->IsStreamData(); // XXX which name is better?
|
|
return NS_OK;
|
|
}
|
|
|
|
|
|
NS_IMETHODIMP nsCacheEntryDescriptor::GetDataSize(PRUint32 *result)
|
|
{
|
|
NS_ENSURE_ARG_POINTER(result);
|
|
if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
|
|
|
|
*result = mCacheEntry->DataSize();
|
|
return NS_OK;
|
|
}
|
|
|
|
|
|
nsresult
|
|
nsCacheEntryDescriptor::RequestDataSizeChange(PRInt32 deltaSize)
|
|
{
|
|
if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
|
|
|
|
nsresult rv;
|
|
rv = nsCacheService::GlobalInstance()->OnDataSizeChange(mCacheEntry, deltaSize);
|
|
if (NS_SUCCEEDED(rv)) {
|
|
// XXX review for signed/unsigned math errors
|
|
PRUint32 newDataSize = mCacheEntry->DataSize() + deltaSize;
|
|
mCacheEntry->SetDataSize(newDataSize);
|
|
mCacheEntry->TouchData();
|
|
}
|
|
return rv;
|
|
}
|
|
|
|
|
|
NS_IMETHODIMP
|
|
nsCacheEntryDescriptor::SetDataSize(PRUint32 dataSize)
|
|
{
|
|
if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
|
|
|
|
// XXX review for signed/unsigned math errors
|
|
PRInt32 deltaSize = dataSize - mCacheEntry->DataSize();
|
|
|
|
// this had better be NS_OK, this call instance is advisory
|
|
nsresult rv = RequestDataSizeChange(deltaSize);
|
|
NS_ASSERTION(NS_SUCCEEDED(rv), "failed SetDataSize() on memory cache object!");
|
|
return rv;
|
|
}
|
|
|
|
|
|
NS_IMETHODIMP
|
|
nsCacheEntryDescriptor::GetTransport(nsITransport ** result)
|
|
{
|
|
NS_ENSURE_ARG_POINTER(result);
|
|
if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
|
|
if (!mCacheEntry->IsStreamData()) return NS_ERROR_CACHE_DATA_IS_NOT_STREAM;
|
|
|
|
NS_ADDREF(*result = &mTransportWrapper);
|
|
return NS_OK;
|
|
}
|
|
|
|
|
|
NS_IMETHODIMP
|
|
nsCacheEntryDescriptor::GetCacheElement(nsISupports ** result)
|
|
{
|
|
NS_ENSURE_ARG_POINTER(result);
|
|
if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
|
|
if (mCacheEntry->IsStreamData()) return NS_ERROR_CACHE_DATA_IS_STREAM;
|
|
|
|
return mCacheEntry->GetData(result);
|
|
}
|
|
|
|
|
|
NS_IMETHODIMP
|
|
nsCacheEntryDescriptor::SetCacheElement(nsISupports * cacheElement)
|
|
{
|
|
if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
|
|
if (mCacheEntry->IsStreamData()) return NS_ERROR_CACHE_DATA_IS_STREAM;
|
|
|
|
return nsCacheService::GlobalInstance()->SetCacheElement(mCacheEntry, cacheElement);
|
|
}
|
|
|
|
|
|
NS_IMETHODIMP
|
|
nsCacheEntryDescriptor::GetAccessGranted(nsCacheAccessMode *result)
|
|
{
|
|
NS_ENSURE_ARG_POINTER(result);
|
|
*result = mAccessGranted;
|
|
return NS_OK;
|
|
}
|
|
|
|
|
|
NS_IMETHODIMP
|
|
nsCacheEntryDescriptor::GetStoragePolicy(nsCacheStoragePolicy *result)
|
|
{
|
|
NS_ENSURE_ARG_POINTER(result);
|
|
if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
|
|
|
|
return mCacheEntry->StoragePolicy();
|
|
}
|
|
|
|
|
|
NS_IMETHODIMP
|
|
nsCacheEntryDescriptor::SetStoragePolicy(nsCacheStoragePolicy policy)
|
|
{
|
|
if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
|
|
// XXX validate policy against session?
|
|
mCacheEntry->SetStoragePolicy(policy);
|
|
mCacheEntry->MarkEntryDirty();
|
|
return NS_OK;
|
|
}
|
|
|
|
|
|
NS_IMETHODIMP
|
|
nsCacheEntryDescriptor::GetFile(nsIFile ** result)
|
|
{
|
|
NS_ENSURE_ARG_POINTER(result);
|
|
if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
|
|
|
|
return nsCacheService::GlobalInstance()->GetFileForEntry(mCacheEntry, result);
|
|
}
|
|
|
|
|
|
NS_IMETHODIMP
|
|
nsCacheEntryDescriptor::GetSecurityInfo(nsISupports ** result)
|
|
{
|
|
NS_ENSURE_ARG_POINTER(result);
|
|
if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
|
|
|
|
return mCacheEntry->GetSecurityInfo(result);
|
|
}
|
|
|
|
|
|
NS_IMETHODIMP
|
|
nsCacheEntryDescriptor::SetSecurityInfo(nsISupports * securityInfo)
|
|
{
|
|
if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
|
|
|
|
mCacheEntry->SetSecurityInfo(securityInfo);
|
|
mCacheEntry->MarkEntryDirty();
|
|
return NS_OK;
|
|
}
|
|
|
|
|
|
NS_IMETHODIMP
|
|
nsCacheEntryDescriptor::Doom()
|
|
{
|
|
if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
|
|
|
|
return nsCacheService::GlobalInstance()->DoomEntry(mCacheEntry);
|
|
}
|
|
|
|
|
|
NS_IMETHODIMP
|
|
nsCacheEntryDescriptor::DoomAndFailPendingRequests(nsresult status)
|
|
{
|
|
if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
|
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
}
|
|
|
|
|
|
NS_IMETHODIMP
|
|
nsCacheEntryDescriptor::MarkValid()
|
|
{
|
|
if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
|
|
|
|
nsresult rv;
|
|
rv = nsCacheService::GlobalInstance()->ValidateEntry(mCacheEntry);
|
|
return rv;
|
|
}
|
|
|
|
|
|
NS_IMETHODIMP
|
|
nsCacheEntryDescriptor::Close()
|
|
{
|
|
if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
|
|
|
|
// tell nsCacheService we're going away
|
|
nsCacheService::GlobalInstance()->CloseDescriptor(this);
|
|
mCacheEntry = nsnull;
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
|
|
NS_IMETHODIMP
|
|
nsCacheEntryDescriptor::GetMetaDataElement(const char *key, char ** result)
|
|
{
|
|
if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
|
|
|
|
if (!key | !result) return NS_ERROR_NULL_POINTER;
|
|
nsAReadableCString *value;
|
|
*result = nsnull;
|
|
|
|
// XXX not thread safe
|
|
nsresult rv = mCacheEntry->GetMetaDataElement(nsDependentCString(key), &value);
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
if (!value) return NS_ERROR_NOT_AVAILABLE;
|
|
|
|
*result = ToNewCString(*value);
|
|
if (!*result) return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
|
|
NS_IMETHODIMP
|
|
nsCacheEntryDescriptor::SetMetaDataElement(const char *key, const char *value)
|
|
{
|
|
if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
|
|
|
|
if (!key) return NS_ERROR_NULL_POINTER;
|
|
// XXX not thread safe
|
|
// XXX allow null value, for clearing key?
|
|
nsresult rv = mCacheEntry->SetMetaDataElement(nsDependentCString(key),
|
|
nsDependentCString(value));
|
|
if (NS_SUCCEEDED(rv))
|
|
mCacheEntry->TouchMetaData();
|
|
return rv;
|
|
}
|
|
|
|
|
|
NS_IMETHODIMP
|
|
nsCacheEntryDescriptor::VisitMetaData(nsICacheMetaDataVisitor * visitor)
|
|
{
|
|
NS_ENSURE_ARG_POINTER(visitor);
|
|
if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
|
|
|
|
return mCacheEntry->VisitMetaDataElements(visitor);
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
* nsCacheTransportWrapper
|
|
******************************************************************************/
|
|
|
|
// XXX NS_IMPL_ISUPPORTS1(nsCacheEntryDescriptor::nsTransportWrapper, nsITransport);
|
|
NS_IMPL_QUERY_INTERFACE1(nsCacheEntryDescriptor::nsTransportWrapper, nsITransport)
|
|
|
|
|
|
// special AddRef and Release, because we are part of the descriptor
|
|
#define GET_DESCRIPTOR_FROM_TRANSPORT_WRAPPER(_this) \
|
|
((nsCacheEntryDescriptor*)((char*)(_this) - \
|
|
offsetof(nsCacheEntryDescriptor, mTransportWrapper)))
|
|
|
|
NS_IMETHODIMP_(nsrefcnt) nsCacheEntryDescriptor::
|
|
nsTransportWrapper::AddRef(void)
|
|
{
|
|
return GET_DESCRIPTOR_FROM_TRANSPORT_WRAPPER(this)->AddRef();
|
|
}
|
|
|
|
NS_IMETHODIMP_(nsrefcnt) nsCacheEntryDescriptor::
|
|
nsTransportWrapper::Release(void)
|
|
{
|
|
return GET_DESCRIPTOR_FROM_TRANSPORT_WRAPPER(this)->Release();
|
|
}
|
|
|
|
|
|
nsresult nsCacheEntryDescriptor::
|
|
nsTransportWrapper::EnsureTransportWithAccess(nsCacheAccessMode mode)
|
|
{
|
|
nsresult rv = NS_OK;
|
|
|
|
nsCacheEntryDescriptor * descriptor = GET_DESCRIPTOR_FROM_TRANSPORT_WRAPPER(this);
|
|
if (!descriptor->mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
|
|
if (!descriptor->mAccessGranted & mode) {
|
|
rv = (mode == nsICache::ACCESS_READ) ?
|
|
NS_ERROR_CACHE_READ_ACCESS_DENIED : NS_ERROR_CACHE_WRITE_ACCESS_DENIED;
|
|
return rv;
|
|
}
|
|
|
|
if (!mTransport) {
|
|
rv = nsCacheService::GlobalInstance()->
|
|
GetTransportForEntry(descriptor->mCacheEntry,
|
|
descriptor->mAccessGranted,
|
|
getter_AddRefs(mTransport));
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
if (mCallbacks) {
|
|
mTransport->SetNotificationCallbacks(mCallbacks, mCallbackFlags);
|
|
}
|
|
}
|
|
return NS_OK;
|
|
}
|
|
|
|
|
|
nsresult
|
|
nsCacheEntryDescriptor::NewOutputStreamWrapper(nsIOutputStream ** result,
|
|
nsCacheEntryDescriptor * descriptor,
|
|
nsIOutputStream * output)
|
|
{
|
|
nsOutputStreamWrapper* cacheOutput =
|
|
new nsOutputStreamWrapper(descriptor, output);
|
|
if (!cacheOutput) return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
nsCOMPtr<nsISupports> ref(cacheOutput);
|
|
nsresult rv = cacheOutput->Init();
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
NS_ADDREF(*result = cacheOutput);
|
|
return NS_OK;
|
|
}
|
|
|
|
|
|
NS_IMETHODIMP nsCacheEntryDescriptor::
|
|
nsTransportWrapper::GetSecurityInfo(nsISupports ** securityInfo)
|
|
{
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
}
|
|
|
|
|
|
NS_IMETHODIMP nsCacheEntryDescriptor::
|
|
nsTransportWrapper::GetNotificationCallbacks(nsIInterfaceRequestor **result)
|
|
{
|
|
NS_ENSURE_ARG_POINTER(result);
|
|
|
|
*result = mCallbacks;
|
|
NS_IF_ADDREF(*result);
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
|
|
NS_IMETHODIMP nsCacheEntryDescriptor::
|
|
nsTransportWrapper::SetNotificationCallbacks(nsIInterfaceRequestor *requestor,
|
|
PRUint32 flags)
|
|
{
|
|
if (mTransport) {
|
|
mTransport->SetNotificationCallbacks(requestor, flags);
|
|
}
|
|
|
|
mCallbacks = requestor;
|
|
mCallbackFlags = flags;
|
|
|
|
return NS_OK;;
|
|
}
|
|
|
|
|
|
NS_IMETHODIMP nsCacheEntryDescriptor::
|
|
nsTransportWrapper::OpenInputStream(PRUint32 offset,
|
|
PRUint32 count,
|
|
PRUint32 flags,
|
|
nsIInputStream ** result)
|
|
{
|
|
NS_ENSURE_ARG_POINTER(result);
|
|
|
|
nsresult rv = EnsureTransportWithAccess(nsICache::ACCESS_READ);
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
return mTransport->OpenInputStream(offset, count, flags, result);
|
|
}
|
|
|
|
|
|
NS_IMETHODIMP nsCacheEntryDescriptor::
|
|
nsTransportWrapper::OpenOutputStream(PRUint32 offset,
|
|
PRUint32 count,
|
|
PRUint32 flags,
|
|
nsIOutputStream ** result)
|
|
{
|
|
NS_ENSURE_ARG_POINTER(result);
|
|
|
|
nsresult rv = EnsureTransportWithAccess(nsICache::ACCESS_WRITE);
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
// XXX allow more than one output stream at a time on a descriptor? Why?
|
|
|
|
// Create the underlying output stream using the wrapped transport.
|
|
nsCOMPtr<nsIOutputStream> output;
|
|
rv = mTransport->OpenOutputStream(offset, count, flags, getter_AddRefs(output));
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
// Wrap this output stream with a stream that monitors how much data gets written,
|
|
// maintains the cache entry's size, and informs the cache device.
|
|
// This mechanism provides a way for the cache device to enforce space limits,
|
|
// and to drive cache entry eviction.
|
|
nsCacheEntryDescriptor * descriptor = GET_DESCRIPTOR_FROM_TRANSPORT_WRAPPER(this);
|
|
|
|
// reset datasize of entry based on offset so OnWrite calculates delta changes correctly.
|
|
rv = descriptor->SetDataSize(offset);
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
return NewOutputStreamWrapper(result, descriptor, output);
|
|
}
|
|
|
|
|
|
NS_IMETHODIMP nsCacheEntryDescriptor::
|
|
nsTransportWrapper::AsyncRead(nsIStreamListener * listener,
|
|
nsISupports * ctxt,
|
|
PRUint32 offset,
|
|
PRUint32 count,
|
|
PRUint32 flags,
|
|
nsIRequest ** result)
|
|
{
|
|
NS_ENSURE_ARG_POINTER(result);
|
|
|
|
nsresult rv = EnsureTransportWithAccess(nsICache::ACCESS_READ);
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
return mTransport->AsyncRead(listener, ctxt, offset, count, flags, result);
|
|
}
|
|
|
|
|
|
NS_IMETHODIMP nsCacheEntryDescriptor::
|
|
nsTransportWrapper::AsyncWrite(nsIStreamProvider * provider,
|
|
nsISupports * ctxt,
|
|
PRUint32 offset,
|
|
PRUint32 count,
|
|
PRUint32 flags,
|
|
nsIRequest ** result)
|
|
{
|
|
// we're not planning on implementing this
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
#if 0
|
|
NS_ENSURE_ARG_POINTER(result);
|
|
|
|
nsresult rv = EnsureTransportWithAccess(nsICache::ACCESS_WRITE);
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
return mTransport->AsyncWrite(provider, ctxt, offset, count, flags, result);
|
|
#endif
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
* nsCacheOutputStream - a wrapper for nsIOutputstream to track the amount of
|
|
* data written to a cache entry.
|
|
******************************************************************************/
|
|
|
|
NS_IMPL_ISUPPORTS1(nsCacheEntryDescriptor::nsOutputStreamWrapper, nsIOutputStream);
|
|
|
|
nsresult nsCacheEntryDescriptor::
|
|
nsOutputStreamWrapper::Init()
|
|
{
|
|
nsCacheAccessMode mode;
|
|
nsresult rv = mDescriptor->GetAccessGranted(&mode);
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
if (mode == nsICache::ACCESS_WRITE) {
|
|
nsCacheEntry* cacheEntry = mDescriptor->CacheEntry();
|
|
if (!cacheEntry) return NS_ERROR_NOT_AVAILABLE;
|
|
|
|
nsCacheDevice* device = cacheEntry->CacheDevice();
|
|
if (!device) return NS_ERROR_NOT_AVAILABLE;
|
|
|
|
// the entry has been truncated to zero bytes, inform the device.
|
|
PRInt32 delta = cacheEntry->DataSize();
|
|
rv = device->OnDataSizeChange(cacheEntry, -delta);
|
|
cacheEntry->SetDataSize(0);
|
|
}
|
|
return rv;
|
|
}
|
|
|
|
|
|
NS_IMETHODIMP nsCacheEntryDescriptor::
|
|
nsOutputStreamWrapper::Write(const char * buf,
|
|
PRUint32 count,
|
|
PRUint32 * result)
|
|
{
|
|
nsresult rv = OnWrite(count);
|
|
if (NS_FAILED(rv)) return rv;
|
|
return mOutput->Write(buf, count, result);
|
|
}
|
|
|
|
|
|
NS_IMETHODIMP nsCacheEntryDescriptor::
|
|
nsOutputStreamWrapper::WriteFrom(nsIInputStream * inStr,
|
|
PRUint32 count,
|
|
PRUint32 * result)
|
|
{
|
|
nsresult rv = OnWrite(count);
|
|
if (NS_FAILED(rv)) return rv;
|
|
return mOutput->WriteFrom(inStr, count, result);
|
|
}
|
|
|
|
|
|
NS_IMETHODIMP nsCacheEntryDescriptor::
|
|
nsOutputStreamWrapper::WriteSegments(nsReadSegmentFun reader,
|
|
void * closure,
|
|
PRUint32 count,
|
|
PRUint32 * result)
|
|
{
|
|
nsresult rv = OnWrite(count);
|
|
if (NS_FAILED(rv)) return rv;
|
|
return mOutput->WriteSegments(reader, closure, count, result);
|
|
}
|
|
|
|
|
|
nsresult nsCacheEntryDescriptor::
|
|
nsOutputStreamWrapper::OnWrite(PRUint32 count)
|
|
{
|
|
// XXX if count > 2^31 error_write_too_big
|
|
return mDescriptor->RequestDataSizeChange((PRInt32)count);
|
|
}
|
|
|
|
|