fix bug 10434, memory leak detection, r=kin

This commit is contained in:
morse%netscape.com 1999-10-14 13:50:36 +00:00
Родитель b7a202c59b
Коммит 6a3cdf94cc
6 изменённых файлов: 691 добавлений и 361 удалений

Просмотреть файл

@ -231,6 +231,18 @@ nsTextServicesDocument::QueryInterface(REFNSIID aIID, void** aInstancePtr)
return NS_NOINTERFACE;
}
nsresult
NS_NewTextServicesDocument(nsTextServicesDocument** result)
{
nsTextServicesDocument* textServicesDocument = new nsTextServicesDocument();
if (! textServicesDocument) {
return NS_ERROR_NULL_POINTER;
}
*result = textServicesDocument;
NS_ADDREF(*result);
return NS_OK;
}
NS_IMETHODIMP
nsTextServicesDocument::InitWithDocument(nsIDOMDocument *aDOMDocument, nsIPresShell *aPresShell)
{

Просмотреть файл

@ -1,4 +1,4 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
/* -*- 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
@ -16,162 +16,260 @@
* Reserved.
*/
#include "nscore.h"
#include "nsIFactory.h"
#include "nsISupports.h"
#include "nsIComponentManager.h"
#include "nsIServiceManager.h"
#include "nsTextServicesCID.h"
#include "nsCOMPtr.h"
#include "nsTextServicesDocument.h"
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
static NS_DEFINE_IID(kIFactoryIID, NS_IFACTORY_IID);
static NS_DEFINE_CID(kComponentManagerCID, NS_COMPONENTMANAGER_CID);
#include "nsTextServicesCID.h"
#include "nsIModule.h"
#include "nsIGenericFactory.h"
static NS_DEFINE_CID(kCTextServicesDocumentCID, NS_TEXTSERVICESDOCUMENT_CID);
class nsTextServicesDocumentFactory : public nsIFactory
nsresult
NS_NewTextServicesDocument(nsTextServicesDocument** result);
// Module implementation
class nsTextServicesModule : public nsIModule
{
public:
nsTextServicesModule();
virtual ~nsTextServicesModule();
nsTextServicesDocumentFactory();
virtual ~nsTextServicesDocumentFactory();
// nsISupports methods
NS_DECL_ISUPPORTS
// nsIFactory methods
NS_IMETHOD CreateInstance(nsISupports *aOuter,
REFNSIID aIID,
void **aResult);
NS_DECL_NSIMODULE
NS_IMETHOD LockFactory(PRBool aLock);
protected:
nsresult Initialize();
void Shutdown();
PRBool mInitialized;
nsCOMPtr<nsIGenericFactory> mFactory;
};
nsTextServicesDocumentFactory::nsTextServicesDocumentFactory()
//----------------------------------------------------------------------
// Functions used to create new instances of a given object by the
// generic factory.
static NS_IMETHODIMP
CreateNewTextServices(nsISupports* aOuter, REFNSIID aIID, void **aResult)
{
mRefCnt = 0;
if (!aResult) {
return NS_ERROR_INVALID_POINTER;
}
if (aOuter) {
*aResult = nsnull;
return NS_ERROR_NO_AGGREGATION;
}
nsTextServicesDocument* inst;
nsresult rv = NS_NewTextServicesDocument(&inst);
if (NS_FAILED(rv)) {
*aResult = nsnull;
return rv;
}
rv = inst->QueryInterface(aIID, aResult);
if (NS_FAILED(rv)) {
*aResult = nsnull;
}
NS_RELEASE(inst); /* get rid of extra refcnt */
return rv;
}
nsTextServicesDocumentFactory::~nsTextServicesDocumentFactory()
//----------------------------------------------------------------------
nsTextServicesModule::nsTextServicesModule()
: mInitialized(PR_FALSE)
{
NS_INIT_ISUPPORTS();
}
NS_IMPL_ADDREF(nsTextServicesDocumentFactory)
NS_IMPL_RELEASE(nsTextServicesDocumentFactory)
nsresult nsTextServicesDocumentFactory::QueryInterface(REFNSIID aIID,
void **aInstancePtr)
nsTextServicesModule::~nsTextServicesModule()
{
if (nsnull == aInstancePtr)
return NS_ERROR_NULL_POINTER;
*aInstancePtr = 0;
if (aIID.Equals(kISupportsIID)) {
*aInstancePtr = (void *)(nsISupports*)this;
} else if (aIID.Equals(kIFactoryIID)) {
*aInstancePtr = (void *)(nsIFactory*)this;
Shutdown();
}
if (nsnull == *aInstancePtr)
return NS_NOINTERFACE;
NS_ADDREF_THIS();
NS_IMPL_ISUPPORTS(nsTextServicesModule, NS_GET_IID(nsIModule))
// Perform our one-time intialization for this module
nsresult
nsTextServicesModule::Initialize()
{
if (mInitialized) {
return NS_OK;
}
mInitialized = PR_TRUE;
return NS_OK;
}
nsresult nsTextServicesDocumentFactory::CreateInstance(nsISupports *aOuter,
REFNSIID aIID,
void **aResult)
// Shutdown this module, releasing all of the module resources
void
nsTextServicesModule::Shutdown()
{
if (!aResult)
return NS_ERROR_NULL_POINTER;
*aResult = 0;
nsISupports *inst = new nsTextServicesDocument();
if (inst == NULL) {
return NS_ERROR_OUT_OF_MEMORY;
// Release the factory object
mFactory = nsnull;
}
nsresult result = inst->QueryInterface(aIID, aResult);
if (NS_FAILED(result)) {
// We didn't get the right interface, so clean up
delete inst;
}
return result;
}
nsresult nsTextServicesDocumentFactory::LockFactory(PRBool aLock)
{
// XXX: Not implemented yet.
return NS_OK;
}
// return the proper factory to the caller
extern "C" NS_EXPORT nsresult NSGetFactory(nsISupports* serviceMgr,
// Create a factory object for creating instances of aClass.
NS_IMETHODIMP
nsTextServicesModule::GetClassObject(nsIComponentManager *aCompMgr,
const nsCID& aClass,
const char *aClassName,
const char *aProgID,
nsIFactory **aFactory)
const nsIID& aIID,
void** r_classObj)
{
if (!aFactory)
return NS_ERROR_NULL_POINTER;
nsresult rv;
if (!aClass.Equals(kCTextServicesDocumentCID))
return NS_NOINTERFACE;
// Defensive programming: Initialize *r_classObj in case of error below
if (!r_classObj) {
return NS_ERROR_INVALID_POINTER;
}
*r_classObj = NULL;
*aFactory = new nsTextServicesDocumentFactory();
// Do one-time-only initialization if necessary
if (!mInitialized) {
rv = Initialize();
if (NS_FAILED(rv)) {
// Initialization failed! yikes!
return rv;
}
}
if (! *aFactory)
// Choose the appropriate factory, based on the desired instance
// class type (aClass).
nsCOMPtr<nsIGenericFactory> fact;
if (aClass.Equals(kCTextServicesDocumentCID)) {
if (!mFactory) {
// Create and save away the factory object for creating
// new instances of TextServices. This way if we are called
// again for the factory, we won't need to create a new
// one.
rv = NS_NewGenericFactory(getter_AddRefs(mFactory),
CreateNewTextServices);
}
fact = mFactory;
}
else {
rv = NS_ERROR_FACTORY_NOT_REGISTERED;
#ifdef DEBUG
char* cs = aClass.ToString();
printf("+++ nsTextServicesModule: unable to create factory for %s\n", cs);
nsCRT::free(cs);
#endif
}
if (fact) {
rv = fact->QueryInterface(aIID, r_classObj);
}
return rv;
}
//----------------------------------------
struct Components {
const char* mDescription;
const nsID* mCID;
const char* mProgID;
};
// The list of components we register
static Components gComponents[] = {
{ NULL, &kCTextServicesDocumentCID,
NULL, },
};
#define NUM_COMPONENTS (sizeof(gComponents) / sizeof(gComponents[0]))
NS_IMETHODIMP
nsTextServicesModule::RegisterSelf(nsIComponentManager *aCompMgr,
nsIFileSpec* aPath,
const char* registryLocation,
const char* componentType)
{
nsresult rv = NS_OK;
#ifdef DEBUG
printf("*** Registering TextServices components\n");
#endif
Components* cp = gComponents;
Components* end = cp + NUM_COMPONENTS;
while (cp < end) {
rv = aCompMgr->RegisterComponentSpec(*cp->mCID, cp->mDescription,
cp->mProgID, aPath, PR_TRUE,
PR_TRUE);
if (NS_FAILED(rv)) {
#ifdef DEBUG
printf("nsTextServicesModule: unable to register %s component => %x\n",
cp->mDescription, rv);
#endif
break;
}
cp++;
}
return rv;
}
NS_IMETHODIMP
nsTextServicesModule::UnregisterSelf(nsIComponentManager* aCompMgr,
nsIFileSpec* aPath,
const char* registryLocation)
{
#ifdef DEBUG
printf("*** Unregistering TextServices components\n");
#endif
Components* cp = gComponents;
Components* end = cp + NUM_COMPONENTS;
while (cp < end) {
nsresult rv = aCompMgr->UnregisterComponentSpec(*cp->mCID, aPath);
if (NS_FAILED(rv)) {
#ifdef DEBUG
printf("nsTextServicesModule: unable to unregister %s component => %x\n",
cp->mDescription, rv);
#endif
}
cp++;
}
return NS_OK;
}
NS_IMETHODIMP
nsTextServicesModule::CanUnload(nsIComponentManager *aCompMgr, PRBool *okToUnload)
{
if (!okToUnload) {
return NS_ERROR_INVALID_POINTER;
}
*okToUnload = PR_FALSE;
return NS_ERROR_FAILURE;
}
//----------------------------------------------------------------------
static nsTextServicesModule *gModule = NULL;
extern "C" NS_EXPORT nsresult NSGetModule(nsIComponentManager *servMgr,
nsIFileSpec* location,
nsIModule** return_cobj)
{
nsresult rv = NS_OK;
NS_ENSURE_ARG_POINTER(return_cobj);
NS_ENSURE_NOT(gModule, NS_ERROR_FAILURE);
// Create and initialize the module instance
nsTextServicesModule *m = new nsTextServicesModule();
if (!m) {
return NS_ERROR_OUT_OF_MEMORY;
return (*aFactory)->QueryInterface(kIFactoryIID, (void**)aFactory);
}
extern "C" NS_EXPORT nsresult NSRegisterSelf(nsISupports* aServMgr, const char *path)
{
nsresult rv;
nsCOMPtr<nsIServiceManager> servMgr(do_QueryInterface(aServMgr, &rv));
if (NS_FAILED(rv)) return rv;
nsIComponentManager* compMgr;
rv = servMgr->GetService(kComponentManagerCID,
nsIComponentManager::GetIID(),
(nsISupports**)&compMgr);
if (NS_FAILED(rv)) return rv;
rv = compMgr->RegisterComponent(kCTextServicesDocumentCID,
NULL, NULL, path,
PR_TRUE, PR_TRUE);
(void)servMgr->ReleaseService(kComponentManagerCID, compMgr);
// Increase refcnt and store away nsIModule interface to m in return_cobj
rv = m->QueryInterface(NS_GET_IID(nsIModule), (void**)return_cobj);
if (NS_FAILED(rv)) {
delete m;
m = nsnull;
}
gModule = m; // WARNING: Weak Reference
return rv;
}
extern "C" NS_EXPORT nsresult NSUnregisterSelf(nsISupports* aServMgr, const char *path)
{
nsresult rv;
nsCOMPtr<nsIServiceManager> servMgr(do_QueryInterface(aServMgr, &rv));
if (NS_FAILED(rv)) return rv;
nsIComponentManager* compMgr;
rv = servMgr->GetService(kComponentManagerCID,
nsIComponentManager::GetIID(),
(nsISupports**)&compMgr);
if (NS_FAILED(rv)) return rv;
rv = compMgr->UnregisterComponent(kCTextServicesDocumentCID, path);
(void)servMgr->ReleaseService(kComponentManagerCID, compMgr);
return rv;
}

Просмотреть файл

@ -109,6 +109,18 @@ nsTransactionManager::QueryInterface(REFNSIID aIID, void** aInstancePtr)
return NS_NOINTERFACE;
}
nsresult
NS_NewTransactionManager(nsITransactionManager** result)
{
nsTransactionManager* transactionManager = new nsTransactionManager();
if (! transactionManager) {
return NS_ERROR_NULL_POINTER;
}
*result = transactionManager;
NS_ADDREF(*result);
return NS_OK;
}
NS_IMETHODIMP
nsTransactionManager::Do(nsITransaction *aTransaction)
{

Просмотреть файл

@ -1,4 +1,4 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
/* -*- 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
@ -16,166 +16,264 @@
* Reserved.
*/
#include "nscore.h"
#include "nsIFactory.h"
#include "nsISupports.h"
#include "nsIComponentManager.h"
#include "nsIServiceManager.h"
#include "nsTransactionManagerCID.h"
#include "nsITransactionManager.h"
#include "nsTransactionItem.h"
#include "nsTransactionStack.h"
#include "nsTransactionManager.h"
#include "nsCOMPtr.h"
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
static NS_DEFINE_IID(kIFactoryIID, NS_IFACTORY_IID);
static NS_DEFINE_CID(kCTransactionManagerCID, NS_TRANSACTIONMANAGER_CID);
static NS_DEFINE_CID(kComponentManagerCID, NS_COMPONENTMANAGER_CID);
class nsTransactionManagerFactory : public nsIFactory
#include "nsTransactionManagerCID.h"
#include "nsITransactionManager.h"
#include "nsTransactionStack.h"
#include "nsIModule.h"
#include "nsIGenericFactory.h"
static NS_DEFINE_CID(kCTransactionManagerCID, NS_TRANSACTIONMANAGER_CID);
nsresult
NS_NewTransactionManager(nsITransactionManager** result);
// Module implementation
class nsTransactionManagerModule : public nsIModule
{
public:
nsTransactionManagerModule();
virtual ~nsTransactionManagerModule();
nsTransactionManagerFactory();
virtual ~nsTransactionManagerFactory();
// nsISupports methods
NS_DECL_ISUPPORTS
// nsIFactory methods
NS_IMETHOD CreateInstance(nsISupports *aOuter,
REFNSIID aIID,
void **aResult);
NS_DECL_NSIMODULE
NS_IMETHOD LockFactory(PRBool aLock);
protected:
nsresult Initialize();
void Shutdown();
PRBool mInitialized;
nsCOMPtr<nsIGenericFactory> mFactory;
};
nsTransactionManagerFactory::nsTransactionManagerFactory()
//----------------------------------------------------------------------
// Functions used to create new instances of a given object by the
// generic factory.
static NS_IMETHODIMP
CreateNewTransactionManager(nsISupports* aOuter, REFNSIID aIID, void **aResult)
{
mRefCnt = 0;
if (!aResult) {
return NS_ERROR_INVALID_POINTER;
}
if (aOuter) {
*aResult = nsnull;
return NS_ERROR_NO_AGGREGATION;
}
nsITransactionManager* inst;
nsresult rv = NS_NewTransactionManager(&inst);
if (NS_FAILED(rv)) {
*aResult = nsnull;
return rv;
}
rv = inst->QueryInterface(aIID, aResult);
if (NS_FAILED(rv)) {
*aResult = nsnull;
}
NS_RELEASE(inst); /* get rid of extra refcnt */
return rv;
}
nsTransactionManagerFactory::~nsTransactionManagerFactory()
//----------------------------------------------------------------------
nsTransactionManagerModule::nsTransactionManagerModule()
: mInitialized(PR_FALSE)
{
NS_INIT_ISUPPORTS();
}
NS_IMPL_ADDREF(nsTransactionManagerFactory)
NS_IMPL_RELEASE(nsTransactionManagerFactory)
nsresult nsTransactionManagerFactory::QueryInterface(REFNSIID aIID,
void **aInstancePtr)
nsTransactionManagerModule::~nsTransactionManagerModule()
{
if (nsnull == aInstancePtr)
return NS_ERROR_NULL_POINTER;
*aInstancePtr = 0;
if (aIID.Equals(kISupportsIID)) {
*aInstancePtr = (void *)(nsISupports*)this;
} else if (aIID.Equals(kIFactoryIID)) {
*aInstancePtr = (void *)(nsIFactory*)this;
Shutdown();
}
if (nsnull == *aInstancePtr)
return NS_NOINTERFACE;
NS_ADDREF_THIS();
NS_IMPL_ISUPPORTS(nsTransactionManagerModule, NS_GET_IID(nsIModule))
// Perform our one-time intialization for this module
nsresult
nsTransactionManagerModule::Initialize()
{
if (mInitialized) {
return NS_OK;
}
mInitialized = PR_TRUE;
return NS_OK;
}
nsresult nsTransactionManagerFactory::CreateInstance(nsISupports *aOuter,
REFNSIID aIID,
void **aResult)
// Shutdown this module, releasing all of the module resources
void
nsTransactionManagerModule::Shutdown()
{
if (!aResult)
return NS_ERROR_NULL_POINTER;
*aResult = 0;
nsISupports *inst = new nsTransactionManager();
if (inst == NULL) {
return NS_ERROR_OUT_OF_MEMORY;
// Release the factory object
mFactory = nsnull;
}
nsresult result = inst->QueryInterface(aIID, aResult);
if (NS_FAILED(result)) {
// We didn't get the right interface, so clean up
delete inst;
}
return result;
}
nsresult nsTransactionManagerFactory::LockFactory(PRBool aLock)
{
// XXX: Not implemented yet.
return NS_OK;
}
// return the proper factory to the caller
extern "C" NS_EXPORT nsresult NSGetFactory(nsISupports* aServMgr,
// Create a factory object for creating instances of aClass.
NS_IMETHODIMP
nsTransactionManagerModule::GetClassObject(nsIComponentManager *aCompMgr,
const nsCID& aClass,
const char *aClassName,
const char *aProgID,
nsIFactory **aFactory)
const nsIID& aIID,
void** r_classObj)
{
if (!aFactory)
return NS_ERROR_NULL_POINTER;
nsresult rv;
// XXX: Should check to make sure aClass is correct type?
// Defensive programming: Initialize *r_classObj in case of error below
if (!r_classObj) {
return NS_ERROR_INVALID_POINTER;
}
*r_classObj = NULL;
*aFactory = new nsTransactionManagerFactory();
// Do one-time-only initialization if necessary
if (!mInitialized) {
rv = Initialize();
if (NS_FAILED(rv)) {
// Initialization failed! yikes!
return rv;
}
}
if (!aFactory)
// Choose the appropriate factory, based on the desired instance
// class type (aClass).
nsCOMPtr<nsIGenericFactory> fact;
if (aClass.Equals(kCTransactionManagerCID)) {
if (!mFactory) {
// Create and save away the factory object for creating
// new instances of TransactionManager. This way if we are called
// again for the factory, we won't need to create a new
// one.
rv = NS_NewGenericFactory(getter_AddRefs(mFactory),
CreateNewTransactionManager);
}
fact = mFactory;
}
else {
rv = NS_ERROR_FACTORY_NOT_REGISTERED;
#ifdef DEBUG
char* cs = aClass.ToString();
printf("+++ nsTransactionManagerModule: unable to create factory for %s\n", cs);
nsCRT::free(cs);
#endif
}
if (fact) {
rv = fact->QueryInterface(aIID, r_classObj);
}
return rv;
}
//----------------------------------------
struct Components {
const char* mDescription;
const nsID* mCID;
const char* mProgID;
};
// The list of components we register
static Components gComponents[] = {
{ NULL, &kCTransactionManagerCID,
NULL, },
};
#define NUM_COMPONENTS (sizeof(gComponents) / sizeof(gComponents[0]))
NS_IMETHODIMP
nsTransactionManagerModule::RegisterSelf(nsIComponentManager *aCompMgr,
nsIFileSpec* aPath,
const char* registryLocation,
const char* componentType)
{
nsresult rv = NS_OK;
#ifdef DEBUG
printf("*** Registering TransactionManager components\n");
#endif
Components* cp = gComponents;
Components* end = cp + NUM_COMPONENTS;
while (cp < end) {
rv = aCompMgr->RegisterComponentSpec(*cp->mCID, cp->mDescription,
cp->mProgID, aPath, PR_TRUE,
PR_TRUE);
if (NS_FAILED(rv)) {
#ifdef DEBUG
printf("nsTransactionManagerModule: unable to register %s component => %x\n",
cp->mDescription, rv);
#endif
break;
}
cp++;
}
return rv;
}
NS_IMETHODIMP
nsTransactionManagerModule::UnregisterSelf(nsIComponentManager* aCompMgr,
nsIFileSpec* aPath,
const char* registryLocation)
{
#ifdef DEBUG
printf("*** Unregistering TransactionManager components\n");
#endif
Components* cp = gComponents;
Components* end = cp + NUM_COMPONENTS;
while (cp < end) {
nsresult rv = aCompMgr->UnregisterComponentSpec(*cp->mCID, aPath);
if (NS_FAILED(rv)) {
#ifdef DEBUG
printf("nsTransactionManagerModule: unable to unregister %s component => %x\n",
cp->mDescription, rv);
#endif
}
cp++;
}
return NS_OK;
}
NS_IMETHODIMP
nsTransactionManagerModule::CanUnload(nsIComponentManager *aCompMgr, PRBool *okToUnload)
{
if (!okToUnload) {
return NS_ERROR_INVALID_POINTER;
}
*okToUnload = PR_FALSE;
return NS_ERROR_FAILURE;
}
//----------------------------------------------------------------------
static nsTransactionManagerModule *gModule = NULL;
extern "C" NS_EXPORT nsresult NSGetModule(nsIComponentManager *servMgr,
nsIFileSpec* location,
nsIModule** return_cobj)
{
nsresult rv = NS_OK;
NS_ENSURE_ARG_POINTER(return_cobj);
NS_ENSURE_NOT(gModule, NS_ERROR_FAILURE);
// Create and initialize the module instance
nsTransactionManagerModule *m = new nsTransactionManagerModule();
if (!m) {
return NS_ERROR_OUT_OF_MEMORY;
return (*aFactory)->QueryInterface(kIFactoryIID, (void**)aFactory);
}
extern "C" NS_EXPORT nsresult NSRegisterSelf(nsISupports* aServMgr, const char *path)
{
nsresult rv;
nsCOMPtr<nsIServiceManager> servMgr(do_QueryInterface(aServMgr, &rv));
if (NS_FAILED(rv)) return rv;
nsIComponentManager* compMgr;
rv = servMgr->GetService(kComponentManagerCID,
nsIComponentManager::GetIID(),
(nsISupports**)&compMgr);
if (NS_FAILED(rv)) return rv;
rv = compMgr->RegisterComponent(kCTransactionManagerCID,
NULL, NULL, path,
PR_TRUE, PR_TRUE);
(void)servMgr->ReleaseService(kComponentManagerCID, compMgr);
// Increase refcnt and store away nsIModule interface to m in return_cobj
rv = m->QueryInterface(NS_GET_IID(nsIModule), (void**)return_cobj);
if (NS_FAILED(rv)) {
delete m;
m = nsnull;
}
gModule = m; // WARNING: Weak Reference
return rv;
}
extern "C" NS_EXPORT nsresult NSUnregisterSelf(nsISupports* aServMgr, const char *path)
{
nsresult rv;
nsCOMPtr<nsIServiceManager> servMgr(do_QueryInterface(aServMgr, &rv));
if (NS_FAILED(rv)) return rv;
nsIComponentManager* compMgr;
rv = servMgr->GetService(kComponentManagerCID,
nsIComponentManager::GetIID(),
(nsISupports**)&compMgr);
if (NS_FAILED(rv)) return rv;
rv = compMgr->UnregisterComponent(kCTransactionManagerCID, path);
(void)servMgr->ReleaseService(kComponentManagerCID, compMgr);
return rv;
}

Просмотреть файл

@ -231,6 +231,18 @@ nsTextServicesDocument::QueryInterface(REFNSIID aIID, void** aInstancePtr)
return NS_NOINTERFACE;
}
nsresult
NS_NewTextServicesDocument(nsTextServicesDocument** result)
{
nsTextServicesDocument* textServicesDocument = new nsTextServicesDocument();
if (! textServicesDocument) {
return NS_ERROR_NULL_POINTER;
}
*result = textServicesDocument;
NS_ADDREF(*result);
return NS_OK;
}
NS_IMETHODIMP
nsTextServicesDocument::InitWithDocument(nsIDOMDocument *aDOMDocument, nsIPresShell *aPresShell)
{

Просмотреть файл

@ -1,4 +1,4 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
/* -*- 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
@ -16,162 +16,260 @@
* Reserved.
*/
#include "nscore.h"
#include "nsIFactory.h"
#include "nsISupports.h"
#include "nsIComponentManager.h"
#include "nsIServiceManager.h"
#include "nsTextServicesCID.h"
#include "nsCOMPtr.h"
#include "nsTextServicesDocument.h"
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
static NS_DEFINE_IID(kIFactoryIID, NS_IFACTORY_IID);
static NS_DEFINE_CID(kComponentManagerCID, NS_COMPONENTMANAGER_CID);
#include "nsTextServicesCID.h"
#include "nsIModule.h"
#include "nsIGenericFactory.h"
static NS_DEFINE_CID(kCTextServicesDocumentCID, NS_TEXTSERVICESDOCUMENT_CID);
class nsTextServicesDocumentFactory : public nsIFactory
nsresult
NS_NewTextServicesDocument(nsTextServicesDocument** result);
// Module implementation
class nsTextServicesModule : public nsIModule
{
public:
nsTextServicesModule();
virtual ~nsTextServicesModule();
nsTextServicesDocumentFactory();
virtual ~nsTextServicesDocumentFactory();
// nsISupports methods
NS_DECL_ISUPPORTS
// nsIFactory methods
NS_IMETHOD CreateInstance(nsISupports *aOuter,
REFNSIID aIID,
void **aResult);
NS_DECL_NSIMODULE
NS_IMETHOD LockFactory(PRBool aLock);
protected:
nsresult Initialize();
void Shutdown();
PRBool mInitialized;
nsCOMPtr<nsIGenericFactory> mFactory;
};
nsTextServicesDocumentFactory::nsTextServicesDocumentFactory()
//----------------------------------------------------------------------
// Functions used to create new instances of a given object by the
// generic factory.
static NS_IMETHODIMP
CreateNewTextServices(nsISupports* aOuter, REFNSIID aIID, void **aResult)
{
mRefCnt = 0;
if (!aResult) {
return NS_ERROR_INVALID_POINTER;
}
if (aOuter) {
*aResult = nsnull;
return NS_ERROR_NO_AGGREGATION;
}
nsTextServicesDocument* inst;
nsresult rv = NS_NewTextServicesDocument(&inst);
if (NS_FAILED(rv)) {
*aResult = nsnull;
return rv;
}
rv = inst->QueryInterface(aIID, aResult);
if (NS_FAILED(rv)) {
*aResult = nsnull;
}
NS_RELEASE(inst); /* get rid of extra refcnt */
return rv;
}
nsTextServicesDocumentFactory::~nsTextServicesDocumentFactory()
//----------------------------------------------------------------------
nsTextServicesModule::nsTextServicesModule()
: mInitialized(PR_FALSE)
{
NS_INIT_ISUPPORTS();
}
NS_IMPL_ADDREF(nsTextServicesDocumentFactory)
NS_IMPL_RELEASE(nsTextServicesDocumentFactory)
nsresult nsTextServicesDocumentFactory::QueryInterface(REFNSIID aIID,
void **aInstancePtr)
nsTextServicesModule::~nsTextServicesModule()
{
if (nsnull == aInstancePtr)
return NS_ERROR_NULL_POINTER;
*aInstancePtr = 0;
if (aIID.Equals(kISupportsIID)) {
*aInstancePtr = (void *)(nsISupports*)this;
} else if (aIID.Equals(kIFactoryIID)) {
*aInstancePtr = (void *)(nsIFactory*)this;
Shutdown();
}
if (nsnull == *aInstancePtr)
return NS_NOINTERFACE;
NS_ADDREF_THIS();
NS_IMPL_ISUPPORTS(nsTextServicesModule, NS_GET_IID(nsIModule))
// Perform our one-time intialization for this module
nsresult
nsTextServicesModule::Initialize()
{
if (mInitialized) {
return NS_OK;
}
mInitialized = PR_TRUE;
return NS_OK;
}
nsresult nsTextServicesDocumentFactory::CreateInstance(nsISupports *aOuter,
REFNSIID aIID,
void **aResult)
// Shutdown this module, releasing all of the module resources
void
nsTextServicesModule::Shutdown()
{
if (!aResult)
return NS_ERROR_NULL_POINTER;
*aResult = 0;
nsISupports *inst = new nsTextServicesDocument();
if (inst == NULL) {
return NS_ERROR_OUT_OF_MEMORY;
// Release the factory object
mFactory = nsnull;
}
nsresult result = inst->QueryInterface(aIID, aResult);
if (NS_FAILED(result)) {
// We didn't get the right interface, so clean up
delete inst;
}
return result;
}
nsresult nsTextServicesDocumentFactory::LockFactory(PRBool aLock)
{
// XXX: Not implemented yet.
return NS_OK;
}
// return the proper factory to the caller
extern "C" NS_EXPORT nsresult NSGetFactory(nsISupports* serviceMgr,
// Create a factory object for creating instances of aClass.
NS_IMETHODIMP
nsTextServicesModule::GetClassObject(nsIComponentManager *aCompMgr,
const nsCID& aClass,
const char *aClassName,
const char *aProgID,
nsIFactory **aFactory)
const nsIID& aIID,
void** r_classObj)
{
if (!aFactory)
return NS_ERROR_NULL_POINTER;
nsresult rv;
if (!aClass.Equals(kCTextServicesDocumentCID))
return NS_NOINTERFACE;
// Defensive programming: Initialize *r_classObj in case of error below
if (!r_classObj) {
return NS_ERROR_INVALID_POINTER;
}
*r_classObj = NULL;
*aFactory = new nsTextServicesDocumentFactory();
// Do one-time-only initialization if necessary
if (!mInitialized) {
rv = Initialize();
if (NS_FAILED(rv)) {
// Initialization failed! yikes!
return rv;
}
}
if (! *aFactory)
// Choose the appropriate factory, based on the desired instance
// class type (aClass).
nsCOMPtr<nsIGenericFactory> fact;
if (aClass.Equals(kCTextServicesDocumentCID)) {
if (!mFactory) {
// Create and save away the factory object for creating
// new instances of TextServices. This way if we are called
// again for the factory, we won't need to create a new
// one.
rv = NS_NewGenericFactory(getter_AddRefs(mFactory),
CreateNewTextServices);
}
fact = mFactory;
}
else {
rv = NS_ERROR_FACTORY_NOT_REGISTERED;
#ifdef DEBUG
char* cs = aClass.ToString();
printf("+++ nsTextServicesModule: unable to create factory for %s\n", cs);
nsCRT::free(cs);
#endif
}
if (fact) {
rv = fact->QueryInterface(aIID, r_classObj);
}
return rv;
}
//----------------------------------------
struct Components {
const char* mDescription;
const nsID* mCID;
const char* mProgID;
};
// The list of components we register
static Components gComponents[] = {
{ NULL, &kCTextServicesDocumentCID,
NULL, },
};
#define NUM_COMPONENTS (sizeof(gComponents) / sizeof(gComponents[0]))
NS_IMETHODIMP
nsTextServicesModule::RegisterSelf(nsIComponentManager *aCompMgr,
nsIFileSpec* aPath,
const char* registryLocation,
const char* componentType)
{
nsresult rv = NS_OK;
#ifdef DEBUG
printf("*** Registering TextServices components\n");
#endif
Components* cp = gComponents;
Components* end = cp + NUM_COMPONENTS;
while (cp < end) {
rv = aCompMgr->RegisterComponentSpec(*cp->mCID, cp->mDescription,
cp->mProgID, aPath, PR_TRUE,
PR_TRUE);
if (NS_FAILED(rv)) {
#ifdef DEBUG
printf("nsTextServicesModule: unable to register %s component => %x\n",
cp->mDescription, rv);
#endif
break;
}
cp++;
}
return rv;
}
NS_IMETHODIMP
nsTextServicesModule::UnregisterSelf(nsIComponentManager* aCompMgr,
nsIFileSpec* aPath,
const char* registryLocation)
{
#ifdef DEBUG
printf("*** Unregistering TextServices components\n");
#endif
Components* cp = gComponents;
Components* end = cp + NUM_COMPONENTS;
while (cp < end) {
nsresult rv = aCompMgr->UnregisterComponentSpec(*cp->mCID, aPath);
if (NS_FAILED(rv)) {
#ifdef DEBUG
printf("nsTextServicesModule: unable to unregister %s component => %x\n",
cp->mDescription, rv);
#endif
}
cp++;
}
return NS_OK;
}
NS_IMETHODIMP
nsTextServicesModule::CanUnload(nsIComponentManager *aCompMgr, PRBool *okToUnload)
{
if (!okToUnload) {
return NS_ERROR_INVALID_POINTER;
}
*okToUnload = PR_FALSE;
return NS_ERROR_FAILURE;
}
//----------------------------------------------------------------------
static nsTextServicesModule *gModule = NULL;
extern "C" NS_EXPORT nsresult NSGetModule(nsIComponentManager *servMgr,
nsIFileSpec* location,
nsIModule** return_cobj)
{
nsresult rv = NS_OK;
NS_ENSURE_ARG_POINTER(return_cobj);
NS_ENSURE_NOT(gModule, NS_ERROR_FAILURE);
// Create and initialize the module instance
nsTextServicesModule *m = new nsTextServicesModule();
if (!m) {
return NS_ERROR_OUT_OF_MEMORY;
return (*aFactory)->QueryInterface(kIFactoryIID, (void**)aFactory);
}
extern "C" NS_EXPORT nsresult NSRegisterSelf(nsISupports* aServMgr, const char *path)
{
nsresult rv;
nsCOMPtr<nsIServiceManager> servMgr(do_QueryInterface(aServMgr, &rv));
if (NS_FAILED(rv)) return rv;
nsIComponentManager* compMgr;
rv = servMgr->GetService(kComponentManagerCID,
nsIComponentManager::GetIID(),
(nsISupports**)&compMgr);
if (NS_FAILED(rv)) return rv;
rv = compMgr->RegisterComponent(kCTextServicesDocumentCID,
NULL, NULL, path,
PR_TRUE, PR_TRUE);
(void)servMgr->ReleaseService(kComponentManagerCID, compMgr);
// Increase refcnt and store away nsIModule interface to m in return_cobj
rv = m->QueryInterface(NS_GET_IID(nsIModule), (void**)return_cobj);
if (NS_FAILED(rv)) {
delete m;
m = nsnull;
}
gModule = m; // WARNING: Weak Reference
return rv;
}
extern "C" NS_EXPORT nsresult NSUnregisterSelf(nsISupports* aServMgr, const char *path)
{
nsresult rv;
nsCOMPtr<nsIServiceManager> servMgr(do_QueryInterface(aServMgr, &rv));
if (NS_FAILED(rv)) return rv;
nsIComponentManager* compMgr;
rv = servMgr->GetService(kComponentManagerCID,
nsIComponentManager::GetIID(),
(nsISupports**)&compMgr);
if (NS_FAILED(rv)) return rv;
rv = compMgr->UnregisterComponent(kCTextServicesDocumentCID, path);
(void)servMgr->ReleaseService(kComponentManagerCID, compMgr);
return rv;
}