From fd33fd7e0bdcc3b4764d1b9aa36764eef2a7ea01 Mon Sep 17 00:00:00 2001 From: "hoa.nguyen%intel.com" Date: Fri, 10 Sep 1999 23:16:40 +0000 Subject: [PATCH] Initial checkin git-svn-id: svn://10.0.0.236/trunk@46876 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/netwerk/cache/include/nsBkgThread.h | 63 ++ mozilla/netwerk/cache/include/nsCacheBkgThd.h | 52 + .../netwerk/cache/include/nsCacheIterator.h | 86 ++ .../netwerk/cache/include/nsCacheManager.h | 208 ++++ mozilla/netwerk/cache/include/nsCacheObject.h | 465 +++++++++ mozilla/netwerk/cache/include/nsCachePref.h | 195 ++++ mozilla/netwerk/cache/include/nsDiskModule.h | 132 +++ mozilla/netwerk/cache/include/nsEnumeration.h | 98 ++ mozilla/netwerk/cache/include/nsFileStream.h | 68 ++ mozilla/netwerk/cache/include/nsIterator.h | 71 ++ mozilla/netwerk/cache/include/nsMemModule.h | 158 +++ mozilla/netwerk/cache/include/nsMemStream.h | 60 ++ mozilla/netwerk/cache/include/nsMonitorable.h | 106 ++ mozilla/netwerk/cache/include/nsStream.h | 71 ++ mozilla/netwerk/cache/mgr/Makefile.in | 55 + mozilla/netwerk/cache/mgr/Makefile.win | 59 ++ mozilla/netwerk/cache/mgr/nsBkgThread.cpp | 92 ++ mozilla/netwerk/cache/mgr/nsCacheBkgThd.cpp | 102 ++ mozilla/netwerk/cache/mgr/nsCacheManager.cpp | 741 ++++++++++++++ mozilla/netwerk/cache/mgr/nsMonitorable.cpp | 38 + mozilla/netwerk/cache/module/Makefile.in | 34 + mozilla/netwerk/cache/module/Makefile.win | 25 + mozilla/netwerk/cache/module/disk/Makefile.in | 61 ++ .../netwerk/cache/module/disk/Makefile.win | 61 ++ .../cache/module/disk/nsCacheModule.cpp | 98 ++ .../cache/module/disk/nsDiskModule.cpp | 839 ++++++++++++++++ .../cache/module/disk/nsDiskModuleFactory.cpp | 87 ++ .../cache/module/disk/nsFileStream.cpp | 110 ++ .../cache/module/disk/nsMonitorable.cpp | 38 + .../netwerk/cache/module/memory/Makefile.in | 57 ++ .../netwerk/cache/module/memory/Makefile.win | 61 ++ .../cache/module/memory/nsMemCacheObject.cpp | 46 + .../cache/module/memory/nsMemCacheObject.h | 99 ++ .../cache/module/memory/nsMemModule.cpp | 485 +++++++++ .../module/memory/nsMemModuleFactory.cpp | 87 ++ .../cache/module/memory/nsMemStream.cpp | 124 +++ .../cache/module/memory/nsMonitorable.cpp | 38 + mozilla/netwerk/cache/obj/Makefile.in | 53 + mozilla/netwerk/cache/obj/Makefile.win | 57 ++ mozilla/netwerk/cache/obj/nsCacheObject.cpp | 936 ++++++++++++++++++ mozilla/netwerk/cache/pref/Makefile.in | 54 + mozilla/netwerk/cache/pref/Makefile.win | 56 ++ mozilla/netwerk/cache/pref/nsCachePref.cpp | 510 ++++++++++ mozilla/netwerk/cache/public/Makefile.in | 38 + mozilla/netwerk/cache/public/Makefile.win | 31 + .../netwerk/cache/public/nsICacheManager.h | 57 ++ mozilla/netwerk/cache/public/nsICacheModule.h | 108 ++ mozilla/netwerk/cache/public/nsICacheObject.h | 106 ++ mozilla/netwerk/cache/public/nsICachePref.h | 90 ++ mozilla/netwerk/cache/tests/Makefile.in | 27 + mozilla/netwerk/cache/tests/Makefile.win | 24 + .../netwerk/cache/tests/xptest/Makefile.in | 55 + .../netwerk/cache/tests/xptest/Makefile.win | 53 + .../netwerk/cache/tests/xptest/disktest.cpp | 817 +++++++++++++++ .../netwerk/cache/tests/xptest/memtest.cpp | 801 +++++++++++++++ 55 files changed, 9143 insertions(+) create mode 100644 mozilla/netwerk/cache/include/nsBkgThread.h create mode 100644 mozilla/netwerk/cache/include/nsCacheBkgThd.h create mode 100644 mozilla/netwerk/cache/include/nsCacheIterator.h create mode 100644 mozilla/netwerk/cache/include/nsCacheManager.h create mode 100644 mozilla/netwerk/cache/include/nsCacheObject.h create mode 100644 mozilla/netwerk/cache/include/nsCachePref.h create mode 100644 mozilla/netwerk/cache/include/nsDiskModule.h create mode 100644 mozilla/netwerk/cache/include/nsEnumeration.h create mode 100644 mozilla/netwerk/cache/include/nsFileStream.h create mode 100644 mozilla/netwerk/cache/include/nsIterator.h create mode 100644 mozilla/netwerk/cache/include/nsMemModule.h create mode 100644 mozilla/netwerk/cache/include/nsMemStream.h create mode 100644 mozilla/netwerk/cache/include/nsMonitorable.h create mode 100644 mozilla/netwerk/cache/include/nsStream.h create mode 100644 mozilla/netwerk/cache/mgr/Makefile.in create mode 100755 mozilla/netwerk/cache/mgr/Makefile.win create mode 100644 mozilla/netwerk/cache/mgr/nsBkgThread.cpp create mode 100644 mozilla/netwerk/cache/mgr/nsCacheBkgThd.cpp create mode 100644 mozilla/netwerk/cache/mgr/nsCacheManager.cpp create mode 100644 mozilla/netwerk/cache/mgr/nsMonitorable.cpp create mode 100644 mozilla/netwerk/cache/module/Makefile.in create mode 100755 mozilla/netwerk/cache/module/Makefile.win create mode 100644 mozilla/netwerk/cache/module/disk/Makefile.in create mode 100755 mozilla/netwerk/cache/module/disk/Makefile.win create mode 100644 mozilla/netwerk/cache/module/disk/nsCacheModule.cpp create mode 100644 mozilla/netwerk/cache/module/disk/nsDiskModule.cpp create mode 100644 mozilla/netwerk/cache/module/disk/nsDiskModuleFactory.cpp create mode 100644 mozilla/netwerk/cache/module/disk/nsFileStream.cpp create mode 100644 mozilla/netwerk/cache/module/disk/nsMonitorable.cpp create mode 100644 mozilla/netwerk/cache/module/memory/Makefile.in create mode 100755 mozilla/netwerk/cache/module/memory/Makefile.win create mode 100644 mozilla/netwerk/cache/module/memory/nsMemCacheObject.cpp create mode 100644 mozilla/netwerk/cache/module/memory/nsMemCacheObject.h create mode 100644 mozilla/netwerk/cache/module/memory/nsMemModule.cpp create mode 100644 mozilla/netwerk/cache/module/memory/nsMemModuleFactory.cpp create mode 100644 mozilla/netwerk/cache/module/memory/nsMemStream.cpp create mode 100644 mozilla/netwerk/cache/module/memory/nsMonitorable.cpp create mode 100644 mozilla/netwerk/cache/obj/Makefile.in create mode 100755 mozilla/netwerk/cache/obj/Makefile.win create mode 100644 mozilla/netwerk/cache/obj/nsCacheObject.cpp create mode 100644 mozilla/netwerk/cache/pref/Makefile.in create mode 100755 mozilla/netwerk/cache/pref/Makefile.win create mode 100644 mozilla/netwerk/cache/pref/nsCachePref.cpp create mode 100644 mozilla/netwerk/cache/public/Makefile.in create mode 100755 mozilla/netwerk/cache/public/Makefile.win create mode 100644 mozilla/netwerk/cache/public/nsICacheManager.h create mode 100644 mozilla/netwerk/cache/public/nsICacheModule.h create mode 100644 mozilla/netwerk/cache/public/nsICacheObject.h create mode 100644 mozilla/netwerk/cache/public/nsICachePref.h create mode 100644 mozilla/netwerk/cache/tests/Makefile.in create mode 100755 mozilla/netwerk/cache/tests/Makefile.win create mode 100644 mozilla/netwerk/cache/tests/xptest/Makefile.in create mode 100755 mozilla/netwerk/cache/tests/xptest/Makefile.win create mode 100644 mozilla/netwerk/cache/tests/xptest/disktest.cpp create mode 100644 mozilla/netwerk/cache/tests/xptest/memtest.cpp diff --git a/mozilla/netwerk/cache/include/nsBkgThread.h b/mozilla/netwerk/cache/include/nsBkgThread.h new file mode 100644 index 00000000000..65ca83d45e0 --- /dev/null +++ b/mozilla/netwerk/cache/include/nsBkgThread.h @@ -0,0 +1,63 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +/* This is a super cool class that does the background thread magic using + * NSPR Threads. This class is used to maintain odd tasks in the background + * like like updating, expiration, validation and garbage collection. + * + * Note that this is a noop active when the cache manager is offline. + * + * In PRThread terms, this is a PR_USER_THREAD with local scope. + * + * -Gagan Saksena 09/15/98 + */ +#ifndef nsBkgThread_h__ +#define nsBkgThread_h__ + +//#include "nsISupports.h" +#include "prthread.h" +#include "prinrval.h" + +class nsBkgThread//: public nsISupports +{ + +public: + nsBkgThread(PRIntervalTime iSleepTime, PRBool bStart=PR_TRUE); + virtual ~nsBkgThread(); +/* + NS_IMETHOD QueryInterface(const nsIID& aIID, + void** aInstancePtr); + NS_IMETHOD_(nsrefcnt) AddRef(void); + NS_IMETHOD_(nsrefcnt) Release(void); +*/ + void Process(void); + virtual void Run(void) = 0; + void Stop(void); +protected: + PRThread* m_pThread; + PRBool m_bContinue; + PRIntervalTime m_SleepTime; + +private: + nsBkgThread(const nsBkgThread& o); + nsBkgThread& operator=(const nsBkgThread& o); + +}; + +#endif // nsBkgThread_h__ + diff --git a/mozilla/netwerk/cache/include/nsCacheBkgThd.h b/mozilla/netwerk/cache/include/nsCacheBkgThd.h new file mode 100644 index 00000000000..d0ffd2be0cd --- /dev/null +++ b/mozilla/netwerk/cache/include/nsCacheBkgThd.h @@ -0,0 +1,52 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +/* This class is the actual implementation of the original class nsBkgThread, + * but I am too lazy to move the comments from nsBkgThread's + * header file to here. :-) + * + * -Gagan Saksena 09/15/98 + */ +#ifndef nsCacheBkgThd_h__ +#define nsCacheBkgThd_h__ + +#include "nsBkgThread.h" + +class nsCacheBkgThd: public nsBkgThread +{ + +public: + nsCacheBkgThd(PRIntervalTime iSleepTime); + virtual ~nsCacheBkgThd(); +/* + NS_IMETHOD QueryInterface(const nsIID& aIID, + void** aInstancePtr); + NS_IMETHOD_(nsrefcnt) AddRef(void); + NS_IMETHOD_(nsrefcnt) Release(void); +*/ + void Run(void); + +protected: + +private: + nsCacheBkgThd(const nsCacheBkgThd& o); + nsCacheBkgThd& operator=(const nsCacheBkgThd& o); +}; + +#endif // nsCacheBkgThd_h__ + diff --git a/mozilla/netwerk/cache/include/nsCacheIterator.h b/mozilla/netwerk/cache/include/nsCacheIterator.h new file mode 100644 index 00000000000..3f12cfb53c4 --- /dev/null +++ b/mozilla/netwerk/cache/include/nsCacheIterator.h @@ -0,0 +1,86 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (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/NPL/ + * + * 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 Mozilla Communicator client code. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corporation. Portions created by Netscape are Copyright (C) 1998 + * Netscape Communications Corporation. All Rights Reserved. + */ + +/* A simple cache iterator for cache architecture. This is a temporary class + * which will be (should be) replaced by more professional quality code, or + * at least moved to a more common area later on. + * + * -Gagan Saksena 09/15/98 + */ +#ifndef nsCacheIterator_h__ +#define nsCacheIterator_h__ + +#include "nsIterator.h" +#include "prtypes.h" +#include "nsICacheModule.h" +#include "nsICacheObject.h" + +class nsCacheIterator: public nsIterator +{ + +public: + nsCacheIterator(nsICacheModule* i_pModule); + virtual ~nsCacheIterator(); + + virtual PRBool IsDone(void) const; + virtual nsICacheObject* Current(void) const; + +private: + nsCacheIterator(const nsCacheIterator& o); + nsCacheIterator& operator=(const nsCacheIterator& o); + nsICacheModule* m_pModule; +}; + +inline +nsCacheIterator::nsCacheIterator(nsICacheModule* i_pModule): m_pModule(i_pModule) +{ +} + +inline +nsCacheIterator::~nsCacheIterator() +{ +} + +inline +PRBool nsCacheIterator::IsDone(void) const +{ + /* + if (m_pModule) + { + return m_pModule->Entries() <= m_Index; + } + else + return PR_FALSE; + */ +} + +inline +nsICacheObject* nsCacheIterator::Current(void) const +{ + nsICacheObject* pObj ; + + if (m_pModule) + { + m_pModule->GetObjectByIndex(m_Index, &pObj); + return pObj ; + } + return 0; +} +#endif // nsCacheIterator_h__ + diff --git a/mozilla/netwerk/cache/include/nsCacheManager.h b/mozilla/netwerk/cache/include/nsCacheManager.h new file mode 100644 index 00000000000..81b9dd91a45 --- /dev/null +++ b/mozilla/netwerk/cache/include/nsCacheManager.h @@ -0,0 +1,208 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +/* + * nsCacheManager- The boss of cache architecture. Contains all "external" + * functions for use by people who don't care/want to know the internals + * of the cache architecture. + * + * - Gagan Saksena 09/15/98 + * + * Design and original implementation by Gagan Saksena 02/02/98 + * + */ + +#ifndef _CacheManager_H_ +#define _CacheManager_H_ + +#include "nsISupports.h" +#include "nsIFactory.h" +#include "nsICacheManager.h" + +#include "prlog.h" + +#include "nsMonitorable.h" +#include "nsICacheModule.h" +#include "nsICacheObject.h" +#include "nsCacheBkgThd.h" +#include + +// class nsMemModule; +// class nsDiskModule; +// class nsCachePref; +// class nsCacheBkgThd; + + +class nsCacheManager : public nsICacheManager , public nsMonitorable +{ + +public: + + nsCacheManager(); + virtual ~nsCacheManager(); + + NS_DECL_ISUPPORTS + + NS_IMETHOD Contains(const char* i_url ) const; + // PRBool Contains(const char* i_url) const ; + + /* Number of modules in the cache manager */ + NS_IMETHOD Entries(PRInt16 * n_Entries) const; + // PRInt16 Entries( ) const ; + + NS_IMETHOD AddModule(PRInt16 * n_Index, nsICacheModule* pModule); + // InsertModule + + NS_IMETHOD GetModule (PRInt16 i_index, nsICacheModule** pmodule) const ; + // nsCacheModule* GetModule(PRInt16 i_index) const; + + NS_IMETHOD GetDiskModule(nsICacheModule** pmodule) const ; + // nsDiskModule* GetDiskModule() const; + + NS_IMETHOD GetMemModule(nsICacheModule** pmodule) const ; + // nsMemModule* GetMemModule() const; + + NS_IMETHOD GetPrefs(nsICachePref** pPref) const ; + // nsCachePref* GetPrefs(void) const; + + NS_IMETHOD GetObj(const char* i_url, void ** o_pObject) const; + + NS_IMETHOD InfoAsHTML(char** o_Buffer) const; + + NS_IMETHOD IsOffline(PRBool *bOffline) const; + + NS_IMETHOD Offline(PRBool bSet); + + NS_IMETHOD Remove(const char* i_url); + + /* Performance measure- microseconds */ + NS_IMETHOD WorstCaseTime(PRUint32 * o_Time) const; + + /* Singleton */ + static nsCacheManager* GetInstance(); + + // Initialize the cache manager. Constructor doesn't call this. + // So you must specify this separately. + + // GetInstance will call it automatically. - yixiong + void Init(); + + // const char* Trace() const; + +protected: + + NS_IMETHOD ContainsExactly(const char* i_url, PRBool * bContain) const; + + nsICacheModule* LastModule() const; + //PRBool Lock(void); + //void Unlock(void); + +/* + class MgrMonitor + { + public: + MgrMonitor() { nsCacheManager::GetInstance()->Lock();} + ~MgrMonitor() { nsCacheManager::GetInstance()->Unlock();} + }; + + friend MgrMonitor; +*/ + +private: + nsCacheBkgThd* m_pBkgThd; + nsICacheModule* m_pFirstModule; + PRMonitor* m_pMonitor; + PRBool m_bOffline; + nsICachePref* m_pPrefs; + + nsCacheManager(const nsCacheManager& cm); + nsCacheManager& operator=(const nsCacheManager& cm); + static nsCacheManager * gInstance ; +}; + +class nsCacheManagerFactory : public nsIFactory +{ + public: + nsCacheManagerFactory( ) ; + virtual ~nsCacheManagerFactory( ) ; + + NS_DECL_ISUPPORTS + + NS_IMETHOD CreateInstance(nsISupports *aOuter, + const nsIID &aIID, + void **aResult) ; + + NS_IMETHOD LockFactory(PRBool aLock) ; +} ; + +inline NS_IMETHODIMP +nsCacheManager::GetDiskModule( nsICacheModule ** pModule) const +{ + PR_ASSERT(m_pFirstModule); + + nsresult rv ; + *pModule = nsnull ; + + // return (m_pFirstModule) ? (nsDiskModule*) m_pFirstModule->NextModule() : NULL; + if (m_pFirstModule) { + + rv = m_pFirstModule->GetNextModule(pModule) ; + + if (NS_SUCCEEDED(rv) && *pModule){ + return NS_OK ; + } +// else +// return NS_ERROR_FAILURE ; + } + + return NS_ERROR_FAILURE ; +} + +inline NS_IMETHODIMP +nsCacheManager::GetMemModule(nsICacheModule ** pModule ) const +{ + PR_ASSERT(m_pFirstModule); + *pModule = m_pFirstModule; + + return NS_OK ; +} + +inline NS_IMETHODIMP +nsCacheManager::GetPrefs(nsICachePref ** pPref) const +{ + PR_ASSERT(m_pPrefs); + *pPref = m_pPrefs; + + return NS_OK ; +} + +inline NS_IMETHODIMP +nsCacheManager::IsOffline(PRBool * bOffline) const +{ + *bOffline = m_bOffline; + return NS_OK ; +} + +inline NS_IMETHODIMP +nsCacheManager::Offline(PRBool i_bSet) +{ + m_bOffline = i_bSet; + return NS_OK ; +} + +#endif diff --git a/mozilla/netwerk/cache/include/nsCacheObject.h b/mozilla/netwerk/cache/include/nsCacheObject.h new file mode 100644 index 00000000000..7dacd6890be --- /dev/null +++ b/mozilla/netwerk/cache/include/nsCacheObject.h @@ -0,0 +1,465 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +/* nsCacheObject is the class that holds the basic definition of the + * cache object. A lot of changes are likely to occur before this + * goes on stage. + * + * -Gagan Saksena 09/15/98 + */ +#ifndef nsCacheObject_h__ +#define nsCacheObject_h__ + +// #if 0 +#include "nsISupports.h" +// #endif +#include "pratom.h" +#include "nscore.h" +#include "nsIFactory.h" +#include "nsRepository.h" +#include "nsIComponentManager.h" +#include "nsIServiceManager.h" +#include "nsStream.h" +#include "prtypes.h" +#include "prinrval.h" +#include "nsICacheObject.h" + +static const PRUint32 kCACHE_VERSION = 5; + +// class nsStream; + +class nsCacheObject : public nsICacheObject +{ + +public: + + enum state_flags + { + INIT=0, + PARTIAL=1, + COMPLETE=2, + ABORTED=3, + EXPIRED=4, + CORRUPT=5 + }; + + nsCacheObject(); + nsCacheObject(const nsCacheObject& another); + nsCacheObject(const char* i_url); + + virtual ~nsCacheObject(); + + NS_DECL_ISUPPORTS + + +/* public interface */ + +// NS_IMETHOD Create(const char * i_url, void * aObj) = 0 ; + +// NS_IMETHOD Destroy(void * pThis) = 0 ; + + NS_IMETHOD GetAddress(char ** Addr) const ; + NS_IMETHOD SetAddress(const char* i_Address) ; + + NS_IMETHOD GetCharset(char ** CSet) const ; + NS_IMETHOD SetCharset(const char* i_CharSet) ; + + NS_IMETHOD GetContentEncoding(char ** Encoding) const ; + NS_IMETHOD SetContentEncoding(const char* i_Encoding) ; + + NS_IMETHOD GetContentLength(PRUint32 * CLeng) const ; + NS_IMETHOD SetContentLength(PRUint32 i_Len) ; + + NS_IMETHOD GetContentType(char ** CType) const ; + NS_IMETHOD SetContentType(const char* i_Type) ; + + NS_IMETHOD GetEtag(char ** Etag) const ; + NS_IMETHOD SetEtag(const char* i_Etag) ; + + NS_IMETHOD GetExpires(PRIntervalTime * iTime) const ; + NS_IMETHOD SetExpires(const PRIntervalTime i_Time) ; + + NS_IMETHOD GetFilename(char ** Filename) const ; + NS_IMETHOD SetFilename(const char* i_Filename) ; + + NS_IMETHOD GetIsCompleted(PRBool *bComplete) const ; + NS_IMETHOD SetIsCompleted(PRBool bComplete) ; + + NS_IMETHOD GetLastAccessed(PRIntervalTime * iTime) const ; + + NS_IMETHOD GetLastModified(PRIntervalTime * iTime) const ; + NS_IMETHOD SetLastModified(const PRIntervalTime i_Time) ; + + NS_IMETHOD GetModuleIndex(PRInt16 * m_index) const ; + NS_IMETHOD SetModuleIndex(const PRUint16 m_index) ; + + NS_IMETHOD GetPageServicesURL(char ** o_url) const ; + NS_IMETHOD SetPageServicesURL(const char* i_Url) ; + + NS_IMETHOD GetPostData(char ** pData) const ; + NS_IMETHOD SetPostData(const char* i_PostData, const PRUint32 i_Len) ; + + NS_IMETHOD GetPostDataLen(PRUint32 * dLeng) const ; + + /* Accessor functions for the size of the cache object */ + NS_IMETHOD GetSize(PRUint32 * pSize) const ; + NS_IMETHOD SetSize(const PRUint32 i_Size) ; + + /* Accessor functions for the state of the cache object. + * Some states are changed internally. + */ + NS_IMETHOD GetState(PRUint32 * pState) const ; + NS_IMETHOD SetState(const PRUint32 i_State) ; + + NS_IMETHOD GetStream(nsStream ** pStream) const ; +// NS_IMETHOD MakeStream(void) ; + + NS_IMETHOD Hits(PRUint32 * pHits) const ; + + NS_IMETHOD IsExpired(PRBool *bGet) const ; + + NS_IMETHOD IsPartial(PRBool *bGet) const ; + + NS_IMETHOD Read(char* o_Destination, PRUint32 i_Len, + PRUint32 * pLeng) ; + + /* Reset the streams/state, read/write locks, etc. */ + NS_IMETHOD Reset(void) ; + +// NS_IMETHOD Synch(void) = 0 ; + + NS_IMETHOD Write(const char* i_buffer, const PRUint32 i_length, + PRUint32 * oLeng) ; + +// NS_IMETHOD InitUrl(const char* i_url) ; + + /* Read and write info about this cache object */ + NS_IMETHOD GetInfo(void** o_info) ; + NS_IMETHOD SetInfo(void* i_info /*, PRUint32 len */); + + NS_IMETHOD GetInfoSize(PRUint32* o_size) ; + +/* end public interface */ + + const char* Trace() const; + +protected: + + void Init(); + + char* m_Charset; + char* m_ContentEncoding; + PRUint32 m_ContentLength; + char* m_ContentType; + char* m_Etag; + PRIntervalTime m_Expires; + char* m_Filename; + PRUint32 m_State; + PRUint16 m_Hits; + PRUint32 m_info_size; + PRBool m_bIsCompleted; /* Marked when the stream complete is called */ + PRIntervalTime m_LastAccessed, m_LastModified; + PRInt16 m_Module; + void* m_pInfo; + char* m_PageServicesURL; + char* m_PostData; + PRUint32 m_PostDataLen; + PRUint32 m_Size; + nsStream* m_pStream; + char* m_URL; + +private: + nsCacheObject& operator=(const nsCacheObject& x); +}; + +inline NS_IMETHODIMP +nsCacheObject::GetAddress(char ** Addr) const +{ + if (!Addr) + return NS_ERROR_NULL_POINTER; + + *Addr = m_URL ; + return NS_OK ; +}; + +inline NS_IMETHODIMP +nsCacheObject::GetCharset(char ** CSet) const +{ + if (!CSet) + return NS_ERROR_NULL_POINTER; + + *CSet = m_Charset; + return NS_OK ; +} + +inline NS_IMETHODIMP +nsCacheObject::GetContentEncoding(char ** Encoding) const +{ + if (!Encoding) + return NS_ERROR_NULL_POINTER; + + *Encoding=m_ContentEncoding; + return NS_OK ; +} + +inline NS_IMETHODIMP +nsCacheObject::GetContentLength(PRUint32 * CLeng) const +{ + if (!CLeng) + return NS_ERROR_NULL_POINTER; + + *CLeng = m_ContentLength; + return NS_OK ; +}; + +inline NS_IMETHODIMP +nsCacheObject::SetContentLength(PRUint32 i_Size) +{ + m_ContentLength = i_Size; + return NS_OK ; +}; + +inline NS_IMETHODIMP +nsCacheObject::GetContentType(char ** CType) const +{ + if (!CType) + return NS_ERROR_NULL_POINTER; + + *CType = m_ContentType; + return NS_OK ; +}; + +inline NS_IMETHODIMP +nsCacheObject::GetEtag(char ** Etag) const +{ + if (!Etag) + return NS_ERROR_NULL_POINTER; + + *Etag = m_Etag; + return NS_OK ; +}; + +inline NS_IMETHODIMP +nsCacheObject::GetExpires(PRIntervalTime * iTime) const +{ + if (!iTime) + return NS_ERROR_NULL_POINTER; + + *iTime = m_Expires; + return NS_OK ; +}; + +inline NS_IMETHODIMP +nsCacheObject::SetExpires(PRIntervalTime i_Expires) +{ + m_Expires = i_Expires; + return NS_OK ; +}; + +inline NS_IMETHODIMP +nsCacheObject::GetFilename(char ** Filename) const +{ + if (!Filename) + return NS_ERROR_NULL_POINTER; + + *Filename = m_Filename; + return NS_OK ; +} + +inline NS_IMETHODIMP +nsCacheObject::Hits(PRUint32 * pHits) const +{ + *pHits = m_Hits; + return NS_OK ; +}; + +inline NS_IMETHODIMP +nsCacheObject::GetIsCompleted(PRBool *bComplete) const +{ + if (m_bIsCompleted) { + *bComplete=PR_TRUE ; + } + else { + *bComplete=PR_FALSE ; + } + return NS_OK ; +} + +inline NS_IMETHODIMP +nsCacheObject::SetIsCompleted(PRBool bComplete) +{ + m_bIsCompleted = bComplete; + return NS_OK ; +} + +inline NS_IMETHODIMP +nsCacheObject::IsExpired(PRBool *bExpired) const +{ + if (nsCacheObject::EXPIRED==m_State) + *bExpired = PR_TRUE ; + + if (m_Expires <= PR_IntervalNow()) { + ((nsCacheObject*)this)->m_State = nsCacheObject::EXPIRED; + *bExpired = PR_TRUE ; + } + else + *bExpired = PR_FALSE ; + + return NS_OK ; + +}; + +inline NS_IMETHODIMP +nsCacheObject::IsPartial(PRBool *bPartial) const +{ + if (m_ContentLength != m_Size) + *bPartial = PR_TRUE ; + else + *bPartial = PR_FALSE ; + + return NS_OK ; +}; + +inline NS_IMETHODIMP +nsCacheObject::GetLastAccessed(PRIntervalTime * iTime) const +{ + *iTime = m_LastAccessed; + return NS_OK ; +}; + +inline NS_IMETHODIMP +nsCacheObject::GetLastModified(PRIntervalTime * iTime) const +{ + *iTime = m_LastModified; + return NS_OK ; +}; + +inline NS_IMETHODIMP +nsCacheObject::SetLastModified(const PRIntervalTime i_LastModified) +{ + m_LastModified = i_LastModified; + return NS_OK ; +}; + +inline NS_IMETHODIMP +nsCacheObject::GetModuleIndex(PRInt16 * m_index) const +{ + *m_index = m_Module; + return NS_OK ; +}; + +inline NS_IMETHODIMP +nsCacheObject::SetModuleIndex(PRUint16 m_index) +{ + m_Module = m_index; + return NS_OK ; +}; + +inline NS_IMETHODIMP +nsCacheObject::GetPageServicesURL(char ** o_url) const +{ + if (!o_url) + return NS_ERROR_NULL_POINTER; + + *o_url = m_PageServicesURL; + return NS_OK ; +} + +inline NS_IMETHODIMP +nsCacheObject::GetPostData(char ** pData) const +{ + if (!pData) + return NS_ERROR_NULL_POINTER; + + *pData = m_PostData; + return NS_OK ; +} + +inline NS_IMETHODIMP +nsCacheObject::GetPostDataLen(PRUint32 * dLeng) const +{ + if (!dLeng) + return NS_ERROR_NULL_POINTER; + + *dLeng = m_PostDataLen; + return NS_OK ; +} + +inline NS_IMETHODIMP +nsCacheObject::GetSize(PRUint32 * pSize) const +{ + if (!pSize) + return NS_ERROR_NULL_POINTER; + + *pSize = m_Size; + return NS_OK ; +}; + +inline NS_IMETHODIMP +nsCacheObject::SetSize(PRUint32 i_Size) +{ + m_Size = i_Size; + return NS_OK ; +}; + +inline NS_IMETHODIMP +nsCacheObject::GetState(PRUint32 * pState) const +{ + if (!pState) + return NS_ERROR_NULL_POINTER; + + *pState = m_State; + return NS_OK ; +}; + +inline NS_IMETHODIMP +nsCacheObject::SetState(PRUint32 i_State) +{ + m_State = i_State; + return NS_OK ; +}; + +inline NS_IMETHODIMP +nsCacheObject::GetStream(nsStream** pStream) const +{ + if (!pStream) + return NS_ERROR_NULL_POINTER; + + *pStream = m_pStream; + return NS_OK ; +} + +///////////////////////////////////////////////////////////////////// +// nsCacheObjectFactory + +class nsCacheObjectFactory : public nsIFactory { +public: + nsCacheObjectFactory(); + virtual ~nsCacheObjectFactory(); + + NS_DECL_ISUPPORTS + + NS_IMETHOD CreateInstance(nsISupports *aOuter, + const nsIID &aIID, + void **aResult); + + NS_IMETHOD LockFactory(PRBool aLock); + +} ; + +#endif // nsCacheObject_h__ diff --git a/mozilla/netwerk/cache/include/nsCachePref.h b/mozilla/netwerk/cache/include/nsCachePref.h new file mode 100644 index 00000000000..89bf22a7d6f --- /dev/null +++ b/mozilla/netwerk/cache/include/nsCachePref.h @@ -0,0 +1,195 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +/* nsCachePref. A class to separate the preference related code to + * one place. This is an incomplete implementation, I need to access + * the libprefs directly, but that would add another dependency. And + * libpref comes with a JS dependency... so holding this off for the + * moment. + * + * -Gagan Saksena 09/15/98 + */ +#ifndef nsCachePref_h__ +#define nsCachePref_h__ + +#include "nsICachePref.h" +#include "nsIFactory.h" +#include "prtypes.h" +#include "prlog.h" + +class nsCachePref : public nsICachePref +{ + +public: + + nsCachePref(void); + virtual ~nsCachePref(); + + /* + NS_IMETHOD QueryInterface(const nsIID& aIID, + void** aInstancePtr); + NS_IMETHOD_(nsrefcnt) AddRef(void); + NS_IMETHOD_(nsrefcnt) Release(void); +*/ + NS_DECL_ISUPPORTS + /* + enum Refresh + { + ONCE, + ALWAYS, + NEVER + }; + */ + NS_IMETHOD GetBkgSleepTime (PRUint32* o_time) ; + + NS_IMETHOD GetDiskCacheDBFilename (char** o_name) ; /* like Fat.db */ + NS_IMETHOD GetDiskCacheFolder (char** o_folder) ; /* Cache dir */ + + NS_IMETHOD GetDiskCacheSSL (PRBool* o_bSet) ; + NS_IMETHOD SetDiskCacheSSL (PRBool i_bSet) ; + + NS_IMETHOD GetDiskCacheSize (PRUint32* o_size) ; + NS_IMETHOD SetDiskCacheSize (const PRUint32 i_size) ; + + NS_IMETHOD GetMemCacheSize (PRUint32 * o_size) ; + NS_IMETHOD SetMemCacheSize (const PRUint32 i_size) ; + + NS_IMETHOD GetFrequency (nsICachePref::Refresh* o_frequency) ; + + /* Revalidating in background, makes IMS calls in the bkg thread to + update cache entries. TODO, this should be at a bigger time period + than the cache cleanup routine */ + NS_IMETHOD RevalidateInBkg (PRBool* i_bRevalidateInBkg) ; + + /* Setup all prefs */ + NS_IMETHOD SetupPrefs(const char* i_Pref) ; + + static nsICachePref* GetInstance(void); + +private: + nsCachePref(const nsCachePref& o); + nsCachePref& operator=(const nsCachePref& o); + + PRBool m_bRevalidateInBkg; + PRBool m_bDiskCacheSSL; + nsICachePref::Refresh m_RefreshFreq; + PRUint32 m_MemCacheSize; + PRUint32 m_DiskCacheSize; + char* m_DiskCacheDBFilename; + char* m_DiskCacheFolder; + PRUint32 m_BkgSleepTime; +}; + +inline NS_IMETHODIMP +nsCachePref::GetDiskCacheSize(PRUint32* o_size) +{ + if (!o_size) + return NS_ERROR_NULL_POINTER ; + + *o_size = m_DiskCacheSize; + return NS_OK ; +} + +inline NS_IMETHODIMP +nsCachePref::SetDiskCacheSize(const PRUint32 i_Size) +{ + m_DiskCacheSize = i_Size; + return NS_OK ; +} + +inline NS_IMETHODIMP +nsCachePref::GetDiskCacheSSL(PRBool* o_bSet) +{ + if (!o_bSet) + return NS_ERROR_NULL_POINTER ; + + *o_bSet = m_bDiskCacheSSL; + return NS_OK ; +} + +inline NS_IMETHODIMP +nsCachePref::SetDiskCacheSSL(PRBool bSet) +{ + m_bDiskCacheSSL = bSet; + return NS_OK ; +} + +inline NS_IMETHODIMP +nsCachePref::GetDiskCacheFolder(char** o_folder) +{ + if (!o_folder) + return NS_ERROR_NULL_POINTER ; + + PR_ASSERT(m_DiskCacheFolder); + *o_folder = m_DiskCacheFolder ; + return NS_OK ; +} + +inline NS_IMETHODIMP +nsCachePref::GetMemCacheSize(PRUint32 * o_size) +{ + if (!o_size) + return NS_ERROR_NULL_POINTER ; + + *o_size = m_MemCacheSize; + return NS_OK ; +} + +inline NS_IMETHODIMP +nsCachePref::SetMemCacheSize(const PRUint32 i_Size) +{ + m_MemCacheSize = i_Size; + return NS_OK ; +} + +inline NS_IMETHODIMP +nsCachePref::RevalidateInBkg(PRBool* o_RevalidateInBkg) +{ + if (!o_RevalidateInBkg) + return NS_ERROR_NULL_POINTER ; + + *o_RevalidateInBkg = m_bRevalidateInBkg; + return NS_OK ; +} + +inline NS_IMETHODIMP +nsCachePref::GetFrequency (nsICachePref::Refresh* o_frequency) +{ + if (!o_frequency) + return NS_ERROR_NULL_POINTER ; + + *o_frequency = m_RefreshFreq ; + return NS_OK ; +} + +///////////////////////////////////////////////////////////////////// +// nsCacheObjectFactory + +class nsCachePrefFactory : public nsIFactory { + public: + nsCachePrefFactory(); + virtual ~nsCachePrefFactory(); + + NS_DECL_ISUPPORTS + NS_IMETHOD CreateInstance(nsISupports *aOuter, + const nsIID &aIID, + void **aResult); + NS_IMETHOD LockFactory(PRBool aLock); +} ; + +#endif // nsCachePref_h__ diff --git a/mozilla/netwerk/cache/include/nsDiskModule.h b/mozilla/netwerk/cache/include/nsDiskModule.h new file mode 100644 index 00000000000..c4f1c4e65c4 --- /dev/null +++ b/mozilla/netwerk/cache/include/nsDiskModule.h @@ -0,0 +1,132 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +/* + * nsDiskModule. The disk cache module that stores the cache objects + * on the disk. + * + * Gagan Saksena 02/03/98 + * + */ +#ifndef _nsDiskModule_H_ +#define _nsDiskModule_H_ + +#include "nsICacheModule.h" +#include "nsIterator.h" +#include "nsCacheIterator.h" +#include "nsEnumeration.h" +#include "nsCachePref.h" +#include "nsMonitorable.h" +#include "mcom_db.h" + + +class nsDiskModule : public nsMonitorable, public nsICacheModule +{ + +public: + NS_DECL_ISUPPORTS + + + ////////////////////////////////////////////////////////////////////////// + // nsICacheModule Methods: + + NS_IMETHOD AddObject(nsICacheObject* i_pObject); + + NS_IMETHOD ContainsURL(const char* i_url, PRBool* o_bContain); + + NS_IMETHOD ContainsCacheObj(nsICacheObject* i_pObject, PRBool* o_bContain) ; + + NS_IMETHOD Enable (PRBool i_Enable); + + NS_IMETHOD GetNumOfEntries (PRUint32* o_entry); + + NS_IMETHOD GetEnumerator (nsEnumeration** o_enum); + /* Enumerations with a function pointer - TODO */ + + //TODO move to own interface for both Garbage Collection and Revalidation + NS_IMETHOD GarbageCollect (void); + + NS_IMETHOD GetObjectByURL (const char* i_url, nsICacheObject** o_pObj); + + NS_IMETHOD GetObjectByIndex (const PRUint32 i_index, nsICacheObject** o_pObj); + + NS_IMETHOD GetStreamFor (const nsICacheObject* i_pObject, nsStream** o_pStream); + + NS_IMETHOD IsEnabled (PRBool* o_bEnabled); + + /* Can't do additions, deletions, validations, expirations */ + NS_IMETHOD IsReadOnly (PRBool* o_bReadOnly); + + NS_IMETHOD GetNextModule (nsICacheModule** o_pCacheModule); + NS_IMETHOD SetNextModule (nsICacheModule* i_pCacheModule); + + NS_IMETHOD RemoveByURL (const char* i_url); + + NS_IMETHOD RemoveByIndex (const PRUint32 i_index); + + NS_IMETHOD RemoveByObject (nsICacheObject* i_pObject); + + NS_IMETHOD RemoveAll (void); + + NS_IMETHOD Revalidate (void); + + NS_IMETHOD ReduceSizeTo (const PRUint32 i_newsize); + + NS_IMETHOD GetSize (PRUint32* o_size); + + NS_IMETHOD SetSize (const PRUint32 i_size); + + NS_IMETHOD GetSizeInUse (PRUint32* o_size); + + ///////////////////////////////////////////////////////////////////////// + // nsDiskModule Methods + nsDiskModule(); + nsDiskModule(const PRUint32 size); + virtual ~nsDiskModule(); + + PRUint32 AverageSize(void) const; + + static NS_METHOD + Create (nsISupports *aOuter, REFNSIID aIID, void** aResult); + +private: + enum sync_frequency + { + EVERYTIME, + IDLE, + NEVER + } m_Sync; + + PRBool InitDB(void); + + nsDiskModule(const nsDiskModule& dm); + nsDiskModule& operator=(const nsDiskModule& dm); + + + PRUint32 m_Entries; + PRUint32 m_Size; + PRUint32 m_SizeInUse; + PRBool m_Enabled; + nsEnumeration* m_pEnumeration; + nsCacheIterator* m_pIterator; + nsICacheModule* m_pNext; + DB* m_pDB; + +}; + +#endif diff --git a/mozilla/netwerk/cache/include/nsEnumeration.h b/mozilla/netwerk/cache/include/nsEnumeration.h new file mode 100644 index 00000000000..7daa8856244 --- /dev/null +++ b/mozilla/netwerk/cache/include/nsEnumeration.h @@ -0,0 +1,98 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (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/NPL/ + * + * 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 Mozilla Communicator client code. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corporation. Portions created by Netscape are Copyright (C) 1998 + * Netscape Communications Corporation. All Rights Reserved. + */ + +/* Another temporary class that needs to be replaced by a commonly + * used one, or made a commonly used one. + * + * -Gagan Saksena 09/15/98 + */ +#ifndef nsEnumeration_h__ +#define nsEnumeration_h__ + +//#include "nsISupports.h" +#include "nsIterator.h" +#include "prlog.h" + +class nsEnumeration //: public nsISupports +{ + +public: + nsEnumeration(nsIterator* iter); + virtual ~nsEnumeration(); + + PRBool HasMoreElements(void); + void* NextElement(void); + void Reset(void); +/* + NS_IMETHOD QueryInterface(const nsIID& aIID, + void** aInstancePtr); + NS_IMETHOD_(nsrefcnt) AddRef(void); + NS_IMETHOD_(nsrefcnt) Release(void); +*/ +protected: + nsIterator* m_pIter; +private: + nsEnumeration(const nsEnumeration& o); + nsEnumeration& operator=(const nsEnumeration& o); +}; + +inline +nsEnumeration::nsEnumeration(nsIterator* iter):m_pIter(iter) +{ + PR_ASSERT(iter); + if (m_pIter) + m_pIter->First(); +} + +inline +nsEnumeration::~nsEnumeration() +{ +} + +inline +PRBool nsEnumeration::HasMoreElements(void) +{ + if (m_pIter) //remove this check for optimization? + return m_pIter->IsDone() ? PR_FALSE : PR_TRUE; + return PR_FALSE; +} + +inline +void* nsEnumeration::NextElement(void) +{ + if (m_pIter) + { + void* pTemp = m_pIter->CurrentItem(); + m_pIter->Next(); + return pTemp; + } + return 0; +} + +inline +void nsEnumeration::Reset(void) +{ + if (m_pIter) + { + m_pIter->First(); + } +} + +#endif // nsEnumeration_h__ + diff --git a/mozilla/netwerk/cache/include/nsFileStream.h b/mozilla/netwerk/cache/include/nsFileStream.h new file mode 100644 index 00000000000..47ee79e22a5 --- /dev/null +++ b/mozilla/netwerk/cache/include/nsFileStream.h @@ -0,0 +1,68 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (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/NPL/ + * + * 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 Mozilla Communicator client code. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corporation. Portions created by Netscape are Copyright (C) 1998 + * Netscape Communications Corporation. All Rights Reserved. + */ + +/* nsFileStream. The file/disk based implementation of the nsStream class. + * It basically maps the read write functions to the file equivalents. + * + * -Gagan Saksena 09/15/98 + */ +#ifndef nsFileStream_h__ +#define nsFileStream_h__ + +//#include "nsISupports.h" +#include "nsStream.h" +#include "prio.h" // PRFileDesc + +class nsFileStream: public nsStream +{ + +public: + nsFileStream(const char* i_Filename); + virtual ~nsFileStream(); +/* + NS_IMETHOD QueryInterface(const nsIID& aIID, + void** aInstancePtr); + NS_IMETHOD_(nsrefcnt) AddRef(void); + NS_IMETHOD_(nsrefcnt) Release(void); +*/ + PRFileDesc* FileDesc(void); + + PRInt32 Read(void* o_Buffer, PRUint32 i_Len); + void Reset(void); + PRInt32 Write(const void* i_Buffer, PRUint32 i_Len); + +protected: + + PRBool Open(void); + +private: + nsFileStream(const nsFileStream& o); + nsFileStream& operator=(const nsFileStream& o); + PRFileDesc* m_pFile; + char* m_pFilename; +}; + +inline +PRFileDesc* nsFileStream::FileDesc(void) +{ + return m_pFile; +} + +#endif // nsFileStream_h__ + diff --git a/mozilla/netwerk/cache/include/nsIterator.h b/mozilla/netwerk/cache/include/nsIterator.h new file mode 100644 index 00000000000..42801f3b1b5 --- /dev/null +++ b/mozilla/netwerk/cache/include/nsIterator.h @@ -0,0 +1,71 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (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/NPL/ + * + * 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 Mozilla Communicator client code. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corporation. Portions created by Netscape are Copyright (C) 1998 + * Netscape Communications Corporation. All Rights Reserved. + */ + +/* Another common class that needs to be replaced/removed/recycled. + * + * -Gagan Saksena 09/15/98 + */ +#ifndef nsIterator_h__ +#define nsIterator_h__ + +//#include "nsISupports.h" +#include "prtypes.h" + +class nsIterator //:public nsISupports +{ + +public: + + virtual void First(void); + virtual PRBool IsDone(void) const = 0; + virtual void Next(void); + virtual void* CurrentItem(void) const; +/* + NS_IMETHOD QueryInterface(const nsIID& aIID, + void** aInstancePtr); + NS_IMETHOD_(nsrefcnt) AddRef(void); + NS_IMETHOD_(nsrefcnt) Release(void); +*/ + +protected: + nsIterator() {m_Index = 0;}; + + PRUint32 m_Index; + +}; + +inline +void nsIterator::First(void) +{ + m_Index = 0; +} + +inline +void nsIterator::Next(void) +{ + ++m_Index; +} + +inline +void* nsIterator::CurrentItem(void) const +{ + return 0; +} +#endif // nsIterator_h__ + diff --git a/mozilla/netwerk/cache/include/nsMemModule.h b/mozilla/netwerk/cache/include/nsMemModule.h new file mode 100644 index 00000000000..5f0ba5a127f --- /dev/null +++ b/mozilla/netwerk/cache/include/nsMemModule.h @@ -0,0 +1,158 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +/* +* nsMemModule. The memory based cache module. +* +* Gagan Saksena +* 02/03/98 +* +*/ + +#ifndef _nsMemModule_H_ +#define _nsMemModule_H_ + +#include "nsICacheModule.h" +#include "nsMemCacheObject.h" +#include "nsCachePref.h" +#include "nsCacheIterator.h" +#include "nsMonitorable.h" + +//#include "nsHash.h" // TODO - replace with nsHashtable when the XPCOM_BRANCH merges + +//#include "nsHashtable.h" + + + +class nsMemModule : public nsMonitorable, public nsICacheModule +{ + +public: + NS_DECL_ISUPPORTS + + + ////////////////////////////////////////////////////////////////////////// + // nsICacheModule Methods: + + NS_IMETHOD AddObject(nsICacheObject* i_pObject); + + NS_IMETHOD ContainsURL(const char* i_url, PRBool* o_bContain); + + NS_IMETHOD ContainsCacheObj(nsICacheObject* i_pObject, PRBool* o_bContain) ; + + NS_IMETHOD Enable (PRBool i_Enable); + + NS_IMETHOD GetNumOfEntries (PRUint32* o_entry); + + NS_IMETHOD GetEnumerator (nsEnumeration** o_enum); + /* Enumerations with a function pointer - TODO */ + + //TODO move to own interface for both Garbage Collection and Revalidation + NS_IMETHOD GarbageCollect (void); + + NS_IMETHOD GetObjectByURL (const char* i_url, nsICacheObject** o_pObj); + + NS_IMETHOD GetObjectByIndex (const PRUint32 i_index, nsICacheObject** o_pObj); + + NS_IMETHOD GetStreamFor (const nsICacheObject* i_pObject, nsStream** o_pStream); + + NS_IMETHOD IsEnabled (PRBool* o_bEnabled); + + /* Can't do additions, deletions, validations, expirations */ + NS_IMETHOD IsReadOnly (PRBool* o_bReadOnly); + + NS_IMETHOD GetNextModule (nsICacheModule** o_pCacheModule); + NS_IMETHOD SetNextModule (nsICacheModule* i_pCacheModule); + + NS_IMETHOD RemoveByURL (const char* i_url); + + NS_IMETHOD RemoveByIndex (const PRUint32 i_index); + + NS_IMETHOD RemoveByObject (nsICacheObject* i_pObject); + + NS_IMETHOD RemoveAll (void); + + NS_IMETHOD Revalidate (void); + + NS_IMETHOD ReduceSizeTo (const PRUint32 i_newsize); + + NS_IMETHOD GetSize (PRUint32* o_size); + + NS_IMETHOD SetSize (const PRUint32 i_size); + + NS_IMETHOD GetSizeInUse (PRUint32* o_size); + + + /////////////////////////////////////////////////////////////////////////// + // Start of nsMemModule specific stuff... + // Here is a sample implementation using linked list + + nsMemModule(); + nsMemModule(const PRUint32 size); + virtual ~nsMemModule(); + + + static NS_METHOD + Create (nsISupports *aOuter, REFNSIID aIID, void **aResult); + +protected: + nsMemCacheObject* LastObject(void) const; + +private: + nsMemCacheObject* m_pFirstObject; + + //nsHash m_ht; //TODO replace with nsHashtable + //Optimization + nsMemCacheObject* m_pLastObject; + + nsMemModule(const nsMemModule& mm); + nsMemModule& operator=(const nsMemModule& mm); + +/* + class nsMemKey : public nsHashKey + { + public: + nsMemKey(); + ~nsMemKey(); + PRUint32 HashValue(); + PRBool Equals(nsHashKey *aKey); + nsHashKey* Clone(); + }; +*/ + + + PRUint32 m_Entries; + PRUint32 m_Size; + PRUint32 m_SizeInUse; + PRBool m_Enabled; + nsEnumeration* m_pEnumeration; + nsCacheIterator* m_pIterator; + nsICacheModule* m_pNext; +}; + + + +inline +NS_IMETHODIMP nsMemModule::Revalidate(void) +{ + // Mem module elements are never revalidated. + // It is a no-op. + return NS_OK; +} + +#endif diff --git a/mozilla/netwerk/cache/include/nsMemStream.h b/mozilla/netwerk/cache/include/nsMemStream.h new file mode 100644 index 00000000000..effc3a08943 --- /dev/null +++ b/mozilla/netwerk/cache/include/nsMemStream.h @@ -0,0 +1,60 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this Mem are subject to the Netscape Public License + * Version 1.0 (the "License"); you may not use this Mem except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/NPL/ + * + * 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 Mozilla Communicator client code. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corporation. Portions created by Netscape are Copyright (C) 1998 + * Netscape Communications Corporation. All Rights Reserved. + */ + +/* nsMemStream. A memory based stream for use with memory objects + * + * -Gagan Saksena 09/15/98. + */ +#ifndef nsMemStream_h__ +#define nsMemStream_h__ + +//#include "nsISupports.h" +#include "nsStream.h" + +class nsMemStream: public nsStream +{ + +public: + nsMemStream(); + virtual ~nsMemStream(); +/* + NS_IMETHOD QueryInterface(const nsIID& aIID, + void** aInstancePtr); + NS_IMETHOD_(nsrefcnt) AddRef(void); + NS_IMETHOD_(nsrefcnt) Release(void); +*/ + PRInt32 Read(void* o_Buffer, PRUint32 i_Len); + void Reset(void); + PRInt32 Write(const void* i_Buffer, PRUint32 i_Len); + +protected: + +private: + nsMemStream(const nsMemStream& o); + nsMemStream& operator=(const nsMemStream& o); + + PRUint32 m_AllocSize; + PRUint32 m_ReadOffset; + PRUint32 m_WriteOffset; + void* m_pStart; + PRUint32 m_Size; +}; + +#endif // nsMemStream_h__ + diff --git a/mozilla/netwerk/cache/include/nsMonitorable.h b/mozilla/netwerk/cache/include/nsMonitorable.h new file mode 100644 index 00000000000..d0c6af3d43b --- /dev/null +++ b/mozilla/netwerk/cache/include/nsMonitorable.h @@ -0,0 +1,106 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (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/NPL/ + * + * 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 Mozilla Communicator client code. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corporation. Portions created by Netscape are Copyright (C) 1998 + * Netscape Communications Corporation. All Rights Reserved. + */ + +/* nsMonitorable. This is a cool class too. Its an easy of adding monitors + * actually PRMonitor behaviour to existing classes. The nsMonitorLocker is + * an excursion class that locks the scope in which is declared (on stack). + * + * -Gagan Saksena 09/15/98 + */ +#ifndef nsMonitorable_h__ +#define nsMonitorable_h__ + +//#include "nsISupports.h" + +#include "prmon.h" +#include "prlog.h" + +class nsMonitorable//: public nsISupports +{ + +public: + nsMonitorable(); + virtual ~nsMonitorable(); + +/* + NS_IMETHOD QueryInterface(const nsIID& aIID, + void** aInstancePtr); + NS_IMETHOD_(nsrefcnt) AddRef(void); + NS_IMETHOD_(nsrefcnt) Release(void); +*/ + PRBool Lock(void); + void Unlock(void); + +protected: + + class MonitorLocker + { + public: + MonitorLocker(nsMonitorable* i_pThis); + ~MonitorLocker(); + private: + nsMonitorable* m_pMonitorable; + }; + + PRMonitor* m_pMonitor; + +private: + nsMonitorable(const nsMonitorable& o); + nsMonitorable& operator=(const nsMonitorable& o); +}; + +inline +nsMonitorable::nsMonitorable(void):m_pMonitor(PR_NewMonitor()) +{ +} + +inline +nsMonitorable::~nsMonitorable() +{ + if (m_pMonitor) + { + PR_DestroyMonitor(m_pMonitor); + m_pMonitor = 0; + } +} + +inline +PRBool nsMonitorable::Lock(void) +{ + if (!m_pMonitor) + { + m_pMonitor = PR_NewMonitor(); + if (!m_pMonitor) + return PR_FALSE; + } + PR_EnterMonitor(m_pMonitor); + return PR_TRUE; +} + + +inline +void nsMonitorable::Unlock(void) +{ + PR_ASSERT(m_pMonitor); + if (m_pMonitor) + PR_ExitMonitor(m_pMonitor); +} + +#endif // nsMonitorable_h__ + diff --git a/mozilla/netwerk/cache/include/nsStream.h b/mozilla/netwerk/cache/include/nsStream.h new file mode 100644 index 00000000000..d37cd963705 --- /dev/null +++ b/mozilla/netwerk/cache/include/nsStream.h @@ -0,0 +1,71 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (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/NPL/ + * + * 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 Mozilla Communicator client code. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corporation. Portions created by Netscape are Copyright (C) 1998 + * Netscape Communications Corporation. All Rights Reserved. + */ + +/* A placeholder for the actual professional strength streams class. Works + * ok for me for now. + * + * -Gagan Saksena 09/15/98 + */ + +#ifndef nsStream_h__ +#define nsStream_h__ + +//#include "nsISupports.h" + +#include "prtypes.h" + +class nsStream//: public nsISupports +{ + +public: + nsStream(); + virtual ~nsStream(); +/* + NS_IMETHOD QueryInterface(const nsIID& aIID, + void** aInstancePtr); + NS_IMETHOD_(nsrefcnt) AddRef(void); + NS_IMETHOD_(nsrefcnt) Release(void); +*/ + virtual + PRInt32 Read(void* o_Buffer, PRUint32 i_Len) = 0; + virtual + void Reset(void) = 0; + virtual + PRInt32 Write(const void* i_Buffer, PRUint32 i_Len) = 0; + +protected: + +private: + nsStream(const nsStream& o); + nsStream& operator=(const nsStream& o); +}; + +inline +nsStream::nsStream(void) +{ + //noop +} + +inline +nsStream::~nsStream() +{ + //noop +} +#endif // nsStream_h__ + diff --git a/mozilla/netwerk/cache/mgr/Makefile.in b/mozilla/netwerk/cache/mgr/Makefile.in new file mode 100644 index 00000000000..3b75ed45170 --- /dev/null +++ b/mozilla/netwerk/cache/mgr/Makefile.in @@ -0,0 +1,55 @@ +# Generated automatically from Makefile.in by configure. +#!gmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +DEPTH = ../../.. +topsrcdir = @top_srcdir@ +VPATH = @srcdir@ +srcdir = @srcdir@ + +include $(DEPTH)/config/autoconf.mk + +LIBRARY_NAME = cachemgr +MODULE=cachemgr +IS_COMPONENT=1 + +LOCAL_INCLUDES += \ + -I$(srcdir)/../public \ + -I$(srcdir)/../include \ + $(NULL) + +CPPSRCS = \ + nsCacheManager.cpp \ + nsMonitorable.cpp \ + nsCacheBkgThd.cpp \ + nsBkgThread.cpp \ + $(NULL) + +EXPORTS = \ + $(NULL) + +EXPORTS := $(addprefix $(srcdir)/, $(EXPORTS)) + +REQUIRES += nspr + +EXTRA_LIBS += $(NSPR_LIBS) + +include $(topsrcdir)/config/config.mk + +#TARGETS = $(LIBRARY) + +include $(topsrcdir)/config/rules.mk diff --git a/mozilla/netwerk/cache/mgr/Makefile.win b/mozilla/netwerk/cache/mgr/Makefile.win new file mode 100755 index 00000000000..b5e98d8f3e5 --- /dev/null +++ b/mozilla/netwerk/cache/mgr/Makefile.win @@ -0,0 +1,59 @@ +#!gmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +DEPTH=..\..\.. +include <$(DEPTH)/config/config.mak> + +MODULE=cachemgr + +IS_COMPONENT=1 +MAKE_OBJ_TYPE=DLL +DLLNAME=cachemgr +DLL=.\$(OBJDIR)\$(DLLNAME).dll + +LLIBS= $(LLIBS) \ + $(LIBNSPR) \ + $(DIST)\lib\xpcom.lib \ + $(NULL) + +CPP_OBJS= \ + .\$(OBJDIR)\nsCacheManager.obj \ + .\$(OBJDIR)\nsMonitorable.obj \ + .\$(OBJDIR)\nsCacheBkgThd.obj \ + .\$(OBJDIR)\nsBkgThread.obj \ + $(NULL) + +LOCAL_INCLUDES= -I. \ + -I..\public \ + -I..\include \ + +INCLUDES = $(LOCAL_INCLUDES) + +REQUIRES = nspr + +INCS = $(INCS) \ + -I..\include \ + -I..\public \ + -I$(DEPTH)\dist\include \ + $(NULL) + +include <$(DEPTH)\config\rules.mak> + +install:: $(DLL) + $(MAKE_INSTALL) $(DLL) $(DIST)\bin\components + $(MAKE_INSTALL) .\$(OBJDIR)\$(DLLNAME).lib $(DIST)\lib + diff --git a/mozilla/netwerk/cache/mgr/nsBkgThread.cpp b/mozilla/netwerk/cache/mgr/nsBkgThread.cpp new file mode 100644 index 00000000000..bde1f2d4164 --- /dev/null +++ b/mozilla/netwerk/cache/mgr/nsBkgThread.cpp @@ -0,0 +1,92 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#include "nsBkgThread.h" +#include "prlog.h" + +static void PR_CALLBACK RunFunction(void* arg); + +static void PR_CALLBACK RunFunction(void* arg) +{ + nsBkgThread* pBT = (nsBkgThread*) arg; + if (pBT) + { + pBT->Process(); + } +} + +nsBkgThread::nsBkgThread(PRIntervalTime iSleepTime, PRBool bStart /* =PR_TRUE */) +{ + m_SleepTime = iSleepTime; + m_bContinue = bStart; + m_pThread = PR_CreateThread( + PR_USER_THREAD, + RunFunction, + this, + PR_PRIORITY_NORMAL, + PR_LOCAL_THREAD, + PR_JOINABLE_THREAD, + 0); + PR_ASSERT(NULL != m_pThread); +} + +nsBkgThread::~nsBkgThread() +{ + m_bContinue = PR_FALSE; + if (m_pThread != NULL) + { + Stop(); + } +} +/* +nsrefcnt nsBkgThread::AddRef(void) +{ + return ++m_RefCnt; +} +nsrefcnt nsBkgThread::Release(void) +{ + if (--m_RefCnt == 0) + { + delete this; + return 0; + } + return m_RefCnt; +} + +nsresult nsBkgThread::QueryInterface(const nsIID& aIID, + void** aInstancePtrResult) +{ + return NS_OK; +} + +*/ +void nsBkgThread::Process(void) +{ + while (m_bContinue) + { + PR_Sleep(m_SleepTime); + Run(); + } +} + +void nsBkgThread::Stop(void) +{ + m_bContinue = PR_FALSE; + PRStatus status = PR_Interrupt(m_pThread); + PR_ASSERT(PR_SUCCESS == status); +} diff --git a/mozilla/netwerk/cache/mgr/nsCacheBkgThd.cpp b/mozilla/netwerk/cache/mgr/nsCacheBkgThd.cpp new file mode 100644 index 00000000000..62a85b83d8e --- /dev/null +++ b/mozilla/netwerk/cache/mgr/nsCacheBkgThd.cpp @@ -0,0 +1,102 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#include "prlog.h" +#include "nsCacheBkgThd.h" +#include "nsIServiceManager.h" +#include "nsCacheManager.h" +//#include "nsCacheModule.h" +#include "nsCachePref.h" + +static NS_DEFINE_IID(kICachePrefIID, NS_ICACHEPREF_IID) ; +static NS_DEFINE_IID(kCachePrefCID, NS_CACHEPREF_CID) ; + +nsCacheBkgThd::nsCacheBkgThd(PRIntervalTime iSleepTime): + nsBkgThread(iSleepTime) +{ +} + +nsCacheBkgThd::~nsCacheBkgThd() +{ +} + +/* +nsrefcnt nsCacheBkgThd::AddRef(void) +{ + return ++m_RefCnt; +} +nsrefcnt nsCacheBkgThd::Release(void) +{ + if (--m_RefCnt == 0) + { + delete this; + return 0; + } + return m_RefCnt; +} + +nsresult nsCacheBkgThd::QueryInterface(const nsIID& aIID, + void** aInstancePtrResult) +{ + return NS_OK; +} +*/ + +void nsCacheBkgThd::Run(void) +{ + /* Step thru all the modules and call cleanup on each */ + nsCacheManager* pCM = nsCacheManager::GetInstance(); + + nsICachePref* pref ; + + nsServiceManager::GetService(kCachePrefCID, + kICachePrefIID, + (nsISupports **)&pref) ; + + PRBool offline ; + + PR_ASSERT(pCM); + pCM->IsOffline(&offline) ; + if (offline) + return; /* Dont update entries if offline */ + PRInt16 i ; + pCM->Entries(&i); + while (i>0) + { + nsICacheModule* pModule ; + pCM->GetModule(--i, &pModule); + PR_ASSERT(pModule); + + /* TODO change this based on if it supports garbage cleaning */ + + PRBool ro, revalidate ; + pModule->IsReadOnly(&ro) ; + if (!ro) + { + pModule->GarbageCollect(); + + pref->RevalidateInBkg(&revalidate) ; + + if (revalidate) + { + pModule->Revalidate(); + } + } + } +} + diff --git a/mozilla/netwerk/cache/mgr/nsCacheManager.cpp b/mozilla/netwerk/cache/mgr/nsCacheManager.cpp new file mode 100644 index 00000000000..ee86ae0a4d4 --- /dev/null +++ b/mozilla/netwerk/cache/mgr/nsCacheManager.cpp @@ -0,0 +1,741 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +/* + * Gagan Saksena 02/02/98 + * + */ + +#include "prtypes.h" +#include "pratom.h" +#include "nscore.h" +#include "prinrval.h" +#include "plstr.h" +#include "prprf.h" //PR_smprintf and PR_smprintf_free + +#include "nsISupports.h" + +#include "nsRepository.h" +#include "nsIComponentManager.h" +#include "nsIServiceManager.h" + +// #include "nsCacheTrace.h" +// #include "nsCachePref.h" +#include "nsICacheModule.h" +//#include "nsMemModule.h" +//#include "nsDiskModule.h" +#include "nsCacheBkgThd.h" + +// #include "nsMemModule.h" +// #include "nsDiskModule.h" +#include "nsCacheManager.h" + +/* TODO move this to InitNetLib */ +// static nsCacheManager TheManager; +nsCacheManager * nsCacheManager::gInstance = NULL ; + +static PRInt32 gLockCnt = 0 ; +static PRInt32 gInstanceCnt = 0 ; + +static NS_DEFINE_IID(kIFactoryIID, NS_IFACTORY_IID) ; +static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID) ; +static NS_DEFINE_IID(kICacheManagerIID, NS_ICACHEMANAGER_IID) ; +static NS_DEFINE_IID(kCacheManagerCID, NS_CACHEMANAGER_CID) ; + +static NS_DEFINE_IID(kICachePrefIID, NS_ICACHEPREF_IID) ; +static NS_DEFINE_IID(kCachePrefCID, NS_CACHEPREF_CID) ; + +static NS_DEFINE_IID(kICacheModuleIID, NS_ICACHEMODULE_IID) ; +static NS_DEFINE_IID(kCacheDiskModuleCID, NS_DISKMODULE_CID) ; +static NS_DEFINE_IID(kCacheMemModuleCID, NS_MEMMODULE_CID) ; + +PRUint32 NumberOfObjects(void); + +nsCacheManager::nsCacheManager(): + m_pFirstModule(0), + m_bOffline(PR_FALSE), + m_pPrefs(0) +{ + NS_INIT_ISUPPORTS( ) ; + PR_AtomicIncrement(&gInstanceCnt) ; +} + +nsCacheManager::~nsCacheManager() +{ + if (m_pPrefs) + { + // delete m_pPrefs; + NS_RELEASE(m_pPrefs) ; + m_pPrefs = 0; + } + if (m_pFirstModule) + { + // delete m_pFirstModule; + NS_RELEASE(m_pFirstModule) ; + m_pFirstModule = 0; + } + if (m_pBkgThd) + { + m_pBkgThd->Stop(); + delete m_pBkgThd; + m_pBkgThd = 0; + } + + // Shutdown( ) ; + + NS_ASSERTION(mRefCnt==0, "wrong Ref count" ) ; + PR_AtomicDecrement(&gInstanceCnt) ; + +} + + +nsCacheManager* +nsCacheManager::GetInstance() +{ + if (!gInstance) + { + gInstance = new nsCacheManager( ) ; + gInstance->Init( ) ; + } + return gInstance ; +// return &TheManager; +} + +#if 0 +/* Caller must free returned char* */ +const char* +nsCacheManager::Trace() const +{ + + char linebuffer[128]; + char* total; + PRInt16 n_entries=0 ; + + Entries(&n_entries) ; + + sprintf(linebuffer, "nsCacheManager: Modules = %d\n", n_entries); + + total = new char[strlen(linebuffer) + 1]; + strcpy(total, linebuffer); + return total; +} +#endif + +NS_IMETHODIMP +nsCacheManager::AddModule(PRInt16 * n_Index, nsICacheModule* pModule) +{ + // PRInt16 *n_Entries ; + // nsresult rv ; + + if (!n_Index) + return NS_ERROR_NULL_POINTER ; + + MonitorLocker ml(this); + if (pModule) + { + if (m_pFirstModule) + LastModule()->SetNextModule(pModule); + else + m_pFirstModule = pModule; + + Entries(n_Index) ; + (*n_Index)-- ; + + return NS_OK ; + } + else + return NS_ERROR_FAILURE ; +} + +NS_IMETHODIMP +nsCacheManager::Contains(const char* i_url) const +{ + MonitorLocker ml((nsMonitorable*)this); + // Add logic to check for IMAP type URLs, byteranges, and search with / appended as well... + // TODO + PRBool bContain ; + + nsresult rv = ContainsExactly(i_url, &bContain); + + if (!bContain) + { + // try alternate stuff + // char* extraBytes; + // char extraBytesSeparator; + } +#if !defined(NDEBUG) && defined(DEBUG_gagan) + fputs(i_url, stdout); + fputs(NS_SUCCEEDED(bStatus) ? " is " : " is not ", stdout); + fputs("in cache\n", stdout); +#endif + return rv ; +} + + +/* +PRBool +nsCacheManager::Contains(const char* i_url) const +{ + MonitorLocker ml((nsMonitorable*)this); + // Add logic to check for IMAP type URLs, byteranges, and search with / appended as well... + // TODO + PRBool bStatus = ContainsExactly(i_url); + if (!bStatus) + { + // try alternate stuff + // char* extraBytes; + // char extraBytesSeparator; + } +#if !defined(NDEBUG) && defined(DEBUG_gagan) + fputs(i_url, stdout); + fputs(bStatus ? " is " : " is not ", stdout); + fputs("in cache\n", stdout); +#endif + return bStatus ; +} +*/ + +NS_IMETHODIMP +nsCacheManager::ContainsExactly(const char* i_url, PRBool * contains) const +{ + nsresult rv ; + + *contains = PR_FALSE ; + + if (m_pFirstModule) + { + nsICacheModule* pModule = m_pFirstModule; + while (pModule) + { + rv = pModule->ContainsURL(i_url, contains) ; + + if ( contains ) + { + return NS_OK; + } + rv = pModule->GetNextModule(&pModule); + } + } + return NS_ERROR_FAILURE ; +} + +NS_IMETHODIMP +nsCacheManager::GetObj(const char* i_url, void ** o_pObject) const +{ + nsresult rv ; + + if ( !o_pObject) + return NS_ERROR_NULL_POINTER ; + + *o_pObject = nsnull ; + + MonitorLocker ml((nsMonitorable*)this); + + if (m_pFirstModule) + { + nsICacheModule* pModule = m_pFirstModule; + + while (pModule) + { + rv = pModule->GetObjectByURL(i_url, (nsICacheObject**) o_pObject); + + if (*o_pObject) + return NS_OK ; + + rv = pModule->GetNextModule(&pModule); + } + } + return NS_ERROR_FAILURE; +} + +NS_IMETHODIMP +nsCacheManager::Entries(PRInt16 * n_Entries) const +{ + nsresult rv ; + + if (!n_Entries) + return NS_ERROR_NULL_POINTER ; + + MonitorLocker ml((nsMonitorable*)this); + if (m_pFirstModule) + { + PRInt16 count=1; + nsICacheModule* pModule ; + + rv = m_pFirstModule->GetNextModule(&pModule); + + while (pModule) + { + count++; + rv = pModule->GetNextModule(&pModule); + } + *n_Entries = count ; + return NS_OK; + } + return NS_ERROR_FAILURE ; +} + +/* +PRInt16 +nsCacheManager::Entries(void) const +{ + MonitorLocker ml((nsMonitorable*)this); + if (m_pFirstModule) + { + PRInt16 count=1; + nsCacheModule* pModule = m_pFirstModule->NextModule(); + while (pModule) + { + count++; + pModule = pModule->NextModule(); + } + return count; + } + return -1 ; +} +*/ + +// todo: use PROGID instead of index +NS_IMETHODIMP +nsCacheManager::GetModule(PRInt16 i_index, nsICacheModule** pModule) const +{ + nsresult rv ; + + if (!pModule) + return NS_ERROR_NULL_POINTER ; + + MonitorLocker ml((nsMonitorable*)this); + + PRInt16 n_entries = 0 ; + + rv = Entries(&n_entries) ; + + if ((i_index < 0) || (i_index >= n_entries)) + return NS_ERROR_FAILURE ; + + *pModule = m_pFirstModule; + + PR_ASSERT(*pModule); + for (PRInt16 i=0; iGetNextModule(pModule)) + { + i++; + PR_ASSERT(*pModule); + } + return NS_OK ; +} + +NS_IMETHODIMP +nsCacheManager::InfoAsHTML(char** o_Buffer) const +{ + PRInt16 n_entries = 0; + Entries(&n_entries) ; + + if (!o_Buffer) + return NS_ERROR_NULL_POINTER ; + + MonitorLocker ml((nsMonitorable*)this); + + char* tmpBuffer =/* TODO - make this cool */ + PR_smprintf("

Your cache has %d modules

\ + It has a total of %d cache objects. Hang in there for the details. \0", + n_entries, + NumberOfObjects()); + + if (tmpBuffer) + { + PL_strncpyz(*o_Buffer, tmpBuffer, PL_strlen(tmpBuffer)+1); + PR_smprintf_free(tmpBuffer); + } + return NS_OK ; +} + +void +nsCacheManager::Init() +{ + nsresult rv=nsnull ; + PRUint32 size ; + + MonitorLocker ml(this); + + //Init prefs + if (!m_pPrefs) + // m_pPrefs = new nsCachePref(); + + rv = nsComponentManager::CreateInstance(kCachePrefCID, + nsnull, + kICachePrefIID, + (void**)&m_pPrefs) ; + + rv=nsnull ; + + if (m_pFirstModule) + delete m_pFirstModule; + + // m_pFirstModule = new nsMemModule(nsCachePref::GetInstance()->MemCacheSize()); + rv = nsComponentManager::CreateInstance(kCacheMemModuleCID, + nsnull, + kICacheModuleIID, + (void**)&m_pFirstModule) ; + + rv = m_pPrefs->GetMemCacheSize(&size) ; + + rv = m_pFirstModule -> SetSize(size) ; + + PR_ASSERT(m_pFirstModule); + + if (m_pFirstModule) + { + rv = m_pPrefs->GetDiskCacheSize(&size) ; + + nsICacheModule* p_Temp ; + // = new nsDiskModule(nsCachePref::GetInstance()->DiskCacheSize()); + + rv = nsComponentManager::CreateInstance(kCacheDiskModuleCID, + nsnull, + kICacheModuleIID, + (void**)&p_Temp) ; + + rv = m_pPrefs->SetDiskCacheSize(size) ; + + rv = p_Temp->SetSize(size) ; + + PR_ASSERT(p_Temp); + rv = m_pFirstModule->SetNextModule(p_Temp); + + PRUint32 time ; + + rv = m_pPrefs->GetBkgSleepTime(&time) ; + + m_pBkgThd = new nsCacheBkgThd(PR_SecondsToInterval(time)); + + PR_ASSERT(m_pBkgThd); + } +} + +nsICacheModule* +nsCacheManager::LastModule() const +{ + MonitorLocker ml((nsMonitorable*)this); + + nsresult rv ; + + if (m_pFirstModule) + { + nsICacheModule* temp = m_pFirstModule; + nsICacheModule* pModule=temp ; + + rv = temp->GetNextModule(&temp) ; + + while(temp) { + pModule = temp ; + rv = temp->GetNextModule(&temp) ; + } + + return pModule; + } + return 0; +} + +NS_IMETHODIMP +nsCacheManager::Remove(const char* i_url) +{ + MonitorLocker ml(this); + nsresult rv ; + + if (m_pFirstModule) + { + nsICacheModule* pModule = m_pFirstModule; + + do { + rv = pModule ->RemoveByURL(i_url) ; + if ( NS_SUCCEEDED(rv) ) return rv ; + + rv = pModule ->GetNextModule(&pModule) ; + } while (pModule) ; + } + + return NS_ERROR_FAILURE ; +} + +NS_IMETHODIMP +nsCacheManager::WorstCaseTime(PRUint32 * o_Time) const +{ + PRIntervalTime start = PR_IntervalNow(); + + o_Time = nsnull ; + + if (NS_SUCCEEDED(this->Contains("a vague string that should not be in any of the modules"))) + { + PR_ASSERT(0); + } + *o_Time = PR_IntervalToMicroseconds(PR_IntervalNow() - start); + + return NS_OK ; +} + +PRUint32 +NumberOfObjects(void) +{ + PRUint32 objs = 0, temp; + nsresult rv ; + nsICacheModule* pModule ; + nsICacheManager* cacheManager ; + + PRInt16 i ; + + rv = nsServiceManager::GetService(kCacheManagerCID, + kICacheManagerIID, + (nsISupports **)&cacheManager) ; + + rv = cacheManager->Entries(&i); + + while (i>0) + { + rv = cacheManager->GetModule(--i, &pModule) ; + pModule->GetNumOfEntries(&temp); + objs+=temp ; + } + return objs; +} + +/* +NS_IMETHODIMP +nsCacheManager::QueryInterface(const nsIID &aIID, void **aResult) +{ + if(!aResult) + return NS_ERROR_NULL_POINTER ; + + if (aIID.Equals(kISupportsIID)) { + *aResult = NS_STATIC_CAST(nsISupports*, this) ; + } + else if (aIID.Equals(kICacheManagerIID)) { + *aResult = NS_STATIC_CAST(nsISupports*, + NS_STATIC_CAST(nsICacheManager*, this)) ; + } + else { + *aResult = nsnull ; + return NS_ERROR_NO_INTERFACE ; + } + + NS_ADDREF(NS_REINTERPRET_CAST(nsISupports*, *aResult)) ; + + return NS_OK ; +} + +NS_IMPL_ADDREF(nsCacheManager) +NS_IMPL_RELEASE(nsCacheManager) +*/ + +NS_IMPL_ISUPPORTS(nsCacheManager, kICacheManagerIID) ; + +nsCacheManagerFactory::nsCacheManagerFactory( ) +{ + NS_INIT_ISUPPORTS( ) ; + PR_AtomicIncrement(&gInstanceCnt) ; +} + +nsCacheManagerFactory::~nsCacheManagerFactory( ) +{ + NS_ASSERTION(mRefCnt == 0, "Wrong ref count") ; + PR_AtomicDecrement(&gInstanceCnt) ; +} + +/* +NS_IMETHODIMP +nsCacheManagerFactory::QueryInterface(const nsIID &aIID, void ** aResult) +{ + if (!aResult) + return NS_ERROR_NULL_POINTER ; + + if (aIID.Equals(kISupportsIID)) { + *aResult = NS_STATIC_CAST(nsISupports*, this) ; + } + else if (aIID.Equals(kIFactoryIID)) { + *aResult = NS_STATIC_CAST(nsISupports*, + NS_STATIC_CAST(nsIFactory*, this)) ; + } + else { + *aResult = nsnull ; + return NS_ERROR_NO_INTERFACE ; + } + + NS_ADDREF(NS_REINTERPRET_CAST(nsISupports*, *aResult)) ; + + return NS_OK ; +} + +NS_IMPL_ADDREF(nsCacheManagerFactory) +NS_IMPL_RELEASE(nsCacheManagerFactory) +*/ + +NS_IMPL_ISUPPORTS(nsCacheManagerFactory, kIFactoryIID) ; + +// Todo, needs to enforce singleton + +NS_IMETHODIMP +nsCacheManagerFactory::CreateInstance(nsISupports *aOuter, + const nsIID &aIID, + void **aResult) +{ + if (!aResult) + return NS_ERROR_NULL_POINTER ; + + *aResult = nsnull ; + + nsISupports *inst = nsCacheManager::GetInstance( ) ; + + if (!inst) { + return NS_ERROR_OUT_OF_MEMORY ; + } + + nsresult rv = inst -> QueryInterface(aIID, aResult) ; + + if (NS_FAILED(rv)) { + delete inst ; + } + + return rv ; +} + +NS_IMETHODIMP +nsCacheManagerFactory::LockFactory(PRBool aLock) +{ + if (aLock) { + PR_AtomicIncrement (&gLockCnt) ; + } + else { + PR_AtomicDecrement (&gLockCnt) ; + } + + return NS_OK ; +} + +// static NS_DEFINE_CID (kCacheManagerCID, NS_CACHEMANAGER_CID) ; +static NS_DEFINE_CID (kComponentManagerCID, NS_COMPONENTMANAGER_CID) ; + +static const char * g_desc = "Mozilla xpcom cache manager" ; + +extern "C" NS_EXPORT nsresult +NSGetFactory(nsISupports *serviceMgr, + const nsCID &aCID, + const char * aClassName, + const char * aProgID, + nsIFactory **aResult) +{ + if (!aResult) + return NS_ERROR_NULL_POINTER ; + + *aResult = nsnull ; + + nsISupports *inst ; + + if (aCID.Equals(kCacheManagerCID)) { + inst = new nsCacheManagerFactory( ) ; + } + else { + return NS_ERROR_NO_INTERFACE ; + } + + if (!inst) + return NS_ERROR_OUT_OF_MEMORY ; + + nsresult rv = inst->QueryInterface(kIFactoryIID, (void **)aResult) ; + + if (NS_FAILED(rv)) { + delete inst ; + } + + return rv ; +} + +extern "C" NS_EXPORT PRBool +NSCanUnload (nsISupports* serviceMgr) +{ + return PRBool(gInstanceCnt == 0 && gLockCnt == 0) ; +} + +extern "C" NS_EXPORT nsresult +NSRegisterSelf(nsISupports *aServMgr, const char *path) +{ + nsresult rv = NS_OK ; + + nsIServiceManager *sm ; + + rv = aServMgr->QueryInterface(nsIServiceManager::GetIID(), (void**)&sm) ; + + if(NS_FAILED(rv)) { + return rv; + } + + nsIComponentManager *cm ; + + rv = sm->GetService(kComponentManagerCID, + nsIComponentManager::GetIID(), + (nsISupports **) &cm) ; + if (NS_FAILED(rv)) { + NS_RELEASE(sm) ; + return rv ; + } + + rv = cm->RegisterComponent(kCacheManagerCID, g_desc, "component://nucache", + path, PR_TRUE, PR_TRUE) ; + + sm->ReleaseService(kComponentManagerCID, cm) ; + + NS_RELEASE(sm) ; + +#ifdef NS_DEBUG + printf("*** %s registered\n", g_desc) ; +#endif + + return rv ; +} + +extern "C" NS_EXPORT nsresult +NSUnregisterSelf(nsISupports* aServMgr, const char *path) +{ + nsresult rv = NS_OK ; + + nsIServiceManager *sm ; + + rv = aServMgr ->QueryInterface(nsIServiceManager::GetIID(), + (void **)&sm) ; + + if(NS_FAILED(rv)) { + return rv ; + } + + nsIComponentManager *cm ; + + rv = sm->GetService(kComponentManagerCID, nsIComponentManager::GetIID(), + (nsISupports**) &cm) ; + + if(NS_FAILED(rv)) { + NS_RELEASE(sm) ; + return rv ; + } + + rv = cm->UnregisterComponent(kCacheManagerCID, path); + + sm->ReleaseService(kComponentManagerCID, cm) ; + + NS_RELEASE(sm) ; + + return rv ; +} + diff --git a/mozilla/netwerk/cache/mgr/nsMonitorable.cpp b/mozilla/netwerk/cache/mgr/nsMonitorable.cpp new file mode 100644 index 00000000000..5407ae06675 --- /dev/null +++ b/mozilla/netwerk/cache/mgr/nsMonitorable.cpp @@ -0,0 +1,38 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (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/NPL/ + * + * 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 Mozilla Communicator client code. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corporation. Portions created by Netscape are Copyright (C) 1998 + * Netscape Communications Corporation. All Rights Reserved. + */ + +/* + * This is the implementation of the nsMonitorable::MonitorLocker class. + * Although the inlines work ok elsewhere, IRIX chokes on these. Hence + * moving these to a cpp. + * -Gagan Saksena 09/15/98 + */ + +#include "nsMonitorable.h" + +nsMonitorable::MonitorLocker::MonitorLocker(nsMonitorable* i_pThis): + m_pMonitorable(i_pThis) +{ + if (m_pMonitorable) m_pMonitorable->Lock(); +} + +nsMonitorable::MonitorLocker::~MonitorLocker() +{ + if (m_pMonitorable) m_pMonitorable->Unlock(); +} diff --git a/mozilla/netwerk/cache/module/Makefile.in b/mozilla/netwerk/cache/module/Makefile.in new file mode 100644 index 00000000000..b85d4f96a45 --- /dev/null +++ b/mozilla/netwerk/cache/module/Makefile.in @@ -0,0 +1,34 @@ +#!gmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +DEPTH = ../../.. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +include $(DEPTH)/config/autoconf.mk + +EXPORTS = \ + $(NULL) + +EXPORTS := $(addprefix $(srcdir)/, $(EXPORTS)) + +DIRS = disk memory + +include $(topsrcdir)/config/config.mk + +include $(topsrcdir)/config/rules.mk diff --git a/mozilla/netwerk/cache/module/Makefile.win b/mozilla/netwerk/cache/module/Makefile.win new file mode 100755 index 00000000000..12864d4827c --- /dev/null +++ b/mozilla/netwerk/cache/module/Makefile.win @@ -0,0 +1,25 @@ +#!gmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + + +DEPTH=..\..\.. +DIRS= \ + disk \ + memory \ + $(NULL) + +include <$(DEPTH)\config\rules.mak> diff --git a/mozilla/netwerk/cache/module/disk/Makefile.in b/mozilla/netwerk/cache/module/disk/Makefile.in new file mode 100644 index 00000000000..bb04afa5b5b --- /dev/null +++ b/mozilla/netwerk/cache/module/disk/Makefile.in @@ -0,0 +1,61 @@ +# Generated automatically from Makefile.in by configure. +# Generated automatically from Makefile.in by configure. +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +DEPTH = ../../../.. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +include $(DEPTH)/config/autoconf.mk + +LIBRARY_NAME = diskcache + +MODULE = diskcache +IS_COMPONENT = 1 + +LOCAL_INCLUDES += \ + -I../../public \ + -I../../include \ + -I../ \ + $(NULL) + +CPPSRCS = \ + nsDiskModule.cpp \ + nsMonitorable.cpp \ + nsFileStream.cpp \ + nsDiskModuleFactory.cpp \ + $(NULL) + +BASE_LIBS= + +NETLIB_LIBS = + +LIBS = + +DEFINES += + +DSO_LDOPTS += -ldb + +include $(topsrcdir)/config/config.mk + +# hack until necko lands +ifndef NECKO +PUBLIC = $(DEPTH)/netwerk/dist/include +endif + +include $(topsrcdir)/config/rules.mk diff --git a/mozilla/netwerk/cache/module/disk/Makefile.win b/mozilla/netwerk/cache/module/disk/Makefile.win new file mode 100755 index 00000000000..d147c492183 --- /dev/null +++ b/mozilla/netwerk/cache/module/disk/Makefile.win @@ -0,0 +1,61 @@ +#!gmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. +# + +DEPTH=..\..\..\.. +include <$(DEPTH)/config/config.mak> + +MODULE=diskcache + +IS_COMPONENT=1 +MAKE_OBJ_TYPE=DLL +DLLNAME=diskcache +DLL=.\$(OBJDIR)\$(DLLNAME).dll + +LLIBS= $(LLIBS) \ + $(LIBNSPR) \ + $(DIST)\lib\xpcom.lib \ + $(DIST)\lib\dbm32.lib \ + $(NULL) + +CPP_OBJS= \ + .\$(OBJDIR)\nsDiskModule.obj \ + .\$(OBJDIR)\nsMonitorable.obj \ + .\$(OBJDIR)\nsFileStream.obj \ + .\$(OBJDIR)\nsDiskModuleFactory.obj \ + $(NULL) + +LOCAL_INCLUDES= -I. \ + -I..\..\public \ + -I..\..\include \ + +INCLUDES = $(LOCAL_INCLUDES) + +REQUIRES = nspr + +INCS = -I..\..\public \ + -I..\..\include \ + $(INCS) \ + -I$(DEPTH)\dist\include \ + $(NULL) + +include <$(DEPTH)\config\rules.mak> + +install:: $(DLL) + $(MAKE_INSTALL) $(DLL) $(DIST)\bin\components + $(MAKE_INSTALL) .\$(OBJDIR)\$(DLLNAME).lib $(DIST)\lib + diff --git a/mozilla/netwerk/cache/module/disk/nsCacheModule.cpp b/mozilla/netwerk/cache/module/disk/nsCacheModule.cpp new file mode 100644 index 00000000000..3b80c0d8ea6 --- /dev/null +++ b/mozilla/netwerk/cache/module/disk/nsCacheModule.cpp @@ -0,0 +1,98 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#include "nsCacheModule.h" +#include "nsCacheTrace.h" +#include "nsCacheIterator.h" + +/* + * nsCacheModule + * + * Gagan Saksena 02/02/98 + * + */ + + +#define DEFAULT_SIZE 10*0x100000L + +nsCacheModule::nsCacheModule(const PRUint32 i_size=DEFAULT_SIZE): + m_Size(i_size), + m_SizeInUse(0), + m_pEnumeration(0), + m_pNext(0), + m_Entries(0) +{ + m_pIterator = new nsCacheIterator(this); +} + +nsCacheModule::~nsCacheModule() +{ + if (m_pNext) + { + delete m_pNext; + m_pNext = 0; + } + if (m_pIterator) + { + delete m_pIterator; + m_pIterator = 0; + } + if (m_pEnumeration) + { + delete m_pEnumeration; + m_pEnumeration = 0; + } +} + +void nsCacheModule::GarbageCollect(void) +{ +} + +PRBool nsCacheModule::ReduceSizeTo(const PRUint32 i_NewSize) +{ + MonitorLocker ml(this); + //TODO + return PR_TRUE; +} + +PRBool nsCacheModule::RemoveAll(void) +{ + MonitorLocker ml(this); + PRBool status = PR_TRUE; + while (m_Entries > 0) + { + status &= Remove(--m_Entries); + } + return status; +} + +#if 0 +// Caller must free this +const char* nsCacheModule::Trace() const +{ + char linebuffer[128]; + char* total; + + PR_sprintf(linebuffer, "nsCacheModule: Objects = %d\n", Entries()); + + total = new char[PR_strlen(linebuffer) + 1]; + strcpy(total, linebuffer); + + return total; +} +#endif diff --git a/mozilla/netwerk/cache/module/disk/nsDiskModule.cpp b/mozilla/netwerk/cache/module/disk/nsDiskModule.cpp new file mode 100644 index 00000000000..ac3091978dc --- /dev/null +++ b/mozilla/netwerk/cache/module/disk/nsDiskModule.cpp @@ -0,0 +1,839 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +/* + * nsDiskModule + * + * Gagan Saksena 02/02/98 + * + */ + +#include "prtypes.h" +#include "prmem.h" +#include "plstr.h" +#include "prlog.h" +#include "prclist.h" +#include "prio.h" +#include "prsystem.h" // Directory Separator + +#include "nsDiskModule.h" +#include "nsICacheObject.h" +#include "nsCacheObject.h" +#include "nsCacheManager.h" +#include "nsFileStream.h" +#include "nsCachePref.h" +#include "nsRepository.h" + +#include "mcom_db.h" + +#define ENSURE_INIT \ + if (!m_pDB) \ + { \ + nsDiskModule* pThis = (nsDiskModule*) this; \ + PRBool res = pThis->InitDB(); \ + PR_ASSERT(res); \ + } + +struct recentlyUsedObject { + PRCList link; + nsICacheObject* cacheObject; +}; + +/* Find pointer to recentlyUsedObject struct + * from the list linkaged embedded in it + */ +#define OBJECT_PTR(_link) \ + ((recentlyUsedObject*) ((char*) (_link) - offsetof(recentlyUsedObject,link))) + +//File static list of recently used cache objects +static PRCList g_RecentlyUsedList; +static nsICacheObject* g_pTempObj=0; +static char* g_FullFilename=0; +const static int MAX_FILENAME_LEN = 512; +const static int MAX_OBJECTS_IN_RECENTLY_USED_LIST = 20; // change later TODO. + +// Every time we cleanup we cleanup to 75% of the max available size. +// This should ideally change to a more const number than a percentage. +// Since someone may have a bigger cache size, so we don't really want to +// be cleaning up 5 megs if some one has a 20 megs cache size. +// I will revisit this issue once the basic architecture is up and running. +#define CLEANUP_FACTOR 0.75 + +//Returns the full filename including the cache directory. +static char* FullFilename(const char* i_Filename); + +//Returns the Least Recently Used object in the database +static nsICacheObject* LRUObject(DB* pDB); + + +static NS_DEFINE_IID (kICacheObjectIID, NS_ICACHEOBJECT_IID); +static NS_DEFINE_IID (kCacheObjectCID, NS_CACHEOBJECT_CID); + +static NS_DEFINE_IID (kICacheManagerIID, NS_ICACHEMANAGER_IID); +static NS_DEFINE_IID (kCacheManagerCID, NS_CACHEMANAGER_CID); + + +static nsICachePref* +GetPrefsInstance () +{ + nsICacheManager* pICacheMgr = nsnull; + nsServiceManager::GetService (kCacheManagerCID, kICacheManagerIID, + (nsISupports **) &pICacheMgr); + + if (!pICacheMgr) + return nsnull; + + nsICachePref* pICachePref = nsnull; + pICacheMgr->GetPrefs (&pICachePref); + return pICachePref; +} + + +// +// Constructors: nsDiskModule +// +nsDiskModule::nsDiskModule(): + m_SizeInUse(0), + m_pEnumeration(0), + m_pNext(0), + m_pDB(0) +{ + nsICachePref* pICachePref = GetPrefsInstance(); + PR_ASSERT (pICachePref); + pICachePref->GetDiskCacheSize (&m_Size); + + PR_INIT_CLIST(&g_RecentlyUsedList); +} + +nsDiskModule::nsDiskModule(const PRUint32 size): + m_Size (size), + m_SizeInUse(0), + m_pEnumeration(0), + m_pNext(0), + m_pDB(0) +{ + PR_INIT_CLIST(&g_RecentlyUsedList); +} + +nsDiskModule::~nsDiskModule() +{ + //This will free up any operational "over the limit" cache objects. + GarbageCollect(); + + if (m_pDB) + { + (*m_pDB->sync)(m_pDB, 0); + (*m_pDB->close)(m_pDB); + m_pDB = 0; + } + + /* Clean up the recently used list */ + recentlyUsedObject* obj; + while (!PR_CLIST_IS_EMPTY(&g_RecentlyUsedList)) + { + obj = (recentlyUsedObject*) PR_LIST_HEAD(&g_RecentlyUsedList); + if (obj->cacheObject) + delete obj->cacheObject; + PR_REMOVE_LINK(&obj->link); + } + + PR_ASSERT(PR_CLIST_IS_EMPTY(&g_RecentlyUsedList)); + + if (g_FullFilename) + { + delete[] g_FullFilename; + g_FullFilename = 0; + } + + if (g_pTempObj) + { + delete g_pTempObj; + g_pTempObj = 0; + } +} + +NS_IMETHODIMP +nsDiskModule::AddObject(nsICacheObject* io_pObject) +{ + ENSURE_INIT; + + if (!m_pDB || !io_pObject) + { + // Set some error state TODO + return NS_ERROR_FAILURE; + } + + char *url = nsnull; + nsresult r = io_pObject->GetAddress (&url); + if (r == NS_OK && url) + { + MonitorLocker ml(this); + + //Remove the earliar copy- silently handles if not found + RemoveByURL(url); + + // TODO optimize these further- make static - Gagan + DBT* key = PR_NEW(DBT); + DBT* data = PR_NEW(DBT); + + //Set the module + io_pObject->SetModuleIndex (nsCacheManager::DISK); + + //Close the corresponding file + nsStream* pStream = (nsStream *) nsnull; + r = io_pObject->GetStream (&pStream); + + if (pStream) + PR_Close(((nsFileStream*)pStream)->FileDesc()); + + key->data = (void*)url; + /* Later on change this to include post data- io_pObject->KeyData() */ + key->size = PL_strlen(url); + + io_pObject->GetInfo ((void **) &data->data); + io_pObject->GetInfoSize (&data->size); + + int status = (*m_pDB->put)(m_pDB, key, data, 0); + if (status == 0) + { +// if (m_Sync == EVERYTIME) + status = (*m_pDB->sync)(m_pDB, 0); + m_Entries++; + PRUint32 size; + io_pObject->GetSize(&size); + m_SizeInUse += size; + } + PR_Free(key); + PR_Free(data); + return ((status == 0) ? NS_OK : NS_ERROR_FAILURE); + } + return NS_ERROR_FAILURE; +} + + +NS_IMETHODIMP +nsDiskModule::ContainsCacheObj(nsICacheObject* io_pObject, PRBool* o_bContain) +{ + ENSURE_INIT; + + *o_bContain = PR_FALSE; + if (!m_pDB || !io_pObject) + return NS_OK; + + char *url; + if (io_pObject->GetAddress (&url) != NS_OK) + return NS_OK; + + nsICacheObject* pTemp = 0; + if (GetObjectByURL(url, &pTemp) != NS_OK) + return NS_OK; + + if (pTemp) + { + //PR_ASSERT(io_pObject == pTemp); + // until I do a copyFrom function + *o_bContain = PR_TRUE; + } + return NS_OK; +} + + +NS_IMETHODIMP +nsDiskModule::ContainsURL(const char* i_url, PRBool* o_bContain) +{ + + ENSURE_INIT; + + *o_bContain = PR_FALSE; + if (!m_pDB || !i_url || !*i_url) + return NS_OK; + + DBT key, data; + + key.data = (void*) i_url; + key.size = PL_strlen(i_url); + + int status = (*m_pDB->get)(m_pDB, &key, &data, 0); + + *o_bContain = (status == 0)? PR_TRUE : PR_FALSE; + return NS_OK; +} + + +NS_IMETHODIMP +nsDiskModule::GarbageCollect(void) +{ + MonitorLocker ml(this); + ReduceSizeTo((PRUint32)(CLEANUP_FACTOR*m_Size)); + + // if the recentlyusedlist has grown too big, trim some objects from there as well + // Count how many are there + int count=0; + if (!PR_CLIST_IS_EMPTY(&g_RecentlyUsedList)) + { + PRCList* list = g_RecentlyUsedList.next; + while (list != &g_RecentlyUsedList) + { + count++; + list = list->next; + } + } + // Then trim the extra ones. + int extra = count-MAX_OBJECTS_IN_RECENTLY_USED_LIST; + while (extra>0) + { + recentlyUsedObject* obj = (recentlyUsedObject*) PR_LIST_HEAD(&g_RecentlyUsedList); + if (obj->cacheObject) + delete obj->cacheObject; + PR_REMOVE_LINK(&obj->link); + extra--; + } + return NS_OK; +} + + +NS_IMETHODIMP +nsDiskModule::GetObjectByIndex(const PRUint32 i_index, + nsICacheObject** ppICacheObject) +{ + ENSURE_INIT; + + if (!ppICacheObject) + return NS_ERROR_NULL_POINTER; + + *ppICacheObject = (nsICacheObject *) nsnull; + if (!m_pDB) + return NS_OK; + +//todo + return NS_ERROR_NOT_IMPLEMENTED; +} + + +NS_IMETHODIMP +nsDiskModule::GetObjectByURL(const char* i_url, nsICacheObject** ppICacheObject) +{ + ENSURE_INIT; + MonitorLocker ml((nsDiskModule*)this); + + if (!ppICacheObject) + return NS_ERROR_NULL_POINTER; + + *ppICacheObject = (nsICacheObject *) nsnull; + + if (!m_pDB || !i_url || !*i_url) + return NS_OK; + + /* Check amongst recently used objects */ + recentlyUsedObject* obj; + PRCList* list = &g_RecentlyUsedList; + if (!PR_CLIST_IS_EMPTY(&g_RecentlyUsedList)) + { + list = g_RecentlyUsedList.next; + nsICacheObject* pObj; + while (list != &g_RecentlyUsedList) + { + obj = OBJECT_PTR(list); + pObj = obj->cacheObject; + char *addr; + nsresult r = pObj->GetAddress (&addr); + if (r != NS_OK) + return r; + if (0 == PL_strcasecmp(i_url, addr)) //todo also validate + { + *ppICacheObject = pObj; + return NS_OK; + } + list = list->next; + } + } + + DBT key, data; + + key.data = (void*) i_url; + key.size = PL_strlen(i_url); + + if (0 == (*m_pDB->get)(m_pDB, &key, &data, 0)) + { + nsICacheObject* pTemp; + nsresult rv = nsComponentManager::CreateInstance(kCacheObjectCID, + nsnull, + kICacheObjectIID, + (void**) &pTemp); + PR_ASSERT(rv == NS_OK); + pTemp->SetInfo(data.data); + recentlyUsedObject* pNode = PR_NEWZAP(recentlyUsedObject); + PR_APPEND_LINK(&pNode->link, &g_RecentlyUsedList); + pNode->cacheObject = pTemp; + *ppICacheObject = pTemp; + } + + return NS_OK; +} + + +NS_IMETHODIMP +nsDiskModule::GetStreamFor(const nsICacheObject* i_pObject, nsStream** o_stream) +{ + ENSURE_INIT; + MonitorLocker ml(this); + + *o_stream = 0; + if (i_pObject) + { + nsresult r = i_pObject->GetStream(o_stream); + if (r != NS_OK) + return r; + + char *filename = nsnull; + i_pObject->GetFilename (&filename); + PR_ASSERT(filename); + + char* fullname = FullFilename(filename); + + if (fullname) + { + *o_stream = new nsFileStream(fullname); + } + } + return NS_OK; +} + + +// Private Function +PRBool nsDiskModule::InitDB(void) +{ + MonitorLocker ml(this); + + if (m_pDB) + return PR_TRUE; + + HASHINFO hash_info = { + 16*1024, /* bucket size */ + 0, /* fill factor */ + 0, /* number of elements */ + 0, /* bytes to cache */ + 0, /* hash function */ + 0}; /* byte order */ + + char *filename; + nsICachePref* pICachePref = GetPrefsInstance(); + PR_ASSERT (pICachePref); + pICachePref->GetDiskCacheDBFilename (&filename); + + m_pDB = dbopen( + FullFilename(filename), + O_RDWR | O_CREAT, + 0600, // this is octal, yixiong + DB_HASH, + &hash_info); + + if (!m_pDB) + return PR_FALSE; + + /* Open and read in the number of existing entries */ + m_Entries = 0; + m_SizeInUse = 0; + int status; + DBT key, data; + if (0 == g_pTempObj) + { + nsresult rv = nsComponentManager::CreateInstance(kCacheObjectCID, + nsnull, + kICacheObjectIID, + (void**) &g_pTempObj); + PR_ASSERT (rv == NS_OK); + } + if(!(status = (*m_pDB->seq)(m_pDB, &key, &data, R_FIRST))) + { + do + { + /* Also validate the corresponding file here *///TODO + + g_pTempObj->SetInfo(data.data); + PRUint32 size; + g_pTempObj->GetSize(&size); + m_SizeInUse += size; + m_Entries++; + } + while(!(status = (*m_pDB->seq) (m_pDB, &key, &data, R_NEXT))); + } + + if (status < 0) + return PR_FALSE; + + return PR_TRUE; +} + + +NS_IMETHODIMP +nsDiskModule::ReduceSizeTo(const PRUint32 i_NewSize) +{ + MonitorLocker ml(this); + + PRInt32 needToFree = m_SizeInUse - i_NewSize; + if ((m_Entries>0) && (needToFree > 0)) + { + PRUint32 avg = m_SizeInUse/m_Entries; + if (avg==0) + return NS_ERROR_FAILURE; + + PRUint32 nObjectsToFree = needToFree/avg; + if (nObjectsToFree < 1) + nObjectsToFree = 1; + + while (nObjectsToFree > 0) + { + RemoveByObject (LRUObject(m_pDB)); + --nObjectsToFree; + } + + return NS_OK; + } + + return NS_ERROR_FAILURE; +} + + +NS_IMETHODIMP +nsDiskModule::RemoveByURL(const char* i_url) +{ + ENSURE_INIT; + nsICacheObject* pICacheObject; + nsresult r = GetObjectByURL(i_url, &pICacheObject); + if (r != NS_OK) + return r; + return RemoveByObject(pICacheObject); +} + + +NS_IMETHODIMP +nsDiskModule::RemoveByObject(nsICacheObject* pObject) +{ + MonitorLocker ml(this); + nsresult bStatus = NS_ERROR_FAILURE; + if (!pObject) + return bStatus; + + //PR_ASSERT(Contains(pObject); + + // TODO Mark the objects state for deletion so that we dont + // read it in the meanwhile. + pObject->SetState(nsCacheObject::EXPIRED); + + //Remove it from the index + DBT key; + pObject->GetAddress((char **) &key.data); + key.size = PL_strlen((char *)key.data); + if (0 == (*m_pDB->del)(m_pDB, &key, 0)) + { + --m_Entries; + PRUint32 size; + pObject->GetSize (&size); + m_SizeInUse -= size; + if (-1 == (*m_pDB->sync)(m_pDB, 0)) + { + //Failed to sync database + PR_ASSERT(0); + } + } + + //Remove it from the recently used list + recentlyUsedObject* obj; + PRCList* list = &g_RecentlyUsedList; + if (!PR_CLIST_IS_EMPTY(&g_RecentlyUsedList)) + { + list = g_RecentlyUsedList.next; + nsICacheObject* pObj; + PRBool bDone = PR_FALSE; + while ((list != &g_RecentlyUsedList) && !bDone) + { + obj = OBJECT_PTR(list); + pObj = obj->cacheObject; + if (pObj == pObject) + { + bDone = PR_TRUE; + PR_REMOVE_LINK(&obj->link); + } + list = list->next; + } + } + + //Remove it from the disk + char *filename; + pObject->GetFilename(&filename); + if (PR_SUCCESS == PR_Delete(FullFilename(filename))) + { + bStatus = NS_OK; + } + else + { + //Failed to delete the file off the disk! + bStatus = NS_ERROR_FAILURE; + } + + //Finally delete it + delete pObject; + pObject = 0; + + return bStatus; +} + + +NS_IMETHODIMP +nsDiskModule::RemoveByIndex(const PRUint32 i_index) +{ + //This will probably go away. + ENSURE_INIT; + //TODO + // Also remove the file corresponding to this item. + //return PR_FALSE; + return NS_ERROR_NOT_IMPLEMENTED; +} + + +NS_IMETHODIMP +nsDiskModule::RemoveAll(void) +{ + MonitorLocker ml (this); + while (m_Entries > 0) + { + RemoveByIndex (--m_Entries); + } + return NS_OK; +} + + +NS_IMETHODIMP +nsDiskModule::Revalidate(void) +{ + ENSURE_INIT; + //TODO - This will add a dependency on HTTP lib + //return PR_FALSE; + return NS_ERROR_NOT_IMPLEMENTED; +} + + +NS_IMETHODIMP +nsDiskModule::SetSize(const PRUint32 i_Size) +{ + MonitorLocker ml(this); + m_Size = i_Size; + if (m_Size >0) + { + ReduceSizeTo((PRUint32)(CLEANUP_FACTOR*m_Size)); + } + else + { + RemoveAll(); + } + + return NS_OK; +} + +char* FullFilename(const char* i_Filename) +{ + static int cacheFolderLength=0; + if (0 == g_FullFilename) + { + g_FullFilename = new char[MAX_FILENAME_LEN]; + *g_FullFilename = '\0'; + if (0 == g_FullFilename) + return 0; + } + char *folder; + nsICachePref* pICachePref = GetPrefsInstance(); + PR_ASSERT (pICachePref); + pICachePref->GetDiskCacheFolder (&folder); + + PR_ASSERT (folder); + PL_strcpy(g_FullFilename, folder); + if (0==cacheFolderLength) + cacheFolderLength = PL_strlen(folder); +#ifndef XP_MAC + if (g_FullFilename[cacheFolderLength-1]!=PR_GetDirectorySeparator()) + { + g_FullFilename[cacheFolderLength] = PR_GetDirectorySeparator(); + g_FullFilename[cacheFolderLength+1] = '\0'; + } +#endif + PL_strcat(g_FullFilename, i_Filename); + return g_FullFilename; +} + +nsICacheObject* LRUObject(DB* pDB) +{ + int status; + DBT key, data; + + nsICacheObject* pTempObj; + nsresult rv = nsComponentManager::CreateInstance(kCacheObjectCID, + nsnull, + kICacheObjectIID, + (void**) &pTempObj); + + if (rv != NS_OK) + return nsnull; + + nsICacheObject* pOldest=0; + if(!(status = (*pDB->seq)(pDB, &key, &data, R_FIRST))) + { + do + { + pTempObj->SetInfo(data.data); + + PRIntervalTime old, current; + if (pOldest) + { + pOldest->GetLastAccessed (&old); + } + pTempObj->GetLastAccessed (¤t); + if (!pOldest || (old > current)) + pOldest = pTempObj; + + } + while(!(status = (*pDB->seq) (pDB, &key, &data, R_NEXT))); + } + return ((nsICacheObject *) pOldest); +} + + +NS_IMETHODIMP +nsDiskModule::QueryInterface(const nsIID& aIID, void** aInstancePtr) +{ + NS_ASSERTION(aInstancePtr, "no instance pointer"); + + *aInstancePtr = 0; + + if (aIID.Equals(nsCOMTypeInfo::GetIID()) || + aIID.Equals(nsCOMTypeInfo::GetIID())) + { + *aInstancePtr = NS_STATIC_CAST (nsICacheModule*, this); + NS_ADDREF_THIS(); + return NS_OK; + } + return NS_NOINTERFACE; +} + + +NS_IMPL_ADDREF(nsDiskModule); +NS_IMPL_RELEASE(nsDiskModule); + + +NS_METHOD +nsDiskModule::Create(nsISupports* aOuter, const nsIID& aIID, void** aResult) +{ + nsDiskModule* cm = new nsDiskModule(); + if (cm == nsnull) + return NS_ERROR_OUT_OF_MEMORY; + + NS_ADDREF (cm); + nsresult rv = cm->QueryInterface (aIID, aResult); + NS_RELEASE (cm); + return rv; +} + + +NS_IMETHODIMP +nsDiskModule::Enable(PRBool i_bEnable) +{ + m_Enabled = i_bEnable; + return NS_OK; +} + +NS_IMETHODIMP +nsDiskModule::GetNumOfEntries(PRUint32* o_nEntries) +{ + *o_nEntries = m_Entries; + return NS_OK; +} + + +NS_IMETHODIMP +nsDiskModule::GetEnumerator(nsEnumeration** o_enum) +{ + MonitorLocker ml((nsMonitorable*)this); + if (!m_pEnumeration) + { + PR_ASSERT(m_pIterator); + ((nsDiskModule*)this)->m_pEnumeration = + new nsEnumeration((nsIterator*)m_pIterator); + } + else + ((nsDiskModule*)this)->m_pEnumeration->Reset(); + *o_enum = m_pEnumeration; + return NS_OK; +} + + +NS_IMETHODIMP +nsDiskModule::IsEnabled(PRBool* o_bEnabled) +{ + *o_bEnabled = m_Enabled; + return NS_OK; +} + + +NS_IMETHODIMP +nsDiskModule::IsReadOnly (PRBool* o_bReadOnly) +{ + *o_bReadOnly = PR_FALSE; // for Now + return NS_OK; +} + + +NS_IMETHODIMP +nsDiskModule::GetNextModule(nsICacheModule** o_pICacheModule) +{ + *o_pICacheModule = m_pNext; + return NS_OK; +} + + +NS_IMETHODIMP +nsDiskModule::SetNextModule(nsICacheModule* pNext) +{ + /* No overwriting */ + PR_ASSERT(m_pNext == 0); + if (m_pNext) + { + /* ERROR */ + delete m_pNext; //Worst case. + m_pNext = 0; + } + m_pNext = pNext; + return NS_OK; +} + + +NS_IMETHODIMP +nsDiskModule::GetSize(PRUint32* o_size) +{ + *o_size = m_Size; + return NS_OK; +} + + +NS_IMETHODIMP +nsDiskModule::GetSizeInUse(PRUint32* o_size) +{ + *o_size = m_SizeInUse; + return NS_OK; +} + +#undef ENSURE_INIT diff --git a/mozilla/netwerk/cache/module/disk/nsDiskModuleFactory.cpp b/mozilla/netwerk/cache/module/disk/nsDiskModuleFactory.cpp new file mode 100644 index 00000000000..0b1a328df56 --- /dev/null +++ b/mozilla/netwerk/cache/module/disk/nsDiskModuleFactory.cpp @@ -0,0 +1,87 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#include "nsIGenericFactory.h" +#include "nsIComponentManager.h" +#include "nsIServiceManager.h" +#include "nsDiskModule.h" +#include "nscore.h" + +static NS_DEFINE_CID(kComponentManagerCID, NS_COMPONENTMANAGER_CID); +static NS_DEFINE_CID(kDiskModuleCID, NS_DISKMODULE_CID); + +//////////////////////////////////////////////////////////////////////////////// + +// return the proper factory to the caller +extern "C" PR_IMPLEMENT(nsresult) +NSGetFactory(nsISupports* aServMgr, + const nsCID &aClass, + const char *aClassName, + const char *aProgID, + nsIFactory **aFactory) +{ + nsresult rv; + if (aFactory == nsnull) + return NS_ERROR_NULL_POINTER; + + nsIGenericFactory* fact; + if (aClass.Equals(kDiskModuleCID)) { + rv = NS_NewGenericFactory(&fact, nsDiskModule::Create); + } + else { + rv = NS_ERROR_FAILURE; + } + + if (NS_SUCCEEDED(rv)) + *aFactory = fact; + return rv; +} + +extern "C" PR_IMPLEMENT(nsresult) +NSRegisterSelf(nsISupports* aServMgr , const char* aPath) +{ + nsresult rv; + + NS_WITH_SERVICE1(nsIComponentManager, compMgr, aServMgr, + kComponentManagerCID, &rv); + if (NS_FAILED(rv)) return rv; + + rv = compMgr->RegisterComponent(kDiskModuleCID, + "Disk Module Cache", + "components://necko/cache/disk", + aPath, PR_TRUE, PR_TRUE); + if (NS_FAILED(rv)) return rv;; + + return rv; +} + +extern "C" PR_IMPLEMENT(nsresult) +NSUnregisterSelf(nsISupports* aServMgr, const char* aPath) +{ + nsresult rv; + + NS_WITH_SERVICE1(nsIComponentManager, compMgr, aServMgr, kComponentManagerCID, &rv); + if (NS_FAILED(rv)) return rv; + + rv = compMgr->UnregisterComponent(kDiskModuleCID, aPath); + if (NS_FAILED(rv)) return rv; + + return rv; +} + +//////////////////////////////////////////////////////////////////////////////// diff --git a/mozilla/netwerk/cache/module/disk/nsFileStream.cpp b/mozilla/netwerk/cache/module/disk/nsFileStream.cpp new file mode 100644 index 00000000000..f6e62e27d08 --- /dev/null +++ b/mozilla/netwerk/cache/module/disk/nsFileStream.cpp @@ -0,0 +1,110 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (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/NPL/ + * + * 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 Mozilla Communicator client code. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corporation. Portions created by Netscape are Copyright (C) 1998 + * Netscape Communications Corporation. All Rights Reserved. + */ + +#include "nsFileStream.h" +#include "plstr.h" +#include "prlog.h" + +nsFileStream::nsFileStream(const char* i_Filename):m_pFile(0),m_pFilename(0) +{ + PR_ASSERT(i_Filename); + if (i_Filename) + { + m_pFilename = new char[PL_strlen(i_Filename)+1]; + PL_strcpy(m_pFilename, i_Filename); + Open(); + } +} + +nsFileStream::~nsFileStream() +{ + if (m_pFilename) + { + delete[] m_pFilename; + m_pFilename = 0; + } + if (m_pFile) + PR_Close(m_pFile); +} + +/* +nsrefcnt nsFileStream::AddRef(void) +{ + return ++m_RefCnt; +} +nsrefcnt nsFileStream::Release(void) +{ + if (--m_RefCnt == 0) + { + delete this; + return 0; + } + return m_RefCnt; +} + +nsresult nsFileStream::QueryInterface(const nsIID& aIID, + void** aInstancePtrResult) +{ + return NS_OK; +} +*/ + +PRBool nsFileStream::Open() +{ + if (m_pFile) + PR_Close(m_pFile); + PR_ASSERT(m_pFilename); + if (m_pFilename) + { + m_pFile = PR_Open( + m_pFilename, + PR_CREATE_FILE | PR_RDWR, + 0600);// Read and write by owner only + + PR_ASSERT(m_pFile); + if (m_pFile) + return PR_TRUE; + } + return PR_FALSE; +} + +PRInt32 nsFileStream::Read(void* o_Buffer, PRUint32 i_Len) +{ + if (!m_pFile && !Open()) + return 0; + + // heck, remove later. + // PRInt32 r = PR_Seek(m_pFile, 0, PR_SEEK_SET) ; + // end heck + + return PR_Read(m_pFile, o_Buffer, i_Len); +} + +void nsFileStream::Reset() +{ + Open(); +} + +PRInt32 nsFileStream::Write(const void* i_Buffer, PRUint32 i_Len) +{ + if (!m_pFile && !Open()) + return 0; + return PR_Write(m_pFile, i_Buffer, i_Len); +} + diff --git a/mozilla/netwerk/cache/module/disk/nsMonitorable.cpp b/mozilla/netwerk/cache/module/disk/nsMonitorable.cpp new file mode 100644 index 00000000000..5407ae06675 --- /dev/null +++ b/mozilla/netwerk/cache/module/disk/nsMonitorable.cpp @@ -0,0 +1,38 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (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/NPL/ + * + * 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 Mozilla Communicator client code. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corporation. Portions created by Netscape are Copyright (C) 1998 + * Netscape Communications Corporation. All Rights Reserved. + */ + +/* + * This is the implementation of the nsMonitorable::MonitorLocker class. + * Although the inlines work ok elsewhere, IRIX chokes on these. Hence + * moving these to a cpp. + * -Gagan Saksena 09/15/98 + */ + +#include "nsMonitorable.h" + +nsMonitorable::MonitorLocker::MonitorLocker(nsMonitorable* i_pThis): + m_pMonitorable(i_pThis) +{ + if (m_pMonitorable) m_pMonitorable->Lock(); +} + +nsMonitorable::MonitorLocker::~MonitorLocker() +{ + if (m_pMonitorable) m_pMonitorable->Unlock(); +} diff --git a/mozilla/netwerk/cache/module/memory/Makefile.in b/mozilla/netwerk/cache/module/memory/Makefile.in new file mode 100644 index 00000000000..c044347714b --- /dev/null +++ b/mozilla/netwerk/cache/module/memory/Makefile.in @@ -0,0 +1,57 @@ +# Generated automatically from Makefile.in by configure. +#!gmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +DEPTH = ../../../.. +topsrcdir = @top_srcdir@ +VPATH = @srcdir@ +srcdir = @srcdir@ + +include $(DEPTH)/config/autoconf.mk + +LIBRARY_NAME = memcache +MODULE=memcache +IS_COMPONENT=1 + +LOCAL_INCLUDES += \ + -I$(srcdir) \ + -I$(srcdir)/../../include \ + -I$(srcdir)/../../public \ + -I$(srcdir)/.. \ + $(NULL) + +CPPSRCS = \ + nsMemModule.cpp \ + nsMemCacheObject.cpp \ + nsMemStream.cpp \ + nsMonitorable.cpp \ + nsMemModuleFactory.cpp \ + $(NULL) + +EXPORTS = + +EXPORTS := $(addprefix $(srcdir)/, $(EXPORTS)) + +REQUIRES += nspr + +EXTRA_LIBS += $(NSPR_LIBS) + +include $(topsrcdir)/config/config.mk + +#TARGETS = $(LIBRARY) + +include $(topsrcdir)/config/rules.mk diff --git a/mozilla/netwerk/cache/module/memory/Makefile.win b/mozilla/netwerk/cache/module/memory/Makefile.win new file mode 100755 index 00000000000..e9e27530fca --- /dev/null +++ b/mozilla/netwerk/cache/module/memory/Makefile.win @@ -0,0 +1,61 @@ +#!gmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. +# + +DEPTH=..\..\..\.. +include <$(DEPTH)/config/config.mak> + +MODULE=MemoryCache + +IS_COMPONENT=1 +MAKE_OBJ_TYPE=DLL +DLLNAME=MemoryCache +DLL=.\$(OBJDIR)\$(DLLNAME).dll + +LLIBS= $(LLIBS) \ + $(LIBNSPR) \ + $(DIST)\lib\xpcom.lib \ + $(NULL) + +CPP_OBJS= \ + .\$(OBJDIR)\nsMemModule.obj \ + .\$(OBJDIR)\nsMonitorable.obj \ + .\$(OBJDIR)\nsMemCacheObject.obj \ + .\$(OBJDIR)\nsMemStream.obj \ + .\$(OBJDIR)\nsMemModuleFactory.obj \ + $(NULL) + +LOCAL_INCLUDES= -I. \ + -I..\..\public \ + -I..\..\include \ + +INCLUDES = $(LOCAL_INCLUDES) + +REQUIRES = nspr + +INCS = -I..\..\public \ + -I..\..\include \ + $(INCS) \ + -I$(DEPTH)\dist\include \ + $(NULL) + +include <$(DEPTH)\config\rules.mak> + +install:: $(DLL) + $(MAKE_INSTALL) $(DLL) $(DIST)\bin\components + $(MAKE_INSTALL) .\$(OBJDIR)\$(DLLNAME).lib $(DIST)\lib + diff --git a/mozilla/netwerk/cache/module/memory/nsMemCacheObject.cpp b/mozilla/netwerk/cache/module/memory/nsMemCacheObject.cpp new file mode 100644 index 00000000000..22f453845ee --- /dev/null +++ b/mozilla/netwerk/cache/module/memory/nsMemCacheObject.cpp @@ -0,0 +1,46 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +/* + * nsMemCacheObject + * + * Gagan Saksena 04/22/98 + * + */ +#include "prtypes.h" +#include "nsMemCacheObject.h" +#include "nsMemStream.h" + +nsMemCacheObject::~nsMemCacheObject() +{ + if (m_pNextObject) + { + delete m_pNextObject; + m_pNextObject = 0; + } + + if (m_pObject) + { + nsStream* pStream; + m_pObject->GetStream(&pStream); + if (pStream) + delete (nsMemStream*)pStream; + delete m_pObject; + m_pObject = 0; + } +} diff --git a/mozilla/netwerk/cache/module/memory/nsMemCacheObject.h b/mozilla/netwerk/cache/module/memory/nsMemCacheObject.h new file mode 100644 index 00000000000..093e500ca31 --- /dev/null +++ b/mozilla/netwerk/cache/module/memory/nsMemCacheObject.h @@ -0,0 +1,99 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +/* The nsMemCacheObject class holds the actual nsCacheObject and a pointer + * to the next nsMemCacheObject. Pretty simple solution for the time being. + * Should be replaced once the memory hash table stuff gets up and running. + * + * -Gagan Saksena 09/15/98. + */ + +#ifndef _nsMemCacheObject_h_ +#define _nsMemCacheObject_h_ + +#include "prtypes.h" +#include "prlog.h" +#include "nsICacheObject.h" +#include "nsCacheObject.h" + +class nsMemCacheObject +{ +public: + + nsMemCacheObject(void); + nsMemCacheObject(nsICacheObject* io_pObject); + nsMemCacheObject(const char* i_url); + ~nsMemCacheObject(); + + void Next(nsMemCacheObject* pObject); + void Next(nsICacheObject* io_pObject); + + nsMemCacheObject* Next(void) const; + + nsICacheObject* ThisObject(void) const; + +private: + nsICacheObject* m_pObject; + nsMemCacheObject* m_pNextObject; + + nsMemCacheObject& operator=(const nsMemCacheObject& mco); + nsMemCacheObject(const nsMemCacheObject&); + +}; + +inline nsMemCacheObject::nsMemCacheObject(void): + m_pObject((nsICacheObject *) new nsCacheObject()), + m_pNextObject(0) +{ +} + +inline nsMemCacheObject::nsMemCacheObject(nsICacheObject* io_pObject): + m_pObject(io_pObject), + m_pNextObject(0) +{ +} + +inline nsMemCacheObject::nsMemCacheObject(const char* i_url): + m_pObject((nsICacheObject *) new nsCacheObject(i_url)), + m_pNextObject(0) +{ +} + +inline nsMemCacheObject* nsMemCacheObject::Next(void) const +{ + return m_pNextObject; +} + +inline void nsMemCacheObject::Next(nsMemCacheObject* pObject) +{ + PR_ASSERT(0==m_pNextObject); + m_pNextObject = pObject; +} + +inline void nsMemCacheObject::Next(nsICacheObject* pObject) +{ + PR_ASSERT(0==m_pNextObject); + m_pNextObject = new nsMemCacheObject(pObject); +} + +inline nsICacheObject* nsMemCacheObject::ThisObject(void) const +{ + return m_pObject; +} + +#endif //_nsMemCacheObject_h_ diff --git a/mozilla/netwerk/cache/module/memory/nsMemModule.cpp b/mozilla/netwerk/cache/module/memory/nsMemModule.cpp new file mode 100644 index 00000000000..296553bb321 --- /dev/null +++ b/mozilla/netwerk/cache/module/memory/nsMemModule.cpp @@ -0,0 +1,485 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#include "prtypes.h" +#include "prmem.h" +#include "plstr.h" +#include "prclist.h" +#include "prio.h" +#include "prsystem.h" +#include "prlog.h" + +#include "nsMemModule.h" +#include "nsMemCacheObject.h" +#include "nsCacheManager.h" +#include "nsICacheManager.h" +#include "nsICachePref.h" +#include "nsMemStream.h" + +/* + * nsMemModule + * + * Gagan Saksena 02/02/98 + * + */ + +static NS_DEFINE_IID(kICacheManagerIID, NS_ICACHEMANAGER_IID); +static NS_DEFINE_IID(kCacheManagerCID, NS_CACHEMANAGER_CID); + +nsMemModule::nsMemModule(): + m_pFirstObject(0), + m_SizeInUse(0), + m_pEnumeration(0), + m_pNext(0) +{ + nsICacheManager* pICacheMgr; + nsresult rv = nsServiceManager::GetService (kCacheManagerCID, + kICacheManagerIID, + (nsISupports **) &pICacheMgr); + PR_ASSERT (rv == NS_OK); + + nsICachePref* pPref; + rv = pICacheMgr->GetPrefs (&pPref); + + PR_ASSERT (rv == NS_OK); + + pPref->GetMemCacheSize(&m_Size); + +} + +nsMemModule::nsMemModule(const PRUint32 size): + m_pFirstObject(0), + m_Size (size), + m_SizeInUse(0), + m_pEnumeration(0), + m_pNext(0) +{ +} + +nsMemModule::~nsMemModule() +{ + if (m_pFirstObject) { + delete m_pFirstObject; + m_pFirstObject = 0; + } +} + + +NS_IMETHODIMP +nsMemModule::AddObject(nsICacheObject* io_pObject) +{ + +#if 0 + if (io_pObject) + { + m_ht.Put(io_pObject->Address(), io_pObject); + } + return NS_ERROR_FAILURE; +#endif + + if (io_pObject) + { + MonitorLocker ml((nsMonitorable*)this); + nsStream* pStream = (nsStream *) nsnull; + io_pObject->GetStream(&pStream); + + // I removed this assert. I don't think it should be here. yixiong + // pStream would be set later by GetStreamFor( ) in nsCacheobject + // PR_ASSERT(pStream); // A valid stream does exist for this + + if (m_pFirstObject) + { + LastObject()->Next(new nsMemCacheObject(io_pObject)); + } + else + { + m_pFirstObject = new nsMemCacheObject(io_pObject); + } + m_Entries++; + + io_pObject->SetModuleIndex(nsCacheManager::MEM); + + return NS_OK; + } + // Todo: Better error handling + return NS_ERROR_FAILURE; +} + + + +NS_IMETHODIMP +nsMemModule::ContainsURL (const char* i_url, PRBool* o_bContain) +{ + MonitorLocker ml((nsMonitorable*)this); + + *o_bContain = PR_FALSE; + if (m_pFirstObject && i_url && *i_url) + { + nsMemCacheObject* pObj = m_pFirstObject; + do + { + char *thisURL = nsnull; + pObj->ThisObject()->GetAddress (&thisURL); + if (0 == PL_strcasecmp(thisURL, i_url)) + { + *o_bContain = PR_TRUE; + break; + } + pObj = pObj->Next(); + } + while (pObj); + } + return NS_OK; +} + + +NS_IMETHODIMP +nsMemModule::ContainsCacheObj(nsICacheObject* i_pObject, PRBool* o_bContain) +{ + MonitorLocker ml((nsMonitorable*)this); + + *o_bContain = PR_FALSE; + char *url = (char *) nsnull; + if (i_pObject) + { + i_pObject->GetAddress (&url); + } + if (url && *url) + { + this->ContainsURL(url, o_bContain); + } + return NS_OK; +} + + +NS_IMETHODIMP +nsMemModule::GarbageCollect(void) +{ + MonitorLocker ml((nsMonitorable*) this); + + if (m_Entries > 0) + { + nsEnumeration* pEnum; + GetEnumerator(&pEnum); + PRUint32 idx = 0; + while (pEnum->HasMoreElements()) + { + nsICacheObject* pObj = (nsICacheObject*) pEnum->NextElement(); + PRBool bExpired = PR_FALSE; + if (pObj) + { + pObj->IsExpired (&bExpired); + } + if (bExpired == PR_TRUE) + { + nsresult r = RemoveByIndex (idx); + PR_ASSERT(r == NS_OK); + } + ++idx; + } + } + return NS_OK; +} + +NS_IMETHODIMP +nsMemModule::GetObjectByIndex (const PRUint32 i_index, + nsICacheObject** ppICacheObject) +{ + MonitorLocker ml((nsMonitorable*)this); + nsMemCacheObject* pNth = 0; + if (m_pFirstObject) + { + PRUint32 idx = 0; + pNth = m_pFirstObject; + while (pNth->Next() && (idx++ != i_index )) + { + pNth = pNth->Next(); + } + } + if (pNth) + *ppICacheObject = pNth->ThisObject(); + else + *ppICacheObject = (nsICacheObject *) nsnull; + return NS_OK; +} + + +NS_IMETHODIMP +nsMemModule::GetObjectByURL(const char* i_url, nsICacheObject** ppICacheObject) +{ + MonitorLocker ml((nsMonitorable*)this); + *ppICacheObject = (nsICacheObject *) nsnull; + + if (m_pFirstObject && i_url && *i_url) + { + nsMemCacheObject* pObj = m_pFirstObject; + do + { + char *thisURL; + pObj->ThisObject()->GetAddress (&thisURL); + if (0 == PL_strcasecmp(thisURL, i_url)) + { + *ppICacheObject = pObj->ThisObject(); + break; + } + pObj = pObj->Next(); + } + while (pObj); + } + return NS_OK; +} + +NS_IMETHODIMP +nsMemModule::GetStreamFor(const nsICacheObject* i_pObject, nsStream** o_stream) +{ + MonitorLocker ml(this); + + *o_stream = nsnull; + if (i_pObject) + { + PRBool bContain = PR_FALSE; + ContainsCacheObj((nsICacheObject*) i_pObject, &bContain); + if (bContain) + { + nsStream* pStream = (nsStream *) nsnull; + i_pObject->GetStream(&pStream); + if (pStream) + { + *o_stream = pStream; + return NS_OK; + } + } + // Set up a new stream for this object + *o_stream = new nsMemStream(); + } + return NS_OK; +} + + +nsMemCacheObject* nsMemModule::LastObject(void) const +{ + MonitorLocker ml((nsMonitorable*)this); + + nsMemCacheObject* pLast = 0; + if (m_pFirstObject) + { + pLast = m_pFirstObject; + while (pLast->Next()) + pLast = pLast->Next(); + } + return pLast; +} + +NS_IMETHODIMP +nsMemModule::ReduceSizeTo(const PRUint32 i_NewSize) +{ + //TODO + return PR_TRUE; +} + + +NS_IMETHODIMP +nsMemModule::RemoveByURL (const char* i_url) +{ + //TODO + return NS_ERROR_NOT_IMPLEMENTED; +} + + +NS_IMETHODIMP +nsMemModule::RemoveByIndex(const PRUint32 i_index) +{ + //TODO + return NS_ERROR_NOT_IMPLEMENTED; +} + + +NS_IMETHODIMP +nsMemModule::RemoveByObject(nsICacheObject* i_pObj) +{ + //TODO + return NS_ERROR_NOT_IMPLEMENTED; +} + + +NS_IMETHODIMP +nsMemModule::RemoveAll() +{ + //TODO + return NS_ERROR_NOT_IMPLEMENTED; +} + + +NS_IMETHODIMP +nsMemModule::SetSize(const PRUint32 i_Size) +{ + //TODO + return NS_ERROR_NOT_IMPLEMENTED; +} + +////////////////////////////////////////////////////////////////////////////// +NS_IMETHODIMP +nsMemModule::QueryInterface(const nsIID& aIID, void** aInstancePtr) +{ + NS_ASSERTION(aInstancePtr, "no instance pointer"); + + *aInstancePtr = 0; + + if (aIID.Equals(nsCOMTypeInfo::GetIID()) || + aIID.Equals(nsCOMTypeInfo::GetIID())) + { + *aInstancePtr = NS_STATIC_CAST (nsICacheModule*, this); + NS_ADDREF_THIS(); + return NS_OK; + } + return NS_NOINTERFACE; +} + + +NS_IMPL_ADDREF(nsMemModule); +NS_IMPL_RELEASE(nsMemModule); + +NS_METHOD +nsMemModule::Create (nsISupports *aOuter, REFNSIID aIID, void** aResult) +{ + if (aOuter) + return NS_ERROR_NO_AGGREGATION; + + nsMemModule* pm = new nsMemModule(); + if (pm == nsnull) + return NS_ERROR_OUT_OF_MEMORY; + + NS_ADDREF (pm); + nsresult rv = pm->QueryInterface (aIID, aResult); + NS_RELEASE (pm); + return rv; +} + +////////////////////////////////////////////////////////////////////////////// + +NS_IMETHODIMP +nsMemModule::Enable(PRBool i_bEnable) +{ + m_Enabled = i_bEnable; + return NS_OK; +} + + +NS_IMETHODIMP +nsMemModule::GetNumOfEntries(PRUint32* o_nEntries) +{ + *o_nEntries = m_Entries; + return NS_OK; +} + + +NS_IMETHODIMP +nsMemModule::GetEnumerator(nsEnumeration** o_enum) +{ + MonitorLocker ml((nsMonitorable*)this); + if (!m_pEnumeration) + { + PR_ASSERT(m_pIterator); + ((nsMemModule*)this)->m_pEnumeration = + new nsEnumeration((nsIterator*)m_pIterator); + } + else + ((nsMemModule*)this)->m_pEnumeration->Reset(); + *o_enum = m_pEnumeration; + return NS_OK; +} + + +NS_IMETHODIMP +nsMemModule::IsEnabled(PRBool* o_bEnabled) +{ + *o_bEnabled = m_Enabled; + return NS_OK; +} + + +NS_IMETHODIMP +nsMemModule::IsReadOnly (PRBool* o_bReadOnly) +{ + *o_bReadOnly = PR_FALSE; // for Now + return NS_OK; +} + + +NS_IMETHODIMP +nsMemModule::GetNextModule(nsICacheModule** o_pICacheModule) +{ + if (m_pNext) { + *o_pICacheModule = m_pNext; + return NS_OK; + } + return NS_ERROR_FAILURE ; +} + + +NS_IMETHODIMP +nsMemModule::SetNextModule(nsICacheModule* pNext) +{ + /* No overwriting */ + PR_ASSERT(m_pNext == 0); + if (m_pNext) + { + /* ERROR */ + delete m_pNext; //Worst case. + m_pNext = 0; + } + m_pNext = pNext; + return NS_OK; +} + + +NS_IMETHODIMP +nsMemModule::GetSize(PRUint32* o_size) +{ + *o_size = m_Size; + return NS_OK; +} + + +NS_IMETHODIMP +nsMemModule::GetSizeInUse(PRUint32* o_size) +{ + *o_size = m_SizeInUse; + return NS_OK; +} + +/* +PRUint32 nsMemModule::nsMemKey::HashValue() +{ + return 0; +} +PRBool nsMemModule::nsMemKey::Equals(nsHashKey *aKey) +{ + return PR_FALSE; +} + +nsHashKey* nsMemModule::nsMemKey::Clone() +{ + return new nsMemModule::nsMemKey(); +} + +nsMemModule::nsMemKey::neMemKey() +{ +} + + */ diff --git a/mozilla/netwerk/cache/module/memory/nsMemModuleFactory.cpp b/mozilla/netwerk/cache/module/memory/nsMemModuleFactory.cpp new file mode 100644 index 00000000000..8fb99dc095c --- /dev/null +++ b/mozilla/netwerk/cache/module/memory/nsMemModuleFactory.cpp @@ -0,0 +1,87 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#include "nsIGenericFactory.h" +#include "nsIComponentManager.h" +#include "nsIServiceManager.h" +#include "nsMemModule.h" +#include "nscore.h" + +static NS_DEFINE_CID(kComponentManagerCID, NS_COMPONENTMANAGER_CID); +static NS_DEFINE_CID(kMemModuleCID, NS_MEMMODULE_CID); + +//////////////////////////////////////////////////////////////////////////////// + +// return the proper factory to the caller +extern "C" PR_IMPLEMENT(nsresult) +NSGetFactory(nsISupports* aServMgr, + const nsCID &aClass, + const char *aClassName, + const char *aProgID, + nsIFactory **aFactory) +{ + nsresult rv; + if (aFactory == nsnull) + return NS_ERROR_NULL_POINTER; + + nsIGenericFactory* fact; + if (aClass.Equals(kMemModuleCID)) { + rv = NS_NewGenericFactory(&fact, nsMemModule::Create); + } + else { + rv = NS_ERROR_FAILURE; + } + + if (NS_SUCCEEDED(rv)) + *aFactory = fact; + return rv; +} + +extern "C" PR_IMPLEMENT(nsresult) +NSRegisterSelf(nsISupports* aServMgr , const char* aPath) +{ + nsresult rv; + + NS_WITH_SERVICE1(nsIComponentManager, compMgr, aServMgr, + kComponentManagerCID, &rv); + if (NS_FAILED(rv)) return rv; + + rv = compMgr->RegisterComponent(kMemModuleCID, + "Mem Module Cache", + "component://necko/cache/MemModule", + aPath, PR_TRUE, PR_TRUE); + if (NS_FAILED(rv)) return rv;; + + return rv; +} + +extern "C" PR_IMPLEMENT(nsresult) +NSUnregisterSelf(nsISupports* aServMgr, const char* aPath) +{ + nsresult rv; + + NS_WITH_SERVICE1(nsIComponentManager, compMgr, aServMgr, kComponentManagerCID, &rv); + if (NS_FAILED(rv)) return rv; + + rv = compMgr->UnregisterComponent(kMemModuleCID, aPath); + if (NS_FAILED(rv)) return rv; + + return rv; +} + +//////////////////////////////////////////////////////////////////////////////// diff --git a/mozilla/netwerk/cache/module/memory/nsMemStream.cpp b/mozilla/netwerk/cache/module/memory/nsMemStream.cpp new file mode 100644 index 00000000000..07d5a2a229d --- /dev/null +++ b/mozilla/netwerk/cache/module/memory/nsMemStream.cpp @@ -0,0 +1,124 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (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/NPL/ + * + * 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 Mozilla Communicator client code. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corporation. Portions created by Netscape are Copyright (C) 1998 + * Netscape Communications Corporation. All Rights Reserved. + */ + +#include "nsMemStream.h" +#include "prmem.h" +#include "prlog.h" /* Assert */ + +#ifndef XP_MAC +#include "memory.h" +#else +#include "cstring" +#endif + +static const PRUint32 kPageSize = 1024;//4096; +nsMemStream::nsMemStream():m_AllocSize(0),m_Size(0),m_pStart(0),m_ReadOffset(0),m_WriteOffset(0) +{ +} + +nsMemStream::~nsMemStream() +{ + PR_FREEIF(m_pStart); +} +/* +nsrefcnt nsMemStream::AddRef(void) +{ + return ++m_RefCnt; +} +nsrefcnt nsMemStream::Release(void) +{ + if (--m_RefCnt == 0) + { + delete this; + return 0; + } + return m_RefCnt; +} + +nsresult nsMemStream::QueryInterface(const nsIID& aIID, + void** aInstancePtrResult) +{ + return NS_OK; +} +*/ + +PRInt32 nsMemStream::Read(void* o_Buffer, PRUint32 i_Len) +{ + if (m_Size > 0) + { + PR_ASSERT(m_pStart); //This has to be there if m_Size > 0 + + char* pCurrentRead = (char*) m_pStart + m_ReadOffset; + + unsigned int validLen = m_Size - m_ReadOffset; + + if (0 == validLen) + return 0; + + if (validLen > i_Len) + validLen = i_Len; + + memcpy(o_Buffer, pCurrentRead, validLen); + m_ReadOffset += validLen; + return validLen; + } + return 0; +} + +void nsMemStream::Reset() +{ + m_ReadOffset = 0; +} + +PRInt32 nsMemStream::Write(const void* i_Buffer, PRUint32 i_Len) +{ + if (!m_pStart) + { + m_pStart = PR_Calloc(1, kPageSize); + if (!m_pStart) + { + PR_Free(m_pStart); + return 0; + } + m_WriteOffset = 0; + m_AllocSize = kPageSize; + } + unsigned int validLen = m_AllocSize - m_Size; + while (validLen < i_Len) + { + //Alloc some more + m_pStart = PR_Realloc(m_pStart, m_AllocSize+kPageSize); + if (!m_pStart) + { + PR_Free(m_pStart); + m_AllocSize = 0; + m_WriteOffset = 0; + m_Size = 0; + return 0; + } + m_AllocSize += kPageSize; + validLen += kPageSize; + } + char* pCurrentWrite = (char*)m_pStart + m_WriteOffset; + memcpy(pCurrentWrite, i_Buffer, i_Len); + m_WriteOffset += i_Len; + m_Size += i_Len; + return i_Len; +} + diff --git a/mozilla/netwerk/cache/module/memory/nsMonitorable.cpp b/mozilla/netwerk/cache/module/memory/nsMonitorable.cpp new file mode 100644 index 00000000000..5407ae06675 --- /dev/null +++ b/mozilla/netwerk/cache/module/memory/nsMonitorable.cpp @@ -0,0 +1,38 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (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/NPL/ + * + * 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 Mozilla Communicator client code. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corporation. Portions created by Netscape are Copyright (C) 1998 + * Netscape Communications Corporation. All Rights Reserved. + */ + +/* + * This is the implementation of the nsMonitorable::MonitorLocker class. + * Although the inlines work ok elsewhere, IRIX chokes on these. Hence + * moving these to a cpp. + * -Gagan Saksena 09/15/98 + */ + +#include "nsMonitorable.h" + +nsMonitorable::MonitorLocker::MonitorLocker(nsMonitorable* i_pThis): + m_pMonitorable(i_pThis) +{ + if (m_pMonitorable) m_pMonitorable->Lock(); +} + +nsMonitorable::MonitorLocker::~MonitorLocker() +{ + if (m_pMonitorable) m_pMonitorable->Unlock(); +} diff --git a/mozilla/netwerk/cache/obj/Makefile.in b/mozilla/netwerk/cache/obj/Makefile.in new file mode 100644 index 00000000000..1f40a0a0dae --- /dev/null +++ b/mozilla/netwerk/cache/obj/Makefile.in @@ -0,0 +1,53 @@ +# Generated automatically from Makefile.in by configure. +#!gmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +DEPTH = ../../.. +topsrcdir = @top_srcdir@ +VPATH = @srcdir@ +srcdir = @srcdir@ + +include $(DEPTH)/config/autoconf.mk + +LIBRARY_NAME = cacheobj +MODULE=cacheobj +IS_COMPONENT=1 + +LOCAL_INCLUDES += \ + -I$(srcdir)/../include \ + -I$(srcdir)/../public \ + -I$(PUBLIC)/netlib \ + $(NULL) + +CPPSRCS = \ + nsCacheObject.cpp \ + $(NULL) + +EXPORTS = \ + $(NULL) + +EXPORTS := $(addprefix $(srcdir)/, $(EXPORTS)) + +REQUIRES += nspr + +EXTRA_LIBS += $(NSPR_LIBS) + +include $(topsrcdir)/config/config.mk + +#TARGETS = $(LIBRARY) + +include $(topsrcdir)/config/rules.mk diff --git a/mozilla/netwerk/cache/obj/Makefile.win b/mozilla/netwerk/cache/obj/Makefile.win new file mode 100755 index 00000000000..54908c45c03 --- /dev/null +++ b/mozilla/netwerk/cache/obj/Makefile.win @@ -0,0 +1,57 @@ +#!gmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + + +DEPTH=..\..\.. +include <$(DEPTH)/config/config.mak> + +MODULE=cacheobj + +IS_COMPONENT=1 +MAKE_OBJ_TYPE=DLL +DLLNAME=cacheobj +DLL=.\$(OBJDIR)\$(DLLNAME).dll + +LLIBS= $(LLIBS) \ + $(LIBNSPR) \ + $(DIST)\lib\xpcom.lib \ + $(NULL) + +CPP_OBJS= \ + .\$(OBJDIR)\nsCacheObject.obj \ + $(NULL) + +LOCAL_INCLUDES= -I. \ + -I..\public \ + -I..\include \ + +INCLUDES = $(LOCAL_INCLUDES) + +REQUIRES = nspr + +INCS = $(INCS) \ + -I..\include \ + -I..\public \ + -I$(DEPTH)\dist\include \ + $(NULL) + +include <$(DEPTH)\config\rules.mak> + +install:: $(DLL) + $(MAKE_INSTALL) $(DLL) $(DIST)\bin\components + $(MAKE_INSTALL) .\$(OBJDIR)\$(DLLNAME).lib $(DIST)\lib + diff --git a/mozilla/netwerk/cache/obj/nsCacheObject.cpp b/mozilla/netwerk/cache/obj/nsCacheObject.cpp new file mode 100644 index 00000000000..83fc96b67e4 --- /dev/null +++ b/mozilla/netwerk/cache/obj/nsCacheObject.cpp @@ -0,0 +1,936 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef XP_MAC +#include "memory.h" +#else +#include "cstring" +#endif + +//#include "nspr.h" +#include "nscore.h" +#include "prmem.h" +#include "prprf.h" +#include "plstr.h" +#include "prinrval.h" + +// #include "nsStream.h" +// #include "nsCacheTrace.h" +#include "nsICacheModule.h" +#include "nsICacheManager.h" + +#include "nsCacheObject.h" + +/* + * nsCacheObject + * + * Gagan Saksena 02/02/98 + * + */ + +static const PRIntervalTime DEFAULT_EXPIRES = PR_SecondsToInterval(86400); +//static const PRIntervalTime DEFAULT_EXPIRES = 1000; +//static const PRIntervalTime DEFAULT_EXPIRES = PR_IntervalNow(); + +// Globals, need to check if safe to unload module +static PRInt32 gLockCnt = 0; +static PRInt32 gInstanceCnt = 0; + +// Define constants for easy use +static NS_DEFINE_IID(kICACHEOBJECTIID, NS_ICACHEOBJECT_IID); +static NS_DEFINE_IID(kIFactoryIID, NS_IFACTORY_IID); +static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID); +static NS_DEFINE_IID(kICACHEMANAGERIID, NS_ICACHEMANAGER_IID); +static NS_DEFINE_IID(kCacheManagerCID, NS_CACHEMANAGER_CID); + +#if !defined(IS_LITTLE_ENDIAN) && !defined(IS_BIG_ENDIAN) +ERROR! Must have a byte order +#endif + +#ifdef IS_LITTLE_ENDIAN +#define COPY_INT32(_a,_b) memcpy(_a, _b, sizeof(int32)) +#else +#define COPY_INT32(_a,_b) /* swap */ \ + do { \ + ((char *)(_a))[0] = ((char *)(_b))[3]; \ + ((char *)(_a))[1] = ((char *)(_b))[2]; \ + ((char *)(_a))[2] = ((char *)(_b))[1]; \ + ((char *)(_a))[3] = ((char *)(_b))[0]; \ + } while(0) +#endif + +/* Convenient macros used in stuffing and reading back cache object to a void * */ +/* TODO: Change these to file scope functions */ +#define STUFF_STRING(string) \ +{ \ + len = (string ? PL_strlen(string)+1 : 0); \ + COPY_INT32((void *)cur_ptr, &len); \ + cur_ptr = cur_ptr + sizeof(int32); \ + if(len) \ + memcpy((void *)cur_ptr, string, len); \ + cur_ptr += len; \ +} + +#define STUFF_NUMBER(number) \ +{ \ + COPY_INT32((void *)cur_ptr, &number); \ + cur_ptr = cur_ptr + sizeof(PRUint32); \ +} + +#define STUFF_TIME(number) \ +{ \ + COPY_INT32((void *)cur_ptr, &number); \ + cur_ptr = cur_ptr + sizeof(PRIntervalTime); \ +} + +#define STUFF_BOOL(bool_val) \ +{ \ + if(bool_val) \ + ((char *)(cur_ptr))[0] = 1; \ + else \ + ((char *)(cur_ptr))[0] = 0; \ + cur_ptr = cur_ptr + sizeof(char); \ +} + +/* if any strings are larger than this then + * there was a serious database error + */ +#define MAX_HUGE_STRING_SIZE 10000 + +#define RETRIEVE_STRING(string) \ +{ \ + if(cur_ptr > max_ptr) \ + { \ + return PR_TRUE; \ + } \ + COPY_INT32(&len, cur_ptr); \ + cur_ptr += sizeof(int32); \ + if(len) \ + { \ + if(len > MAX_HUGE_STRING_SIZE) \ + { \ + return PR_FALSE; \ + } \ + string = new char[len]; \ + if(!string) \ + { \ + return PR_FALSE; \ + } \ + memcpy(string, cur_ptr, len); \ + cur_ptr += len; \ + } \ +} + +#define RETRIEVE_NUMBER(number) \ +{ \ + if(cur_ptr > max_ptr) \ + return PR_TRUE; \ + COPY_INT32(&number, cur_ptr); \ + cur_ptr += sizeof(int32); \ +} + +#define RETRIEVE_TIME(number) \ +{ \ + if(cur_ptr > max_ptr) \ + return PR_TRUE; \ + COPY_INT32(&number, cur_ptr); \ + cur_ptr += sizeof(PRIntervalTime); \ +} + +#define RETRIEVE_BOOL(bool) \ +{ \ + if(cur_ptr > max_ptr) \ + return PR_TRUE; \ + if(((char *)(cur_ptr))[0]) \ + bool = TRUE; \ + else \ + bool = FALSE; \ + cur_ptr += sizeof(char); \ +} + +/* TODO- Further optimization, initialize these to null, + but that will add more work on copy constructor which is ok */ +nsCacheObject::nsCacheObject(): + m_Charset(new char[1]), + m_ContentEncoding(new char[1]), + m_ContentType(new char[1]), + m_Etag(new char[1]), + m_Filename(new char[1]), + m_State(INIT), + m_bIsCompleted(PR_FALSE), + m_Module(-1), + m_pInfo(0), + m_PageServicesURL(new char[1]), + m_PostData(new char[1]), + m_PostDataLen(0), + m_pStream(0), + m_URL(new char[1]) +{ + Init(); + *m_Charset = '\0'; + *m_ContentEncoding = '\0'; + *m_ContentType = '\0'; + *m_Etag = '\0'; + *m_Filename = '\0'; + *m_PageServicesURL = '\0'; + *m_PostData = '\0'; + *m_URL = '\0'; + + NS_INIT_ISUPPORTS() ; + PR_AtomicIncrement(&gInstanceCnt) ; +} + +nsCacheObject::~nsCacheObject() +{ + if (m_Charset) + delete[] m_Charset; + if (m_ContentEncoding) + delete[] m_ContentEncoding; + if (m_ContentType) + delete[] m_ContentType; + if (m_Etag) + delete[] m_Etag; + if (m_Filename) + delete[] m_Filename; + if (m_PageServicesURL) + delete[] m_PageServicesURL; + if (m_PostData) + delete[] m_PostData; + if (m_URL) + delete[] m_URL; + if (m_pStream) + delete m_pStream; + + NS_ASSERTION(mRefCnt == 0, "wrong ref count") ; + PR_AtomicDecrement(&gInstanceCnt) ; +} + +nsCacheObject::nsCacheObject(const nsCacheObject& another): + m_Charset(new char[PL_strlen(another.m_Charset)+1]), + m_ContentEncoding(new char[PL_strlen(another.m_ContentEncoding)+1]), + m_ContentType(new char[PL_strlen(another.m_ContentType)+1]), + m_Etag(new char[PL_strlen(another.m_Etag)+1]), + m_Filename(new char[PL_strlen(another.m_Filename)+1]), + m_State(another.m_State), + m_bIsCompleted(another.m_bIsCompleted), + m_pInfo(0), /* Should this be copied as well? */ + m_PageServicesURL(new char[PL_strlen(another.m_PageServicesURL)+1]), + m_PostData(new char[another.m_PostDataLen+1]), + m_PostDataLen(another.m_PostDataLen), + m_pStream(0), + m_URL(new char[PL_strlen(another.m_URL)+1]) +{ + PL_strncpyz(m_Charset, another.m_Charset, PL_strlen(another.m_Charset)+1); + PL_strncpyz(m_ContentEncoding, another.m_ContentEncoding, PL_strlen(another.m_ContentEncoding)+1); + PL_strncpyz(m_ContentType, another.m_ContentType, PL_strlen(another.m_ContentType)+1); + PL_strncpyz(m_Etag, another.m_Etag, PL_strlen(another.m_Etag)+1); + PL_strncpyz(m_Filename, another.m_Filename, PL_strlen(another.m_Filename)+1); + PL_strncpyz(m_PageServicesURL, another.m_PageServicesURL, PL_strlen(another.m_PageServicesURL)+1); + PL_strncpyz(m_PostData, another.m_PostData, another.m_PostDataLen+1); + PL_strncpyz(m_URL, another.m_URL, PL_strlen(another.m_URL)+1); + + m_Hits = another.m_Hits; + m_LastAccessed = another.m_LastAccessed; + m_LastModified = another.m_LastModified; + m_Size = another.m_Size; + m_Module = another.m_Module; + + NS_INIT_ISUPPORTS() ; + PR_AtomicIncrement(&gInstanceCnt) ; + +} + +nsCacheObject::nsCacheObject(const char* i_url): + m_Charset(new char[1]), + m_ContentEncoding(new char[1]), + m_ContentType(new char[1]), + m_Etag(new char[1]), + m_Filename(new char[1]), + m_State(INIT), + m_bIsCompleted(PR_FALSE), + m_Module(-1), + m_pInfo(0), + m_PageServicesURL(new char[1]), + m_PostData(new char[1]), + m_PostDataLen(0), + m_pStream(0), + m_URL(new char[PL_strlen(i_url)+1]) +{ + Init(); + PR_ASSERT(i_url); + PL_strncpyz(m_URL, i_url, PL_strlen(i_url)+1); + + *m_Charset = '\0'; + *m_ContentEncoding = '\0'; + *m_ContentType = '\0'; + *m_Etag = '\0'; + *m_Filename = '\0'; + *m_PageServicesURL = '\0'; + *m_PostData = '\0'; + + NS_INIT_ISUPPORTS() ; + PR_AtomicIncrement(&gInstanceCnt) ; + +} + +NS_IMPL_ISUPPORTS(nsCacheObject, nsCOMTypeInfo::GetIID( )) ; + +NS_IMETHODIMP +nsCacheObject::SetAddress(const char* i_url) +{ + PR_ASSERT(i_url && *i_url); + if (!i_url) + return NS_ERROR_NULL_POINTER ; + if (m_URL) + delete[] m_URL; + int len = PL_strlen(i_url); + m_URL = new char[len + 1]; + PL_strncpyz(m_URL, i_url, len+1); + + return NS_OK ; +} + +NS_IMETHODIMP +nsCacheObject::SetCharset(const char* i_Charset) +{ +// PR_ASSERT(i_Charset && *i_Charset); + if (!i_Charset) //TODO reset m_charset here + return NS_ERROR_NULL_POINTER ; + if (m_Charset) + delete[] m_Charset; + int len = PL_strlen(i_Charset); + m_Charset = new char[len + 1]; + PL_strncpyz(m_Charset, i_Charset, len+1); + + return NS_OK ; +} + +NS_IMETHODIMP +nsCacheObject::SetContentEncoding(const char* i_Encoding) +{ +// PR_ASSERT(i_Encoding && *i_Encoding); + if (!i_Encoding) + return NS_ERROR_NULL_POINTER ; + if (m_ContentEncoding) + delete[] m_ContentEncoding; + int len = PL_strlen(i_Encoding); + m_ContentEncoding = new char[len + 1]; + PL_strncpyz(m_ContentEncoding, i_Encoding, len+1); + + return NS_OK ; +} + +NS_IMETHODIMP +nsCacheObject::SetContentType(const char* i_Type) +{ +// PR_ASSERT(i_Type && *i_Type); + if (!i_Type) + { + /* Reset to empty */ // TODO ?? + return NS_ERROR_NULL_POINTER ; + } + if (m_ContentType) + delete[] m_ContentType; + int len = PL_strlen(i_Type); + m_ContentType = new char[len + 1]; + PL_strncpyz(m_ContentType, i_Type, len+1); + + return NS_OK ; +} + +NS_IMETHODIMP +nsCacheObject::SetEtag(const char* i_etag) +{ +// PR_ASSERT(i_etag && *i_etag); + if (!i_etag) + return NS_ERROR_NULL_POINTER ; + if (m_Etag) + delete[] m_Etag; + m_Etag = new char[PL_strlen(i_etag) + 1]; + PL_strncpyz(m_Etag, i_etag, PL_strlen(i_etag)+1); + + return NS_OK ; +} + +NS_IMETHODIMP +nsCacheObject::SetFilename(const char* i_Filename) +{ +// PR_ASSERT(i_Filename && *i_Filename); + if (!i_Filename) + return NS_ERROR_NULL_POINTER ; + if (m_Filename) + delete[] m_Filename; + int len = PL_strlen(i_Filename); + m_Filename = new char[len +1]; + PL_strncpyz(m_Filename, i_Filename, len+1); + + return NS_OK ; +} + +NS_IMETHODIMP +nsCacheObject::GetInfo(void** o_info) +{ + if (!o_info) + return NS_ERROR_NULL_POINTER ; + + if (m_pInfo) { + *o_info = m_pInfo; + return NS_OK ; + } + + nsCacheObject* pThis = (nsCacheObject*) this; + + if (m_URL){ + + pThis->m_info_size = sizeof(nsCacheObject); + + pThis->m_info_size -= sizeof(void*); // m_info itself is not being serialized + pThis->m_info_size -= sizeof(char*); // neither is m_PostData + pThis->m_info_size -= sizeof(nsStream*); // nor the stream + pThis->m_info_size -= sizeof(PRBool); // bIsCompleted. + //todo -optimize till here + + //Add the strings sizes + pThis->m_info_size += PL_strlen(m_Charset)+1; + pThis->m_info_size += PL_strlen(m_ContentEncoding)+1; + pThis->m_info_size += PL_strlen(m_ContentType)+1; + pThis->m_info_size += PL_strlen(m_Etag)+1; + pThis->m_info_size += PL_strlen(m_Filename)+1; + pThis->m_info_size += PL_strlen(m_PageServicesURL)+1; + pThis->m_info_size += PL_strlen(m_URL)+1; + + //Add the Postdata len + pThis->m_info_size += m_PostDataLen+1; + + //For the virtual function table. This is really nasty, yixiong + pThis->m_info_size -= sizeof(void*) ; + + void* new_obj = PR_Calloc(1, m_info_size * sizeof(char)); + + if (!new_obj) + { + PR_Free(new_obj); + return NS_ERROR_OUT_OF_MEMORY ; + } + + PRUint32 len; + + char* cur_ptr = (char*) new_obj; + /* put the total size of the struct into + * the first field so that we have + * a cross check against corruption + */ + COPY_INT32((void *)cur_ptr, &m_info_size); + + cur_ptr += sizeof(PRUint32); + + /* put the version number of the structure + * format that we are using. By using a version + * string when writting we can support + * backwards compatibility in our reading code + */ + COPY_INT32((void *)cur_ptr, &kCACHE_VERSION); + cur_ptr += sizeof(PRUint32); + + STUFF_STRING(m_Charset); + STUFF_STRING(m_ContentEncoding); + STUFF_NUMBER(m_ContentLength); + STUFF_STRING(m_ContentType); + STUFF_STRING(m_Etag); + STUFF_TIME(m_Expires); + STUFF_STRING(m_Filename); + STUFF_NUMBER(m_Hits); + STUFF_TIME(m_LastAccessed); + STUFF_TIME(m_LastModified); + STUFF_NUMBER(m_Module); + STUFF_STRING(m_PageServicesURL); + STUFF_NUMBER(m_PostDataLen); + + /* There is a possibility of it not being a string! */ + if (m_PostData) + { + // 4 bytes missing, yixiong + memcpy(cur_ptr, m_PostData, m_PostDataLen+1); + cur_ptr += m_PostDataLen+1; + } + STUFF_NUMBER(m_Size); + STUFF_NUMBER(m_State); + STUFF_STRING(m_URL); + + // Important Assertion. Dont remove! + // If this fails then you or somebody has added a variable to the + // nsCacheObject class and a decision on its "cacheability" has + // not yet been made. + PR_ASSERT(cur_ptr == (char*) new_obj + m_info_size); + pThis->m_pInfo = new_obj; + + *o_info = pThis->m_pInfo ; + } + return NS_OK ; +} + +NS_IMETHODIMP +nsCacheObject::SetInfo(void* i_data) +{ + if (!i_data) + return NS_ERROR_NULL_POINTER ; + + char* cur_ptr = (char*) i_data; + + //Reset the m_pInfo; + if (m_pInfo) + { + PR_Free(m_pInfo); + m_pInfo = 0; + } + + //Reset all strings + if (m_Charset) + delete[] m_Charset; + if (m_ContentEncoding) + delete[] m_ContentEncoding; + if (m_ContentType) + delete[] m_ContentType; + if (m_Etag) + delete[] m_Etag; + if (m_Filename) + delete[] m_Filename; + if (m_PageServicesURL) + delete[] m_PageServicesURL; + if (m_URL) + delete[] m_URL; + if (m_PostData) + delete[] m_PostData; + + m_PostDataLen = 0; + + COPY_INT32(&m_info_size, cur_ptr); + char* max_ptr = cur_ptr + m_info_size; + cur_ptr += sizeof(PRUint32); + + PRUint32 version; + COPY_INT32(&version, cur_ptr); + cur_ptr += sizeof(PRUint32); + + PR_ASSERT(version == kCACHE_VERSION); + if (version != kCACHE_VERSION) + { + //TODO Bad cache version + return NS_ERROR_FAILURE ; + } + + PRUint32 len; + + RETRIEVE_STRING(m_Charset); + RETRIEVE_STRING(m_ContentEncoding); + RETRIEVE_NUMBER(m_ContentLength); + RETRIEVE_STRING(m_ContentType); + RETRIEVE_STRING(m_Etag); + RETRIEVE_TIME(m_Expires); + RETRIEVE_STRING(m_Filename); + RETRIEVE_NUMBER(m_Hits); + RETRIEVE_TIME(m_LastAccessed); + RETRIEVE_TIME(m_LastModified); + RETRIEVE_NUMBER(m_Module); + RETRIEVE_STRING(m_PageServicesURL); + RETRIEVE_NUMBER(m_PostDataLen); + // Special case- + m_PostData = new char[m_PostDataLen + 1]; + if (m_PostData) + { + memcpy(m_PostData, cur_ptr, m_PostDataLen+1); + } + cur_ptr += m_PostDataLen +1; + + RETRIEVE_NUMBER(m_Size); + RETRIEVE_NUMBER(m_State); + RETRIEVE_STRING(m_URL); + + // Most important assertion! Don't ever remove! + PR_ASSERT(cur_ptr == max_ptr); + + // Since we are reading off its info from an indexed entry + m_bIsCompleted = PR_TRUE; + + return NS_OK ; +} + +NS_IMETHODIMP +nsCacheObject::GetInfoSize(PRUint32 *o_size) +{ + if (!m_pInfo) + { + GetInfo(&m_pInfo); + } + *o_size = m_info_size; + return NS_OK ; +} + +void nsCacheObject::Init() +{ + m_Size = 0; + m_Expires = PR_IntervalNow() + DEFAULT_EXPIRES; + m_Hits = 0; +} + +NS_IMETHODIMP +nsCacheObject::SetPageServicesURL(const char* i_Url) +{ +// PR_ASSERT(i_Url && *i_Url); + if (!i_Url) + return NS_ERROR_NULL_POINTER ; + if (m_PageServicesURL) + delete[] m_PageServicesURL; + m_PageServicesURL = new char[PL_strlen(i_Url) + 1]; + PL_strncpyz(m_PageServicesURL, i_Url, PL_strlen(i_Url)+1); + + return NS_OK ; +} + +NS_IMETHODIMP +nsCacheObject::SetPostData(const char* i_data, const PRUint32 i_Len) +{ + if (!i_data || (0 ==i_Len)) + return NS_ERROR_NULL_POINTER ; + if (m_PostData) + delete[] m_PostData; + m_PostData = new char[i_Len+1]; + PL_strncpyz(m_PostData, i_data, i_Len+1); + m_PostDataLen = i_Len; + + return NS_OK ; +} + +NS_IMETHODIMP +nsCacheObject::Read(char* o_Buffer, PRUint32 len, PRUint32 * pLeng) +{ + nsresult rv ; + + if (!m_pStream) + { + PR_ASSERT(m_Module >=0); + if (0 <= m_Module) + { + nsICacheModule* pModule ; + nsICacheManager* cacheManager ; + rv = nsServiceManager::GetService(kCacheManagerCID, + kICACHEMANAGERIID, + (nsISupports **)&cacheManager) ; + + rv = cacheManager->GetModule(m_Module, &pModule); + + if (NS_SUCCEEDED(rv) && pModule) + { + rv = pModule->GetStreamFor(this, &m_pStream); + if (NS_SUCCEEDED(rv) && m_pStream) + { + *pLeng = m_pStream->Read(o_Buffer, len); + return NS_OK ; + } + } + } + return NS_ERROR_FAILURE ; + } + *pLeng = m_pStream->Read(o_Buffer, len); + return NS_OK ; +} + +NS_IMETHODIMP +nsCacheObject::Reset(void) +{ + if (m_pStream) + m_pStream->Reset(); + // TODO change states too. + + return NS_OK ; +} + +#if 0 +/* Caller must free returned string */ +// TODO change to use PR_stuff... +const char* nsCacheObject::Trace() const +{ + char linebuffer[256]; + char* total; + + PR_Sprintf(linebuffer, "nsCacheObject:URL=%s,SIZE=%d,ET=%s,\n\tLM=%d,LA=%d,EXP=%d,HITS=%d\n", + m_URL, + m_Size, + m_Etag, + m_LastModified, + m_LastAccessed, + m_Expires, + m_Hits); + + total = new char[PL_strlen(linebuffer) +1]; + PL_strcpy(total, linebuffer); + + return total; +} +#endif + +NS_IMETHODIMP +nsCacheObject::Write(const char* i_Buffer, const PRUint32 len, PRUint32 * oLeng) +{ + nsresult rv ; + + if (!oLeng) + return NS_ERROR_NULL_POINTER ; + + PRUint32 amountWritten = 0; + if (!m_pStream) + { + PR_ASSERT(m_Module >=0); + if (0 <= m_Module) + { + nsICacheModule* pModule ; + nsICacheManager* cacheManager ; + + rv = nsServiceManager::GetService(kCacheManagerCID, + kICACHEMANAGERIID, + (nsISupports **)&cacheManager) ; + + rv = cacheManager->GetModule(m_Module, &pModule); + + if (NS_SUCCEEDED(rv) && pModule) + { + rv = pModule->GetStreamFor(this, &m_pStream); + PR_ASSERT(m_pStream); + if (!m_pStream) + return NS_ERROR_FAILURE ; + } + } + else + return NS_ERROR_FAILURE ; + } + amountWritten = m_pStream->Write(i_Buffer, len); + m_Size += amountWritten; + *oLeng = amountWritten; + + return NS_OK ; +} + +nsCacheObjectFactory::nsCacheObjectFactory () +{ + NS_INIT_ISUPPORTS(); + PR_AtomicIncrement(&gInstanceCnt); +} + +nsCacheObjectFactory::~nsCacheObjectFactory () +{ + NS_ASSERTION(mRefCnt == 0,"Wrong ref count"); + PR_AtomicDecrement(&gInstanceCnt); +} + +/* +NS_IMETHODIMP +nsCacheObjectFactory::QueryInterface(const nsIID &aIID, void **aResult) +{ + if (!aResult) + return NS_ERROR_NULL_POINTER; + + if (aIID.Equals(kISupportsIID)) { + *aResult = NS_STATIC_CAST(nsISupports*,this); + } else if (aIID.Equals(kIFactoryIID)) { + *aResult = NS_STATIC_CAST(nsISupports*,NS_STATIC_CAST(nsIFactory*,this)); + } else { + *aResult = nsnull; + return NS_ERROR_NO_INTERFACE; + } + + NS_ADDREF(NS_REINTERPRET_CAST(nsISupports*,*aResult)); + + return NS_OK; +} + +NS_IMPL_ADDREF(nsCacheObjectFactory) +NS_IMPL_RELEASE(nsCacheObjectFactory) +*/ + +NS_IMPL_ISUPPORTS(nsCacheObjectFactory, kIFactoryIID) ; + +NS_IMETHODIMP +nsCacheObjectFactory::CreateInstance(nsISupports *aOuter, + const nsIID &aIID, + void **aResult) +{ + if (!aResult) + return NS_ERROR_NULL_POINTER; + + *aResult = nsnull; + + nsISupports *inst = new nsCacheObject(); + + if (!inst) { + return NS_ERROR_OUT_OF_MEMORY; + } + + // All XPCOM methods return nsresult + nsresult rv = inst->QueryInterface(aIID, aResult); + + // There are handy macros, NS_SUCCEEDED and NS_FAILED + // to test the return value of an XPCOM method. + if (NS_FAILED(rv)) { + // We didn't get the right interface, so clean up + delete inst; + } + + return rv; +} + +NS_IMETHODIMP +nsCacheObjectFactory::LockFactory(PRBool aLock) +{ + if (aLock) { + PR_AtomicIncrement(&gLockCnt); + } else { + PR_AtomicDecrement(&gLockCnt); + } + + return NS_OK; +} + + +///////////////////////////////////////////////////////////////////// +// Exported functions. With these in place we can compile +// this module into a dynamically loaded and registered +// component. + +static NS_DEFINE_CID(kCacheObjectCID, NS_CACHEOBJECT_CID); +static NS_DEFINE_CID(kComponentManagerCID, NS_COMPONENTMANAGER_CID); + +// The "name" of our component +static const char* g_desc = "Cache Object XPCOM Module"; + +extern "C" NS_EXPORT nsresult +NSGetFactory(nsISupports *serviceMgr, + const nsCID &aCID, + const char *aClassName, + const char *aProgID, + nsIFactory **aResult) +{ + if (!aResult) + return NS_ERROR_NULL_POINTER; + + *aResult = nsnull; + + nsISupports *inst; + + if (aCID.Equals(kCacheObjectCID)) { + // Ok, we know this CID and here is the factory + // that can manufacture the objects + inst = new nsCacheObjectFactory(); + } else { + return NS_ERROR_NO_INTERFACE; + } + + if (!inst) + return NS_ERROR_OUT_OF_MEMORY; + + nsresult rv = inst->QueryInterface(kIFactoryIID, + (void **) aResult); + + if (NS_FAILED(rv)) { + delete inst; + } + + return rv; +} + +extern "C" NS_EXPORT PRBool +NSCanUnload(nsISupports* serviceMgr) +{ + return PRBool(gInstanceCnt == 0 && gLockCnt == 0); +} + +extern "C" NS_EXPORT nsresult +NSRegisterSelf(nsISupports *aServMgr, const char *path) +{ + nsresult rv = NS_OK; + + // We will use the service manager to obtain the component + // manager, which will enable us to register a component + // with a ProgID (text string) instead of just the CID. + + nsIServiceManager *sm; + + // We can get the IID of an interface with the static GetIID() method as + // well. + rv = aServMgr->QueryInterface(nsIServiceManager::GetIID(), (void **)&sm); + + if (NS_FAILED(rv)) + return rv; + + nsIComponentManager *cm; + + rv = sm->GetService(kComponentManagerCID, nsIComponentManager::GetIID(), (nsISupports **)&cm); + + if (NS_FAILED(rv)) { + NS_RELEASE(sm); + + return rv; + } + + // Note the text string, we can access the hello component with just this + // string without knowing the CID + rv = cm->RegisterComponent(kCacheObjectCID, g_desc, "component://cacheobject", + path, PR_TRUE, PR_TRUE); + + sm->ReleaseService(kComponentManagerCID, cm); + + NS_RELEASE(sm); + +#ifdef NS_DEBUG + printf("*** %s registered\n",g_desc); +#endif + + return rv; +} + +extern "C" NS_EXPORT nsresult +NSUnregisterSelf(nsISupports* aServMgr, const char *path) +{ + nsresult rv = NS_OK; + + nsIServiceManager *sm; + + rv = aServMgr->QueryInterface(nsIServiceManager::GetIID(), (void **)&sm); + + if (NS_FAILED(rv)) + return rv; + + nsIComponentManager *cm; + + rv = sm->GetService(kComponentManagerCID, nsIComponentManager::GetIID(), (nsISupports **)&cm); + + if (NS_FAILED(rv)) { + NS_RELEASE(sm); + + return rv; + } + + rv = cm->UnregisterComponent(kCacheObjectCID, path); + + sm->ReleaseService(kComponentManagerCID, cm); + + NS_RELEASE(sm); + + return rv; +} + + diff --git a/mozilla/netwerk/cache/pref/Makefile.in b/mozilla/netwerk/cache/pref/Makefile.in new file mode 100644 index 00000000000..67ac188c0c2 --- /dev/null +++ b/mozilla/netwerk/cache/pref/Makefile.in @@ -0,0 +1,54 @@ +# Generated automatically from Makefile.in by configure. +#!gmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +DEPTH = ../../.. +topsrcdir = @top_srcdir@ +VPATH = @srcdir@ +srcdir = @srcdir@ + +include $(DEPTH)/config/autoconf.mk + +LIBRARY_NAME = cachepref +MODULE=cachepref +IS_COMPONENT=1 + +LOCAL_INCLUDES += \ + -I$(srcdir)/../include \ + -I$(srcdir)/../public \ + -I$(PUBLIC)/netlib \ + $(NULL) + +CPPSRCS = \ + nsCachePref.cpp \ +# nsCachePrefFactory.cpp \ + $(NULL) + +EXPORTS = \ + $(NULL) + +EXPORTS := $(addprefix $(srcdir)/, $(EXPORTS)) + +REQUIRES += nspr + +EXTRA_LIBS += $(NSPR_LIBS) + +include $(topsrcdir)/config/config.mk + +#TARGETS = $(LIBRARY) + +include $(topsrcdir)/config/rules.mk diff --git a/mozilla/netwerk/cache/pref/Makefile.win b/mozilla/netwerk/cache/pref/Makefile.win new file mode 100755 index 00000000000..9a6dd2e7cd6 --- /dev/null +++ b/mozilla/netwerk/cache/pref/Makefile.win @@ -0,0 +1,56 @@ +#!gmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +DEPTH=..\..\.. +include <$(DEPTH)/config/config.mak> + +MODULE=cachepref + +IS_COMPONENT=1 +MAKE_OBJ_TYPE=DLL +DLLNAME=cachepref +DLL=.\$(OBJDIR)\$(DLLNAME).dll + +LLIBS= $(LLIBS) \ + $(LIBNSPR) \ + $(DIST)\lib\xpcom.lib \ + $(NULL) + +CPP_OBJS= \ + .\$(OBJDIR)\nsCachePref.obj \ + $(NULL) + +LOCAL_INCLUDES= -I. \ + -I..\public \ + -I..\include \ + +INCLUDES = $(LOCAL_INCLUDES) + +REQUIRES = nspr + +INCS = $(INCS) \ + -I..\include \ + -I..\public \ + -I$(DEPTH)\dist\include \ + $(NULL) + +include <$(DEPTH)\config\rules.mak> + +install:: $(DLL) + $(MAKE_INSTALL) $(DLL) $(DIST)\bin\components + $(MAKE_INSTALL) .\$(OBJDIR)\$(DLLNAME).lib $(DIST)\lib + diff --git a/mozilla/netwerk/cache/pref/nsCachePref.cpp b/mozilla/netwerk/cache/pref/nsCachePref.cpp new file mode 100644 index 00000000000..d11178ef051 --- /dev/null +++ b/mozilla/netwerk/cache/pref/nsCachePref.cpp @@ -0,0 +1,510 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef XP_UNIX +#include "xp.h" // This complains on unix. Works ok without there. +#endif +//#include "prefapi.h" +#include "nsIPref.h" +#include "prmem.h" +#include "prprf.h" +#include "nsICacheManager.h" +#include "plstr.h" +#if defined(XP_PC) +#include +#endif /* XP_PC */ +#include "nspr.h" +#include "nscore.h" +#include "nsRepository.h" +#include "nsIFactory.h" +#include "nsIComponentManager.h" +#include "nsIServiceManager.h" + +#ifdef XP_MAC +#include "uprefd.h" +#endif + +#include "nsCachePref.h" + +static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID); +static NS_DEFINE_IID(kICachePrefIID, NS_ICACHEPREF_IID); +static NS_DEFINE_IID(kCachePrefCID, NS_CACHEPREF_CID); +static NS_DEFINE_IID(kICACHEMANAGERIID, NS_ICACHEMANAGER_IID); +static NS_DEFINE_IID(kCacheManagerCID, NS_CACHEMANAGER_CID); +static NS_DEFINE_IID(knsPrefCID, NS_PREF_CID); +static NS_DEFINE_IID(kInsPrefIID, NS_IPREF_IID); + +static const PRUint32 MEM_CACHE_SIZE_DEFAULT = 1024*1024; +static const PRUint32 DISK_CACHE_SIZE_DEFAULT = 5*MEM_CACHE_SIZE_DEFAULT; +static const PRUint32 BKG_THREAD_SLEEP = 15*60; /*in seconds, 15 minutes */ +static const PRUint16 BUGS_FOUND_SO_FAR = 0; + +//Preferences +static const char * const MEM_CACHE_PREF = "browser.cache.memory_cache_size"; +static const char * const DISK_CACHE_PREF = "browser.cache.disk_cache_size"; +static const char * const CACHE_DIR_PREF = "browser.cache.directory"; +static const char * const FREQ_PREF = "browser.cache.check_doc_frequency"; +//Not implemented as yet... +static const char * const BKG_CLEANUP = "browser.cache.cleanup_period"; //Default for BKG_THREAD_SLEEP + +/* Find a bug in NU_CACHE, get these many chocolates */ +static const PRUint16 CHOCOLATES_PER_BUG_FOUND = 2^BUGS_FOUND_SO_FAR; + +static int PR_CALLBACK Cache_PrefChangedFunc(const char *pref, void *data); + +static PRInt32 gInstanceCnt = 0 ; +static PRInt32 gLockCnt = 0 ; + +nsCachePref::nsCachePref(void): + m_RefreshFreq(ONCE) , + m_MemCacheSize(MEM_CACHE_SIZE_DEFAULT), + m_DiskCacheSize(DISK_CACHE_SIZE_DEFAULT), + m_DiskCacheDBFilename(new char[6+1]), + m_DiskCacheFolder(0), + m_BkgSleepTime(BKG_THREAD_SLEEP) +{ + nsIPref * pref=nsnull ; + nsresult rv = nsServiceManager::GetService(knsPrefCID, + kInsPrefIID, + (nsISupports **)&pref) ; + + rv = pref->RegisterCallback("browser.cache",Cache_PrefChangedFunc,0); + + m_DiskCacheDBFilename = "nufat.db" ; + SetupPrefs(0); + + NS_INIT_ISUPPORTS() ; + PR_AtomicIncrement(&gInstanceCnt) ; +} + +nsCachePref::~nsCachePref() +{ + if (m_DiskCacheFolder) + { + delete m_DiskCacheFolder; + m_DiskCacheFolder = 0; + } + + NS_ASSERTION(mRefCnt == 0, "Wrong ref count") ; + PR_AtomicDecrement(&gInstanceCnt) ; +} + +//Read all the stuff from pref here. +NS_IMETHODIMP +nsCachePref::SetupPrefs(const char* i_Pref) +{ + PRBool bSetupAll = PR_FALSE; + + PRInt32 nTemp; + char* tempPref=0; + + if (!i_Pref) + bSetupAll = PR_TRUE; + + nsIPref * pref ; + + nsServiceManager::GetService(knsPrefCID, + kInsPrefIID, + (nsISupports **)&pref) ; + + if (bSetupAll || !PL_strcmp(i_Pref,MEM_CACHE_PREF)) + { + if (NS_SUCCEEDED(pref->GetIntPref(MEM_CACHE_PREF,&nTemp)) ) { + m_MemCacheSize = 1024*nTemp; + } + else { + m_MemCacheSize = MEM_CACHE_SIZE_DEFAULT; + } + } + + if (bSetupAll || !PL_strcmp(i_Pref,DISK_CACHE_PREF)) + { + if (NS_SUCCEEDED(pref->GetIntPref(DISK_CACHE_PREF,&nTemp))) + m_DiskCacheSize = 1024*nTemp; + else + m_DiskCacheSize = DISK_CACHE_SIZE_DEFAULT; + } + + if (bSetupAll || !PL_strcmp(i_Pref,FREQ_PREF)) + { + if (NS_SUCCEEDED(pref->GetIntPref(FREQ_PREF,&nTemp))) + { + m_RefreshFreq = (nsCachePref::Refresh)nTemp; + } + else + m_RefreshFreq = ONCE; + } + + if (bSetupAll || !PL_strcmp(i_Pref,CACHE_DIR_PREF)) + { + /* the CopyPathPref is not in nsIPref, is CopyCharPref ok? -xyz */ + + nsresult rv = pref->CopyCharPref(CACHE_DIR_PREF,&tempPref) ; + + if (NS_SUCCEEDED(rv)) + { + PR_ASSERT(tempPref); + + delete [] m_DiskCacheFolder; + m_DiskCacheFolder = new char[PL_strlen(tempPref)+2]; + if (!m_DiskCacheFolder) + { + if (tempPref) + PR_Free(tempPref); + return NS_OK ; + } + PL_strcpy(m_DiskCacheFolder, tempPref); + } + else //TODO set to temp folder + { +#if defined(XP_PC) + char tmpBuf[_MAX_PATH]; + PRFileInfo dir; + PRStatus status; + char *cacheDir = new char [_MAX_PATH]; + if (!cacheDir) + return NS_OK; + cacheDir = _getcwd(cacheDir, _MAX_PATH); + + // setup the cache dir. + PL_strcpy(tmpBuf, cacheDir); + sprintf(cacheDir,"%s%s%s%s", tmpBuf, "\\", "cache", "\\"); + status = PR_GetFileInfo(cacheDir, &dir); + if (PR_FAILURE == status) { + // Create the dir. + status = PR_MkDir(cacheDir, 0600); + if (PR_SUCCESS != status) { + m_DiskCacheFolder = new char[1]; + *m_DiskCacheFolder = '\0'; + return NS_OK; + } + } + m_DiskCacheFolder = cacheDir; +#endif /* XP_PC */ + + delete [] m_DiskCacheFolder; + m_DiskCacheFolder = new char[5] ; + PL_strcpy(m_DiskCacheFolder, "/tmp") ; + } + + } + + if (tempPref) + PR_Free(tempPref); + + return NS_OK ; +} + +NS_IMETHODIMP +nsCachePref::GetBkgSleepTime(PRUint32* o_time) +{ + *o_time = BKG_THREAD_SLEEP; + return NS_OK ; +} + +NS_IMETHODIMP +nsCachePref::GetDiskCacheDBFilename(char** o_name) +{ + *o_name = "nufat.db"; + return NS_OK ; +} + +nsICachePref* +nsCachePref::GetInstance() +{ + nsICacheManager * cachemanager ; + nsICachePref * cachepref ; + + nsresult rv = nsServiceManager::GetService(kCacheManagerCID, + kICACHEMANAGERIID, + (nsISupports **) &cachemanager) ; + + rv = cachemanager->GetPrefs(&cachepref); + return cachepref ; +} + +/* +nsrefcnt nsCachePref::AddRef(void) +{ + return ++m_RefCnt; +} +nsrefcnt nsCachePref::Release(void) +{ + if (--m_RefCnt == 0) + { + delete this; + return 0; + } + return m_RefCnt; +} + +nsresult nsCachePref::QueryInterface(const nsIID& aIID, + void** aInstancePtrResult) +{ + return NS_OK; +} +*/ + +NS_IMPL_ISUPPORTS(nsCachePref, nsCOMTypeInfo::GetIID() ) ; + +int PR_CALLBACK Cache_PrefChangedFunc(const char *pref, void *data) { + + // nsCachePref::GetInstance()->SetupPrefs(pref); + nsICachePref* cachepref ; + + nsresult rv = nsServiceManager::GetService(kCachePrefCID, + kICachePrefIID, + (nsISupports **)&cachepref) ; + + if (NS_FAILED(rv)) + return PR_FALSE ; + else + { + cachepref->SetupPrefs(pref) ; + return PR_TRUE; + } +} + + +///////////////////////////////////////////////////////////////////// +// Exported functions. With these in place we can compile +// this module into a dynamically loaded and registered +// component. + +//static NS_DEFINE_CID(kCacheObjectCID, NS_CACHEOBJECT_CID); +/* +#include "nsIFactory.h" +#include "nsIComponentManager.h" +#include "nsIServiceManager.h" +#include "nspr.h" +#include "nscore.h" +#include "nsRepository.h" +#include "nsICacheManager.h" + +#include "nsICachePref.h" +#include "nsCachePref.h" +*/ + +// static NS_DEFINE_IID(kICachePrefIID, NS_ICACHEPREF_IID); +//static NS_DEFINE_IID(kCachePrefCID, NS_CACHEPREF_CID); +static NS_DEFINE_CID(kComponentManagerCID, NS_COMPONENTMANAGER_CID); +// static NS_DEFINE_IID(kICACHEMANAGERIID, NS_ICACHEMANAGER_IID); +static NS_DEFINE_IID(kIFactoryIID, NS_IFACTORY_IID); + + +// The "name" of our component +static const char* g_desc = "Cache Prefrence XPCOM Module"; + +nsCachePrefFactory::nsCachePrefFactory () +{ + NS_INIT_ISUPPORTS(); + PR_AtomicIncrement(&gInstanceCnt); +} + +nsCachePrefFactory::~nsCachePrefFactory () +{ + NS_ASSERTION(mRefCnt == 0,"Wrong ref count"); + PR_AtomicDecrement(&gInstanceCnt); +} + +/* +NS_IMETHODIMP +nsCacheObjectFactory::QueryInterface(const nsIID &aIID, void **aResult) +{ + if (!aResult) + return NS_ERROR_NULL_POINTER; + + if (aIID.Equals(kISupportsIID)) { + *aResult = NS_STATIC_CAST(nsISupports*,this); + } else if (aIID.Equals(kIFactoryIID)) { + *aResult = NS_STATIC_CAST(nsISupports*,NS_STATIC_CAST(nsIFactory*,this)); + } else { + *aResult = nsnull; + return NS_ERROR_NO_INTERFACE; + } + + NS_ADDREF(NS_REINTERPRET_CAST(nsISupports*,*aResult)); + + return NS_OK; +} + +NS_IMPL_ADDREF(nsCacheObjectFactory) +NS_IMPL_RELEASE(nsCacheObjectFactory) +*/ + +NS_IMPL_ISUPPORTS(nsCachePrefFactory, kIFactoryIID) ; + +NS_IMETHODIMP +nsCachePrefFactory::CreateInstance(nsISupports *aOuter, + const nsIID &aIID, + void **aResult) +{ + if (!aResult) + return NS_ERROR_NULL_POINTER; + + *aResult = nsnull; + + nsISupports *inst = new nsCachePref(); + + if (!inst) { + return NS_ERROR_OUT_OF_MEMORY; + } + + // All XPCOM methods return nsresult + nsresult rv = inst->QueryInterface(aIID, aResult); + + // There are handy macros, NS_SUCCEEDED and NS_FAILED + // to test the return value of an XPCOM method. + if (NS_FAILED(rv)) { + // We didn't get the right interface, so clean up + delete inst; + } + + return rv; +} + +NS_IMETHODIMP +nsCachePrefFactory::LockFactory(PRBool aLock) +{ + if (aLock) { + PR_AtomicIncrement(&gLockCnt); + } else { + PR_AtomicDecrement(&gLockCnt); + } + + return NS_OK; +} + +extern "C" NS_EXPORT nsresult +NSGetFactory(nsISupports *serviceMgr, + const nsCID &aCID, + const char *aClassName, + const char *aProgID, + nsIFactory **aResult) +{ + if (!aResult) + return NS_ERROR_NULL_POINTER; + + *aResult = nsnull; + + nsISupports *inst; + + if (aCID.Equals(kCachePrefCID)) { + // Ok, we know this CID and here is the factory + // that can manufacture the objects + inst = new nsCachePrefFactory(); + } else { + return NS_ERROR_NO_INTERFACE; + } + + if (!inst) + return NS_ERROR_OUT_OF_MEMORY; + + nsresult rv = inst->QueryInterface(kIFactoryIID, + (void **) aResult); + + if (NS_FAILED(rv)) { + delete inst; + } + + return rv; +} + +extern "C" NS_EXPORT PRBool +NSCanUnload(nsISupports* serviceMgr) +{ + return PRBool(gInstanceCnt == 0 && gLockCnt == 0); +} + +extern "C" NS_EXPORT nsresult +NSRegisterSelf(nsISupports *aServMgr, const char *path) +{ + nsresult rv = NS_OK; + + // We will use the service manager to obtain the component + // manager, which will enable us to register a component + // with a ProgID (text string) instead of just the CID. + + nsIServiceManager *sm; + + // We can get the IID of an interface with the static GetIID() method as + // well. + rv = aServMgr->QueryInterface(nsIServiceManager::GetIID(), (void **)&sm); + + if (NS_FAILED(rv)) + return rv; + + nsIComponentManager *cm; + + rv = sm->GetService(kComponentManagerCID, nsIComponentManager::GetIID(), (nsISupports **)&cm); + + if (NS_FAILED(rv)) { + NS_RELEASE(sm); + + return rv; + } + + // Note the text string, we can access the hello component with just this + // string without knowing the CID + rv = cm->RegisterComponent(kCachePrefCID, g_desc, "component://cachePref", + path, PR_TRUE, PR_TRUE); + + sm->ReleaseService(kComponentManagerCID, cm); + + NS_RELEASE(sm); + +#ifdef NS_DEBUG + printf("*** %s registered\n",g_desc); +#endif + + return rv; +} + +extern "C" NS_EXPORT nsresult +NSUnregisterSelf(nsISupports* aServMgr, const char *path) +{ + nsresult rv = NS_OK; + + nsIServiceManager *sm; + + rv = aServMgr->QueryInterface(nsIServiceManager::GetIID(), (void **)&sm); + + if (NS_FAILED(rv)) + return rv; + + nsIComponentManager *cm; + + rv = sm->GetService(kComponentManagerCID, nsIComponentManager::GetIID(), (nsISupports **)&cm); + + if (NS_FAILED(rv)) { + NS_RELEASE(sm); + + return rv; + } + + rv = cm->UnregisterComponent(kCachePrefCID, path); + + sm->ReleaseService(kComponentManagerCID, cm); + + NS_RELEASE(sm); + + return rv; +} + + + diff --git a/mozilla/netwerk/cache/public/Makefile.in b/mozilla/netwerk/cache/public/Makefile.in new file mode 100644 index 00000000000..c2a7add777e --- /dev/null +++ b/mozilla/netwerk/cache/public/Makefile.in @@ -0,0 +1,38 @@ +#!gmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +DEPTH=../../.. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +include $(DEPTH)/config/autoconf.mk + +EXPORTS = \ + nsICacheManager.h \ + nsICacheObject.h \ + nsICachePref.h \ + nsICacheModule.h \ + $(NULL) + +EXPORTS := $(addprefix $(srcdir)/, $(EXPORTS)) + +#MODULE = cache + +include $(topsrcdir)/config/config.mk + +include $(topsrcdir)/config/rules.mk diff --git a/mozilla/netwerk/cache/public/Makefile.win b/mozilla/netwerk/cache/public/Makefile.win new file mode 100755 index 00000000000..d29f37f233d --- /dev/null +++ b/mozilla/netwerk/cache/public/Makefile.win @@ -0,0 +1,31 @@ +#!gmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + + +DEPTH = ..\..\.. +include <$(DEPTH)/config/config.mak> + + +EXPORTS = \ + nsICacheManager.h \ + nsICacheObject.h \ + nsICachePref.h \ + nsICacheModule.h \ + $(NULL) + +include <$(DEPTH)/config/rules.mak> + diff --git a/mozilla/netwerk/cache/public/nsICacheManager.h b/mozilla/netwerk/cache/public/nsICacheManager.h new file mode 100644 index 00000000000..81dae7df7c9 --- /dev/null +++ b/mozilla/netwerk/cache/public/nsICacheManager.h @@ -0,0 +1,57 @@ +#ifndef _nsICacheManger_H_ +#define _nsICacheManger_H_ + +#include "nsISupports.h" +#include "nsICacheModule.h" +#include "nsICachePref.h" + +// nsICacheManager {05A4BC00-3E1A-11d3-87EE-000629D01344} +#define NS_ICACHEMANAGER_IID \ +{0x5a4bc00, 0x3e1a, 0x11d3, \ + {0x87, 0xee, 0x0, 0x6, 0x29, 0xd0, 0x13, 0x44}} + +// {B8B5D4E0-3F92-11d3-87EF-000629D01344} +#define NS_CACHEMANAGER_CID \ + {0xb8b5d4e0, 0x3f92, 0x11d3, \ + {0x87, 0xef, 0x0, 0x6, 0x29, 0xd0, 0x13, 0x44}} + +class nsICacheManager : public nsISupports +{ + public: + + //Reserved modules + enum modules + { + MEM =0, + DISK=1 + }; + + NS_DEFINE_STATIC_IID_ACCESSOR(NS_ICACHEMANAGER_IID) ; + + NS_IMETHOD Contains(const char* i_url) const = 0 ; + + NS_IMETHOD Entries(PRInt16 * n_Entries) const = 0 ; + + NS_IMETHOD GetObj(const char* i_url, void ** o_Object) const = 0 ; + + NS_IMETHOD GetModule(PRInt16 i_index, nsICacheModule** o_module) const = 0 ; + NS_IMETHOD GetDiskModule(nsICacheModule** o_module) const = 0 ; + NS_IMETHOD GetMemModule(nsICacheModule** o_module) const = 0 ; + + NS_IMETHOD AddModule (PRInt16 * o_Index, nsICacheModule * pModule) = 0 ; + + NS_IMETHOD GetPrefs(nsICachePref** o_Pref) const = 0 ; + + NS_IMETHOD InfoAsHTML(char** o_Buffer) const = 0 ; + + NS_IMETHOD IsOffline(PRBool * bOffline) const = 0 ; + + NS_IMETHOD Offline(PRBool bSet) = 0 ; + + NS_IMETHOD Remove(const char* i_url) = 0 ; + + NS_IMETHOD WorstCaseTime(PRUint32 * o_Time) const = 0 ; + +} ; + +#endif diff --git a/mozilla/netwerk/cache/public/nsICacheModule.h b/mozilla/netwerk/cache/public/nsICacheModule.h new file mode 100644 index 00000000000..d0c70b69e72 --- /dev/null +++ b/mozilla/netwerk/cache/public/nsICacheModule.h @@ -0,0 +1,108 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +/* + * nsCacheModule. A class that defines the way a cache module + * should be written. Its the super class for any new modules. + * Two sample modules derived from this one are nsMemModule and nsDiskModule. + * + * Gagan Saksena 02/03/98 + * + */ + +#ifndef nsICacheModule_h__ +#define nsICacheModule_h__ + +#include +#include "nsICacheObject.h" +#include "nsEnumeration.h" + +// {5D51B24F-E6C2-11d1-AFE5-006097BFC036} +#define NS_ICACHEMODULE_IID \ +{ 0x5d51b24f, 0xe6c2, 0x11d1, \ +{ 0xaf, 0xe5, 0x0, 0x60, 0x97, 0xbf, 0xc0, 0x36 } }; + + +class nsICacheModule : public nsISupports +{ + +public: + NS_DEFINE_STATIC_IID_ACCESSOR (NS_ICACHEMODULE_IID); + + + NS_IMETHOD AddObject(nsICacheObject* i_pObject) = 0; + + NS_IMETHOD ContainsURL(const char* i_url, PRBool* o_bContain) = 0; + + NS_IMETHOD ContainsCacheObj(nsICacheObject* i_pObject, PRBool* o_bContain) = 0; + + NS_IMETHOD Enable (PRBool i_bEnable) = 0; + + NS_IMETHOD GetNumOfEntries (PRUint32* o_nEntries) = 0; + + NS_IMETHOD GetEnumerator (nsEnumeration** o_enum) = 0; + /* Enumerations with a function pointer - TODO */ + + //TODO move to own interface for both Garbage Collection and Revalidation + NS_IMETHOD GarbageCollect (void) = 0; + + NS_IMETHOD GetObjectByURL (const char* i_url, nsICacheObject** o_pObj) = 0; + + NS_IMETHOD GetObjectByIndex (const PRUint32 i_index, nsICacheObject** o_pObj) = 0; + + NS_IMETHOD GetStreamFor (const nsICacheObject* i_pObject, nsStream** o_pStream) = 0; + + NS_IMETHOD IsEnabled (PRBool* o_bEnabled) = 0; + + /* Can't do additions, deletions, validations, expirations */ + NS_IMETHOD IsReadOnly (PRBool* o_bReadOnly) = 0; + + NS_IMETHOD GetNextModule (nsICacheModule** o_pCacheModule) = 0; + NS_IMETHOD SetNextModule (nsICacheModule* i_pCacheModule) = 0; + + NS_IMETHOD RemoveByURL (const char* i_url) = 0; + + NS_IMETHOD RemoveByIndex (const PRUint32 i_index) = 0; + + NS_IMETHOD RemoveByObject (nsICacheObject* i_pObject) = 0; + + NS_IMETHOD RemoveAll (void) = 0; + + NS_IMETHOD Revalidate (void) = 0; + + NS_IMETHOD ReduceSizeTo (const PRUint32 i_newsize) = 0; + + NS_IMETHOD GetSize (PRUint32* o_size) = 0; + + NS_IMETHOD SetSize (const PRUint32 i_size) = 0; + + NS_IMETHOD GetSizeInUse (PRUint32* o_size) = 0; + +}; + +// {5D51B24E-E6C1-11d0-AFE5-006097BFC036} +#define NS_DISKMODULE_CID \ +{ 0x5d51b24e, 0xe6c1, 0x11d0, \ +{ 0xaf, 0xe5, 0x0, 0x60, 0x97, 0xbf, 0xc0, 0x36 } }; + +// {5D51B250-E6C2-11d1-AFE5-006097BFC036} +#define NS_MEMMODULE_CID \ +{ 0x5d51b250, 0xe6c2, 0x11d1, \ +{ 0xaf, 0xe5, 0x0, 0x60, 0x97, 0xbf, 0xc0, 0x36 } }; + +#endif diff --git a/mozilla/netwerk/cache/public/nsICacheObject.h b/mozilla/netwerk/cache/public/nsICacheObject.h new file mode 100644 index 00000000000..bb5786ad77d --- /dev/null +++ b/mozilla/netwerk/cache/public/nsICacheObject.h @@ -0,0 +1,106 @@ +#ifndef _NS_CACHEOBJECT_H_ +#define _NS_CACHEOBJECT_H_ + +#include "nsISupports.h" +#include "nsStream.h" + +#include "prtypes.h" +#include "prinrval.h" + +// nsICacheObject {A2D9A8A0-414B-11d3-87EF-000629D01344} +#define NS_ICACHEOBJECT_IID \ + {0xa2d9a8a0, 0x414b, 0x11d3, \ + {0x87, 0xef, 0x0, 0x6, 0x29, 0xd0, 0x13, 0x44 }} + +// nsCacheObject {A2D9A8A1-414B-11d3-87EF-000629D01344} +#define NS_CACHEOBJECT_CID \ + {0xa2d9a8a1, 0x414b, 0x11d3, \ + {0x87, 0xef, 0x0, 0x6, 0x29, 0xd0, 0x13, 0x44 }} + + +class nsICacheObject :public nsISupports +{ + public: + + NS_DEFINE_STATIC_IID_ACCESSOR(NS_ICACHEOBJECT_IID); + + /* Cache Object- check nsCacheObject.h for details on these functions */ + + /* This is added because we need to initialize a new cacheobject + NS_IMETHOD InitUrl(const char * i_url) = 0 ; + */ + + NS_IMETHOD GetAddress(char ** Addr) const = 0 ; + NS_IMETHOD SetAddress(const char* i_Address) = 0 ; + + NS_IMETHOD GetCharset(char ** CSet) const = 0 ; + NS_IMETHOD SetCharset(const char* i_CharSet) = 0 ; + + NS_IMETHOD GetContentEncoding(char ** Encoding) const = 0 ; + NS_IMETHOD SetContentEncoding(const char* i_Encoding) = 0 ; + + NS_IMETHOD GetContentLength(PRUint32 * CLeng) const = 0 ; + NS_IMETHOD SetContentLength(PRUint32 i_Len) = 0 ; + + NS_IMETHOD GetContentType(char ** CType) const = 0 ; + NS_IMETHOD SetContentType(const char* i_Type) = 0 ; + + NS_IMETHOD GetEtag(char ** Etag) const = 0 ; + NS_IMETHOD SetEtag(const char* i_Etag) = 0 ; + + NS_IMETHOD GetExpires(PRIntervalTime * iTime) const = 0 ; + NS_IMETHOD SetExpires(const PRIntervalTime i_Time) = 0 ; + + NS_IMETHOD GetFilename(char ** Filename) const = 0 ; + NS_IMETHOD SetFilename(const char* i_Filename) = 0 ; + + NS_IMETHOD GetIsCompleted(PRBool * bComplete) const = 0 ; + NS_IMETHOD SetIsCompleted(PRBool bComplete) = 0 ; + + NS_IMETHOD GetLastAccessed(PRIntervalTime * iTime) const = 0 ; + NS_IMETHOD SetLastModified(const PRIntervalTime i_Time) = 0 ; + + NS_IMETHOD GetLastModified(PRIntervalTime * iTime) const = 0 ; + + NS_IMETHOD GetModuleIndex(PRInt16 * m_index) const = 0 ; + NS_IMETHOD SetModuleIndex(const PRUint16 m_index) = 0 ; + + NS_IMETHOD GetPageServicesURL(char ** o_url) const = 0 ; + NS_IMETHOD SetPageServicesURL(const char* i_Url) = 0 ; + + NS_IMETHOD GetPostData(char ** pData) const = 0 ; + NS_IMETHOD SetPostData(const char* i_PostData, const PRUint32 i_Len) = 0 ; + + NS_IMETHOD GetPostDataLen(PRUint32 * dLeng) const = 0 ; + + NS_IMETHOD GetSize(PRUint32 * pSize) const = 0 ; + NS_IMETHOD SetSize(const PRUint32 i_Size) = 0 ; + + NS_IMETHOD GetState(PRUint32 * pState) const = 0 ; + NS_IMETHOD SetState(const PRUint32 i_State) = 0 ; + + NS_IMETHOD GetStream(nsStream ** pStream) const = 0 ; +// NS_IMETHOD MakeStream(void) = 0 ; + + NS_IMETHOD Hits(PRUint32 * pHits) const = 0 ; + + NS_IMETHOD IsExpired(PRBool * bGet) const = 0 ; + + NS_IMETHOD IsPartial(PRBool * bGet) const = 0; + + NS_IMETHOD Read(char* o_Destination, PRUint32 i_Len, PRUint32 * pLeng) = 0 ; + + NS_IMETHOD Reset(void) = 0 ; + + NS_IMETHOD Write(const char* i_buffer, const PRUint32 i_length, + PRUint32 * oLeng) = 0 ; + + /* Read and write info about this cache object */ + NS_IMETHOD GetInfo(void** o_info)=0 ; + NS_IMETHOD SetInfo(void* i_info /*, PRUint32 len */)=0; + + NS_IMETHOD GetInfoSize(PRUint32* o_size)=0 ; + +} ; + +#endif // _NSICACHEOBJECT_H_ diff --git a/mozilla/netwerk/cache/public/nsICachePref.h b/mozilla/netwerk/cache/public/nsICachePref.h new file mode 100644 index 00000000000..7de895f789c --- /dev/null +++ b/mozilla/netwerk/cache/public/nsICachePref.h @@ -0,0 +1,90 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +/* nsICachePref. A class to separate the preference related code to + * one place. This is an incomplete implementation, I need to access + * the libprefs directly, but that would add another dependency. And + * libpref comes with a JS dependency... so holding this off for the + * moment. + * + * -Gagan Saksena 09/15/98 + */ +#ifndef nsICachePref_h__ +#define nsICachePref_h__ + +#include "nsISupports.h" +#include "prtypes.h" +#include "prlog.h" + + +// {7C3ED031-45E4-11d3-9B7F-0004ACB74CEC} +#define NS_ICACHEPREF_IID \ +{ 0x7c3ed031, 0x45e4, 0x11d3, \ +{ 0x9b, 0x7f, 0x0, 0x4, 0xac, 0xb7, 0x4c, 0xec } }; + +// myCachePrefCID {99E9C911-46D9-11d3-87EF-000629D01344} +#define NS_CACHEPREF_CID \ +{ 0x99e9c911, 0x46d9, 0x11d3, \ +{ 0x87, 0xef, 0x0, 0x6, 0x29, 0xd0, 0x13, 0x44}} ; + +class nsICachePref : public nsISupports +{ +public: + NS_DEFINE_STATIC_IID_ACCESSOR (NS_ICACHEPREF_IID); + + // Was "static nsCachePref* GetInstance(void)" + // Do I need this GetInstance?????? +// NS_IMETHOD GetInstance(nsICachePref** o_pICachePref ) = 0; + + enum Refresh + { + ONCE, + ALWAYS, + NEVER + }; + + NS_IMETHOD GetBkgSleepTime (PRUint32* o_time) = 0; + + NS_IMETHOD GetDiskCacheDBFilename (char** o_name) = 0; /* like Fat.db */ + + NS_IMETHOD GetDiskCacheFolder (char** o_folder) = 0; /* Cache dir */ + + NS_IMETHOD GetDiskCacheSSL (PRBool* o_bSet) = 0; + + NS_IMETHOD SetDiskCacheSSL (PRBool i_bSet) = 0; + + NS_IMETHOD GetDiskCacheSize (PRUint32* o_size) = 0; + NS_IMETHOD SetDiskCacheSize (const PRUint32 i_size) = 0; + + NS_IMETHOD GetMemCacheSize (PRUint32 * o_size) = 0; + NS_IMETHOD SetMemCacheSize (const PRUint32 i_size) = 0; + + NS_IMETHOD GetFrequency (nsICachePref::Refresh* o_frequency) = 0; + + /* Revalidating in background, makes IMS calls in the bkg thread to + update cache entries. TODO, this should be at a bigger time period + than the cache cleanup routine */ + NS_IMETHOD RevalidateInBkg (PRBool* i_bRevalidateInBkg) = 0; + + /* Setup all prefs */ + NS_IMETHOD SetupPrefs(const char* i_Pref) = 0; + +}; + +#endif // nsICachePref_h__ + diff --git a/mozilla/netwerk/cache/tests/Makefile.in b/mozilla/netwerk/cache/tests/Makefile.in new file mode 100644 index 00000000000..e4b8f660b37 --- /dev/null +++ b/mozilla/netwerk/cache/tests/Makefile.in @@ -0,0 +1,27 @@ +#!gmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +DEPTH = ../../.. +topsrcdir = @top_srcdir@ +VPATH = @srcdir@ +srcdir = @srcdir@ + +include $(DEPTH)/config/autoconf.mk + +DIRS = xptest + +include $(topsrcdir)/config/rules.mk diff --git a/mozilla/netwerk/cache/tests/Makefile.win b/mozilla/netwerk/cache/tests/Makefile.win new file mode 100755 index 00000000000..385274ed0d7 --- /dev/null +++ b/mozilla/netwerk/cache/tests/Makefile.win @@ -0,0 +1,24 @@ +#!gmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + + +DEPTH=..\..\.. +DIRS= \ + xptest \ + $(NULL) + +include <$(DEPTH)\config\rules.mak> diff --git a/mozilla/netwerk/cache/tests/xptest/Makefile.in b/mozilla/netwerk/cache/tests/xptest/Makefile.in new file mode 100644 index 00000000000..babba34db81 --- /dev/null +++ b/mozilla/netwerk/cache/tests/xptest/Makefile.in @@ -0,0 +1,55 @@ +# Generated automatically from Makefile.in by configure. +# Generated automatically from Makefile.in by configure. +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +DEPTH = ../../../.. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +include $(DEPTH)/config/autoconf.mk + +#DIRS = dynamic + +CPPSRCS = \ + disktest.cpp \ + memtest.cpp \ + $(NULL) + +#PROGRAM = cachetest +#LIBRARY_NAME = xpcomsample +SIMPLE_PROGRAMS = $(CPPSRCS:.cpp=) + +include $(topsrcdir)/config/config.mk + +DEFINES += -DUSE_NSREG -DCACHE +LIBS_DIR += -L$(DIST)/bin/components +INCLUDES += -I$(srcdir)/../../public -I$(srcdir)/../../include -I.. +IS_COMPONENT = + +LIBS = \ + -lpref \ + -lsecfree \ + -lmozjs \ + -lxpcom \ + $(ZLIB_LIBS) \ + $(NSPR_LIBS) \ + $(NULL) + +#SIMPLE_PROGRAMS = $(addprefix $(OBJDIR)/, $(CPPSRCS:.cpp=)) + +include $(topsrcdir)/config/rules.mk diff --git a/mozilla/netwerk/cache/tests/xptest/Makefile.win b/mozilla/netwerk/cache/tests/xptest/Makefile.win new file mode 100755 index 00000000000..98650bd1557 --- /dev/null +++ b/mozilla/netwerk/cache/tests/xptest/Makefile.win @@ -0,0 +1,53 @@ +#!nmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +DEPTH=..\..\..\.. + +MAKE_OBJ_TYPE = EXE +PROG1 = .\$(OBJDIR)\disktest.exe +PROG2 = .\$(OBJDIR)\memtest.exe +PROGRAMS = $(PROG1) $(PROG2) + +LCFLAGS=-DUSE_NSREG -GX -DCACHE + +REQUIRES=libreg + +INCS = -I..\..\public \ + -I..\..\include \ + $(INCS) \ + -I$(DEPTH)\dist\include \ + $(NULL) + +LLIBS= \ + $(DIST)\lib\xpcom.lib \ + $(DIST)\lib\raptorgfxwin.lib \ + $(LIBNSPR) \ +!if "$(MOZ_BITS)"=="32" && defined(MOZ_DEBUG) && defined(GLOWCODE) +LLIBS=$(LLIBS) $(GLOWDIR)\glowcode.lib +!endif + +include <$(DEPTH)\config\rules.mak> + +install:: $(PROGRAMS) + -for %p in ($(PROGRAMS)) do $(MAKE_INSTALL) %p $(DIST)\bin + +clobber:: + -for %p in ($(PROGRAMS)) do $(RM) %p $(DIST)\bin\%p + +$(PROG1): $(OBJDIR) disktest.cpp + +$(PROG2): $(OBJDIR) memtest.cpp diff --git a/mozilla/netwerk/cache/tests/xptest/disktest.cpp b/mozilla/netwerk/cache/tests/xptest/disktest.cpp new file mode 100644 index 00000000000..381c653b50f --- /dev/null +++ b/mozilla/netwerk/cache/tests/xptest/disktest.cpp @@ -0,0 +1,817 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +/* + The TestProtocols tests the basic protocols architecture and can + be used to test individual protocols as well. If this grows too + big then we should split it to individual protocols. + + -Gagan Saksena 04/29/99 +*/ + +/* + This program would actually create a cache file in your /tmp + directory. It would try to use the default name from URI. If + that name can not be found, it will use nucache. Also, a database + file (for indexing, I guess) named nufat.db would also be generated + in the same directory. + + This is only a temporary solution. We are still waiting for the final + decision on which database to use. + + -yixiong 08/10/99 +*/ + +#include +#ifdef WIN32 +#include +#endif +#include "nspr.h" +#include "nscore.h" +#include "nsCOMPtr.h" +#include "nsIEventQueueService.h" +#include "nsIIOService.h" +#include "nsIServiceManager.h" +#include "nsIStreamListener.h" +#include "nsIInputStream.h" +#include "nsIBufferInputStream.h" +#include "nsCRT.h" +#include "nsIChannel.h" +#include "nsIURL.h" +#include "nsIHTTPChannel.h" +#include "nsIHttpEventSink.h" +#include "nsIEventSinkGetter.h" +#include "nsIDNSService.h" + +#include "nsISimpleEnumerator.h" +#include "nsIHTTPHeader.h" +#include "nsXPIDLString.h" + +#ifdef CACHE +#include "nsICacheManager.h" +#include "nsICacheObject.h" +#endif + +#ifdef NECKO +// this test app handles cookies. +#include "nsICookieService.h" +static NS_DEFINE_CID(nsCookieServiceCID, NS_COOKIESERVICE_CID); +#endif // NECKO + +static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID); +static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID); + +#ifdef CACHE +static NS_DEFINE_IID(kICacheManagerIID, NS_ICACHEMANAGER_IID) ; +static NS_DEFINE_IID(kCacheManagerCID, NS_CACHEMANAGER_CID) ; + +static NS_DEFINE_IID(kICacheObjectIID, NS_ICACHEOBJECT_IID) ; +static NS_DEFINE_CID(kCacheObjectCID, NS_CACHEOBJECT_CID); +#endif + +//static PRTime gElapsedTime; // enable when we time it... +static int gKeepRunning = 0; +static PRBool gVerbose = PR_FALSE; +static nsIEventQueue* gEventQ = nsnull; + +class URLLoadInfo : public nsISupports +{ +public: + + URLLoadInfo(const char* aUrl); + virtual ~URLLoadInfo(); + + // ISupports interface... + NS_DECL_ISUPPORTS + + const char* Name() { return mURLString.GetBuffer(); } + PRInt32 mBytesRead; + PRTime mTotalTime; + PRTime mConnectTime; + nsString mURLString; +}; + +URLLoadInfo::URLLoadInfo(const char *aUrl) : mURLString(aUrl) +{ + NS_INIT_REFCNT(); + + mBytesRead = 0; + mConnectTime = mTotalTime = PR_Now(); +} + +URLLoadInfo::~URLLoadInfo() +{ +} + + +NS_IMPL_ISUPPORTS(URLLoadInfo,nsCOMTypeInfo::GetIID()); + + +class TestHTTPEventSink : public nsIHTTPEventSink +{ +public: + + TestHTTPEventSink(); + virtual ~TestHTTPEventSink(); + + // ISupports interface... + NS_DECL_ISUPPORTS + + // nsIHTTPEventSink interface... + NS_IMETHOD OnAwaitingInput(nsISupports* i_Context); + + NS_IMETHOD OnHeadersAvailable(nsISupports* i_Context); + + NS_IMETHOD OnProgress(nsISupports* i_Context, + PRUint32 i_Progress, + PRUint32 i_ProgressMax); + + // OnRedirect gets fired only if you have set FollowRedirects on the handler! + NS_IMETHOD OnRedirect(nsISupports* i_Context, + nsIURI* i_NewLocation); +}; + +TestHTTPEventSink::TestHTTPEventSink() +{ + NS_INIT_REFCNT(); +} + +TestHTTPEventSink::~TestHTTPEventSink() +{ +} + + +NS_IMPL_ISUPPORTS(TestHTTPEventSink,nsCOMTypeInfo::GetIID()); + +NS_IMETHODIMP +TestHTTPEventSink::OnAwaitingInput(nsISupports* context) +{ + printf("\n+++ TestHTTPEventSink::OnAwaitingInput +++\n"); + return NS_OK; +} + +NS_IMETHODIMP +TestHTTPEventSink::OnHeadersAvailable(nsISupports* context) +{ + nsCOMPtr enumerator; + nsCOMPtr pHTTPCon(do_QueryInterface(context)); + PRBool bMoreHeaders; + + printf("cachetest: 162, OnHeadersAvailable, \n") ; + + if (pHTTPCon) { + pHTTPCon->GetRequestHeaderEnumerator(getter_AddRefs(enumerator)); + + printf("Request headers:\n"); + enumerator->HasMoreElements(&bMoreHeaders); + while (bMoreHeaders) { + nsCOMPtr item; + nsCOMPtr header; + + enumerator->GetNext(getter_AddRefs(item)); + header = do_QueryInterface(item); + + if (header) { + nsCOMPtr key; + nsAutoString field(eOneByte); + nsXPIDLCString value; + + header->GetField(getter_AddRefs(key)); + key->ToString(field); + printf("\t%s: ", field.GetBuffer()); + + header->GetValue(getter_Copies(value)); + printf("%s\n", (const char*)value); + } + + enumerator->HasMoreElements(&bMoreHeaders); + } + + pHTTPCon->GetResponseHeaderEnumerator(getter_AddRefs(enumerator)); + + printf("Response headers:\n"); + enumerator->HasMoreElements(&bMoreHeaders); + while (bMoreHeaders) { + nsCOMPtr item; + nsCOMPtr header; + + enumerator->GetNext(getter_AddRefs(item)); + header = do_QueryInterface(item); + + if (header) { + nsCOMPtr key; + nsAutoString field(eOneByte); + nsXPIDLCString value; + + header->GetField(getter_AddRefs(key)); + key->ToString(field); + printf("\t%s: ", field.GetBuffer()); + + header->GetValue(getter_Copies(value)); + printf("%s\n", (const char*)value); + } + + enumerator->HasMoreElements(&bMoreHeaders); + } + + } + + + if (gVerbose) { + printf("\n+++ TestHTTPEventSink::OnHeadersAvailable +++\n"); + nsCOMPtr pHTTPCon(do_QueryInterface(context)); + if (pHTTPCon) { + char* type; + //optimize later TODO allow atoms here...! intead of just the header strings + pHTTPCon->GetContentType(&type); + if (type) { + printf("\nReceiving ... %s\n", type); + nsCRT::free(type); + } + } + } + return NS_OK; +} + +NS_IMETHODIMP +TestHTTPEventSink::OnProgress(nsISupports* context, PRUint32 i_Progress, PRUint32 i_ProgressMax) +{ + printf("\n+++ TestHTTPEventSink::OnProgress +++\n"); + return NS_OK; +} + +NS_IMETHODIMP +TestHTTPEventSink::OnRedirect(nsISupports* context, nsIURI* i_NewLocation) +{ + printf("\n+++ TestHTTPEventSink::OnRedirect +++\n"); + return NS_OK; +} + + +class InputTestConsumer : public nsIStreamListener +{ +public: + + InputTestConsumer(); + virtual ~InputTestConsumer(); + + // ISupports interface... + NS_DECL_ISUPPORTS + + // IStreamListener interface... + NS_IMETHOD OnStartRequest(nsIChannel* channel, nsISupports* context); + + NS_IMETHOD OnDataAvailable(nsIChannel* channel, nsISupports* context, + nsIInputStream *aIStream, + PRUint32 aSourceOffset, + PRUint32 aLength); + + NS_IMETHOD OnStopRequest(nsIChannel* channel, nsISupports* context, + nsresult aStatus, + const PRUnichar* aMsg); + +#ifdef CACHE + private: + + nsICacheObject* mCacheFile ; +#endif +}; + + +InputTestConsumer::InputTestConsumer() +{ + NS_INIT_REFCNT(); + +#ifdef CACHE + mCacheFile = nsnull ; +#endif +} + +InputTestConsumer::~InputTestConsumer() +{ +#ifdef CACHE + NS_IF_RELEASE(mCacheFile) ; +#endif +} + + +NS_IMPL_ISUPPORTS(InputTestConsumer,nsCOMTypeInfo::GetIID()); + + +NS_IMETHODIMP +InputTestConsumer::OnStartRequest(nsIChannel* channel, nsISupports* context) +{ +#ifdef CACHE + /* Stuff taken from nsPluginHostImpl.cpp */ + + char * aContentType = nsnull ; + nsIURI* aURL = nsnull ; + nsICacheModule* diskCache ; + nsICacheManager* cacheManager ; + + nsresult rv = NS_OK, r1, r2 ; + + rv = channel->GetContentType(&aContentType) ; + if (NS_FAILED(rv)) return rv ; + + rv = channel ->GetURI(&aURL) ; + if (NS_FAILED(rv)) return rv ; + + char * cString; + char * fileName ; + + nsCOMPtr pURL(do_QueryInterface(aURL)) ; + + if (pURL) { + pURL -> GetSpec(&cString) ; + + /* Todo, use PROGID instead */ + rv = nsComponentManager::CreateInstance(kCacheObjectCID, + nsnull, + kICacheObjectIID, + (void**)&mCacheFile) ; + + if (NS_FAILED(rv)) { + return rv ; + } + + r1 = NS_ERROR_FAILURE ; + r1 = mCacheFile->SetAddress(cString) ; + + /* use the actual filname of the net-based file as the cache filename */ + r1 = pURL->GetFileName(&fileName) ; + + if(!fileName) { + fileName=new char[50] ; + strcpy(fileName, "nucache") ; + } + + r2 = mCacheFile ->SetFilename(fileName) ; + + delete [] fileName ; + } + + /* todo: use PROGID instead */ + rv = nsServiceManager::GetService(kCacheManagerCID, + kICacheManagerIID, + (nsISupports **)&cacheManager) ; + if (NS_FAILED(rv)) return rv ; + + // cacheManager->Init( ) ; + + rv = cacheManager->GetDiskModule(&diskCache) ; + if (NS_FAILED(rv)) return rv ; + + rv = diskCache->AddObject(mCacheFile) ; + +#endif + + URLLoadInfo* info = (URLLoadInfo*)context; + if (info) { + info->mConnectTime = PR_Now() - info->mConnectTime; + } + + if (gVerbose) { + printf("\nStarted loading: %s\n", info ? info->Name() : "UNKNOWN URL"); + } +/* + nsCOMPtr pURI(do_QueryInterface(context)); + char* location = nsnull; + + if (pURI) { + pURI->GetSpec(&location); + } + + printf("\nStarted loading: %s\n", location ? location : "UNKNOWN URL"); + if (location) { + nsCRT::free(location); + } +*/ + return NS_OK; +} + + +NS_IMETHODIMP +InputTestConsumer::OnDataAvailable(nsIChannel* channel, + nsISupports* context, + nsIInputStream *aIStream, + PRUint32 aSourceOffset, + PRUint32 aLength) +{ + char buf[1025]; + PRUint32 amt, amt_wrote; + nsresult rv; + URLLoadInfo* info = (URLLoadInfo*)context; + + do { + rv = aIStream->Read(buf, 1024, &amt); + +#ifdef CACHE + if (nsnull != mCacheFile ) { + mCacheFile->Write((char*)buf, amt, &amt_wrote) ; + } +#endif + + if (rv == NS_BASE_STREAM_EOF) break; + if (NS_FAILED(rv)) return rv; + if (gVerbose) { + buf[amt] = '\0'; + puts(buf); + } + if (info) { + info->mBytesRead += amt; + } + } while (amt); + + return NS_OK; +} + + +NS_IMETHODIMP +InputTestConsumer::OnStopRequest(nsIChannel* channel, + nsISupports* context, + nsresult aStatus, + const PRUnichar* aMsg) +{ + URLLoadInfo* info = (URLLoadInfo*)context; + + if (info) { + double connectTime; + double readTime; + PRUint32 httpStatus, o_amt=0, l ; + PRInt16 m ; + PRBool bHTTPURL = PR_FALSE, b; + char buf[2000], *s ; + PRIntervalTime t ; + + if (mCacheFile) { + mCacheFile->GetLastModified(&t) ; + printf("\nlast modified: %d\n", t) ; + + mCacheFile->GetEtag(&s) ; + printf("etag: %s\n", s) ; + + mCacheFile->GetContentType(&s) ; + printf("content type: %s\n", s) ; + + mCacheFile->GetCharset(&s) ; + printf("character set: %s\n", s) ; + + mCacheFile->GetContentEncoding(&s) ; + printf("Content encoding: %s\n", s) ; + + mCacheFile->GetContentLength(&l) ; + printf("Content Length: %d\n", l) ; + + mCacheFile->GetExpires(&t) ; + printf("Expires: %d\n", t) ; + + mCacheFile->GetFilename(&s) ; + printf("Filename: %s\n", s) ; + + mCacheFile->GetState(&l) ; + printf("State: %d\n", l) ; + + mCacheFile->GetInfoSize(&l) ; + printf("Info size: %d\n", l) ; + + mCacheFile->IsPartial(&b) ; + printf("Is completed: %s\n", b?"True":"False") ; + + mCacheFile->GetLastAccessed(&t) ; + printf("Last Access time: %d\n", t) ; + + mCacheFile->GetLastModified(&t) ; + printf("Last Modified time: %d\n", t) ; + + mCacheFile->GetModuleIndex(&m) ; + printf("Module: %d\n", m) ; + + mCacheFile->GetPageServicesURL(&s) ; + printf("Page Service URL: %s\n", s) ; + + mCacheFile->GetPostData(&s) ; + printf("Post Data: %s\n", s) ; + + mCacheFile->GetPostDataLen(&l) ; + printf("Post Data Length: %d\n", l) ; + + mCacheFile->GetSize(&l) ; + printf("Size: %d\n", l) ; + + mCacheFile->GetAddress(&s) ; + printf("URL Address: %s \n", s) ; + + /* I know my test webpage is less than 2000 bytes. yixiong */ + mCacheFile->Read (buf, (PRUint32) 2000, &o_amt) ; + buf[o_amt] = '\0' ; +// printf("%s\n o_amt = %d \n", buf, o_amt) ; + } + + info->mTotalTime = PR_Now() - info->mTotalTime; + + connectTime = (info->mConnectTime/1000.0)/1000.0; + readTime = ((info->mTotalTime-info->mConnectTime)/1000.0)/1000.0; + + nsCOMPtr pHTTPCon(do_QueryInterface(channel)); + if (pHTTPCon) { + pHTTPCon->GetResponseStatus(&httpStatus); + bHTTPURL = PR_TRUE; + } + + printf("\nFinished loading: %s Status Code: %x\n", info->Name(), aStatus); + if (bHTTPURL) + printf("\tHTTP Status: %u\n", httpStatus); + if (NS_ERROR_UNKNOWN_HOST == aStatus) { + printf("\tDNS lookup failed.\n"); + } + printf("\tRead: %d bytes.\n", info->mBytesRead); + printf("\tTime to connect: %.3f seconds\n", connectTime); + printf("\tTime to read: %.3f seconds.\n", readTime); + if (readTime > 0.0) { + printf("\tThroughput: %.0f bps.\n", (info->mBytesRead*8)/readTime); + } else { + printf("\tThroughput: REAL FAST!!\n"); + } + } else { + printf("\nFinished loading: UNKNOWN URL. Status Code: %x\n", aStatus); + } +/* + nsCOMPtr pURI(do_QueryInterface(context)); + char* location = nsnull; + + if (pURI) { + pURI->GetSpec(&location); + } + + printf("\nFinished loading: %s Status Code: %x\n", location ? location : "UNKNOWN URL", aStatus); + + if (location) { + nsCRT::free(location); + } +*/ + gKeepRunning -= 1; + return NS_OK; +} + +//////////////////////////////////////////////////////////////////////////////// + +class nsEventSinkGetter : public nsIEventSinkGetter { +public: + NS_DECL_ISUPPORTS + + nsEventSinkGetter() { + NS_INIT_REFCNT(); + } + + NS_IMETHOD GetEventSink(const char* verb, const nsIID& eventSinkIID, + nsISupports* *result) { + nsresult rv = NS_ERROR_FAILURE; + + if (nsCRT::strcmp(verb, "load") == 0) { // makeshift verb for now + if (eventSinkIID.Equals(nsCOMTypeInfo::GetIID())) { + TestHTTPEventSink *sink; + + sink = new TestHTTPEventSink(); + if (sink == nsnull) + return NS_ERROR_OUT_OF_MEMORY; + NS_ADDREF(sink); + rv = sink->QueryInterface(eventSinkIID, (void**)result); + NS_RELEASE(sink); + } + } + return rv; + } +}; + +NS_IMPL_ISUPPORTS(nsEventSinkGetter, nsCOMTypeInfo::GetIID()); + +//////////////////////////////////////////////////////////////////////////////// + + +nsresult StartLoadingURL(const char* aUrlString) +{ + nsresult rv; + + NS_WITH_SERVICE(nsIIOService, pService, kIOServiceCID, &rv); + if (pService) { + nsCOMPtr pURL; + + rv = pService->NewURI(aUrlString, nsnull, getter_AddRefs(pURL)); + if (NS_FAILED(rv)) { + printf("ERROR: NewURI failed for %s\n", aUrlString); + return rv; + } + nsCOMPtr pChannel; + nsEventSinkGetter* pMySink; + + pMySink = new nsEventSinkGetter(); + NS_IF_ADDREF(pMySink); + if (!pMySink) { + NS_ERROR("Failed to create a new consumer!"); + return NS_ERROR_OUT_OF_MEMORY;; + } + + // Async reading thru the calls of the event sink interface + rv = pService->NewChannelFromURI("load", pURL, nsnull, pMySink, + getter_AddRefs(pChannel)); + if (NS_FAILED(rv)) { + printf("ERROR: NewChannelFromURI failed for %s\n", aUrlString); + return rv; + } + NS_RELEASE(pMySink); + + /* + You may optionally add/set other headers on this + request object. This is done by QI for the specific + protocolConnection. + */ + nsCOMPtr pHTTPCon(do_QueryInterface(pChannel)); + + if (pHTTPCon) { + // Setting a sample user agent string. + nsCOMPtr userAgent; + + userAgent = NS_NewAtom("user-agent"); + rv = pHTTPCon->SetRequestHeader(userAgent, "Mozilla/5.0 [en] (Win98; U)"); + if (NS_FAILED(rv)) return rv; + } + + InputTestConsumer* listener; + + listener = new InputTestConsumer; + NS_IF_ADDREF(listener); + if (!listener) { + NS_ERROR("Failed to create a new stream listener!"); + return NS_ERROR_OUT_OF_MEMORY;; + } + + URLLoadInfo* info; + info = new URLLoadInfo(aUrlString); + NS_IF_ADDREF(info); + if (!info) { + NS_ERROR("Failed to create a load info!"); + return NS_ERROR_OUT_OF_MEMORY;; + } + + + rv = pChannel->AsyncRead(0, // staring position + -1, // number of bytes to read + info, // ISupports context + listener); // IStreamListener consumer + if (NS_SUCCEEDED(rv)) { + gKeepRunning += 1; + } + NS_RELEASE(listener); + NS_RELEASE(info); + } + + return rv; +} + + +nsresult LoadURLsFromFile(char *aFileName) +{ + nsresult rv = NS_OK; + PRInt32 len, offset; + PRFileDesc* fd; + char buffer[1024]; + nsString fileBuffer; + nsAutoString urlString(eOneByte); + + fd = PR_Open(aFileName, PR_RDONLY, 777); + if (!fd) { + return NS_ERROR_FAILURE; + } + + // Keep reading the file until EOF (or an error) is reached... + do { + len = PR_Read(fd, buffer, sizeof(buffer)); + if (len>0) { + fileBuffer.Append(buffer, len); + // Treat each line as a URL... + while ((offset = fileBuffer.FindChar('\n')) != -1) { + fileBuffer.Left(urlString, offset); + fileBuffer.Cut(0, offset+1); + + urlString.StripChars("\r"); + if (urlString.Length()) { + printf("\t%s\n", urlString.GetBuffer()); + rv = StartLoadingURL(urlString.GetBuffer()); + } + } + } + } while (len>0); + + // If anything is left in the fileBuffer, treat it as a URL... + fileBuffer.StripChars("\r"); + if (fileBuffer.Length()) { + printf("\t%s\n", fileBuffer.GetBuffer()); + StartLoadingURL(fileBuffer.GetBuffer()); + } + + PR_Close(fd); + return NS_OK; +} + + +nsresult NS_AutoregisterComponents() +{ + nsresult rv = nsComponentManager::AutoRegister(nsIComponentManager::NS_Startup, NULL /* default */); + return rv; +} + +int +main(int argc, char* argv[]) +{ + nsresult rv= (nsresult)-1; + if (argc < 2) { + printf("usage: %s [-verbose] [-file ] ... \n", argv[0]); + return -1; + } + + /* + The following code only deals with XPCOM registration stuff. and setting + up the event queues. Copied from TestSocketIO.cpp + */ + + rv = NS_AutoregisterComponents(); + if (NS_FAILED(rv)) return rv; + + + // Create the Event Queue for this thread... + NS_WITH_SERVICE(nsIEventQueueService, eventQService, kEventQueueServiceCID, &rv); + if (NS_FAILED(rv)) return rv; + + rv = eventQService->CreateThreadEventQueue(); + if (NS_FAILED(rv)) return rv; + + eventQService->GetThreadEventQueue(PR_CurrentThread(), &gEventQ); + +#if 0 // Jud sez + // fire up an instance of the cookie manager. + // I'm doing this using the serviceManager for convenience's sake. + // Presumably an application will init it's own cookie service a + // different way (this way works too though). + NS_WITH_SERVICE(nsICookieService, cookieService, nsCookieServiceCID, &rv); + if (NS_FAILED(rv)) return rv; +#endif // NECKO + + int i; + printf("\nTrying to load:\n"); + for (i=1; iGetEvent(&gEvent); + rv = gEventQ->HandleEvent(gEvent); +#endif /* XP_UNIX */ +#endif /* !WIN32 */ + } + + return rv; +} diff --git a/mozilla/netwerk/cache/tests/xptest/memtest.cpp b/mozilla/netwerk/cache/tests/xptest/memtest.cpp new file mode 100644 index 00000000000..c05ca99603b --- /dev/null +++ b/mozilla/netwerk/cache/tests/xptest/memtest.cpp @@ -0,0 +1,801 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +/* + The TestProtocols tests the basic protocols architecture and can + be used to test individual protocols as well. If this grows too + big then we should split it to individual protocols. + + -Gagan Saksena 04/29/99 +*/ + +#include +#ifdef WIN32 +#include +#endif +#include "nspr.h" +#include "nscore.h" +#include "nsCOMPtr.h" +#include "nsIEventQueueService.h" +#include "nsIIOService.h" +#include "nsIServiceManager.h" +#include "nsIStreamListener.h" +#include "nsIInputStream.h" +#include "nsIBufferInputStream.h" +#include "nsCRT.h" +#include "nsIChannel.h" +#include "nsIURL.h" +#include "nsIHTTPChannel.h" +#include "nsIHttpEventSink.h" +#include "nsIEventSinkGetter.h" +#include "nsIDNSService.h" + +#include "nsISimpleEnumerator.h" +#include "nsIHTTPHeader.h" +#include "nsXPIDLString.h" + +#ifdef CACHE +#include "nsICacheManager.h" +#include "nsICacheObject.h" +#endif + +#ifdef NECKO +// this test app handles cookies. +#include "nsICookieService.h" +static NS_DEFINE_CID(nsCookieServiceCID, NS_COOKIESERVICE_CID); +#endif // NECKO + +static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID); +static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID); + +#ifdef CACHE +static NS_DEFINE_IID(kICacheManagerIID, NS_ICACHEMANAGER_IID) ; +static NS_DEFINE_IID(kCacheManagerCID, NS_CACHEMANAGER_CID) ; + +static NS_DEFINE_IID(kICacheObjectIID, NS_ICACHEOBJECT_IID) ; +static NS_DEFINE_CID(kCacheObjectCID, NS_CACHEOBJECT_CID); +#endif + +//static PRTime gElapsedTime; // enable when we time it... +static int gKeepRunning = 0; +static PRBool gVerbose = PR_FALSE; +static nsIEventQueue* gEventQ = nsnull; + +class URLLoadInfo : public nsISupports +{ +public: + + URLLoadInfo(const char* aUrl); + virtual ~URLLoadInfo(); + + // ISupports interface... + NS_DECL_ISUPPORTS + + const char* Name() { return mURLString.GetBuffer(); } + PRInt32 mBytesRead; + PRTime mTotalTime; + PRTime mConnectTime; + nsString mURLString; +}; + +URLLoadInfo::URLLoadInfo(const char *aUrl) : mURLString(aUrl) +{ + NS_INIT_REFCNT(); + + mBytesRead = 0; + mConnectTime = mTotalTime = PR_Now(); +} + +URLLoadInfo::~URLLoadInfo() +{ +} + + +NS_IMPL_ISUPPORTS(URLLoadInfo,nsCOMTypeInfo::GetIID()); + + +class TestHTTPEventSink : public nsIHTTPEventSink +{ +public: + + TestHTTPEventSink(); + virtual ~TestHTTPEventSink(); + + // ISupports interface... + NS_DECL_ISUPPORTS + + // nsIHTTPEventSink interface... + NS_IMETHOD OnAwaitingInput(nsISupports* i_Context); + + NS_IMETHOD OnHeadersAvailable(nsISupports* i_Context); + + NS_IMETHOD OnProgress(nsISupports* i_Context, + PRUint32 i_Progress, + PRUint32 i_ProgressMax); + + // OnRedirect gets fired only if you have set FollowRedirects on the handler! + NS_IMETHOD OnRedirect(nsISupports* i_Context, + nsIURI* i_NewLocation); +}; + +TestHTTPEventSink::TestHTTPEventSink() +{ + NS_INIT_REFCNT(); +} + +TestHTTPEventSink::~TestHTTPEventSink() +{ +} + + +NS_IMPL_ISUPPORTS(TestHTTPEventSink,nsCOMTypeInfo::GetIID()); + +NS_IMETHODIMP +TestHTTPEventSink::OnAwaitingInput(nsISupports* context) +{ + printf("\n+++ TestHTTPEventSink::OnAwaitingInput +++\n"); + return NS_OK; +} + +NS_IMETHODIMP +TestHTTPEventSink::OnHeadersAvailable(nsISupports* context) +{ + nsCOMPtr enumerator; + nsCOMPtr pHTTPCon(do_QueryInterface(context)); + PRBool bMoreHeaders; + + printf("cachetest: 162, OnHeadersAvailable, \n") ; + + if (pHTTPCon) { + pHTTPCon->GetRequestHeaderEnumerator(getter_AddRefs(enumerator)); + + printf("Request headers:\n"); + enumerator->HasMoreElements(&bMoreHeaders); + while (bMoreHeaders) { + nsCOMPtr item; + nsCOMPtr header; + + enumerator->GetNext(getter_AddRefs(item)); + header = do_QueryInterface(item); + + if (header) { + nsCOMPtr key; + nsAutoString field(eOneByte); + nsXPIDLCString value; + + header->GetField(getter_AddRefs(key)); + key->ToString(field); + printf("\t%s: ", field.GetBuffer()); + + header->GetValue(getter_Copies(value)); + printf("%s\n", (const char*)value); + } + + enumerator->HasMoreElements(&bMoreHeaders); + } + + pHTTPCon->GetResponseHeaderEnumerator(getter_AddRefs(enumerator)); + + printf("Response headers:\n"); + enumerator->HasMoreElements(&bMoreHeaders); + while (bMoreHeaders) { + nsCOMPtr item; + nsCOMPtr header; + + enumerator->GetNext(getter_AddRefs(item)); + header = do_QueryInterface(item); + + if (header) { + nsCOMPtr key; + nsAutoString field(eOneByte); + nsXPIDLCString value; + + header->GetField(getter_AddRefs(key)); + key->ToString(field); + printf("\t%s: ", field.GetBuffer()); + + header->GetValue(getter_Copies(value)); + printf("%s\n", (const char*)value); + } + + enumerator->HasMoreElements(&bMoreHeaders); + } + + } + + + if (gVerbose) { + printf("\n+++ TestHTTPEventSink::OnHeadersAvailable +++\n"); + nsCOMPtr pHTTPCon(do_QueryInterface(context)); + if (pHTTPCon) { + char* type; + //optimize later TODO allow atoms here...! intead of just the header strings + pHTTPCon->GetContentType(&type); + if (type) { + printf("\nReceiving ... %s\n", type); + nsCRT::free(type); + } + } + } + return NS_OK; +} + +NS_IMETHODIMP +TestHTTPEventSink::OnProgress(nsISupports* context, PRUint32 i_Progress, PRUint32 i_ProgressMax) +{ + printf("\n+++ TestHTTPEventSink::OnProgress +++\n"); + return NS_OK; +} + +NS_IMETHODIMP +TestHTTPEventSink::OnRedirect(nsISupports* context, nsIURI* i_NewLocation) +{ + printf("\n+++ TestHTTPEventSink::OnRedirect +++\n"); + return NS_OK; +} + + +class InputTestConsumer : public nsIStreamListener +{ +public: + + InputTestConsumer(); + virtual ~InputTestConsumer(); + + // ISupports interface... + NS_DECL_ISUPPORTS + + // IStreamListener interface... + NS_IMETHOD OnStartRequest(nsIChannel* channel, nsISupports* context); + + NS_IMETHOD OnDataAvailable(nsIChannel* channel, nsISupports* context, + nsIInputStream *aIStream, + PRUint32 aSourceOffset, + PRUint32 aLength); + + NS_IMETHOD OnStopRequest(nsIChannel* channel, nsISupports* context, + nsresult aStatus, + const PRUnichar* aMsg); + +#ifdef CACHE + private: + + nsICacheObject* mCacheFile ; +#endif +}; + + +InputTestConsumer::InputTestConsumer() +{ + NS_INIT_REFCNT(); + +#ifdef CACHE + mCacheFile = nsnull ; +#endif +} + +InputTestConsumer::~InputTestConsumer() +{ +#ifdef CACHE + NS_IF_RELEASE(mCacheFile) ; +#endif +} + + +NS_IMPL_ISUPPORTS(InputTestConsumer,nsCOMTypeInfo::GetIID()); + + +NS_IMETHODIMP +InputTestConsumer::OnStartRequest(nsIChannel* channel, nsISupports* context) +{ +#ifdef CACHE + /* Stuff taken from nsPluginHostImpl.cpp */ + + char * aContentType = nsnull ; + nsIURI* aURL = nsnull ; + nsICacheModule* memCache ; + nsICacheManager* cacheManager ; + + nsresult rv = NS_OK, r1, r2 ; + + rv = channel->GetContentType(&aContentType) ; + if (NS_FAILED(rv)) return rv ; + + rv = channel ->GetURI(&aURL) ; + if (NS_FAILED(rv)) return rv ; + + char * cString; + char * fileName ; + + nsCOMPtr pURL(do_QueryInterface(aURL)) ; + + if (pURL) { + pURL -> GetSpec(&cString) ; + + /* Todo, use PROGID instead */ + rv = nsComponentManager::CreateInstance(kCacheObjectCID, + nsnull, + kICacheObjectIID, + (void**)&mCacheFile) ; + + if (NS_FAILED(rv)) { + return rv ; + } + + r1 = NS_ERROR_FAILURE ; + r1 = mCacheFile->SetAddress(cString) ; + + /* use the actual filname of the net-based file as the cache filename */ + pURL->GetFileName(&fileName) ; + + /* temp hack, name resolution needs to be added */ + if(!fileName) { + fileName=new char[50] ; + strcpy(fileName, "nucache") ; + } + + r2 = mCacheFile ->SetFilename(fileName) ; + delete [] fileName ; + } + + /* todo: use PROGID instead */ + rv = nsServiceManager::GetService(kCacheManagerCID, + kICacheManagerIID, + (nsISupports **)&cacheManager) ; + if (NS_FAILED(rv)) return rv ; + + rv = cacheManager->GetMemModule(&memCache) ; + if (NS_FAILED(rv)) return rv ; + + rv = memCache->AddObject(mCacheFile) ; + +#endif + + URLLoadInfo* info = (URLLoadInfo*)context; + if (info) { + info->mConnectTime = PR_Now() - info->mConnectTime; + } + + if (gVerbose) { + printf("\nStarted loading: %s\n", info ? info->Name() : "UNKNOWN URL"); + } +/* + nsCOMPtr pURI(do_QueryInterface(context)); + char* location = nsnull; + + if (pURI) { + pURI->GetSpec(&location); + } + + printf("\nStarted loading: %s\n", location ? location : "UNKNOWN URL"); + if (location) { + nsCRT::free(location); + } +*/ + return NS_OK; +} + + +NS_IMETHODIMP +InputTestConsumer::OnDataAvailable(nsIChannel* channel, + nsISupports* context, + nsIInputStream *aIStream, + PRUint32 aSourceOffset, + PRUint32 aLength) +{ + char buf[1025]; + PRUint32 amt, amt_wrote; + nsresult rv; + URLLoadInfo* info = (URLLoadInfo*)context; + + do { + rv = aIStream->Read(buf, 1024, &amt); + +#ifdef CACHE + if (nsnull != mCacheFile ) { + mCacheFile->Write((char*)buf, amt, &amt_wrote) ; + } +#endif + + if (rv == NS_BASE_STREAM_EOF) break; + if (NS_FAILED(rv)) return rv; + if (gVerbose) { + buf[amt] = '\0'; + puts(buf); + } + if (info) { + info->mBytesRead += amt; + } + } while (amt); + + return NS_OK; +} + + +NS_IMETHODIMP +InputTestConsumer::OnStopRequest(nsIChannel* channel, + nsISupports* context, + nsresult aStatus, + const PRUnichar* aMsg) +{ + URLLoadInfo* info = (URLLoadInfo*)context; + + if (info) { + double connectTime; + double readTime; + PRUint32 httpStatus, o_amt=0 ; + PRBool bHTTPURL = PR_FALSE ; + char buf[2000] ; + + if (mCacheFile) { + /* + mCacheFile->GetLastModified(&t) ; + printf("\nlast modified: %d\n", t) ; + + mCacheFile->GetEtag(&s) ; + printf("etag: %s\n", s) ; + + mCacheFile->GetContentType(&s) ; + printf("content type: %s\n", s) ; + + mCacheFile->GetCharset(&s) ; + printf("character set: %s\n", s) ; + + mCacheFile->GetContentEncoding(&s) ; + printf("Content encoding: %s\n", s) ; + + mCacheFile->GetContentLength(&l) ; + printf("Content Length: %d\n", l) ; + + mCacheFile->GetExpires(&t) ; + printf("Expires: %d\n", t) ; + + mCacheFile->GetFilename(&s) ; + printf("Filename: %s\n", s) ; + + mCacheFile->GetState(&l) ; + printf("State: %d\n", l) ; + + mCacheFile->GetInfoSize(&l) ; + printf("Info size: %d\n", l) ; + + mCacheFile->IsPartial(&b) ; + printf("Is completed: %s\n", b?"True":"False") ; + + mCacheFile->GetLastAccessed(&t) ; + printf("Last Access time: %d\n", t) ; + + mCacheFile->GetLastModified(&t) ; + printf("Last Modified time: %d\n", t) ; + + mCacheFile->GetModuleIndex(&m) ; + printf("Module: %d\n", m) ; + + mCacheFile->GetPageServicesURL(&s) ; + printf("Page Service URL: %s\n", s) ; + + mCacheFile->GetPostData(&s) ; + printf("Post Data: %s\n", s) ; + + mCacheFile->GetPostDataLen(&l) ; + printf("Post Data Length: %d\n", l) ; + + mCacheFile->GetSize(&l) ; + printf("Size: %d\n", l) ; + + mCacheFile->GetAddress(&s) ; + printf("URL Address: %s \n", s) ; + */ + + mCacheFile->Read (buf, (PRUint32) 2000, &o_amt) ; + buf[o_amt] = '\0' ; + printf("%s\no_amt = %d \n", buf, o_amt) ; + } + + info->mTotalTime = PR_Now() - info->mTotalTime; + + connectTime = (info->mConnectTime/1000.0)/1000.0; + readTime = ((info->mTotalTime-info->mConnectTime)/1000.0)/1000.0; + + nsCOMPtr pHTTPCon(do_QueryInterface(channel)); + if (pHTTPCon) { + pHTTPCon->GetResponseStatus(&httpStatus); + bHTTPURL = PR_TRUE; + } + + printf("\nFinished loading: %s Status Code: %x\n", info->Name(), aStatus); + if (bHTTPURL) + printf("\tHTTP Status: %u\n", httpStatus); + if (NS_ERROR_UNKNOWN_HOST == aStatus) { + printf("\tDNS lookup failed.\n"); + } + printf("\tRead: %d bytes.\n", info->mBytesRead); + printf("\tTime to connect: %.3f seconds\n", connectTime); + printf("\tTime to read: %.3f seconds.\n", readTime); + if (readTime > 0.0) { + printf("\tThroughput: %.0f bps.\n", (info->mBytesRead*8)/readTime); + } else { + printf("\tThroughput: REAL FAST!!\n"); + } + } else { + printf("\nFinished loading: UNKNOWN URL. Status Code: %x\n", aStatus); + } +/* + nsCOMPtr pURI(do_QueryInterface(context)); + char* location = nsnull; + + if (pURI) { + pURI->GetSpec(&location); + } + + printf("\nFinished loading: %s Status Code: %x\n", location ? location : "UNKNOWN URL", aStatus); + + if (location) { + nsCRT::free(location); + } +*/ + gKeepRunning -= 1; + return NS_OK; +} + +//////////////////////////////////////////////////////////////////////////////// + +class nsEventSinkGetter : public nsIEventSinkGetter { +public: + NS_DECL_ISUPPORTS + + nsEventSinkGetter() { + NS_INIT_REFCNT(); + } + + NS_IMETHOD GetEventSink(const char* verb, const nsIID& eventSinkIID, + nsISupports* *result) { + nsresult rv = NS_ERROR_FAILURE; + + if (nsCRT::strcmp(verb, "load") == 0) { // makeshift verb for now + if (eventSinkIID.Equals(nsCOMTypeInfo::GetIID())) { + TestHTTPEventSink *sink; + + sink = new TestHTTPEventSink(); + if (sink == nsnull) + return NS_ERROR_OUT_OF_MEMORY; + NS_ADDREF(sink); + rv = sink->QueryInterface(eventSinkIID, (void**)result); + NS_RELEASE(sink); + } + } + return rv; + } +}; + +NS_IMPL_ISUPPORTS(nsEventSinkGetter, nsCOMTypeInfo::GetIID()); + +//////////////////////////////////////////////////////////////////////////////// + + +nsresult StartLoadingURL(const char* aUrlString) +{ + nsresult rv; + + NS_WITH_SERVICE(nsIIOService, pService, kIOServiceCID, &rv); + if (pService) { + nsCOMPtr pURL; + + rv = pService->NewURI(aUrlString, nsnull, getter_AddRefs(pURL)); + if (NS_FAILED(rv)) { + printf("ERROR: NewURI failed for %s\n", aUrlString); + return rv; + } + nsCOMPtr pChannel; + nsEventSinkGetter* pMySink; + + pMySink = new nsEventSinkGetter(); + NS_IF_ADDREF(pMySink); + if (!pMySink) { + NS_ERROR("Failed to create a new consumer!"); + return NS_ERROR_OUT_OF_MEMORY;; + } + + // Async reading thru the calls of the event sink interface + rv = pService->NewChannelFromURI("load", pURL, nsnull, pMySink, + getter_AddRefs(pChannel)); + if (NS_FAILED(rv)) { + printf("ERROR: NewChannelFromURI failed for %s\n", aUrlString); + return rv; + } + NS_RELEASE(pMySink); + + /* + You may optionally add/set other headers on this + request object. This is done by QI for the specific + protocolConnection. + */ + nsCOMPtr pHTTPCon(do_QueryInterface(pChannel)); + + if (pHTTPCon) { + // Setting a sample user agent string. + nsCOMPtr userAgent; + + userAgent = NS_NewAtom("user-agent"); + rv = pHTTPCon->SetRequestHeader(userAgent, "Mozilla/5.0 [en] (Win98; U)"); + if (NS_FAILED(rv)) return rv; + } + + InputTestConsumer* listener; + + listener = new InputTestConsumer; + NS_IF_ADDREF(listener); + if (!listener) { + NS_ERROR("Failed to create a new stream listener!"); + return NS_ERROR_OUT_OF_MEMORY;; + } + + URLLoadInfo* info; + info = new URLLoadInfo(aUrlString); + NS_IF_ADDREF(info); + if (!info) { + NS_ERROR("Failed to create a load info!"); + return NS_ERROR_OUT_OF_MEMORY;; + } + + + rv = pChannel->AsyncRead(0, // staring position + -1, // number of bytes to read + info, // ISupports context + listener); // IStreamListener consumer + if (NS_SUCCEEDED(rv)) { + gKeepRunning += 1; + } + NS_RELEASE(listener); + NS_RELEASE(info); + } + + return rv; +} + + +nsresult LoadURLsFromFile(char *aFileName) +{ + nsresult rv = NS_OK; + PRInt32 len, offset; + PRFileDesc* fd; + char buffer[1024]; + nsString fileBuffer; + nsAutoString urlString(eOneByte); + + fd = PR_Open(aFileName, PR_RDONLY, 777); + if (!fd) { + return NS_ERROR_FAILURE; + } + + // Keep reading the file until EOF (or an error) is reached... + do { + len = PR_Read(fd, buffer, sizeof(buffer)); + if (len>0) { + fileBuffer.Append(buffer, len); + // Treat each line as a URL... + while ((offset = fileBuffer.FindChar('\n')) != -1) { + fileBuffer.Left(urlString, offset); + fileBuffer.Cut(0, offset+1); + + urlString.StripChars("\r"); + if (urlString.Length()) { + printf("\t%s\n", urlString.GetBuffer()); + rv = StartLoadingURL(urlString.GetBuffer()); + } + } + } + } while (len>0); + + // If anything is left in the fileBuffer, treat it as a URL... + fileBuffer.StripChars("\r"); + if (fileBuffer.Length()) { + printf("\t%s\n", fileBuffer.GetBuffer()); + StartLoadingURL(fileBuffer.GetBuffer()); + } + + PR_Close(fd); + return NS_OK; +} + + +nsresult NS_AutoregisterComponents() +{ + nsresult rv = nsComponentManager::AutoRegister(nsIComponentManager::NS_Startup, NULL /* default */); + return rv; +} + +int +main(int argc, char* argv[]) +{ + nsresult rv= (nsresult)-1; + if (argc < 2) { + printf("usage: %s [-verbose] [-file ] ... \n", argv[0]); + return -1; + } + + /* + The following code only deals with XPCOM registration stuff. and setting + up the event queues. Copied from TestSocketIO.cpp + */ + + rv = NS_AutoregisterComponents(); + if (NS_FAILED(rv)) return rv; + + + // Create the Event Queue for this thread... + NS_WITH_SERVICE(nsIEventQueueService, eventQService, kEventQueueServiceCID, &rv); + if (NS_FAILED(rv)) return rv; + + rv = eventQService->CreateThreadEventQueue(); + if (NS_FAILED(rv)) return rv; + + eventQService->GetThreadEventQueue(PR_CurrentThread(), &gEventQ); + +#if 0 // Jud sez + // fire up an instance of the cookie manager. + // I'm doing this using the serviceManager for convenience's sake. + // Presumably an application will init it's own cookie service a + // different way (this way works too though). + NS_WITH_SERVICE(nsICookieService, cookieService, nsCookieServiceCID, &rv); + if (NS_FAILED(rv)) return rv; +#endif // NECKO + + int i; + printf("\nTrying to load:\n"); + for (i=1; iGetEvent(&gEvent); + rv = gEventQ->HandleEvent(gEvent); +#endif /* XP_UNIX */ +#endif /* !WIN32 */ + } + + return rv; +}