зеркало из https://github.com/mozilla/pjs.git
282 строки
6.7 KiB
C++
282 строки
6.7 KiB
C++
/* -*- 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.
|
|
*/
|
|
|
|
#define NS_IMPL_IDS
|
|
#include "prlock.h"
|
|
#include "nsIFactory.h"
|
|
#include "nsIServiceManager.h"
|
|
#include "nsRepository.h"
|
|
#include "nsIObserverService.h"
|
|
#include "nsObserverService.h"
|
|
#include "nsIObserverList.h"
|
|
#include "nsObserverList.h"
|
|
#include "nsHashtable.h"
|
|
#include "nsString.h"
|
|
|
|
static NS_DEFINE_IID(kIObserverServiceIID, NS_IOBSERVERSERVICE_IID);
|
|
static NS_DEFINE_IID(kObserverServiceCID, NS_OBSERVERSERVICE_CID);
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
class nsObserverService : public nsIObserverService {
|
|
public:
|
|
|
|
static nsresult GetObserverService(nsIObserverService** anObserverService);
|
|
|
|
NS_IMETHOD AddObserver(nsIObserver** anObserver, nsString* aTopic);
|
|
NS_IMETHOD RemoveObserver(nsIObserver** anObserver, nsString* aTopic);
|
|
NS_IMETHOD EnumerateObserverList(nsIEnumerator** anEnumerator, nsString* aTopic);
|
|
|
|
|
|
nsObserverService();
|
|
virtual ~nsObserverService(void);
|
|
|
|
NS_DECL_ISUPPORTS
|
|
|
|
|
|
private:
|
|
|
|
NS_IMETHOD GetObserverList(nsIObserverList** anObserverList, nsString* aTopic);
|
|
|
|
nsHashtable *mObserverTopicTable;
|
|
|
|
};
|
|
|
|
static nsObserverService* gObserverService = nsnull; // The one-and-only ObserverService
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
// nsObserverService Implementation
|
|
|
|
|
|
NS_IMPL_ISUPPORTS(nsObserverService, kIObserverServiceIID);
|
|
|
|
NS_BASE nsresult NS_NewObserverService(nsIObserverService** anObserverService)
|
|
{
|
|
return nsObserverService::GetObserverService(anObserverService);
|
|
}
|
|
|
|
nsObserverService::nsObserverService()
|
|
: mObserverTopicTable(NULL)
|
|
{
|
|
NS_INIT_REFCNT();
|
|
mObserverTopicTable = nsnull;
|
|
}
|
|
|
|
nsObserverService::~nsObserverService(void)
|
|
{
|
|
if(mObserverTopicTable)
|
|
delete mObserverTopicTable;
|
|
gObserverService = nsnull;
|
|
}
|
|
|
|
|
|
nsresult nsObserverService::GetObserverService(nsIObserverService** anObserverService)
|
|
{
|
|
if (! gObserverService) {
|
|
nsObserverService* it = new nsObserverService();
|
|
if (! it)
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
gObserverService = it;
|
|
}
|
|
|
|
NS_ADDREF(gObserverService);
|
|
*anObserverService = gObserverService;
|
|
return NS_OK;
|
|
}
|
|
|
|
nsresult nsObserverService::GetObserverList(nsIObserverList** anObserverList, nsString* aTopic)
|
|
{
|
|
if (anObserverList == NULL)
|
|
{
|
|
return NS_ERROR_NULL_POINTER;
|
|
}
|
|
|
|
if(mObserverTopicTable == NULL) {
|
|
mObserverTopicTable = new nsHashtable(256, PR_TRUE);
|
|
if (mObserverTopicTable == NULL)
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
}
|
|
|
|
|
|
// Safely convert to a C-string
|
|
char buf[128];
|
|
char* topic = buf;
|
|
|
|
if ((*aTopic).Length() >= sizeof(buf))
|
|
topic = new char[(*aTopic).Length() + 1];
|
|
|
|
if (topic == nsnull)
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
(*aTopic).ToCString(topic, (*aTopic).Length() + 1);
|
|
|
|
nsCStringKey key(topic);
|
|
|
|
nsIObserverList *topicObservers = nsnull;
|
|
if(mObserverTopicTable->Exists(&key)) {
|
|
topicObservers = (nsIObserverList *) mObserverTopicTable->Get(&key);
|
|
if (topicObservers != NULL) {
|
|
*anObserverList = topicObservers;
|
|
} else {
|
|
NS_NewObserverList(&topicObservers);
|
|
mObserverTopicTable->Put(&key, topicObservers);
|
|
}
|
|
} else {
|
|
NS_NewObserverList(&topicObservers);
|
|
*anObserverList = topicObservers;
|
|
mObserverTopicTable->Put(&key, topicObservers);
|
|
|
|
}
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
nsresult nsObserverService::AddObserver(nsIObserver** anObserver, nsString* aTopic)
|
|
{
|
|
nsIObserverList* anObserverList;
|
|
nsresult rv;
|
|
|
|
if (anObserver == NULL)
|
|
{
|
|
return NS_ERROR_NULL_POINTER;
|
|
}
|
|
|
|
if (aTopic == NULL)
|
|
{
|
|
return NS_ERROR_NULL_POINTER;
|
|
}
|
|
|
|
rv = GetObserverList(&anObserverList, aTopic);
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
if (anObserverList) {
|
|
return anObserverList->AddObserver(anObserver);
|
|
}
|
|
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
nsresult nsObserverService::RemoveObserver(nsIObserver** anObserver, nsString* aTopic)
|
|
{
|
|
nsIObserverList* anObserverList;
|
|
nsresult rv;
|
|
|
|
if (anObserver == NULL)
|
|
{
|
|
return NS_ERROR_NULL_POINTER;
|
|
}
|
|
|
|
if (aTopic == NULL)
|
|
{
|
|
return NS_ERROR_NULL_POINTER;
|
|
}
|
|
|
|
rv = GetObserverList(&anObserverList, aTopic);
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
if (anObserverList) {
|
|
return anObserverList->RemoveObserver(anObserver);
|
|
}
|
|
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
nsresult nsObserverService::EnumerateObserverList(nsIEnumerator** anEnumerator, nsString* aTopic)
|
|
{
|
|
nsIObserverList* anObserverList;
|
|
nsresult rv;
|
|
|
|
if (anEnumerator == NULL)
|
|
{
|
|
return NS_ERROR_NULL_POINTER;
|
|
}
|
|
|
|
if (aTopic == NULL)
|
|
{
|
|
return NS_ERROR_NULL_POINTER;
|
|
}
|
|
|
|
rv = GetObserverList(&anObserverList, aTopic);
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
if (anObserverList) {
|
|
return anObserverList->EnumerateObserverList(anEnumerator);
|
|
}
|
|
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
// nsObserverServiceFactory Implementation
|
|
|
|
static NS_DEFINE_IID(kIFactoryIID, NS_IFACTORY_IID);
|
|
NS_IMPL_ISUPPORTS(nsObserverServiceFactory, kIFactoryIID);
|
|
|
|
nsObserverServiceFactory::nsObserverServiceFactory(void)
|
|
{
|
|
NS_INIT_REFCNT();
|
|
}
|
|
|
|
nsObserverServiceFactory::~nsObserverServiceFactory(void)
|
|
{
|
|
|
|
}
|
|
|
|
nsresult
|
|
nsObserverServiceFactory::CreateInstance(nsISupports *aOuter, REFNSIID aIID, void **aResult)
|
|
{
|
|
if (! aResult)
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
if (aOuter)
|
|
return NS_ERROR_NO_AGGREGATION;
|
|
|
|
*aResult = nsnull;
|
|
|
|
nsresult rv;
|
|
nsIObserverService* inst = nsnull;
|
|
|
|
|
|
if (NS_FAILED(rv = NS_NewObserverService(&inst)))
|
|
return rv;
|
|
|
|
|
|
if (!inst)
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
rv = inst->QueryInterface(aIID, aResult);
|
|
|
|
if (NS_FAILED(rv)) {
|
|
*aResult = NULL;
|
|
}
|
|
return rv;
|
|
}
|
|
|
|
nsresult
|
|
nsObserverServiceFactory::LockFactory(PRBool aLock)
|
|
{
|
|
return NS_OK;
|
|
}
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|