Compare commits

..

13 Commits

Author SHA1 Message Date
dp%netscape.com
e81bd482cd Removing stray UnregistryFactory()
git-svn-id: svn://10.0.0.236/branches/XPCOM_M6_BRANCH@30403 18797224-902f-48f8-a5cc-f745e15eee43
1999-05-05 18:59:51 +00:00
dp%netscape.com
140731e7dd No more conditionals on NS_OK. Use NS_SUCCEEDED()
git-svn-id: svn://10.0.0.236/branches/XPCOM_M6_BRANCH@30108 18797224-902f-48f8-a5cc-f745e15eee43
1999-05-04 15:22:46 +00:00
dp%netscape.com
212915f904 Removing dead code : CreateInstance2
git-svn-id: svn://10.0.0.236/branches/XPCOM_M6_BRANCH@30024 18797224-902f-48f8-a5cc-f745e15eee43
1999-05-04 00:36:56 +00:00
dp%netscape.com
d4bab80a7f Comment fix.
git-svn-id: svn://10.0.0.236/branches/XPCOM_M6_BRANCH@29993 18797224-902f-48f8-a5cc-f745e15eee43
1999-05-03 21:17:47 +00:00
dp%netscape.com
b9707ef001 Comments changed.
git-svn-id: svn://10.0.0.236/branches/XPCOM_M6_BRANCH@29992 18797224-902f-48f8-a5cc-f745e15eee43
1999-05-03 21:17:26 +00:00
dp%netscape.com
5a01a176a1 Removed dead code
git-svn-id: svn://10.0.0.236/branches/XPCOM_M6_BRANCH@29990 18797224-902f-48f8-a5cc-f745e15eee43
1999-05-03 21:15:21 +00:00
dp%netscape.com
1d538a1827 Surrounding PR_LOG with #ifdef NS_DEBUG
git-svn-id: svn://10.0.0.236/branches/XPCOM_M6_BRANCH@29989 18797224-902f-48f8-a5cc-f745e15eee43
1999-05-03 21:12:50 +00:00
dp%netscape.com
808dd82067 Comment and formatting changes.
git-svn-id: svn://10.0.0.236/branches/XPCOM_M6_BRANCH@29976 18797224-902f-48f8-a5cc-f745e15eee43
1999-05-03 20:31:02 +00:00
dp%netscape.com
987acaaa25 Removing dead code
git-svn-id: svn://10.0.0.236/branches/XPCOM_M6_BRANCH@29942 18797224-902f-48f8-a5cc-f745e15eee43
1999-05-01 14:36:32 +00:00
dp%netscape.com
0729289762 Comment changes
git-svn-id: svn://10.0.0.236/branches/XPCOM_M6_BRANCH@29941 18797224-902f-48f8-a5cc-f745e15eee43
1999-05-01 14:36:19 +00:00
dp%netscape.com
cf99e010ec Fixing leaking of macFileName
git-svn-id: svn://10.0.0.236/branches/XPCOM_M6_BRANCH@29940 18797224-902f-48f8-a5cc-f745e15eee43
1999-05-01 14:35:19 +00:00
dp%netscape.com
2105f976bd - Cleaning up platform specific ifdefs
- Removing dead code
- Returning proper error value from AutoRegister()
- Fixing nsDll leak


git-svn-id: svn://10.0.0.236/branches/XPCOM_M6_BRANCH@29939 18797224-902f-48f8-a5cc-f745e15eee43
1999-05-01 14:34:29 +00:00
(no author)
9ca264d61a This commit was manufactured by cvs2svn to create branch 'XPCOM_M6_BRANCH'.
git-svn-id: svn://10.0.0.236/branches/XPCOM_M6_BRANCH@29901 18797224-902f-48f8-a5cc-f745e15eee43
1999-04-30 22:54:30 +00:00
238 changed files with 45992 additions and 18494 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,163 @@
/* -*- 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 "nsDebug.h"
#include "nsIAllocator.h"
#include "nsXPIDLString.h"
#include "plstr.h"
// If the allocator changes, fix it here.
#define XPIDL_STRING_ALLOC(__len) ((PRUnichar*) nsAllocator::Alloc((__len) * sizeof(PRUnichar)))
#define XPIDL_CSTRING_ALLOC(__len) ((char*) nsAllocator::Alloc((__len) * sizeof(char)))
#define XPIDL_FREE(__ptr) (nsAllocator::Free(__ptr))
////////////////////////////////////////////////////////////////////////
// nsXPIDLString
nsXPIDLString::nsXPIDLString()
: mBufOwner(PR_FALSE),
mBuf(0)
{
}
nsXPIDLString::~nsXPIDLString()
{
if (mBufOwner && mBuf)
XPIDL_FREE(mBuf);
}
nsXPIDLString::operator const PRUnichar*()
{
return mBuf;
}
PRUnichar*
nsXPIDLString::Copy(const PRUnichar* aString)
{
NS_ASSERTION(aString, "null ptr");
if (! aString)
return 0;
PRInt32 len = 0;
{
const PRUnichar* p = aString;
while (*p++)
len++;
}
PRUnichar* result = XPIDL_STRING_ALLOC(len + 1);
if (result) {
PRUnichar* q = result;
while (*aString) {
*q = *aString;
q++;
aString++;
}
*q = '\0';
}
return result;
}
PRUnichar**
nsXPIDLString::StartAssignmentByValue()
{
if (mBufOwner && mBuf)
XPIDL_FREE(mBuf);
mBufOwner = PR_TRUE;
return &mBuf;
}
const PRUnichar**
nsXPIDLString::StartAssignmentByReference()
{
if (mBufOwner && mBuf)
XPIDL_FREE(mBuf);
mBufOwner = PR_FALSE;
return (const PRUnichar**) &mBuf;
}
////////////////////////////////////////////////////////////////////////
// nsXPIDLCString
nsXPIDLCString::nsXPIDLCString()
: mBufOwner(PR_FALSE),
mBuf(0)
{
}
nsXPIDLCString::~nsXPIDLCString()
{
if (mBufOwner && mBuf)
XPIDL_FREE(mBuf);
}
nsXPIDLCString::operator const char*()
{
return mBuf;
}
char*
nsXPIDLCString::Copy(const char* aCString)
{
NS_ASSERTION(aCString, "null ptr");
if (! aCString)
return 0;
PRInt32 len = PL_strlen(aCString);
char* result = XPIDL_CSTRING_ALLOC(len + 1);
if (result)
PL_strcpy(result, aCString);
return result;
}
char**
nsXPIDLCString::StartAssignmentByValue()
{
if (mBufOwner && mBuf)
XPIDL_FREE(mBuf);
mBufOwner = PR_TRUE;
return &mBuf;
}
const char**
nsXPIDLCString::StartAssignmentByReference()
{
if (mBufOwner && mBuf)
XPIDL_FREE(mBuf);
mBufOwner = PR_FALSE;
return (const char**) &mBuf;
}

View File

@@ -0,0 +1,294 @@
/* -*- 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.
*/
/*
A set of string wrapper classes that ease transition to use of XPIDL
interfaces. nsXPIDLString and nsXPIDLCString are to XPIDL `wstring'
and `string' out params as nsCOMPtr is to generic XPCOM interface
pointers. They help you deal with object ownership.
Consider the following interface:
interface nsIFoo {
attribute string Bar;
};
This will generated the following C++ header file:
class nsIFoo {
NS_IMETHOD SetBar(const PRUnichar* aValue);
NS_IMETHOD GetBar(PRUnichar* *aValue);
};
The GetBar() method will allocate a copy of the nsIFoo object's
"bar" attribute, and leave you to deal with freeing it:
nsIFoo* aFoo; // assume we get this somehow
PRUnichar* bar;
aFoo->GetFoo(&bar);
// Use bar here...
delete[] bar;
(Strictly speaking, the `delete[] bar' should use the proper XPCOM
de-allocator that; we'll ignore that for now.) This makes your life
harder, because you need to convolute your code to ensure that you
don't leak `bar'.
Enter nsXPIDLString, which manages the ownership of the allocated
string, and automatically destroys it when the nsXPIDLString goes
out of scope:
nsIFoo* aFoo;
nsXPIDLString bar;
aFoo->GetFoo( getter_Copies(bar) );
// Use bar here...
Like nsCOMPtr, nsXPIDLString uses some syntactic sugar to make it
painfully clear exactly what the code expects. You need to wrap an
nsXPIDLString object with either `getter_Copies()' or
`getter_Shares()': these tell the nsXPIDLString how ownership is
being handled. In the case of `getter_Copies()', the callee is
allocating a copy (which is usually the case). In the case of
`getter_Shares()', the callee is returning a const reference to `the
real deal' (this can be done using the [shared] attribute in XPIDL).
*/
#ifndef nsXPIDLString_h__
#define nsXPIDLString_h__
#include "nsCom.h"
#include "prtypes.h"
#ifndef __PRUNICHAR__
#define __PRUNICHAR__
typedef PRUint16 PRUnichar;
#endif /* __PRUNICHAR__ */
////////////////////////////////////////////////////////////////////////
// nsXPIDLString
//
// A wrapper for Unicode strings. With the |getter_Copies()| and
// |getter_Shares()| helper functions, this can be used instead of
// the "naked" |PRUnichar*| interface for |wstring| parameters in
// XPIDL interfaces.
//
class NS_COM nsXPIDLString {
private:
PRUnichar* mBuf;
PRBool mBufOwner;
PRUnichar** StartAssignmentByValue();
const PRUnichar** StartAssignmentByReference();
public:
/**
* Construct a new, uninitialized wrapper for a Unicode string.
*/
nsXPIDLString();
virtual ~nsXPIDLString();
/**
* Return a reference to the immutable Unicode string.
*/
operator const PRUnichar*();
/**
* Make a copy of the Unicode string. Use this function in the
* callee to ensure that the correct memory allocator is used.
*/
static PRUnichar* Copy(const PRUnichar* aString);
// A helper class for assignment-by-value. This class is an
// implementation detail and should not be considered part of the
// public interface.
class NS_COM GetterCopies {
private:
nsXPIDLString& mXPIDLString;
public:
GetterCopies(nsXPIDLString& aXPIDLString)
: mXPIDLString(aXPIDLString) {}
operator PRUnichar**() {
return mXPIDLString.StartAssignmentByValue();
}
friend GetterCopies getter_Copies(nsXPIDLString& aXPIDLString);
};
friend class GetterCopies;
// A helper class for assignment-by-reference. This class is an
// implementation detail and should not be considered part of the
// public interface.
class NS_COM GetterShares {
private:
nsXPIDLString& mXPIDLString;
public:
GetterShares(nsXPIDLString& aXPIDLString)
: mXPIDLString(aXPIDLString) {}
operator const PRUnichar**() {
return mXPIDLString.StartAssignmentByReference();
}
friend GetterShares getter_Shares(nsXPIDLString& aXPIDLString);
};
friend class GetterShares;
private:
// not to be implemented
nsXPIDLString(nsXPIDLString& aXPIDLString) {}
nsXPIDLString& operator =(nsXPIDLString& aXPIDLString) { return *this; }
};
/**
* Use this function to "wrap" the nsXPIDLString object that is to
* receive an |out| value.
*/
inline nsXPIDLString::GetterCopies
getter_Copies(nsXPIDLString& aXPIDLString)
{
return nsXPIDLString::GetterCopies(aXPIDLString);
}
/**
* Use this function to "wrap" the nsXPIDLString object that is to
* receive a |[shared] out| value.
*/
inline nsXPIDLString::GetterShares
getter_Shares(nsXPIDLString& aXPIDLString)
{
return nsXPIDLString::GetterShares(aXPIDLString);
}
////////////////////////////////////////////////////////////////////////
// nsXPIDLCString
//
// A wrapper for Unicode strings. With the |getter_Copies()| and
// |getter_Shares()| helper functions, this can be used instead of
// the "naked" |char*| interface for |string| parameters in XPIDL
// interfaces.
//
class NS_COM nsXPIDLCString {
private:
char* mBuf;
PRBool mBufOwner;
char** StartAssignmentByValue();
const char** StartAssignmentByReference();
public:
/**
* Construct a new, uninitialized wrapper for a single-byte string.
*/
nsXPIDLCString();
virtual ~nsXPIDLCString();
/**
* Return a reference to the immutable single-byte string.
*/
operator const char*();
/**
* Make a copy of the single-byte string. Use this function in the
* callee to ensure that the correct memory allocator is used.
*/
static char* Copy(const char* aString);
// A helper class for assignment-by-value. This class is an
// implementation detail and should not be considered part of the
// public interface.
class NS_COM GetterCopies {
private:
nsXPIDLCString& mXPIDLString;
public:
GetterCopies(nsXPIDLCString& aXPIDLString)
: mXPIDLString(aXPIDLString) {}
operator char**() {
return mXPIDLString.StartAssignmentByValue();
}
friend GetterCopies getter_Copies(nsXPIDLCString& aXPIDLString);
};
friend class GetterCopies;
// A helper class for assignment-by-reference. This class is an
// implementation detail and should not be considered part of the
// public interface.
class NS_COM GetterShares {
private:
nsXPIDLCString& mXPIDLString;
public:
GetterShares(nsXPIDLCString& aXPIDLString)
: mXPIDLString(aXPIDLString) {}
operator const char**() {
return mXPIDLString.StartAssignmentByReference();
}
friend GetterShares getter_Shares(nsXPIDLCString& aXPIDLString);
};
friend class GetterShares;
private:
// not to be implemented
nsXPIDLCString(nsXPIDLCString& aXPIDLString) {}
nsXPIDLCString& operator =(nsXPIDLCString& aXPIDLString) { return *this; }
};
/**
* Use this function to "wrap" the nsXPIDLCString object that is to
* receive an |out| value.
*/
inline nsXPIDLCString::GetterCopies
getter_Copies(nsXPIDLCString& aXPIDLString)
{
return nsXPIDLCString::GetterCopies(aXPIDLString);
}
/**
* Use this function to "wrap" the nsXPIDLCString object that is to
* receive a |[shared] out| value.
*/
inline nsXPIDLCString::GetterShares
getter_Shares(nsXPIDLCString& aXPIDLString)
{
return nsXPIDLCString::GetterShares(aXPIDLString);
}
#endif // nsXPIDLString_h__

6027
mozilla/xpcom/base/IIDS.h Normal file

File diff suppressed because it is too large Load Diff

170
mozilla/xpcom/base/nsAgg.h Normal file
View File

@@ -0,0 +1,170 @@
/* -*- 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.
*/
#ifndef nsAgg_h___
#define nsAgg_h___
#include "nsISupports.h"
/**
* Outer objects can implement nsIOuter if they choose, allowing them to
* get notification if their inner objects (children) are effectively freed.
* This allows them to reset any state associated with the inner object and
* potentially unload it.
*/
class nsIOuter : public nsISupports {
public:
/**
* This method is called whenever an inner object's refcount is about to
* become zero and the inner object should be released by the outer. This
* allows the outer to clean up any state associated with the inner and
* potentially unload the inner object. This method should call
* inner->Release().
*/
NS_IMETHOD
ReleaseInner(nsISupports* inner) = 0;
};
#define NS_IOUTER_IID \
{ /* ea0bf9f0-3d67-11d2-8163-006008119d7a */ \
0xea0bf9f0, \
0x3d67, \
0x11d2, \
{0x81, 0x63, 0x00, 0x60, 0x08, 0x11, 0x9d, 0x7a} \
}
////////////////////////////////////////////////////////////////////////////////
// Put this in your class's declaration:
#define NS_DECL_AGGREGATED \
NS_DECL_ISUPPORTS \
\
protected: \
\
/* You must implement this operation instead of the nsISupports */ \
/* methods if you inherit from nsAggregated. */ \
NS_IMETHOD \
AggregatedQueryInterface(const nsIID& aIID, void** aInstancePtr); \
\
class Internal : public nsISupports { \
public: \
\
Internal() {} \
\
NS_IMETHOD QueryInterface(const nsIID& aIID, \
void** aInstancePtr); \
NS_IMETHOD_(nsrefcnt) AddRef(void); \
NS_IMETHOD_(nsrefcnt) Release(void); \
\
}; \
\
friend class Internal; \
\
nsISupports* fOuter; \
Internal fAggregated; \
\
nsISupports* GetInner(void) { return &fAggregated; } \
\
public: \
// Put this in your class's constructor:
#define NS_INIT_AGGREGATED(outer) \
PR_BEGIN_MACRO \
NS_INIT_REFCNT(); \
fOuter = outer; \
PR_END_MACRO
// Put this in your class's implementation file:
#define NS_IMPL_AGGREGATED(_class) \
NS_IMETHODIMP \
_class::QueryInterface(const nsIID& aIID, void** aInstancePtr) \
{ \
/* try our own interfaces first before delegating to outer */ \
nsresult rslt = AggregatedQueryInterface(aIID, aInstancePtr); \
if (rslt != NS_OK && fOuter) \
return fOuter->QueryInterface(aIID, aInstancePtr); \
else \
return rslt; \
} \
\
NS_IMETHODIMP_(nsrefcnt) \
_class::AddRef(void) \
{ \
++mRefCnt; /* keep track of our refcount as well as outer's */ \
if (fOuter) \
return NS_ADDREF(fOuter); \
else \
return mRefCnt; \
} \
\
NS_IMETHODIMP_(nsrefcnt) \
_class::Release(void) \
{ \
if (fOuter) { \
nsISupports* outer = fOuter; /* in case we release ourself */ \
nsIOuter* outerIntf; \
static NS_DEFINE_IID(kIOuterIID, NS_IOUTER_IID); \
if (mRefCnt == 1 && \
outer->QueryInterface(kIOuterIID, \
(void**)&outerIntf) == NS_OK) { \
outerIntf->ReleaseInner(GetInner()); \
outerIntf->Release(); \
} \
else \
--mRefCnt; /* keep track of our refcount as well as outer's */ \
return outer->Release(); \
} \
else { \
if (--mRefCnt == 0) { \
delete this; \
return 0; \
} \
return mRefCnt; \
} \
} \
\
NS_IMETHODIMP \
_class::Internal::QueryInterface(const nsIID& aIID, void** aInstancePtr) \
{ \
_class* agg = (_class*)((char*)(this) - offsetof(_class, fAggregated)); \
return agg->AggregatedQueryInterface(aIID, aInstancePtr); \
} \
\
NS_IMETHODIMP_(nsrefcnt) \
_class::Internal::AddRef(void) \
{ \
_class* agg = (_class*)((char*)(this) - offsetof(_class, fAggregated)); \
return ++agg->mRefCnt; \
} \
\
NS_IMETHODIMP_(nsrefcnt) \
_class::Internal::Release(void) \
{ \
_class* agg = (_class*)((char*)(this) - offsetof(_class, fAggregated)); \
if (--agg->mRefCnt == 0) { \
delete agg; \
return 0; \
} \
return agg->mRefCnt; \
} \
#endif /* nsAgg_h___ */

View File

@@ -0,0 +1,185 @@
/* -*- 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.
*/
////////////////////////////////////////////////////////////////////////////////
// Implementation of nsIAllocator using NSPR
////////////////////////////////////////////////////////////////////////////////
#include "nsAllocator.h"
#include "nsIServiceManager.h"
#include <string.h> /* for memcpy */
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
static NS_DEFINE_IID(kIAllocatorIID, NS_IALLOCATOR_IID);
nsAllocatorImpl::nsAllocatorImpl(nsISupports* outer)
{
NS_INIT_AGGREGATED(outer);
}
nsAllocatorImpl::~nsAllocatorImpl(void)
{
}
NS_IMPL_AGGREGATED(nsAllocatorImpl);
NS_METHOD
nsAllocatorImpl::AggregatedQueryInterface(const nsIID& aIID, void** aInstancePtr)
{
if (NULL == aInstancePtr) {
return NS_ERROR_NULL_POINTER;
}
if (aIID.Equals(kIAllocatorIID) ||
aIID.Equals(kISupportsIID)) {
*aInstancePtr = (void*) this;
AddRef();
return NS_OK;
}
return NS_NOINTERFACE;
}
NS_METHOD
nsAllocatorImpl::Create(nsISupports* outer, const nsIID& aIID, void* *aInstancePtr)
{
if (outer && !aIID.Equals(kISupportsIID))
return NS_NOINTERFACE; // XXX right error?
nsAllocatorImpl* mm = new nsAllocatorImpl(outer);
if (mm == NULL)
return NS_ERROR_OUT_OF_MEMORY;
mm->AddRef();
if (aIID.Equals(kISupportsIID))
*aInstancePtr = mm->GetInner();
else
*aInstancePtr = mm;
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
NS_METHOD_(void*)
nsAllocatorImpl::Alloc(PRUint32 size)
{
return PR_Malloc(size);
}
NS_METHOD_(void*)
nsAllocatorImpl::Realloc(void* ptr, PRUint32 size,
PRInt32 oldSize)
{
return PR_Realloc(ptr, size);
}
NS_METHOD
nsAllocatorImpl::Free(void* ptr, PRInt32 size)
{
PR_Free(ptr);
return NS_OK;
}
NS_METHOD
nsAllocatorImpl::HeapMinimize(void)
{
#ifdef XP_MAC
// This used to live in the memory allocators no Mac, but does no more
// Needs to be hooked up in the new world.
// CallCacheFlushers(0x7fffffff);
#endif
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
nsAllocatorFactory::nsAllocatorFactory(void)
{
NS_INIT_REFCNT();
}
nsAllocatorFactory::~nsAllocatorFactory(void)
{
}
static NS_DEFINE_IID(kIFactoryIID, NS_IFACTORY_IID);
NS_IMPL_ISUPPORTS(nsAllocatorFactory, kIFactoryIID);
NS_METHOD
nsAllocatorFactory::CreateInstance(nsISupports *aOuter,
REFNSIID aIID,
void **aResult)
{
return nsAllocatorImpl::Create(aOuter, aIID, aResult);
}
NS_METHOD
nsAllocatorFactory::LockFactory(PRBool aLock)
{
return NS_OK; // XXX what?
}
////////////////////////////////////////////////////////////////////////////////
/*
* Public shortcuts to the shared allocator's methods
* (all these methods are class statics)
*/
// public:
void* nsAllocator::Alloc(PRUint32 size)
{
if(!EnsureAllocator()) return NULL;
return mAllocator->Alloc(size);
}
void* nsAllocator::Realloc(void* ptr, PRUint32 size)
{
if(!EnsureAllocator()) return NULL;
return mAllocator->Realloc(ptr, size);
}
void nsAllocator::Free(void* ptr)
{
if(!EnsureAllocator()) return;
mAllocator->Free(ptr);
}
void nsAllocator::HeapMinimize()
{
if(!EnsureAllocator()) return;
mAllocator->HeapMinimize();
}
void* nsAllocator::Clone(const void* ptr, PRUint32 size)
{
if(!ptr || !EnsureAllocator()) return NULL;
void* p = mAllocator->Alloc(size);
if(p) memcpy(p, ptr, size);
return p;
}
// private:
nsIAllocator* nsAllocator::mAllocator = NULL;
PRBool nsAllocator::FetchAllocator()
{
NS_DEFINE_IID(kAllocatorCID, NS_ALLOCATOR_CID);
NS_DEFINE_IID(kIAllocatorIID, NS_IALLOCATOR_IID);
nsServiceManager::GetService(kAllocatorCID, kIAllocatorIID,
(nsISupports **)&mAllocator);
NS_ASSERTION(mAllocator, "failed to get Allocator!");
return (PRBool) mAllocator;
}

View File

@@ -0,0 +1,96 @@
/* -*- 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.
*/
////////////////////////////////////////////////////////////////////////////////
// Implementation of nsIAllocator using NSPR
////////////////////////////////////////////////////////////////////////////////
#ifndef nsAllocator_h__
#define nsAllocator_h__
#include "nsIAllocator.h"
#include "prmem.h"
#include "nsAgg.h"
#include "nsIFactory.h"
class nsAllocatorImpl : public nsIAllocator {
public:
static const nsCID& CID() { static nsCID cid = NS_ALLOCATOR_CID; return cid; }
/**
* Allocates a block of memory of a particular size.
*
* @param size - the size of the block to allocate
* @result the block of memory
*/
NS_IMETHOD_(void*) Alloc(PRUint32 size);
/**
* Reallocates a block of memory to a new size.
*
* @param ptr - the block of memory to reallocate
* @param size - the new size
* @param oldSize - the current size of the block. If -1 (the default),
* the implementation must be able to determine the block size by
* examining the block pointer.
* @result the rellocated block of memory
*/
NS_IMETHOD_(void*) Realloc(void* ptr, PRUint32 size,
PRInt32 oldSize = -1);
/**
* Frees a block of memory.
*
* @param ptr - the block of memory to free
*/
NS_IMETHOD Free(void* ptr, PRInt32 size = -1);
/**
* Attempts to shrink the heap.
*/
NS_IMETHOD HeapMinimize(void);
////////////////////////////////////////////////////////////////////////////
nsAllocatorImpl(nsISupports* outer);
virtual ~nsAllocatorImpl(void);
NS_DECL_AGGREGATED
static NS_METHOD
Create(nsISupports* outer, const nsIID& aIID, void* *aInstancePtr);
};
////////////////////////////////////////////////////////////////////////////////
class nsAllocatorFactory : public nsIFactory {
public:
NS_IMETHOD CreateInstance(nsISupports *aOuter,
REFNSIID aIID,
void **aResult);
NS_IMETHOD LockFactory(PRBool aLock);
nsAllocatorFactory(void);
virtual ~nsAllocatorFactory(void);
NS_DECL_ISUPPORTS
};
////////////////////////////////////////////////////////////////////////////////
#endif // nsAllocator_h__

View File

@@ -0,0 +1,54 @@
/* -*- 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 "nsCOMPtr.h"
void
nsCOMPtr_base::assign_with_AddRef( nsISupports* rawPtr )
{
if ( rawPtr )
NSCAP_ADDREF(rawPtr);
if ( mRawPtr )
NSCAP_RELEASE(mRawPtr);
mRawPtr = rawPtr;
}
void
nsCOMPtr_base::assign_with_QueryInterface( nsISupports* rawPtr, const nsIID& iid, nsresult* result )
{
nsresult status = NS_OK;
if ( !rawPtr || !NS_SUCCEEDED( status = rawPtr->QueryInterface(iid, NSCAP_REINTERPRET_CAST(void**, &rawPtr)) ) )
rawPtr = 0;
if ( mRawPtr )
NSCAP_RELEASE(mRawPtr);
mRawPtr = rawPtr;
if ( result )
*result = status;
}
void**
nsCOMPtr_base::begin_assignment()
{
if ( mRawPtr )
NSCAP_RELEASE(mRawPtr);
mRawPtr = 0;
return NSCAP_REINTERPRET_CAST(void**, &mRawPtr);
}

View File

@@ -0,0 +1,493 @@
/* -*- 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 nsCOMPtr_h___
#define nsCOMPtr_h___
// Wrapping includes can speed up compiles (see "Large Scale C++ Software Design")
#ifndef nsDebug_h___
#include "nsDebug.h"
// for |NS_PRECONDITION|
#endif
#ifndef nsISupports_h___
#include "nsISupports.h"
// for |nsresult|, |NS_ADDREF|, et al
#endif
/*
Having problems?
See the User Manual at:
<http://www.meer.net/ScottCollins/doc/nsCOMPtr.html>, or
<http://www.mozilla.org/projects/xpcom/nsCOMPtr.html>
*/
/*
TO DO...
+ make StartAssignment optionally inlined
+ make constructor for |nsQueryInterface| explicit (suddenly construct/assign from raw pointer becomes illegal)
+ Improve internal documentation
+ mention *&
+ alternatives for comparison
+ do_QueryInterface
*/
/*
WARNING:
This file defines several macros for internal use only. These macros begin with the
prefix |NSCAP_|. Do not use these macros in your own code. They are for internal use
only for cross-platform compatibility, and are subject to change without notice.
*/
/*
Set up some |#define|s to turn off a couple of troublesome C++ features.
Interestingly, none of the compilers barf on template stuff. These are set up automatically
by the autoconf system for all Unixes. (Temporarily, I hope) I have to define them
myself for Mac and Windows.
*/
// under Metrowerks (Mac), we don't have autoconf yet
#ifdef __MWERKS__
#define HAVE_CPP_USING
#define HAVE_CPP_EXPLICIT
#define HAVE_CPP_NEW_CASTS
#endif
// under VC++ (Windows), we don't have autoconf yet
#ifdef _MSC_VER
#define HAVE_CPP_EXPLICIT
#define HAVE_CPP_USING
#define HAVE_CPP_NEW_CASTS
#if (_MSC_VER<1100)
// before 5.0, VC++ couldn't handle explicit
#undef HAVE_CPP_EXPLICIT
#elif (_MSC_VER==1100)
// VC++5.0 has an internal compiler error (sometimes) without this
#undef HAVE_CPP_USING
#endif
#define NSCAP_FEATURE_INLINE_STARTASSIGNMENT
// under VC++, we win by inlining StartAssignment
#endif
/*
If the compiler doesn't support |explicit|, we'll just make it go away, trusting
that the builds under compilers that do have it will keep us on the straight and narrow.
*/
#ifndef HAVE_CPP_EXPLICIT
#define explicit
#endif
#ifdef HAVE_CPP_NEW_CASTS
#define NSCAP_REINTERPRET_CAST(T,x) reinterpret_cast<T>(x)
#else
#define NSCAP_REINTERPRET_CAST(T,x) ((T)(x))
#endif
#ifdef NSCAP_FEATURE_DEBUG_MACROS
#define NSCAP_ADDREF(ptr) NS_ADDREF(ptr)
#define NSCAP_RELEASE(ptr) NS_RELEASE(ptr)
#else
#define NSCAP_ADDREF(ptr) (ptr)->AddRef()
#define NSCAP_RELEASE(ptr) (ptr)->Release()
#endif
/*
WARNING:
VC++4.2 is very picky. To compile under VC++4.2, the classes must be defined
in an order that satisfies:
nsDerivedSafe < nsCOMPtr
nsDontAddRef < nsCOMPtr
nsCOMPtr < nsGetterAddRefs
The other compilers probably won't complain, so please don't reorder these
classes, on pain of breaking 4.2 compatibility.
*/
template <class T>
class nsDerivedSafe : public T
/*
No client should ever see or have to type the name of this class. It is the
artifact that makes it a compile-time error to call |AddRef| and |Release|
on a |nsCOMPtr|.
See |nsCOMPtr::operator->|, |nsCOMPtr::operator*|, et al.
*/
{
private:
#ifdef HAVE_CPP_USING
using T::AddRef;
using T::Release;
#else
NS_IMETHOD_(nsrefcnt) AddRef(void);
NS_IMETHOD_(nsrefcnt) Release(void);
#endif
void operator delete( void*, size_t ); // NOT TO BE IMPLEMENTED
// declaring |operator delete| private makes calling delete on an interface pointer a compile error
nsDerivedSafe<T>& operator=( const nsDerivedSafe<T>& ); // NOT TO BE IMPLEMENTED
// you may not call |operator=()| through a dereferenced |nsCOMPtr|, because you'd get the wrong one
};
#if !defined(HAVE_CPP_USING) && defined(NEED_CPP_UNUSED_IMPLEMENTATIONS)
template <class T>
nsrefcnt
nsDerivedSafe<T>::AddRef()
{
return 0;
}
template <class T>
nsrefcnt
nsDerivedSafe<T>::Release()
{
return 0;
}
#endif
template <class T>
struct nsDontQueryInterface
/*
...
*/
{
explicit
nsDontQueryInterface( T* aRawPtr )
: mRawPtr(aRawPtr)
{
// nothing else to do here
}
T* mRawPtr;
};
template <class T>
inline
nsDontQueryInterface<T>
dont_QueryInterface( T* aRawPtr )
{
return nsDontQueryInterface<T>(aRawPtr);
}
struct nsQueryInterface
{
explicit
nsQueryInterface( nsISupports* aRawPtr, nsresult* error = 0 )
: mRawPtr(aRawPtr),
mErrorPtr(error)
{
// nothing else to do here
}
nsISupports* mRawPtr;
nsresult* mErrorPtr;
};
inline
nsQueryInterface
do_QueryInterface( nsISupports* aRawPtr, nsresult* error = 0 )
{
return nsQueryInterface(aRawPtr, error);
}
template <class T>
struct nsDontAddRef
/*
...cooperates with |nsCOMPtr| to allow you to assign in a pointer _without_
|AddRef|ing it. You would rarely use this directly, but rather through the
machinery of |getter_AddRefs| in the argument list to functions that |AddRef|
their results before returning them to the caller.
See also |getter_AddRefs()| and |class nsGetterAddRefs|.
*/
{
explicit
nsDontAddRef( T* aRawPtr )
: mRawPtr(aRawPtr)
{
// nothing else to do here
}
T* mRawPtr;
};
// This call is now deprecated. Use |getter_AddRefs()| instead.
template <class T>
inline
nsDontAddRef<T>
dont_AddRef( T* aRawPtr )
/*
...makes typing easier, because it deduces the template type, e.g.,
you write |dont_AddRef(fooP)| instead of |nsDontAddRef<IFoo>(fooP)|.
*/
{
return nsDontAddRef<T>(aRawPtr);
}
template <class T>
inline
nsDontAddRef<T>
getter_AddRefs( T* aRawPtr )
{
return nsDontAddRef<T>(aRawPtr);
}
class nsCOMPtr_base
{
public:
nsCOMPtr_base( nsISupports* rawPtr = 0 )
: mRawPtr(rawPtr)
{
// nothing else to do here
}
~nsCOMPtr_base()
{
if ( mRawPtr )
NSCAP_RELEASE(mRawPtr);
}
NS_EXPORT void assign_with_AddRef( nsISupports* );
NS_EXPORT void assign_with_QueryInterface( nsISupports*, const nsIID&, nsresult* );
NS_EXPORT void** begin_assignment();
protected:
nsISupports* mRawPtr;
};
template <class T>
class nsCOMPtr : private nsCOMPtr_base
/*
...
*/
{
public:
typedef T element_type;
nsCOMPtr()
// : nsCOMPtr_base(0)
{
// nothing else to do here
}
nsCOMPtr( const nsQueryInterface& aSmartPtr )
// : nsCOMPtr_base(0)
{
assign_with_QueryInterface(aSmartPtr.mRawPtr, T::GetIID(), aSmartPtr.mErrorPtr);
}
nsCOMPtr( const nsDontAddRef<T>& aSmartPtr )
: nsCOMPtr_base(aSmartPtr.mRawPtr)
{
// nothing else to do here
}
nsCOMPtr( const nsDontQueryInterface<T>& aSmartPtr )
: nsCOMPtr_base(aSmartPtr.mRawPtr)
{
if ( mRawPtr )
NSCAP_ADDREF(mRawPtr);
}
nsCOMPtr( const nsCOMPtr<T>& aSmartPtr )
: nsCOMPtr_base(aSmartPtr.mRawPtr)
{
if ( mRawPtr )
NSCAP_ADDREF(mRawPtr);
}
nsCOMPtr<T>&
operator=( const nsQueryInterface& rhs )
{
assign_with_QueryInterface(rhs.mRawPtr, T::GetIID(), rhs.mErrorPtr);
return *this;
}
nsCOMPtr<T>&
operator=( const nsDontAddRef<T>& rhs )
{
if ( mRawPtr )
NSCAP_RELEASE(mRawPtr);
mRawPtr = rhs.mRawPtr;
return *this;
}
nsCOMPtr<T>&
operator=( const nsDontQueryInterface<T>& rhs )
{
assign_with_AddRef(rhs.mRawPtr);
return *this;
}
nsCOMPtr<T>&
operator=( const nsCOMPtr<T>& rhs )
{
assign_with_AddRef(rhs.mRawPtr);
return *this;
}
nsDerivedSafe<T>*
get() const
// returns a |nsDerivedSafe<T>*| to deny clients the use of |AddRef| and |Release|
{
return NSCAP_REINTERPRET_CAST(nsDerivedSafe<T>*, mRawPtr);
}
nsDerivedSafe<T>*
operator->() const
// returns a |nsDerivedSafe<T>*| to deny clients the use of |AddRef| and |Release|
{
NS_PRECONDITION(mRawPtr != 0, "You can't dereference a NULL nsCOMPtr with operator->().");
return get();
}
nsDerivedSafe<T>&
operator*() const
// returns a |nsDerivedSafe<T>*| to deny clients the use of |AddRef| and |Release|
{
NS_PRECONDITION(mRawPtr != 0, "You can't dereference a NULL nsCOMPtr with operator*().");
return *get();
}
operator nsDerivedSafe<T>*() const
{
return get();
}
#if 0
private:
friend class nsGetterAddRefs<T>;
/*
In a perfect world, the following member function, |StartAssignment|, would be private.
It is and should be only accessed by the closely related class |nsGetterAddRefs<T>|.
Unfortunately, some compilers---most notably VC++5.0---fail to grok the
friend declaration above or in any alternate acceptable form. So, physically
it will be public (until our compilers get smarter); but it is not to be
considered part of the logical public interface.
*/
#endif
T**
StartAssignment()
{
#ifndef NSCAP_FEATURE_INLINE_STARTASSIGNMENT
return NSCAP_REINTERPRET_CAST(T**, begin_assignment());
#else
if ( mRawPtr )
NSCAP_RELEASE(mRawPtr);
mRawPtr = 0;
return NSCAP_REINTERPRET_CAST(T**, &mRawPtr);
#endif
}
};
template <class T>
class nsGetterAddRefs
/*
...
This class is designed to be used for anonymous temporary objects in the
argument list of calls that return COM interface pointers, e.g.,
nsCOMPtr<IFoo> fooP;
...->QueryInterface(iid, nsGetterAddRefs<IFoo>(fooP))
...->QueryInterface(iid, getter_AddRefs(fooP))
When initialized with a |nsCOMPtr|, as in the example above, it returns
a |void**| (or |T**| if needed) that the outer call (|QueryInterface| in this
case) can fill in.
*/
{
public:
explicit
nsGetterAddRefs( nsCOMPtr<T>& aSmartPtr )
: mTargetSmartPtr(aSmartPtr)
{
// nothing else to do
}
operator void**()
{
// NS_PRECONDITION(mTargetSmartPtr != 0, "getter_AddRefs into no destination");
return NSCAP_REINTERPRET_CAST(void**, mTargetSmartPtr.StartAssignment());
}
T*&
operator*()
{
// NS_PRECONDITION(mTargetSmartPtr != 0, "getter_AddRefs into no destination");
return *(mTargetSmartPtr.StartAssignment());
}
operator T**()
{
// NS_PRECONDITION(mTargetSmartPtr != 0, "getter_AddRefs into no destination");
return mTargetSmartPtr.StartAssignment();
}
private:
nsCOMPtr<T>& mTargetSmartPtr;
};
template <class T>
inline
nsGetterAddRefs<T>
getter_AddRefs( nsCOMPtr<T>& aSmartPtr )
/*
Used around a |nsCOMPtr| when
...makes the class |nsGetterAddRefs<T>| invisible.
*/
{
return nsGetterAddRefs<T>(aSmartPtr);
}
#endif // !defined(nsCOMPtr_h___)

229
mozilla/xpcom/base/nsCom.h Normal file
View File

@@ -0,0 +1,229 @@
/* -*- 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 "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 nsCom_h__
#define nsCom_h__
/*
* API Import/Export macros
*/
#ifdef _IMPL_NS_COM
#ifdef XP_PC
#define NS_COM _declspec(dllexport)
#elif defined(XP_MAC)
#define NS_COM __declspec(export)
#else /* !XP_PC */
#define NS_COM
#endif /* !XP_PC */
#else /* !_IMPL_NS_COM */
#ifdef XP_PC
#define NS_COM _declspec(dllimport)
#else /* !XP_PC */
#define NS_COM
#endif /* !XP_PC */
#endif /* !_IMPL_NS_COM */
/*
* DLL Export macro
*/
#if defined(XP_PC)
#define NS_EXPORT _declspec(dllexport)
#define NS_EXPORT_(type) _declspec(dllexport) type __stdcall
#define NS_IMETHOD_(type) virtual type __stdcall
#define NS_IMETHOD virtual nsresult __stdcall
#define NS_IMETHODIMP_(type) type __stdcall
#define NS_IMETHODIMP nsresult __stdcall
#define NS_METHOD_(type) type __stdcall
#define NS_METHOD nsresult __stdcall
#define NS_CALLBACK_(_type, _name) _type (__stdcall * _name)
#define NS_CALLBACK(_name) nsresult (__stdcall * _name)
#elif defined(XP_MAC)
#define NS_EXPORT __declspec(export)
#define NS_EXPORT_(type) __declspec(export) type
#define NS_IMETHOD_(type) virtual type
#define NS_IMETHOD virtual nsresult
#define NS_IMETHODIMP_(type) type
#define NS_IMETHODIMP nsresult
#define NS_METHOD_(type) type
#define NS_METHOD nsresult
#define NS_CALLBACK_(_type, _name) _type (* _name)
#define NS_CALLBACK(_name) nsresult (* _name)
#else /* !XP_PC && !XP_MAC */
#define NS_EXPORT
#define NS_EXPORT_(type) type
#define NS_IMETHOD_(type) virtual type
#define NS_IMETHOD virtual nsresult
#define NS_IMETHODIMP_(type) type
#define NS_IMETHODIMP nsresult
#define NS_METHOD_(type) type
#define NS_METHOD nsresult
#define NS_CALLBACK_(_type, _name) _type (* _name)
#define NS_CALLBACK(_name) nsresult (* _name)
#endif /* !XP_PC */
/* use these functions to associate get/set methods with a
C++ member variable
*/
#define NS_METHOD_GETTER(_method, _type, _member) \
_method(_type* aResult) \
{\
if (!aResult) return NS_ERROR_NULL_POINTER; \
*aResult = _member; \
return NS_OK; \
}
#define NS_METHOD_SETTER(_method, _type, _member) \
_method(_type aResult) \
{ \
_member = aResult; \
return NS_OK; \
}
/*
* special for strings to get/set char* strings
* using PL_strdup and PR_FREEIF
*/
#define NS_METHOD_GETTER_STR(_method,_member) \
_method(char* *aString)\
{\
if (!aString) return NS_ERROR_NULL_POINTER; \
*aString = PL_strdup(_member); \
return NS_OK; \
}
#define NS_METHOD_SETTER_STR(_method, _member) \
_method(char *aString)\
{\
PR_FREEIF(_member);\
if (aString) _member = PL_strdup(aString); \
else _member = nsnull;\
return NS_OK; \
}
/* Getter/Setter macros.
Usage:
NS_IMPL_[CLASS_]GETTER[_<type>](method, [type,] member);
NS_IMPL_[CLASS_]SETTER[_<type>](method, [type,] member);
NS_IMPL_[CLASS_]GETSET[_<type>]([class, ]postfix, [type,] member);
where:
CLASS_ - implementation is inside a class definition
(otherwise the class name is needed)
Do NOT use in publicly exported header files, because
the implementation may be included many times over.
Instead, use the non-CLASS_ version.
_<type> - For more complex (STR, IFACE) data types
(otherwise the simple data type is needed)
method - name of the method, such as GetWidth or SetColor
type - simple data type if required
member - class member variable such as m_width or mColor
class - the class name, such as Window or MyObject
postfix - Method part after Get/Set such as "Width" for "GetWidth"
Example:
class Window {
public:
NS_IMPL_CLASS_GETSET(Width, int, m_width);
NS_IMPL_CLASS_GETTER_STR(GetColor, m_color);
NS_IMETHOD SetColor(char *color);
private:
int m_width; // read/write
char *m_color; // readonly
};
// defined outside of class
NS_IMPL_SETTER_STR(Window::GetColor, m_color);
Questions/Comments to alecf@netscape.com
*/
/*
* Getter/Setter implementation within a class definition
*/
/* simple data types */
#define NS_IMPL_CLASS_GETTER(_method, _type, _member) \
NS_IMETHOD NS_METHOD_GETTER(_method, _type, _member)
#define NS_IMPL_CLASS_SETTER(_method, _type, _member) \
NS_IMETHOD NS_METHOD_SETTER(_method, _type, _member)
#define NS_IMPL_CLASS_GETSET(_postfix, _type, _member) \
NS_IMPL_CLASS_GETTER(Get##_postfix, _type, _member) \
NS_IMPL_CLASS_SETTER(Set##_postfix, _type, _member)
/* strings */
#define NS_IMPL_CLASS_GETTER_STR(_method, _member) \
NS_IMETHOD NS_METHOD_GETTER_STR(_method, _member)
#define NS_IMPL_CLASS_SETTER_STR(_method, _member) \
NS_IMETHOD NS_METHOD_SETTER_STR(_method, _member)
#define NS_IMPL_CLASS_GETSET_STR(_postfix, _member) \
NS_IMPL_CLASS_GETTER_STR(Get##_postfix, _member) \
NS_IMPL_CLASS_SETTER_STR(Set##_postfix, _member)
/* Getter/Setter implementation outside of a class definition */
/* simple data types */
#define NS_IMPL_GETTER(_method, _type, _member) \
NS_IMETHODIMP NS_METHOD_GETTER(_method, _type, _member)
#define NS_IMPL_SETTER(_method, _type, _member) \
NS_IMETHODIMP NS_METHOD_SETTER(_method, _type, _member)
#define NS_IMPL_GETSET(_class, _postfix, _type, _member) \
NS_IMPL_GETTER(_class::Get##_postfix, _type, _member) \
NS_IMPL_SETTER(_class::Set##_postfix, _type, _member)
/* strings */
#define NS_IMPL_GETTER_STR(_method, _member) \
NS_IMETHODIMP NS_METHOD_GETTER_STR(_method, _member)
#define NS_IMPL_SETTER_STR(_method, _member) \
NS_IMETHODIMP NS_METHOD_SETTER_STR(_method, _member)
#define NS_IMPL_GETSET_STR(_class, _postfix, _member) \
NS_IMPL_GETTER_STR(_class::Get##_postfix, _member) \
NS_IMPL_SETTER_STR(_class::Set##_postfix, _member)
#endif

View File

@@ -0,0 +1,178 @@
/* -*- 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 "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 "nsDebug.h"
#include "prlog.h"
#include "prinit.h"
#if defined(XP_UNIX)
/* for abort() */
#include <stdlib.h>
#endif
#if defined(_WIN32)
#include <windows.h>
#elif defined(XP_MAC)
#define TEMP_MAC_HACK
//------------------------
#ifdef TEMP_MAC_HACK
#include <MacTypes.h>
#include <Processes.h>
// TEMPORARY UNTIL WE HAVE MACINTOSH ENVIRONMENT VARIABLES THAT CAN TURN ON
// LOGGING ON MACINTOSH
// At this moment, NSPR's logging is a no-op on Macintosh.
#include <stdarg.h>
#include <stdio.h>
#undef PR_LOG
#define PR_LOG(module,level,args) dprintf args
static void dprintf(const char *format, ...)
{
va_list ap;
Str255 buffer;
va_start(ap, format);
buffer[0] = vsnprintf((char *)buffer + 1, sizeof(buffer) - 1, format, ap);
va_end(ap);
DebugStr(buffer);
}
#endif // TEMP_MAC_HACK
//------------------------
#elif defined(XP_UNIX)
#include<stdlib.h>
#endif
/**
* Implementation of the nsDebug methods. Note that this code is
* always compiled in, in case some other module that uses it is
* compiled with debugging even if this library is not.
*/
static PRLogModuleInfo* gDebugLog;
static void InitLog(void)
{
if (0 == gDebugLog) {
gDebugLog = PR_NewLogModule("nsDebug");
gDebugLog->level = PR_LOG_DEBUG;
}
}
NS_COM void nsDebug::Abort(const char* aFile, PRIntn aLine)
{
InitLog();
PR_LOG(gDebugLog, PR_LOG_ERROR,
("Abort: at file %s, line %d", aFile, aLine));
PR_LogFlush();
#if defined(_WIN32)
long* __p = (long*) 0x7;
*__p = 0x7;
#elif defined(XP_MAC)
ExitToShell();
#elif defined(XP_UNIX)
PR_Abort();
#endif
}
NS_COM void nsDebug::Break(const char* aFile, PRIntn aLine)
{
#ifndef TEMP_MAC_HACK
InitLog();
PR_LOG(gDebugLog, PR_LOG_ERROR,
("Break: at file %s, line %d", aFile, aLine));
PR_LogFlush();
//XXX this works on win32 only for now. For all the other platforms call Abort
#if defined(_WIN32)
::DebugBreak();
#else
Abort(aFile, aLine);
#endif
#endif // TEMP_MAC_HACK
}
NS_COM void nsDebug::PreCondition(const char* aStr, const char* aExpr,
const char* aFile, PRIntn aLine)
{
InitLog();
PR_LOG(gDebugLog, PR_LOG_ERROR,
("PreCondition: \"%s\" (%s) at file %s, line %d", aStr, aExpr,
aFile, aLine));
Break(aFile, aLine);
}
NS_COM void nsDebug::PostCondition(const char* aStr, const char* aExpr,
const char* aFile, PRIntn aLine)
{
InitLog();
PR_LOG(gDebugLog, PR_LOG_ERROR,
("PostCondition: \"%s\" (%s) at file %s, line %d", aStr, aExpr,
aFile, aLine));
Break(aFile, aLine);
}
NS_COM void nsDebug::Assertion(const char* aStr, const char* aExpr,
const char* aFile, PRIntn aLine)
{
InitLog();
PR_LOG(gDebugLog, PR_LOG_ERROR,
("Assertion: \"%s\" (%s) at file %s, line %d", aStr, aExpr,
aFile, aLine));
Break(aFile, aLine);
}
NS_COM void nsDebug::NotYetImplemented(const char* aMessage,
const char* aFile, PRIntn aLine)
{
InitLog();
PR_LOG(gDebugLog, PR_LOG_ERROR,
("NotYetImplemented: \"%s\" at file %s, line %d", aMessage,
aFile, aLine));
Break(aFile, aLine);
}
NS_COM void nsDebug::NotReached(const char* aMessage,
const char* aFile, PRIntn aLine)
{
InitLog();
PR_LOG(gDebugLog, PR_LOG_ERROR,
("NotReached: \"%s\" at file %s, line %d", aMessage, aFile, aLine));
Break(aFile, aLine);
}
NS_COM void nsDebug::Error(const char* aMessage,
const char* aFile, PRIntn aLine)
{
InitLog();
PR_LOG(gDebugLog, PR_LOG_ERROR,
("Error: \"%s\" at file %s, line %d", aMessage, aFile, aLine));
Break(aFile, aLine);
}
NS_COM void nsDebug::Warning(const char* aMessage,
const char* aFile, PRIntn aLine)
{
InitLog();
PR_LOG(gDebugLog, PR_LOG_ERROR,
("Warning: \"%s\" at file %s, line %d", aMessage, aFile, aLine));
PR_LogFlush();
}

View File

@@ -0,0 +1,183 @@
/* -*- 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 "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 nsDebug_h___
#define nsDebug_h___
#include "nsCom.h"
#include "prtypes.h"
#ifdef DEBUG
#define NS_DEBUG
#endif
/**
* Namespace for debugging methods. Note that your code must use the
* macros defined later in this file so that the debug code can be
* conditionally compiled out.
*/
/* in case this is included by a C file */
#ifdef __cplusplus
class nsDebug {
public:
// XXX add in log controls here
// XXX probably want printf type arguments
/**
* Abort the executing program. This works on all architectures.
*/
static NS_COM void Abort(const char* aFile, PRIntn aLine);
/**
* Break the executing program into the debugger.
*/
static NS_COM void Break(const char* aFile, PRIntn aLine);
/**
* Log a pre-condition message to the debug log
*/
static NS_COM void PreCondition(const char* aStr, const char* aExpr,
const char* aFile, PRIntn aLine);
/**
* Log a post-condition message to the debug log
*/
static NS_COM void PostCondition(const char* aStr, const char* aExpr,
const char* aFile, PRIntn aLine);
/**
* Log an assertion message to the debug log
*/
static NS_COM void Assertion(const char* aStr, const char* aExpr,
const char* aFile, PRIntn aLine);
/**
* Log a not-yet-implemented message to the debug log
*/
static NS_COM void NotYetImplemented(const char* aMessage,
const char* aFile, PRIntn aLine);
/**
* Log a not-reached message to the debug log
*/
static NS_COM void NotReached(const char* aMessage,
const char* aFile, PRIntn aLine);
/**
* Log an error message to the debug log. This call returns.
*/
static NS_COM void Error(const char* aMessage,
const char* aFile, PRIntn aLine);
/**
* Log a warning message to the debug log.
*/
static NS_COM void Warning(const char* aMessage,
const char* aFile, PRIntn aLine);
};
#ifdef NS_DEBUG
/**
* Test a precondition for truth. If the expression is not true then
* trigger a program failure.
*/
#define NS_PRECONDITION(expr,str) \
if (!(expr)) \
nsDebug::PreCondition(str, #expr, __FILE__, __LINE__)
/**
* Test an assertion for truth. If the expression is not true then
* trigger a program failure.
*/
#define NS_ASSERTION(expr,str) \
if (!(expr)) \
nsDebug::Assertion(str, #expr, __FILE__, __LINE__)
/**
* Test an assertion for truth. If the expression is not true then
* trigger a program failure. The expression will still be
* executed in release mode.
*/
#define NS_VERIFY(expr,str) \
if (!(expr)) \
nsDebug::Assertion(str, #expr, __FILE__, __LINE__)
/**
* Test a post-condition for truth. If the expression is not true then
* trigger a program failure.
*/
#define NS_POSTCONDITION(expr,str) \
if (!(expr)) \
nsDebug::PostCondition(str, #expr, __FILE__, __LINE__)
/**
* This macros triggers a program failure if executed. It indicates that
* an attempt was made to execute some unimplimented functionality.
*/
#define NS_NOTYETIMPLEMENTED(str) \
nsDebug::NotYetImplemented(str, __FILE__, __LINE__)
/**
* This macros triggers a program failure if executed. It indicates that
* an attempt was made to execute some unimplimented functionality.
*/
#define NS_NOTREACHED(str) \
nsDebug::NotReached(str, __FILE__, __LINE__)
/**
* Log an error message.
*/
#define NS_ERROR(str) \
nsDebug::Error(str, __FILE__, __LINE__)
/**
* Log a warning message.
*/
#define NS_WARNING(str) \
nsDebug::Warning(str, __FILE__, __LINE__)
/**
* Trigger an abort
*/
#define NS_ABORT() \
nsDebug::Abort(__FILE__, __LINE__)
/**
* Cause a break
*/
#define NS_BREAK() \
nsDebug::Break(__FILE__, __LINE__)
#else /* NS_DEBUG */
#define NS_PRECONDITION(expr,str) {}
#define NS_ASSERTION(expr,str) {}
#define NS_VERIFY(expr,str) expr
#define NS_POSTCONDITION(expr,str) {}
#define NS_NOTYETIMPLEMENTED(str) {}
#define NS_NOTREACHED(str) {}
#define NS_ERROR(str) {}
#define NS_WARNING(str) {}
#define NS_ABORT() {}
#define NS_BREAK() {}
#endif /* ! NS_DEBUG */
#endif /* __cplusplus */
#endif /* nsDebug_h___ */

View File

@@ -0,0 +1,195 @@
/* -*- 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 "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 nsError_h
#define nsError_h
#ifndef prtypes_h___
#include "prtypes.h"
#endif
/**
* Generic result data type
*/
typedef PRUint32 nsresult;
/*
* To add error code to your module, you need to do the following:
*
* 1) Add a module offset code. Add yours to the bottom of the list
* right below this comment, adding 1.
*
* 2) In your module, define a header file which uses one of the
* NE_ERROR_GENERATExxxxxx macros. Some examples below:
*
* #define NS_ERROR_MYMODULE_MYERROR1 NS_ERROR_GENERATE(NS_ERROR_SEVERITY_ERROR,NS_ERROR_MODULE_MYMODULE,1)
* #define NS_ERROR_MYMODULE_MYERROR2 NS_ERROR_GENERATE_SUCCESS(NS_ERROR_MODULE_MYMODULE,2)
* #define NS_ERROR_MYMODULE_MYERROR3 NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_MYMODULE,3)
*
*/
/**
* @name Standard Module Offset Code. Each Module should identify a unique number
* and then all errors associated with that module become offsets from the
* base associated with that module id. There are 16 bits of code bits for
* each module.
*/
#define NS_ERROR_MODULE_XPCOM 1
#define NS_ERROR_MODULE_BASE 2
#define NS_ERROR_MODULE_GFX 3
#define NS_ERROR_MODULE_WIDGET 4
#define NS_ERROR_MODULE_CALENDAR 5
#define NS_ERROR_MODULE_NETWORK 6
#define NS_ERROR_MODULE_PLUGINS 7
#define NS_ERROR_MODULE_LAYOUT 8
#define NS_ERROR_MODULE_HTMLPARSER 9
#define NS_ERROR_MODULE_RDF 10
#define NS_ERROR_MODULE_UCONV 11
#define NS_ERROR_MODULE_REG 12
#define NS_ERROR_MODULE_FILES 13
#define NS_ERROR_MODULE_MAILNEWS 16
#define NS_ERROR_MODULE_EDITOR 17
/**
* @name Standard Error Handling Macros
*/
#define NS_FAILED(_nsresult) ((_nsresult) & 0x80000000)
#define NS_SUCCEEDED(_nsresult) (!((_nsresult) & 0x80000000))
/**
* @name Severity Code. This flag identifies the level of warning
*/
#define NS_ERROR_SEVERITY_SUCCESS 0
#define NS_ERROR_SEVERITY_ERROR 1
/**
* @name Mozilla Code. This flag separates consumers of mozilla code
* from the native platform
*/
#define NS_ERROR_MODULE_BASE_OFFSET 0x45
/**
* @name Standard Error Generating Macros
*/
#define NS_ERROR_GENERATE(sev,module,code) \
((nsresult) (((PRUint32)(sev)<<31) | ((PRUint32)(module+NS_ERROR_MODULE_BASE_OFFSET)<<16) | ((PRUint32)(code))) )
#define NS_ERROR_GENERATE_SUCCESS(module,code) \
((nsresult) (((PRUint32)(NS_ERROR_SEVERITY_SUCCESS)<<31) | ((PRUint32)(module+NS_ERROR_MODULE_BASE_OFFSET)<<16) | ((PRUint32)(code))) )
#define NS_ERROR_GENERATE_FAILURE(module,code) \
((nsresult) (((PRUint32)(NS_ERROR_SEVERITY_ERROR)<<31) | ((PRUint32)(module+NS_ERROR_MODULE_BASE_OFFSET)<<16) | ((PRUint32)(code))) )
/**
* @name Standard Macros for retrieving error bits
*/
#if PR_BYTES_PER_INT == 4
#define NS_IS_ERROR(err) (((nsresult)(err))<0)
#else
#define NS_IS_ERROR(err) (((((PRUint32)(err)) >> 31) & 0x1) == NS_ERROR_SEVERITY_ERROR)
#endif
#define NS_ERROR_GET_CODE(err) ((err) & 0xffff)
#define NS_ERROR_GET_MODULE(err) (((((err) >> 16) - NS_ERROR_MODULE_BASE_OFFSET) & 0x1fff))
#define NS_ERROR_GET_SEVERITY(err) (((err) >> 31) & 0x1)
/**
* @name Standard return values
*/
/*@{*/
/* Standard "it worked" return value */
#define NS_OK 0
/* The backwards COM false */
#define NS_COMFALSE 1
#define NS_ERROR_BASE ((nsresult) 0xC1F30000)
/* Returned when an instance is not initialized */
#define NS_ERROR_NOT_INITIALIZED (NS_ERROR_BASE + 1)
/* Returned when an instance is already initialized */
#define NS_ERROR_ALREADY_INITIALIZED (NS_ERROR_BASE + 2)
/* Returned by a not implemented function */
#define NS_ERROR_NOT_IMPLEMENTED ((nsresult) 0x80004001L)
/* Returned when a given interface is not supported. */
#define NS_NOINTERFACE ((nsresult) 0x80004002L)
#define NS_ERROR_NO_INTERFACE NS_NOINTERFACE
#define NS_ERROR_INVALID_POINTER ((nsresult) 0x80004003L)
#define NS_ERROR_NULL_POINTER NS_ERROR_INVALID_POINTER
/* Returned when a function aborts */
#define NS_ERROR_ABORT ((nsresult) 0x80004004L)
/* Returned when a function fails */
#define NS_ERROR_FAILURE ((nsresult) 0x80004005L)
/* Returned when an unexpected error occurs */
#define NS_ERROR_UNEXPECTED ((nsresult) 0x8000ffffL)
/* Returned when a memory allocation failes */
#define NS_ERROR_OUT_OF_MEMORY ((nsresult) 0x8007000eL)
/* Returned when an illegal value is passed */
#define NS_ERROR_ILLEGAL_VALUE ((nsresult) 0x80070057L)
#define NS_ERROR_INVALID_ARG NS_ERROR_ILLEGAL_VALUE
/* Returned when a class doesn't allow aggregation */
#define NS_ERROR_NO_AGGREGATION ((nsresult) 0x80040110L)
/* Returned when a class doesn't allow aggregation */
#define NS_ERROR_NOT_AVAILABLE ((nsresult) 0x80040111L)
/* Returned when a class is not registered */
#define NS_ERROR_FACTORY_NOT_REGISTERED ((nsresult) 0x80040154L)
/* Returned when a dynamically loaded factory couldn't be found */
#define NS_ERROR_FACTORY_NOT_LOADED ((nsresult) 0x800401f8L)
/* Returned when a factory doesn't support signatures */
#define NS_ERROR_FACTORY_NO_SIGNATURE_SUPPORT \
(NS_ERROR_BASE + 0x101)
/* Returned when a factory already is registered */
#define NS_ERROR_FACTORY_EXISTS (NS_ERROR_BASE + 0x100)
/*@}*/
////////////////////////////////////////////////////////////////////////////////
#ifdef XP_PC
#pragma warning(disable: 4251) // 'nsCOMPtr<class nsIInputStream>' needs to have dll-interface to be used by clients of class 'nsInputStream'
#pragma warning(disable: 4275) // non dll-interface class 'nsISupports' used as base for dll-interface class 'nsIRDFNode'
#endif
#endif

View File

@@ -0,0 +1,110 @@
/* -*- 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.
*/
#ifndef nsIAllocator_h___
#define nsIAllocator_h___
#include "nsISupports.h"
/**
* Unlike IMalloc, this interface returns nsresults and doesn't
* implement the problematic GetSize and DidAlloc routines.
*/
#define NS_IALLOCATOR_IID \
{ /* 56def700-b1b9-11d2-8177-006008119d7a */ \
0x56def700, \
0xb1b9, \
0x11d2, \
{0x81, 0x77, 0x00, 0x60, 0x08, 0x11, 0x9d, 0x7a} \
}
class nsIAllocator : public nsISupports {
public:
static const nsIID& GetIID() { static nsIID iid = NS_IALLOCATOR_IID; return iid; }
/**
* Allocates a block of memory of a particular size.
*
* @param size - the size of the block to allocate
* @result the block of memory
*/
NS_IMETHOD_(void*) Alloc(PRUint32 size) = 0;
/**
* Reallocates a block of memory to a new size.
*
* @param ptr - the block of memory to reallocate
* @param size - the new size
* @param oldSize - the current size of the block. If -1 (the default),
* the implementation must be able to determine the block size by
* examining the block pointer.
* @result the rellocated block of memory
*/
NS_IMETHOD_(void*) Realloc(void* ptr, PRUint32 size,
PRInt32 oldSize = -1) = 0;
/**
* Frees a block of memory.
*
* @param ptr - the block of memory to free
* @param size - the size of the block to be freed. If -1 (the default),
* the implementation must be able to determine the block size by
* examining the block pointer.
*/
NS_IMETHOD Free(void* ptr, PRInt32 size = -1) = 0;
/**
* Attempts to shrink the heap.
*/
NS_IMETHOD HeapMinimize(void) = 0;
};
// To get the global memory manager service:
#define NS_ALLOCATOR_CID \
{ /* aafe6770-b1bb-11d2-8177-006008119d7a */ \
0xaafe6770, \
0xb1bb, \
0x11d2, \
{0x81, 0x77, 0x00, 0x60, 0x08, 0x11, 0x9d, 0x7a} \
}
/*
* Public shortcuts to the shared allocator's methods
*/
class nsAllocator
{
public:
static NS_EXPORT void* Alloc(PRUint32 size);
static NS_EXPORT void* Realloc(void* ptr, PRUint32 size);
static NS_EXPORT void Free(void* ptr);
static NS_EXPORT void HeapMinimize();
static NS_EXPORT void* Clone(const void* ptr, PRUint32 size);
private:
nsAllocator(); // not implemented
static PRBool EnsureAllocator() {return mAllocator || FetchAllocator();}
static PRBool FetchAllocator();
static nsIAllocator* mAllocator;
};
////////////////////////////////////////////////////////////////////////////////
#endif /* nsIAllocator_h___ */

View File

@@ -0,0 +1,73 @@
/* -*- 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 "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 "nsID.h"
#include "prprf.h"
static const char gIDFormat[] =
"{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}";
static const char gIDFormat2[] =
"%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x";
/*
* Turns a {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} string into
* an nsID
*/
NS_COM PRBool nsID::Parse(char *aIDStr)
{
PRInt32 count = 0;
PRInt32 n1, n2, n3[8];
PRInt32 n0;
if (NULL != aIDStr) {
count = PR_sscanf(aIDStr,
(aIDStr[0] == '{') ? gIDFormat : gIDFormat2,
&n0, &n1, &n2,
&n3[0],&n3[1],&n3[2],&n3[3],
&n3[4],&n3[5],&n3[6],&n3[7]);
m0 = (PRInt32) n0;
m1 = (PRInt16) n1;
m2 = (PRInt16) n2;
for (int i = 0; i < 8; i++) {
m3[i] = (PRInt8) n3[i];
}
}
return (PRBool) (count == 11);
}
/*
* Returns an allocated string in {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}
* format. Caller should delete [] the string.
*/
NS_COM char *nsID::ToString() const
{
char *res = new char[39];
if (res != NULL) {
PR_snprintf(res, 39, gIDFormat,
m0, (PRUint32) m1, (PRUint32) m2,
(PRUint32) m3[0], (PRUint32) m3[1], (PRUint32) m3[2],
(PRUint32) m3[3], (PRUint32) m3[4], (PRUint32) m3[5],
(PRUint32) m3[6], (PRUint32) m3[7]);
}
return res;
}

101
mozilla/xpcom/base/nsID.h Normal file
View File

@@ -0,0 +1,101 @@
/* -*- 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 "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 nsID_h__
#define nsID_h__
#include "prtypes.h"
#include "string.h"
#include "nsCom.h"
/**
* A "unique identifier". This is modeled after OSF DCE UUIDs.
*/
struct nsID {
/**
* @name Indentifier values
*/
//@{
PRUint32 m0;
PRUint16 m1;
PRUint16 m2;
PRUint8 m3[8];
//@}
/**
* @name Methods
*/
//@{
/**
* Equivalency method. Compares this nsID with another.
* @return <b>PR_TRUE</b> if they are the same, <b>PR_FALSE</b> if not.
*/
inline PRBool Equals(const nsID& other) const {
return (PRBool)
((((PRUint32*) &m0)[0] == ((PRUint32*) &other.m0)[0]) &&
(((PRUint32*) &m0)[1] == ((PRUint32*) &other.m0)[1]) &&
(((PRUint32*) &m0)[2] == ((PRUint32*) &other.m0)[2]) &&
(((PRUint32*) &m0)[3] == ((PRUint32*) &other.m0)[3]));
}
/**
* nsID Parsing method. Turns a {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}
* string into an nsID
*/
NS_COM PRBool Parse(char *aIDStr);
/**
* nsID string encoder. Returns an allocated string in
* {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} format. Caller should free string.
*/
NS_COM char* ToString() const;
//@}
};
/**
* Declare an ID. If NS_IMPL_IDS is set, a variable <i>_name</i> is declared
* with the given values, otherwise <i>_name</i> is declared as an
* <tt>extern</tt> variable.
*/
#ifdef NS_IMPL_IDS
#define NS_DECLARE_ID(_name,m0,m1,m2,m30,m31,m32,m33,m34,m35,m36,m37) \
extern "C" const nsID _name = {m0,m1,m2,{m30,m31,m32,m33,m34,m35,m36,m37}}
#else
#define NS_DECLARE_ID(_name,m0,m1,m2,m30,m31,m32,m33,m34,m35,m36,m37) \
extern "C" const nsID _name
#endif
/*
* Class IDs
*/
typedef nsID nsCID;
// Define an CID
#define NS_DEFINE_CID(_name, _cidspec) \
const nsCID _name = _cidspec
#define REFNSCID const nsCID&
#endif

View File

@@ -0,0 +1,44 @@
/* -*- 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.
*/
#ifndef __nsIID_h
#define __nsIID_h
#include "nsID.h"
/**
* An "interface id" which can be used to uniquely identify a given
* interface.
*/
typedef nsID nsIID;
/**
* A macro shorthand for <tt>const nsIID&<tt>
*/
#define REFNSIID const nsIID&
/**
* Define an IID (obsolete)
*/
#define NS_DEFINE_IID(_name, _iidspec) \
const nsIID _name = _iidspec
#endif /* __nsIID_h */

142
mozilla/xpcom/base/nsIPtr.h Normal file
View File

@@ -0,0 +1,142 @@
/* -*- 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 "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 nsIPtr_h___
#define nsIPtr_h___
#include "nsISupports.h"
/*
* nsIPtr is an "auto-release pointer" class for nsISupports based interfaces
*
* It's intent is to be a "set and forget" pointer to help with managing
* active references to nsISupports bases objects.
*
* The pointer object ensures that the underlying pointer is always
* released whenever the value is changed or when the object leaves scope.
*
* Proper care needs to be taken when assigning pointers to a nsIPtr.
* When asigning from a C pointer (nsISupports*), the pointer presumes
* an active reference and subsumes it. When assigning from another nsIPtr,
* a new reference is established.
*
* There are 3 ways to assign a value to a nsIPtr.
* 1) Direct construction or assignment from a C pointer.
* 2) Direct construction or assignment form another nsIPtr.
* 3) Usage of an "out parameter" method.
* a) AssignRef() releases the underlying pointer and returns a reference to it.
* Useful for pointer reference out paramaters.
* b) AssignPtr() releases the underlying pointer and returns a pointer to it.
* c) Query() releases the underlying pointer and returns a (void**) pointer to it.
* Useful for calls to QueryInterface()
* 4) The SetAddRef() method. This is equivalent to an assignment followed by an AddRef().
*
* examples:
*
* class It {
* void NS_NewFoo(nsIFoo** aFoo);
* nsIFoo* GetFoo(void);
* void GetBar(nsIBar*& aBar);
* };
*
* nsIFooPtr foo = it->GetFoo();
* nsIBarPtr bar;
*
* it->NS_NewFoo(foo.AssignPtr());
* it->GetBar(bar.AssignRef());
* it->QueryInterface(kIFooIID, foo.Query());
* bar.SetAddRef(new Bar());
*
* Advantages:
* Set and forget. Once a pointer is assigned to a nsIPtr, it is impossible
* to forget to release it.
* Always pre-initialized. You can't forget to initialize the pointer.
*
* Disadvantages:
* Usage of this class doesn't eliminate the need to think about ref counts
* and assign values properly, AddRef'ing as needed.
* The nsIPtr doesn't typecast exactly like a C pointer. In order to achieve
* typecasting, it may be necessary to first cast to a C pointer of the
* underlying type.
*
*/
#define NS_DEF_PTR(cls) \
class cls##Ptr { \
public: \
cls##Ptr(void) : mPtr(0) {} \
cls##Ptr(const cls##Ptr& aCopy) : mPtr(aCopy.mPtr) \
{ NS_IF_ADDREF(mPtr); } \
cls##Ptr(cls* aInterface) : mPtr(aInterface) {} \
~cls##Ptr(void) { NS_IF_RELEASE(mPtr); } \
cls##Ptr& operator=(const cls##Ptr& aCopy) \
{ if(mPtr == aCopy.mPtr) return *this; \
NS_IF_ADDREF(aCopy.mPtr); \
NS_IF_RELEASE(mPtr); \
mPtr = aCopy.mPtr; return *this; } \
cls##Ptr& operator=(cls* aInterface) \
{ if(mPtr == aInterface) return *this; \
NS_IF_RELEASE(mPtr); mPtr = aInterface; \
return *this; } \
cls##Ptr& operator=(PRInt32 aInt) \
{ NS_IF_RELEASE(mPtr); \
return *this; } \
void SetAddRef(cls* aInterface) \
{ if(aInterface == mPtr) return; \
NS_IF_ADDREF(aInterface); \
NS_IF_RELEASE(mPtr); mPtr = aInterface; } \
cls* AddRef(void) { NS_ADDREF(mPtr); return mPtr; } \
cls* IfAddRef(void) \
{ NS_IF_ADDREF(mPtr); return mPtr; } \
cls*& AssignRef(void) \
{ NS_IF_RELEASE(mPtr); return mPtr; } \
cls** AssignPtr(void) \
{ NS_IF_RELEASE(mPtr); return &mPtr; } \
void** Query(void) \
{ NS_IF_RELEASE(mPtr); return (void**)&mPtr; } \
PRBool IsNull() const \
{ return PRBool(0 == mPtr); } \
PRBool IsNotNull() const \
{ return PRBool(0 != mPtr); } \
PRBool operator==(const cls##Ptr& aCopy) const \
{ return PRBool(mPtr == aCopy.mPtr); } \
PRBool operator==(cls* aInterface) const \
{ return PRBool(mPtr == aInterface); } \
PRBool operator!=(const cls##Ptr& aCopy) const \
{ return PRBool(mPtr != aCopy.mPtr); } \
PRBool operator!=(cls* aInterface) const \
{ return PRBool(mPtr != aInterface); } \
cls* operator->(void) { return mPtr; } \
cls& operator*(void) { return *mPtr; } \
operator cls*(void) { return mPtr; } \
const cls* operator->(void) const { return mPtr; } \
const cls& operator*(void) const { return *mPtr; } \
operator const cls* (void) const { return mPtr; } \
private: \
void* operator new(size_t size) { return 0; } \
void operator delete(void* aPtr) {} \
cls* mPtr; \
public: \
friend inline PRBool operator==(const cls* aInterface, const cls##Ptr& aPtr) \
{ return PRBool(aInterface == aPtr.mPtr); } \
friend inline PRBool operator!=(const cls* aInterface, const cls##Ptr& aPtr) \
{ return PRBool(aInterface != aPtr.mPtr); } \
}
#endif // nsIPtr_h___

View File

@@ -0,0 +1,557 @@
/* -*- 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.
*/
#ifndef __nsISupportsUtils_h
#define __nsISupportsUtils_h
/**
* A macro to build the static const IID accessor method
*/
#define NS_DEFINE_STATIC_IID_ACCESSOR(the_iid) \
static const nsIID& GetIID() {static nsIID iid = the_iid; return iid;}
/**
* A macro to build the static const CID accessor method
*/
#define NS_DEFINE_STATIC_CID_ACCESSOR(the_cid) \
static const nsID& GetCID() {static nsID cid = the_cid; return cid;}
/**
* Some convenience macros for implementing AddRef and Release
*/
/**
* Declare the reference count variable and the implementations of the
* AddRef and QueryInterface methods.
*/
#define NS_DECL_ISUPPORTS \
public: \
NS_IMETHOD QueryInterface(REFNSIID aIID, \
void** aInstancePtr); \
NS_IMETHOD_(nsrefcnt) AddRef(void); \
NS_IMETHOD_(nsrefcnt) Release(void); \
protected: \
nsrefcnt mRefCnt; \
public:
#define NS_DECL_ISUPPORTS_EXPORTED \
public: \
NS_EXPORT NS_IMETHOD QueryInterface(REFNSIID aIID, \
void** aInstancePtr); \
NS_EXPORT NS_IMETHOD_(nsrefcnt) AddRef(void); \
NS_EXPORT NS_IMETHOD_(nsrefcnt) Release(void); \
protected: \
nsrefcnt mRefCnt; \
public:
////////////////////////////////////////////////////////////////////////////////
/**
* Initialize the reference count variable. Add this to each and every
* constructor you implement.
*/
#define NS_INIT_REFCNT() mRefCnt = 0
#define NS_INIT_ISUPPORTS() NS_INIT_REFCNT() // what it should have been called in the first place
/**
* Use this macro to implement the AddRef method for a given <i>_class</i>
* @param _class The name of the class implementing the method
*/
#define NS_IMPL_ADDREF(_class) \
NS_IMETHODIMP_(nsrefcnt) _class::AddRef(void) \
{ \
NS_PRECONDITION(PRInt32(mRefCnt) >= 0, "illegal refcnt"); \
return ++mRefCnt; \
}
/**
* Use this macro to implement the Release method for a given <i>_class</i>
* @param _class The name of the class implementing the method
*/
#define NS_IMPL_RELEASE(_class) \
NS_IMETHODIMP_(nsrefcnt) _class::Release(void) \
{ \
NS_PRECONDITION(0 != mRefCnt, "dup release"); \
if (--mRefCnt == 0) { \
NS_DELETEXPCOM(this); \
return 0; \
} \
return mRefCnt; \
}
////////////////////////////////////////////////////////////////////////////////
/*
* Some convenience macros for implementing QueryInterface
*/
/**
* This implements query interface with two assumptions: First, the
* class in question implements nsISupports and it's own interface and
* nothing else. Second, the implementation of the class's primary
* inheritance chain leads to it's own interface.
*
* @param _class The name of the class implementing the method
* @param _classiiddef The name of the #define symbol that defines the IID
* for the class (e.g. NS_ISUPPORTS_IID)
*/
#define NS_IMPL_QUERY_INTERFACE(_class,_classiiddef) \
NS_IMETHODIMP _class::QueryInterface(REFNSIID aIID, void** aInstancePtr) \
{ \
if (NULL == aInstancePtr) { \
return NS_ERROR_NULL_POINTER; \
} \
\
*aInstancePtr = NULL; \
\
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID); \
static NS_DEFINE_IID(kClassIID, _classiiddef); \
if (aIID.Equals(kClassIID)) { \
*aInstancePtr = (void*) this; \
NS_ADDREF_THIS(); \
return NS_OK; \
} \
if (aIID.Equals(kISupportsIID)) { \
*aInstancePtr = (void*) ((nsISupports*)this); \
NS_ADDREF_THIS(); \
return NS_OK; \
} \
return NS_NOINTERFACE; \
}
/**
* Convenience macro for implementing all nsISupports methods for
* a simple class.
* @param _class The name of the class implementing the method
* @param _classiiddef The name of the #define symbol that defines the IID
* for the class (e.g. NS_ISUPPORTS_IID)
*/
#define NS_IMPL_ISUPPORTS(_class,_classiiddef) \
NS_IMPL_ADDREF(_class) \
NS_IMPL_RELEASE(_class) \
NS_IMPL_QUERY_INTERFACE(_class,_classiiddef)
////////////////////////////////////////////////////////////////////////////////
/**
* Declare that you're going to inherit from something that already
* implements nsISupports, but also implements an additional interface, thus
* causing an ambiguity. In this case you don't need another mRefCnt, you
* just need to forward the definitions to the appropriate superclass. E.g.
*
* class Bar : public Foo, public nsIBar { // both provide nsISupports
* public:
* NS_DECL_ISUPPORTS_INHERITED
* ...other nsIBar and Bar methods...
* };
*/
#define NS_DECL_ISUPPORTS_INHERITED \
public: \
NS_IMETHOD QueryInterface(REFNSIID aIID, \
void** aInstancePtr); \
NS_IMETHOD_(nsrefcnt) AddRef(void); \
NS_IMETHOD_(nsrefcnt) Release(void); \
/**
* These macros can be used in conjunction with NS_DECL_ISUPPORTS_INHERITED
* to implement the nsISupports methods, forwarding the invocations to a
* superclass that already implements nsISupports.
*
* Note that I didn't make these inlined because they're virtual methods.
*/
#define NS_IMPL_ADDREF_INHERITED(Class, Super) \
NS_IMETHODIMP_(nsrefcnt) Class::AddRef(void) \
{ \
return Super::AddRef(); \
} \
#define NS_IMPL_RELEASE_INHERITED(Class, Super) \
NS_IMETHODIMP_(nsrefcnt) Class::Release(void) \
{ \
return Super::Release(); \
} \
#define NS_IMPL_QUERY_INTERFACE_INHERITED(Class, Super, AdditionalInterface) \
NS_IMETHODIMP Class::QueryInterface(REFNSIID aIID, void** aInstancePtr) \
{ \
if (!aInstancePtr) return NS_ERROR_NULL_POINTER; \
if (aIID.Equals(AdditionalInterface::GetIID())) { \
*aInstancePtr = NS_STATIC_CAST(AdditionalInterface*, this); \
NS_ADDREF_THIS(); \
return NS_OK; \
} \
return Super::QueryInterface(aIID, aInstancePtr); \
} \
#define NS_IMPL_ISUPPORTS_INHERITED(Class, Super, AdditionalInterface) \
NS_IMPL_QUERY_INTERFACE_INHERITED(Class, Super, AdditionalInterface) \
NS_IMPL_ADDREF_INHERITED(Class, Super) \
NS_IMPL_RELEASE_INHERITED(Class, Super) \
////////////////////////////////////////////////////////////////////////////////
/**
*
* Threadsafe implementations of the ISupports convenience macros
*
*/
/**
* IID for the nsIsThreadsafe interface
* {88210890-47a6-11d2-bec3-00805f8a66dc}
*
* This interface is *only* used for debugging purposes to determine if
* a given component is threadsafe.
*/
#define NS_ISTHREADSAFE_IID \
{ 0x88210890, 0x47a6, 0x11d2, \
{0xbe, 0xc3, 0x00, 0x80, 0x5f, 0x8a, 0x66, 0xdc} }
#if defined(NS_MT_SUPPORTED)
#define NS_LOCK_INSTANCE() \
PR_CEnterMonitor((void*)this)
#define NS_UNLOCK_INSTANCE() \
PR_CExitMonitor((void*)this)
/**
* Use this macro to implement the AddRef method for a given <i>_class</i>
* @param _class The name of the class implementing the method
*/
#if defined(XP_PC)
#define NS_IMPL_THREADSAFE_ADDREF(_class) \
NS_IMETHODIMP_(nsrefcnt) _class::AddRef(void) \
{ \
NS_PRECONDITION(PRInt32(mRefCnt) >= 0, "illegal refcnt"); \
return InterlockedIncrement((LONG*)&mRefCnt); \
}
#else /* ! XP_PC */
#define NS_IMPL_THREADSAFE_ADDREF(_class) \
nsrefcnt _class::AddRef(void) \
{ \
nsrefcnt count; \
NS_LOCK_INSTANCE(); \
NS_PRECONDITION(PRInt32(mRefCnt) >= 0, "illegal refcnt"); \
count = ++mRefCnt; \
NS_UNLOCK_INSTANCE(); \
return count; \
}
#endif /* ! XP_PC */
/**
* Use this macro to implement the Release method for a given <i>_class</i>
* @param _class The name of the class implementing the method
*/
#if defined(XP_PC)
#define NS_IMPL_THREADSAFE_RELEASE(_class) \
NS_IMETHODIMP_(nsrefcnt) _class::Release(void) \
{ \
NS_PRECONDITION(0 != mRefCnt, "dup release"); \
if (0 == InterlockedDecrement((LONG*)&mRefCnt)) { \
NS_DELETEXPCOM(this); \
return 0; \
} \
return mRefCnt; /* Not threadsafe but who cares. */ \
}
#else /* ! XP_PC */
#define NS_IMPL_THREADSAFE_RELEASE(_class) \
nsrefcnt _class::Release(void) \
{ \
nsrefcnt count; \
NS_PRECONDITION(0 != mRefCnt, "dup release"); \
NS_LOCK_INSTANCE(); \
count = --mRefCnt; \
NS_UNLOCK_INSTANCE(); \
if (0 == count) { \
NS_DELETEXPCOM(this); \
return 0; \
} \
return count; \
}
#endif /* ! XP_PC */
////////////////////////////////////////////////////////////////////////////////
/*
* Some convenience macros for implementing QueryInterface
*/
/**
* This implements query interface with two assumptions: First, the
* class in question implements nsISupports and it's own interface and
* nothing else. Second, the implementation of the class's primary
* inheritance chain leads to it's own interface.
*
* @param _class The name of the class implementing the method
* @param _classiiddef The name of the #define symbol that defines the IID
* for the class (e.g. NS_ISUPPORTS_IID)
*/
#if defined(NS_DEBUG)
#define NS_VERIFY_THREADSAFE_INTERFACE(_iface) \
if (NULL != (_iface)) { \
nsISupports* tmp; \
static NS_DEFINE_IID(kIsThreadsafeIID, NS_ISTHREADSAFE_IID); \
NS_PRECONDITION((NS_OK == _iface->QueryInterface(kIsThreadsafeIID, \
(void**)&tmp)), \
"Interface is not threadsafe"); \
}
#define NS_IMPL_THREADSAFE_QUERY_INTERFACE(_class,_classiiddef) \
NS_IMETHODIMP _class::QueryInterface(REFNSIID aIID, void** aInstancePtr) \
{ \
if (NULL == aInstancePtr) { \
return NS_ERROR_NULL_POINTER; \
} \
\
*aInstancePtr = NULL; \
\
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID); \
static NS_DEFINE_IID(kIsThreadsafeIID, NS_ISTHREADSAFE_IID); \
static NS_DEFINE_IID(kClassIID, _classiiddef); \
if (aIID.Equals(kClassIID)) { \
*aInstancePtr = (void*) this; \
NS_ADDREF_THIS(); \
return NS_OK; \
} \
if (aIID.Equals(kISupportsIID)) { \
*aInstancePtr = (void*) ((nsISupports*)this); \
NS_ADDREF_THIS(); \
return NS_OK; \
} \
if (aIID.Equals(kIsThreadsafeIID)) { \
return NS_OK; \
} \
return NS_NOINTERFACE; \
}
#else /* !NS_DEBUG */
#define NS_VERIFY_THREADSAFE_INTERFACE(_iface)
#define NS_IMPL_THREADSAFE_QUERY_INTERFACE(_class,_classiiddef) \
NS_IMPL_QUERY_INTERFACE(_class, _classiiddef)
#endif /* !NS_DEBUG */
/**
* Convenience macro for implementing all nsISupports methods for
* a simple class.
* @param _class The name of the class implementing the method
* @param _classiiddef The name of the #define symbol that defines the IID
* for the class (e.g. NS_ISUPPORTS_IID)
*/
#define NS_IMPL_THREADSAFE_ISUPPORTS(_class,_classiiddef) \
NS_IMPL_THREADSAFE_ADDREF(_class) \
NS_IMPL_THREADSAFE_RELEASE(_class) \
NS_IMPL_THREADSAFE_QUERY_INTERFACE(_class,_classiiddef)
#else /* !NS_MT_SUPPORTED */
#define NS_LOCK_INSTANCE()
#define NS_UNLOCK_INSTANCE()
#define NS_IMPL_THREADSAFE_ADDREF(_class) NS_IMPL_ADDREF(_class)
#define NS_IMPL_THREADSAFE_RELEASE(_class) NS_IMPL_RELEASE(_class)
#define NS_VERIFY_THREADSAFE_INTERFACE(_iface)
#define NS_IMPL_THREADSAFE_QUERY_INTERFACE(_class,_classiiddef) \
NS_IMPL_QUERY_INTERFACE(_class, _classiiddef)
#define NS_IMPL_THREADSAFE_ISUPPORTS(_class,_classiiddef) \
NS_IMPL_ADDREF(_class) \
NS_IMPL_RELEASE(_class) \
NS_IMPL_QUERY_INTERFACE(_class,_classiiddef)
#endif /* !NS_MT_SUPPORTED */
////////////////////////////////////////////////////////////////////////////////
// Debugging Macros
////////////////////////////////////////////////////////////////////////////////
/**
* Macro for instantiating a new object that implements nsISupports.
* Use this in your factory methods to allow for refcnt tracing.
* Note that you can only use this if you adhere to the no arguments
* constructor com policy (which you really should!).
* @param _result Where the new instance pointer is stored
* @param _type The type of object to call "new" with.
*/
#ifdef MOZ_TRACE_XPCOM_REFCNT
#define NS_NEWXPCOM(_result,_type) \
PR_BEGIN_MACRO \
_result = new _type(); \
nsTraceRefcnt::Create(_result, #_type, __FILE__, __LINE__); \
PR_END_MACRO
#else
#define NS_NEWXPCOM(_result,_type) \
_result = new _type()
#endif
/**
* Macro for deleting an object that implements nsISupports.
* Use this in your Release methods to allow for refcnt tracing.
* @param _ptr The object to delete.
*/
#ifdef MOZ_TRACE_XPCOM_REFCNT
#define NS_DELETEXPCOM(_ptr) \
PR_BEGIN_MACRO \
nsTraceRefcnt::Destroy((_ptr), __FILE__, __LINE__); \
delete (_ptr); \
PR_END_MACRO
#else
#define NS_DELETEXPCOM(_ptr) \
delete (_ptr)
#endif
/**
* Macro for adding a reference to an interface.
* @param _ptr The interface pointer.
*/
#ifdef MOZ_TRACE_XPCOM_REFCNT
#define NS_ADDREF(_ptr) \
((nsrefcnt) nsTraceRefcnt::AddRef((_ptr), (_ptr)->AddRef(), \
__FILE__, __LINE__))
#else
#define NS_ADDREF(_ptr) \
(_ptr)->AddRef()
#endif
/**
* Macro for adding a reference to this. This macro should be used
* because NS_ADDREF (when tracing) may require an ambiguous cast
* from the pointers primary type to nsISupports. This macro sidesteps
* that entire problem.
*/
#ifdef MOZ_TRACE_XPCOM_REFCNT
#define NS_ADDREF_THIS() \
((nsrefcnt) nsTraceRefcnt::AddRef(this, AddRef(), __FILE__, __LINE__))
#else
#define NS_ADDREF_THIS() \
AddRef()
#endif
/**
* Macro for adding a reference to an interface that checks for NULL.
* @param _ptr The interface pointer.
*/
#ifdef MOZ_TRACE_XPCOM_REFCNT
#define NS_IF_ADDREF(_ptr) \
((0 != (_ptr)) \
? ((nsrefcnt) nsTraceRefcnt::AddRef((_ptr), (_ptr)->AddRef(), __FILE__, \
__LINE__)) \
: 0)
#else
#define NS_IF_ADDREF(_ptr) \
((0 != (_ptr)) ? (_ptr)->AddRef() : 0)
#endif
/**
* Macro for releasing a reference to an interface.
*
* Note that when MOZ_TRACE_XPCOM_REFCNT is defined that the release will
* be done before the trace message is logged. If the reference count
* goes to zero and implementation of Release logs a message, the two
* messages will be logged out of order.
*
* @param _ptr The interface pointer.
*/
#ifdef MOZ_TRACE_XPCOM_REFCNT
#define NS_RELEASE(_ptr) \
PR_BEGIN_MACRO \
nsTraceRefcnt::Release((_ptr), (_ptr)->Release(), __FILE__, __LINE__); \
(_ptr) = 0; \
PR_END_MACRO
#else
#define NS_RELEASE(_ptr) \
PR_BEGIN_MACRO \
(_ptr)->Release(); \
(_ptr) = 0; \
PR_END_MACRO
#endif
/**
* Macro for releasing a reference to an interface, except that this
* macro preserves the return value from the underlying Release call.
* The interface pointer argument will only be NULLed if the reference count
* goes to zero.
*
* Note that when MOZ_TRACE_XPCOM_REFCNT is defined that the release will
* be done before the trace message is logged. If the reference count
* goes to zero and implementation of Release logs a message, the two
* messages will be logged out of order.
*
* @param _ptr The interface pointer.
*/
#ifdef MOZ_TRACE_XPCOM_REFCNT
#define NS_RELEASE2(_ptr, _result) \
PR_BEGIN_MACRO \
_result = ((nsrefcnt) nsTraceRefcnt::Release((_ptr), (_ptr)->Release(), \
__FILE__, __LINE__)); \
if (0 == (_result)) (_ptr) = 0; \
PR_END_MACRO
#else
#define NS_RELEASE2(_ptr, _result) \
PR_BEGIN_MACRO \
_result = (_ptr)->Release(); \
if (0 == (_result)) (_ptr) = 0; \
PR_END_MACRO
#endif
/**
* Macro for releasing a reference to an interface that checks for NULL;
*
* Note that when MOZ_TRACE_XPCOM_REFCNT is defined that the release will
* be done before the trace message is logged. If the reference count
* goes to zero and implementation of Release logs a message, the two
* messages will be logged out of order.
*
* @param _ptr The interface pointer.
*/
#ifdef MOZ_TRACE_XPCOM_REFCNT
#define NS_IF_RELEASE(_ptr) \
PR_BEGIN_MACRO \
((0 != (_ptr)) \
? ((nsrefcnt) nsTraceRefcnt::Release((_ptr), (_ptr)->Release(), \
__FILE__, __LINE__)) \
: 0); \
(_ptr) = 0; \
PR_END_MACRO
#else
#define NS_IF_RELEASE(_ptr) \
PR_BEGIN_MACRO \
((0 != (_ptr)) ? (_ptr)->Release() : 0); \
(_ptr) = 0; \
PR_END_MACRO
#endif
////////////////////////////////////////////////////////////////////////////////
#endif /* __nsISupportsUtils_h */

View File

@@ -0,0 +1,318 @@
/* -*- 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 "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 "nsISupports.h"
#include "prprf.h"
#include "prlog.h"
#if defined(_WIN32)
#include <windows.h>
#endif
#if defined(NS_MT_SUPPORTED)
#include "prlock.h"
static PRLock* gTraceLock;
#define LOCK_TRACELOG() PR_Lock(gTraceLock)
#define UNLOCK_TRACELOG() PR_Unlock(gTraceLock)
#else /* ! NT_MT_SUPPORTED */
#define LOCK_TRACELOG()
#define UNLOCK_TRACELOG()
#endif /* ! NS_MT_SUPPORTED */
#if defined(MOZ_TRACE_XPCOM_REFCNT)
static PRLogModuleInfo* gTraceRefcntLog;
static void InitTraceLog(void)
{
if (0 == gTraceRefcntLog) {
gTraceRefcntLog = PR_NewLogModule("xpcomrefcnt");
#if defined(NS_MT_SUPPORTED)
gTraceLock = PR_NewLock();
#endif /* NS_MT_SUPPORTED */
}
}
#if defined(_WIN32)
#include "imagehlp.h"
#include <stdio.h>
#if 0
static BOOL __stdcall
EnumSymbolsCB(LPSTR aSymbolName,
ULONG aSymbolAddress,
ULONG aSymbolSize,
PVOID aUserContext)
{
int* countp = (int*) aUserContext;
int count = *countp;
if (count < 3) {
printf(" %p[%4d]: %s\n", aSymbolAddress, aSymbolSize, aSymbolName);
count++;
*countp = count++;
}
return TRUE;
}
static BOOL __stdcall
EnumModulesCB(LPSTR aModuleName,
ULONG aBaseOfDll,
PVOID aUserContext)
{
HANDLE myProcess = ::GetCurrentProcess();
printf("module=%s dll=%x\n", aModuleName, aBaseOfDll);
// int count = 0;
// SymEnumerateSymbols(myProcess, aBaseOfDll, EnumSymbolsCB, (void*) &count);
return TRUE;
}
#endif
/**
* Walk the stack, translating PC's found into strings and recording the
* chain in aBuffer. For this to work properly, the dll's must be rebased
* so that the address in the file agrees with the address in memory.
* Otherwise StackWalk will return FALSE when it hits a frame in a dll's
* whose in memory address doesn't match it's in-file address.
*
* Fortunately, there is a handy dandy routine in IMAGEHLP.DLL that does
* the rebasing and accordingly I've made a tool to use it to rebase the
* DLL's in one fell swoop (see xpcom/tools/windows/rebasedlls.cpp).
*/
void
nsTraceRefcnt::WalkTheStack(char* aBuffer, int aBufLen)
{
CONTEXT context;
STACKFRAME frame;
char* cp = aBuffer;
aBuffer[0] = '\0';
aBufLen--; // leave room for nul
HANDLE myProcess = ::GetCurrentProcess();
HANDLE myThread = ::GetCurrentThread();
// Get the context information for this thread. That way we will
// know where our sp, fp, pc, etc. are and can fill in the
// STACKFRAME with the initial values.
context.ContextFlags = CONTEXT_FULL;
GetThreadContext(myThread, &context);
if (!SymInitialize(myProcess, ".;..\\lib", TRUE)) {
return;
}
#if 0
SymEnumerateModules(myProcess, EnumModulesCB, NULL);
#endif
// Setup initial stack frame to walk from
memset(&frame, 0, sizeof(frame));
frame.AddrPC.Mode = AddrModeFlat;
frame.AddrPC.Offset = context.Eip;
frame.AddrReturn.Mode = AddrModeFlat;
frame.AddrReturn.Offset = context.Ebp;
frame.AddrFrame.Mode = AddrModeFlat;
frame.AddrFrame.Offset = context.Ebp;
frame.AddrStack.Mode = AddrModeFlat;
frame.AddrStack.Offset = context.Esp;
frame.Params[0] = context.Eax;
frame.Params[1] = context.Ecx;
frame.Params[2] = context.Edx;
frame.Params[3] = context.Ebx;
// Now walk the stack and map the pc's to symbol names that we stuff
// append to *cp.
int skip = 2;
int syms = 0;
while (aBufLen > 0) {
char symbolBuffer[sizeof(IMAGEHLP_SYMBOL) + 512];
PIMAGEHLP_SYMBOL pSymbol = (PIMAGEHLP_SYMBOL) symbolBuffer;
pSymbol->SizeOfStruct = sizeof(symbolBuffer);
pSymbol->MaxNameLength = 512;
DWORD oldAddress = frame.AddrPC.Offset;
BOOL b = ::StackWalk(IMAGE_FILE_MACHINE_I386, myProcess, myThread,
&frame, &context, NULL,
SymFunctionTableAccess,
SymGetModuleBase,
NULL);
if (!b || (0 == frame.AddrPC.Offset)) {
if (syms <= 1) {
skip = 7;
}
break;
}
if (--skip >= 0) {
continue;
}
DWORD disp;
if (SymGetSymFromAddr(myProcess, frame.AddrPC.Offset, &disp, pSymbol)) {
int nameLen = strlen(pSymbol->Name);
if (nameLen + 2 > aBufLen) {
break;
}
memcpy(cp, pSymbol->Name, nameLen);
cp += nameLen;
*cp++ = ' ';
aBufLen -= nameLen + 1;
syms++;
}
else {
if (11 > aBufLen) {
break;
}
char tmp[30];
PR_snprintf(tmp, sizeof(tmp), "0x%08x ", frame.AddrPC.Offset);
memcpy(cp, tmp, 11);
cp += 11;
aBufLen -= 11;
syms++;
}
}
*cp = 0;
}
#endif /* _WIN32 */
#else /* MOZ_TRACE_XPCOM_REFCNT */
void
nsTraceRefcnt::WalkTheStack(char* aBuffer, int aBufLen)
{
aBuffer[0] = '\0';
}
#endif /* MOZ_TRACE_XPCOM_REFCNT */
NS_COM void
nsTraceRefcnt::LoadLibrarySymbols(const char* aLibraryName,
void* aLibrayHandle)
{
#ifdef MOZ_TRACE_XPCOM_REFCNT
#if defined(_WIN32)
InitTraceLog();
if (PR_LOG_TEST(gTraceRefcntLog,PR_LOG_DEBUG)) {
HANDLE myProcess = ::GetCurrentProcess();
if (!SymInitialize(myProcess, ".;..\\lib", TRUE)) {
return;
}
BOOL b = ::SymLoadModule(myProcess,
NULL,
(char*)aLibraryName,
(char*)aLibraryName,
0,
0);
// DWORD lastError = 0;
// if (!b) lastError = ::GetLastError();
// printf("loading symbols for library %s => %s [%d]\n", aLibraryName,
// b ? "true" : "false", lastError);
}
#endif
#endif
}
NS_COM unsigned long
nsTraceRefcnt::AddRef(void* aPtr,
unsigned long aNewRefcnt,
const char* aFile,
PRIntn aLine)
{
#ifdef MOZ_TRACE_XPCOM_REFCNT
InitTraceLog();
LOCK_TRACELOG();
if (PR_LOG_TEST(gTraceRefcntLog,PR_LOG_DEBUG)) {
char sb[1000];
WalkTheStack(sb, sizeof(sb));
PR_LOG(gTraceRefcntLog, PR_LOG_DEBUG,
("AddRef: %p: %d=>%d [%s] in %s (line %d)",
aPtr, aNewRefcnt-1, aNewRefcnt, sb, aFile, aLine));
}
UNLOCK_TRACELOG();
#endif
return aNewRefcnt;
}
NS_COM unsigned long
nsTraceRefcnt::Release(void* aPtr,
unsigned long aNewRefcnt,
const char* aFile,
PRIntn aLine)
{
#ifdef MOZ_TRACE_XPCOM_REFCNT
InitTraceLog();
LOCK_TRACELOG();
if (PR_LOG_TEST(gTraceRefcntLog,PR_LOG_DEBUG)) {
char sb[1000];
WalkTheStack(sb, sizeof(sb));
PR_LOG(gTraceRefcntLog, PR_LOG_DEBUG,
("Release: %p: %d=>%d [%s] in %s (line %d)",
aPtr, aNewRefcnt+1, aNewRefcnt, sb, aFile, aLine));
}
UNLOCK_TRACELOG();
#endif
return aNewRefcnt;
}
NS_COM void
nsTraceRefcnt::Create(void* aPtr,
const char* aType,
const char* aFile,
PRIntn aLine)
{
#ifdef MOZ_TRACE_XPCOM_REFCNT
InitTraceLog();
LOCK_TRACELOG();
if (PR_LOG_TEST(gTraceRefcntLog,PR_LOG_DEBUG)) {
char sb[1000];
WalkTheStack(sb, sizeof(sb));
PR_LOG(gTraceRefcntLog, PR_LOG_DEBUG,
("Create: %p[%s]: [%s] in %s (line %d)",
aPtr, aType, sb, aFile, aLine));
}
UNLOCK_TRACELOG();
#endif
}
NS_COM void
nsTraceRefcnt::Destroy(void* aPtr,
const char* aFile,
PRIntn aLine)
{
#ifdef MOZ_TRACE_XPCOM_REFCNT
InitTraceLog();
LOCK_TRACELOG();
if (PR_LOG_TEST(gTraceRefcntLog,PR_LOG_DEBUG)) {
char sb[1000];
WalkTheStack(sb, sizeof(sb));
PR_LOG(gTraceRefcntLog, PR_LOG_DEBUG,
("Destroy: %p: [%s] in %s (line %d)",
aPtr, sb, aFile, aLine));
}
UNLOCK_TRACELOG();
#endif
}

View File

@@ -0,0 +1,61 @@
/* -*- 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 "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.
*/
#ifndef nsTraceRefcnt_h___
#define nsTraceRefcnt_h___
#include "nsCom.h"
/**
* This class is used to support tracing (and logging using nspr) of
* addref and release calls. Note that only calls that use the
* NS_ADDREF and related macros in nsISupports can be traced.
*
* The name of the nspr log module is "xpcomrefcnt" (case matters).
*
* This code only performs tracing built with debugging AND when
* built with -DMOZ_TRACE_XPCOM_REFCNT (because it's expensive!).
*/
class nsTraceRefcnt {
public:
static NS_COM unsigned long AddRef(void* aPtr,
unsigned long aNewRefcnt,
const char* aFile,
int aLine);
static NS_COM unsigned long Release(void* aPtr,
unsigned long aNewRefcnt,
const char* aFile,
int aLine);
static NS_COM void Create(void* aPtr,
const char* aType,
const char* aFile,
int aLine);
static NS_COM void Destroy(void* aPtr,
const char* aFile,
int aLine);
static NS_COM void LoadLibrarySymbols(const char* aLibraryName,
void* aLibrayHandle);
static NS_COM void WalkTheStack(char* aBuffer, int aBufLen);
};
#endif /* nsTraceRefcnt_h___ */

View File

@@ -0,0 +1,318 @@
/* -*- 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 "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 "nsISupports.h"
#include "prprf.h"
#include "prlog.h"
#if defined(_WIN32)
#include <windows.h>
#endif
#if defined(NS_MT_SUPPORTED)
#include "prlock.h"
static PRLock* gTraceLock;
#define LOCK_TRACELOG() PR_Lock(gTraceLock)
#define UNLOCK_TRACELOG() PR_Unlock(gTraceLock)
#else /* ! NT_MT_SUPPORTED */
#define LOCK_TRACELOG()
#define UNLOCK_TRACELOG()
#endif /* ! NS_MT_SUPPORTED */
#if defined(MOZ_TRACE_XPCOM_REFCNT)
static PRLogModuleInfo* gTraceRefcntLog;
static void InitTraceLog(void)
{
if (0 == gTraceRefcntLog) {
gTraceRefcntLog = PR_NewLogModule("xpcomrefcnt");
#if defined(NS_MT_SUPPORTED)
gTraceLock = PR_NewLock();
#endif /* NS_MT_SUPPORTED */
}
}
#if defined(_WIN32)
#include "imagehlp.h"
#include <stdio.h>
#if 0
static BOOL __stdcall
EnumSymbolsCB(LPSTR aSymbolName,
ULONG aSymbolAddress,
ULONG aSymbolSize,
PVOID aUserContext)
{
int* countp = (int*) aUserContext;
int count = *countp;
if (count < 3) {
printf(" %p[%4d]: %s\n", aSymbolAddress, aSymbolSize, aSymbolName);
count++;
*countp = count++;
}
return TRUE;
}
static BOOL __stdcall
EnumModulesCB(LPSTR aModuleName,
ULONG aBaseOfDll,
PVOID aUserContext)
{
HANDLE myProcess = ::GetCurrentProcess();
printf("module=%s dll=%x\n", aModuleName, aBaseOfDll);
// int count = 0;
// SymEnumerateSymbols(myProcess, aBaseOfDll, EnumSymbolsCB, (void*) &count);
return TRUE;
}
#endif
/**
* Walk the stack, translating PC's found into strings and recording the
* chain in aBuffer. For this to work properly, the dll's must be rebased
* so that the address in the file agrees with the address in memory.
* Otherwise StackWalk will return FALSE when it hits a frame in a dll's
* whose in memory address doesn't match it's in-file address.
*
* Fortunately, there is a handy dandy routine in IMAGEHLP.DLL that does
* the rebasing and accordingly I've made a tool to use it to rebase the
* DLL's in one fell swoop (see xpcom/tools/windows/rebasedlls.cpp).
*/
void
nsTraceRefcnt::WalkTheStack(char* aBuffer, int aBufLen)
{
CONTEXT context;
STACKFRAME frame;
char* cp = aBuffer;
aBuffer[0] = '\0';
aBufLen--; // leave room for nul
HANDLE myProcess = ::GetCurrentProcess();
HANDLE myThread = ::GetCurrentThread();
// Get the context information for this thread. That way we will
// know where our sp, fp, pc, etc. are and can fill in the
// STACKFRAME with the initial values.
context.ContextFlags = CONTEXT_FULL;
GetThreadContext(myThread, &context);
if (!SymInitialize(myProcess, ".;..\\lib", TRUE)) {
return;
}
#if 0
SymEnumerateModules(myProcess, EnumModulesCB, NULL);
#endif
// Setup initial stack frame to walk from
memset(&frame, 0, sizeof(frame));
frame.AddrPC.Mode = AddrModeFlat;
frame.AddrPC.Offset = context.Eip;
frame.AddrReturn.Mode = AddrModeFlat;
frame.AddrReturn.Offset = context.Ebp;
frame.AddrFrame.Mode = AddrModeFlat;
frame.AddrFrame.Offset = context.Ebp;
frame.AddrStack.Mode = AddrModeFlat;
frame.AddrStack.Offset = context.Esp;
frame.Params[0] = context.Eax;
frame.Params[1] = context.Ecx;
frame.Params[2] = context.Edx;
frame.Params[3] = context.Ebx;
// Now walk the stack and map the pc's to symbol names that we stuff
// append to *cp.
int skip = 2;
int syms = 0;
while (aBufLen > 0) {
char symbolBuffer[sizeof(IMAGEHLP_SYMBOL) + 512];
PIMAGEHLP_SYMBOL pSymbol = (PIMAGEHLP_SYMBOL) symbolBuffer;
pSymbol->SizeOfStruct = sizeof(symbolBuffer);
pSymbol->MaxNameLength = 512;
DWORD oldAddress = frame.AddrPC.Offset;
BOOL b = ::StackWalk(IMAGE_FILE_MACHINE_I386, myProcess, myThread,
&frame, &context, NULL,
SymFunctionTableAccess,
SymGetModuleBase,
NULL);
if (!b || (0 == frame.AddrPC.Offset)) {
if (syms <= 1) {
skip = 7;
}
break;
}
if (--skip >= 0) {
continue;
}
DWORD disp;
if (SymGetSymFromAddr(myProcess, frame.AddrPC.Offset, &disp, pSymbol)) {
int nameLen = strlen(pSymbol->Name);
if (nameLen + 2 > aBufLen) {
break;
}
memcpy(cp, pSymbol->Name, nameLen);
cp += nameLen;
*cp++ = ' ';
aBufLen -= nameLen + 1;
syms++;
}
else {
if (11 > aBufLen) {
break;
}
char tmp[30];
PR_snprintf(tmp, sizeof(tmp), "0x%08x ", frame.AddrPC.Offset);
memcpy(cp, tmp, 11);
cp += 11;
aBufLen -= 11;
syms++;
}
}
*cp = 0;
}
#endif /* _WIN32 */
#else /* MOZ_TRACE_XPCOM_REFCNT */
void
nsTraceRefcnt::WalkTheStack(char* aBuffer, int aBufLen)
{
aBuffer[0] = '\0';
}
#endif /* MOZ_TRACE_XPCOM_REFCNT */
NS_COM void
nsTraceRefcnt::LoadLibrarySymbols(const char* aLibraryName,
void* aLibrayHandle)
{
#ifdef MOZ_TRACE_XPCOM_REFCNT
#if defined(_WIN32)
InitTraceLog();
if (PR_LOG_TEST(gTraceRefcntLog,PR_LOG_DEBUG)) {
HANDLE myProcess = ::GetCurrentProcess();
if (!SymInitialize(myProcess, ".;..\\lib", TRUE)) {
return;
}
BOOL b = ::SymLoadModule(myProcess,
NULL,
(char*)aLibraryName,
(char*)aLibraryName,
0,
0);
// DWORD lastError = 0;
// if (!b) lastError = ::GetLastError();
// printf("loading symbols for library %s => %s [%d]\n", aLibraryName,
// b ? "true" : "false", lastError);
}
#endif
#endif
}
NS_COM unsigned long
nsTraceRefcnt::AddRef(void* aPtr,
unsigned long aNewRefcnt,
const char* aFile,
PRIntn aLine)
{
#ifdef MOZ_TRACE_XPCOM_REFCNT
InitTraceLog();
LOCK_TRACELOG();
if (PR_LOG_TEST(gTraceRefcntLog,PR_LOG_DEBUG)) {
char sb[1000];
WalkTheStack(sb, sizeof(sb));
PR_LOG(gTraceRefcntLog, PR_LOG_DEBUG,
("AddRef: %p: %d=>%d [%s] in %s (line %d)",
aPtr, aNewRefcnt-1, aNewRefcnt, sb, aFile, aLine));
}
UNLOCK_TRACELOG();
#endif
return aNewRefcnt;
}
NS_COM unsigned long
nsTraceRefcnt::Release(void* aPtr,
unsigned long aNewRefcnt,
const char* aFile,
PRIntn aLine)
{
#ifdef MOZ_TRACE_XPCOM_REFCNT
InitTraceLog();
LOCK_TRACELOG();
if (PR_LOG_TEST(gTraceRefcntLog,PR_LOG_DEBUG)) {
char sb[1000];
WalkTheStack(sb, sizeof(sb));
PR_LOG(gTraceRefcntLog, PR_LOG_DEBUG,
("Release: %p: %d=>%d [%s] in %s (line %d)",
aPtr, aNewRefcnt+1, aNewRefcnt, sb, aFile, aLine));
}
UNLOCK_TRACELOG();
#endif
return aNewRefcnt;
}
NS_COM void
nsTraceRefcnt::Create(void* aPtr,
const char* aType,
const char* aFile,
PRIntn aLine)
{
#ifdef MOZ_TRACE_XPCOM_REFCNT
InitTraceLog();
LOCK_TRACELOG();
if (PR_LOG_TEST(gTraceRefcntLog,PR_LOG_DEBUG)) {
char sb[1000];
WalkTheStack(sb, sizeof(sb));
PR_LOG(gTraceRefcntLog, PR_LOG_DEBUG,
("Create: %p[%s]: [%s] in %s (line %d)",
aPtr, aType, sb, aFile, aLine));
}
UNLOCK_TRACELOG();
#endif
}
NS_COM void
nsTraceRefcnt::Destroy(void* aPtr,
const char* aFile,
PRIntn aLine)
{
#ifdef MOZ_TRACE_XPCOM_REFCNT
InitTraceLog();
LOCK_TRACELOG();
if (PR_LOG_TEST(gTraceRefcntLog,PR_LOG_DEBUG)) {
char sb[1000];
WalkTheStack(sb, sizeof(sb));
PR_LOG(gTraceRefcntLog, PR_LOG_DEBUG,
("Destroy: %p: [%s] in %s (line %d)",
aPtr, sb, aFile, aLine));
}
UNLOCK_TRACELOG();
#endif
}

View File

@@ -0,0 +1,61 @@
/* -*- 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 "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.
*/
#ifndef nsTraceRefcnt_h___
#define nsTraceRefcnt_h___
#include "nsCom.h"
/**
* This class is used to support tracing (and logging using nspr) of
* addref and release calls. Note that only calls that use the
* NS_ADDREF and related macros in nsISupports can be traced.
*
* The name of the nspr log module is "xpcomrefcnt" (case matters).
*
* This code only performs tracing built with debugging AND when
* built with -DMOZ_TRACE_XPCOM_REFCNT (because it's expensive!).
*/
class nsTraceRefcnt {
public:
static NS_COM unsigned long AddRef(void* aPtr,
unsigned long aNewRefcnt,
const char* aFile,
int aLine);
static NS_COM unsigned long Release(void* aPtr,
unsigned long aNewRefcnt,
const char* aFile,
int aLine);
static NS_COM void Create(void* aPtr,
const char* aType,
const char* aFile,
int aLine);
static NS_COM void Destroy(void* aPtr,
const char* aFile,
int aLine);
static NS_COM void LoadLibrarySymbols(const char* aLibraryName,
void* aLibrayHandle);
static NS_COM void WalkTheStack(char* aBuffer, int aBufLen);
};
#endif /* nsTraceRefcnt_h___ */

View File

@@ -0,0 +1,168 @@
/* -*- 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 "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 __mozIClassRegistry_h
#define __mozIClassRegistry_h
#include "nsIComponentManager.h"
/*---------------------------- mozIClassRegistry -------------------------------
| This interface provides access to a mapping from mnemonic interface names |
| to shared libraries where implementations of those interfaces can be located.|
| |
| This interface is designed to provide two things: |
| 1. A means of less static binding between clients and the code that |
| implements the XPCOM interfaces those clients use. This accomplished |
| by the mapping from interface names to nsCID (and the shared libraries |
| that implement those classes). |
| 2. A means of dynamically changing the mapping from interface name to |
| implementation. The canonical example of this is to switch to a |
| "native" widget set versus an "XP" (implemented using gfx) set. |
| |
| The first goal is achieved by storing (in a "Netscape Registry" file, see |
| nsReg.h) information that maps interface/class "names" to information about |
| where to load implementations of those interfaces. That information |
| includes the interface ID, class ID (of the implementation class), and the |
| name of the shared library that contains the implementation. |
| |
| The class registry object will register those classes with the "repository" |
| (see nsComponentManager.h) the first time a request is made to create an |
| instance. Subsequent requests will simply be forwarded to the repository |
| after the appropriate interface and class IDs are determined. |
| |
| The second goal is accomplished by permitting the mnemonic interface |
| "names" to be "overloaded", that is, mapped to distinct implementations |
| by separate class registry objects. Further, class registries can be |
| cascaded: they can be chained together so that when a name is not |
| recognized by one registry, it can pass the request to the next registry in |
| the chain. Users can control resolution by making the request of a |
| registry further up/down the chain. |
| |
| For example, consider the case of "native" vs. "gfx" widgets. This might |
| be structured by a class registry arrangment like this: |
| |
| nativeWidgetRegistry baseWidgetRegistry |
| +----------+ +----------+ |
| | ----+---------------->| | |
| +----------+ +----------+ |
| |toolbar| -+-----+ |toolbar| -+-----+ |
| +----------+ | +----------+ | |
| |button | -+-----+ |button | -+-----+ |
| +----------+ | +----------+ | |
| V V |
| +-----------------+ +-----------------+ |
| | native.dll | | base.dll | |
| +-----------------+ +-----------------+ |
| |
| If a specialized implementation of widgets is present (e.g., native.dll) |
| then a corresponding class registry object is created and added to the |
| head of the registry chain. Object creation requests (normal ones) are |
| resolved to the native implementation. If such a library is not present, |
| then the resolution is to the base implementation. If objects of the |
| base implementation are required, then creation requests can be directed |
| directly to the baseWidgetRegistry object, rather than the head of the |
| registry chain. |
| |
| It is intended that there be a single instance of this interface, accessed |
| via the Service Manager (see nsServiceManager.h). |
------------------------------------------------------------------------------*/
struct mozIClassRegistry : public ISupports {
/*------------------------------ CreateInstance ----------------------------
| Create an instance of the requested class/interface. The interface |
| ID is required to specify how the result will be treated. The class |
| named by aName must support this interface. The result is placed in |
| ncomment aResult (NULL if the request fails). "start" specifies the |
| registry at which the search for an implementation of the named |
| interface should start. It defaults to 0 (indicating to start at the |
| head of the registry chain). |
--------------------------------------------------------------------------*/
NS_IMETHOD CreateInstance( const char *anInterfaceName,
const nsIID &aIID,
void* *aResult,
const char *start = 0 ) = 0;
/*--------------------------- CreateEnumerator -----------------------------
| Creates an nsIEnumerator interface object that can be used to examine |
| the contents of the registry. "pattern" specifies either "*" or the |
| name of a specific interface that you want to query. "result" will |
| be set to point to a new object (which will be freed on the last call |
| to its Release() member). See nsIEnumerator.h for details on how to |
| use the returned interface pointer. |
--------------------------------------------------------------------------*/
NS_IMETHOD CreateEnumerator( const char *pattern,
nsIEnumerator* *result ) = 0;
}; // mozIClassRegistry
/*-------------------------- mozIClassRegistryEntry ----------------------------
| Objects of this class represent the individual elements that comprise a |
| mozIClassRegistry interface. You obtain such objects by applying the |
| CreateEnumerator member function to the class registry and then applying |
| the CurrentItem member function to the resulting nsIEnumerator interface. |
| |
| Each entry can be queried for the following information: |
| o sub-registry name |
| o interface name |
| o Class ID |
| o IIDs implemented |
| |
| The information obtained from the entry (specifically, the const char* |
| strings) remains valid for the life of the entry (i.e., until you |
| Release() it). |
| |
| Here is an example of code that uses this interface to dump the contents |
| of a mozIClassRegistry: |
| |
| mozIClassRegistry *reg = nsServiceManager::GetService( kIDRegistry ); |
| nsIEnumerator *enum; |
| reg->CreateEnumerator( "*", &enum ); |
| for ( enum->First(); !enum->IsDone(); enum->Next(); ) { |
| mozIClassRegistryEntry *entry; |
| enum->CurrentItem( &entry ); |
| const char *subreg; |
| const char *name; |
| nsCID cid; |
| int numIIDs; |
| entry->GetSubRegistryName( &subreg ); |
| entry->GetInterfaceName( &name ); |
| entry->GetClassID( &cid ); |
| entry->GetNumIIDs( &numIIDs ); |
| cout << subreg << "/" << name << " = " << cid.ToString() << endl; |
| for ( int i = 0; i < numIIDs; i++ ) { |
| nsIID iid; |
| entry->GetInterfaceID( i, &iid ); |
| cout << "/tIID[" << i << "] = " << iid.ToString() << endl; |
| } |
| entry->Release(); |
| } |
| enum->Release(); |
------------------------------------------------------------------------------*/
struct mozIClassRegistryEntry : public nsISupports {
NS_IMETHOD GetSubRegistryName( const char **result ) = 0;
NS_IMETHOD GetInterfaceName( const char **result ) = 0;
NS_IMETHOD GetClassID( nsCID *result ) = 0;
NS_IMETHOD GetNumIIDs( int *result ) = 0;
NS_IMETHOD GetInterfaceID( int n, nsIID *result ) = 0;
}; // mozIClassRegistryEntry
// {5D41A440-8E37-11d2-8059-00600811A9C3}
#define MOZ_ICLASSREGISTRY_IID { 0x5d41a440, 0x8e37, 0x11d2, { 0x80, 0x59, 0x0, 0x60, 0x8, 0x11, 0xa9, 0xc3 } }
// {D1B54831-AC07-11d2-805E-00600811A9C3}
#define MOZ_ICLASSREGISTRYENTRY_IID { 0xd1b54831, 0xac07, 0x11d2, { 0x80, 0x5e, 0x0, 0x60, 0x8, 0x11, 0xa9, 0xc3 } }
#endif

View File

@@ -0,0 +1,326 @@
/* -*- 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 "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 __mozIRegistry_h
#define __mozIRegistry_h
#include "nsISupports.h"
class nsIEnumerator;
/*------------------------------- mozIRegistry ---------------------------------
| This interface provides access to a tree of arbitrary values. |
| |
| Each node of the tree contains either a value or a subtree or both. |
| |
| The value at any of these leaf nodes can be any of these "primitive" types: |
| o string (null terminated UTF string) |
| o array of 32-bit integers |
| o arbitrary array of bytes |
| o file identifier |
| Of course, since you can store an arbitrary array of bytes, you can put |
| any data you like into a registry (although you have the burden of |
| encoding/decoding your data in that case). |
| |
| Each branch of the tree is labelled with a string "key." The entire path |
| from a given point of the tree to another point further down can be |
| presented as a single string composed of each branch's label, concatenated |
| to the next, with an intervening forward slash ('/'). The term "key" |
| refers to both specific tree branch labels and to such concatenated paths. |
| |
| The branches from a given node must have unique labels. Distinct nodes can |
| have branches with the same label. |
| |
| For example, here's a small registry tree: |
| | |
| /\ |
| / \ |
| / \ |
| / \ |
| "Classes" "Users" |
| / \ |
| / \ |
| / ["joe"] |
| / / \ |
| | / \ |
| /\ / \ |
| / \ "joe" "bob" |
| / \ / \ |
| / \ |
| "{xxxx-xx-1}" "{xxxx-xx-2}" ["c:/joe"] ["d:/Robert"] |
| | | |
| /\ /\ |
| / \ / \ |
| / \ / \ |
| "Library" "Version" "Library" "Version" |
| / \ / \ |
| ["foo.dll"] 2 ["bar.dll"] 1 |
| |
| In this example, there are 2 keys under the root: "Classes" and "Users". |
| The first denotes a subtree only (which has two subtrees, ...). The second |
| denotes both a value ["joe"] and two subtrees labelled "joe" and "bob". |
| The value at the node "/Users" is ["joe"], at "/Users/bob" is ["d:/Robert"]. |
| The value at "/Classes/{xxxx-xx-1}/Version" is 2. |
| |
| The registry interface provides functions that let you navigate the tree |
| and manipulate it's contents. |
| |
| Please note that the registry itself does not impose any structure or |
| meaning on the contents of the tree. For example, the registry doesn't |
| control whether the value at the key "/Users" is the label for the subtree |
| with information about the last active user. That meaning is applied by |
| the code that stores these values and uses them for that purpose. |
| |
| [Any resemblence between this example and actual contents of any actual |
| registry is purely coincidental.] |
------------------------------------------------------------------------------*/
struct mozIRegistry : public nsISupports {
/*------------------------------ Constants ---------------------------------
| The following enumerated types and values are used by the registry |
| interface. |
--------------------------------------------------------------------------*/
typedef enum {
String = 1,
Int32,
Bytes,
File
} DataType;
/*-------------------------------- Types -----------------------------------
| The following data types are used by this interface. All are basically |
| opaque types. You obtain objects of these types via certain member |
| function calls and re-use them later (without having to know what they |
| contain). |
| |
| Key - Placeholder to represent a particular node in a registry |
| tree. There are 3 enumerated values that correspond to |
| specific nodes: |
| Common - Where most stuff goes. |
| Users - Special subtree to hold info about |
| "users"; if you don't know what goes |
| here, don't mess with it. |
| CurrentUser - Subtree under Users corresponding to |
| whatever user is designed the "current" |
| one; see note above. |
| You can specify any of these enumerated values as "keys" |
| on any member function that takes a mozRegistry::Key. |
| ValueInfo - Structure describing a registry value. |
--------------------------------------------------------------------------*/
typedef uint32 Key;
enum { Users = 1, Common = 2, CurrentUser = 3 };
struct ValueInfo {
DataType type;
uint32 length;
};
/*--------------------------- Opening/Closing ------------------------------
| These functions open the specified registry file (Open() with a non-null |
| argument) or the default "standard" registry file (Open() with a null |
| argument or OpenDefault()). |
| |
| Once opened, you can access the registry contents via the read/write |
| or query functions. |
| |
| The registry file will be closed automatically when the registry object |
| is destroyed. You can close the file prior to that by using the |
| Close() function. |
--------------------------------------------------------------------------*/
NS_IMETHOD Open( const char *regFile = 0 ) = 0;
NS_IMETHOD OpenDefault() = 0;
NS_IMETHOD Close() = 0;
/*----------------------- Reading/Writing Values ---------------------------
| These functions read/write the registry values at a given node. |
| |
| All functions require you to specify where in the registry key to |
| get/set the value. The location is specified using two components: |
| o A "base key" indicating where to start from; this is a value of type |
| mozIRegistry::Key. You use either one of the special "root" key |
| values or a subkey obtained via some other member function call. |
| o A "relative path," expressed as a sequence of subtree names |
| separated by forward slashes. This path describes how to get from |
| the base key to the node at which you want to store the data. This |
| component can be a null pointer which means the value goes directly |
| at the node denoted by the base key. |
| |
| When you request a value of a given type, the data stored at the |
| specified node must be of the type requested. If not, an error results. |
| |
| GetString - Obtains a newly allocated copy of a string type value. The |
| caller is obligated to free the returned string using |
| PR_Free. |
| SetString - Stores the argument string at the specified node. |
| GetInt - Obtains an int32 value at the specified node. The result |
| is returned into an int32 location you specify. |
| SetInt - Stores a given int32 value at a node. |
| GetBytes - Obtains a byte array value; this returns both an allocated |
| array of bytes and a length (necessary because there may be |
| embedded null bytes in the array). You must free the |
| resulting array using PR_Free. |
| SetBytes - Stores a given array of bytes; you specify the bytes via a |
| pointer and a length. |
| GetIntArray - Obtains the array of int32 values stored at a given node. |
| The result is composed of two values: a pointer to an |
| array of integer values (which must be freed using |
| PR_Free) and the number of elements in that array. |
| SetIntArray - Stores a set of int32 values at a given node. You must |
| provide a pointer to the array and the number of entries. |
--------------------------------------------------------------------------*/
NS_IMETHOD GetString( Key baseKey, const char *path, char **result ) = 0;
NS_IMETHOD SetString( Key baseKey, const char *path, const char *value ) = 0;
NS_IMETHOD GetInt( Key baseKey, const char *path, int32 *result ) = 0;
NS_IMETHOD SetInt( Key baseKey, const char *path, int32 value ) = 0;
NS_IMETHOD GetBytes( Key baseKey, const char *path, void **result, uint32 *len ) = 0;
NS_IMETHOD SetBytes( Key baseKey, const char *path, void *value, uint32 len ) = 0;
NS_IMETHOD GetIntArray( Key baseKey, const char *path, int32 **result, uint32 *len ) = 0;
NS_IMETHOD SetIntArray( Key baseKey, const char *path, const int32 *value, uint32 len ) = 0;
/*------------------------------ Navigation --------------------------------
| These functions let you navigate through the registry tree, querying |
| its contents. |
| |
| As above, all these functions requires a starting tree location ("base |
| key") specified as a mozIRegistry::Key. Some also require a path |
| name to locate the registry node location relative to this base key. |
| |
| AddSubtree - Adds a new registry subtree at the specified |
| location. Returns the resulting key in |
| the location specified by the third argument |
| (unless that pointer is 0). |
| RemoveNode - Removes the specified registry subtree or |
| value at the specified location. |
| GetSubtree - Returns a mozIRegistry::Key that can be used |
| to refer to the specified registry location. |
| EnumerateSubtrees - Returns a nsIEnumerator object that you can |
| use to enumerate all the subtrees descending |
| from a specified location. You must free the |
| enumerator via Release() when you're done with |
| it. |
| EnumerateAllSubtrees - Like EnumerateSubtrees, but will recursively |
| enumerate lower-level subtrees, too. |
| GetValueInfo - Returns a uint32 value that designates the type |
| of data stored at this location in the registry; |
| the possible values are defined by the enumerated |
| type mozIRegistry::DataType. |
| GetValueLength - Returns a uint32 value that indicates the length |
| of this registry value; the length is the number |
| of characters (for Strings), the number of bytes |
| (for Bytes), or the number of int32 values (for |
| Int32). |
| EnumerateValues - Returns a nsIEnumerator that you can use to |
| enumerate all the value nodes descending from |
| a specified location. |
--------------------------------------------------------------------------*/
NS_IMETHOD AddSubtree( Key baseKey, const char *path, Key *result ) = 0;
NS_IMETHOD RemoveSubtree( Key baseKey, const char *path ) = 0;
NS_IMETHOD GetSubtree( Key baseKey, const char *path, Key *result ) = 0;
NS_IMETHOD EnumerateSubtrees( Key baseKey, nsIEnumerator **result ) = 0;
NS_IMETHOD EnumerateAllSubtrees( Key baseKey, nsIEnumerator **result ) = 0;
NS_IMETHOD GetValueType( Key baseKey, const char *path, uint32 *result ) = 0;
NS_IMETHOD GetValueLength( Key baseKey, const char *path, uint32 *result ) = 0;
NS_IMETHOD EnumerateValues( Key baseKey, nsIEnumerator **result ) = 0;
/*------------------------------ User Name ---------------------------------
| These functions manipulate the current "user name." This value controls |
| the behavior of certain registry functions (namely, ?). |
| |
| GetCurrentUserName allocates a copy of the current user name (which the |
| caller should free using PR_Free). |
--------------------------------------------------------------------------*/
NS_IMETHOD GetCurrentUserName( char **result ) = 0;
NS_IMETHOD SetCurrentUserName( const char *name ) = 0;
/*------------------------------ Utilities ---------------------------------
| Various utility functions: |
| |
| Pack() is used to compress the contents of an open registry file. |
--------------------------------------------------------------------------*/
NS_IMETHOD Pack() = 0;
}; // mozIRegistry
/*----------------------------- mozIRegistryNode -------------------------------
| This interface is implemented by all the objects obtained from the |
| nsIEnumerators that mozIRegistry provides when you call either of the |
| subtree enumeration functions EnumerateSubtrees or EnumerateAllSubtrees. |
| |
| You can call this function to get the name of this subtree. This is the |
| relative path from the base key from which you got this interface. |
| |
| GetName - Returns the path name of this node; this is the relative path |
| from the base key from which this subtree was obtained. The |
| function allocates a copy of the name; the caller must free it |
| using PR_Free. |
------------------------------------------------------------------------------*/
struct mozIRegistryNode : public nsISupports {
NS_IMETHOD GetName( char **result ) = 0;
}; // mozIRegistryNode
/*----------------------------- mozIRegistryValue ------------------------------
| This interface is implemented by the objects obtained from the |
| nsIEnumerators that mozIRegistry provides when you call the |
| EnumerateValues function. An object supporting this interface is |
| returned when you call the CurrentItem() function on that enumerator. |
| |
| You use the member functions of this interface to obtain information |
| about each registry value. |
| |
| GetName - Returns the path name of this node; this is the relative |
| path\ from the base key from which this value was obtained. |
| The function allocates a copy of the name; the caller must |
| subsequently free it via PR_Free. |
| GetValueType - Returns (into a location provided by the caller) the type |
| of the value; the types are defined by the enumerated |
| type mozIRegistry::DataType. |
| GetValueLength - Returns a uint32 value that indicates the length |
| of this registry value; the length is the number |
| of characters (for Strings), the number of bytes |
| (for Bytes), or the number of int32 values (for |
| Int32). |
------------------------------------------------------------------------------*/
struct mozIRegistryValue : public nsISupports {
NS_IMETHOD GetName( char **result ) = 0;
NS_IMETHOD GetValueType( uint32 *result ) = 0;
NS_IMETHOD GetValueLength( uint32 *result ) = 0;
}; // mozIRegistryEntry
/*------------------------------- Error Codes ----------------------------------
------------------------------------------------------------------------------*/
#define NS_ERROR_REG_BADTYPE NS_ERROR_GENERATE_FAILURE( NS_ERROR_MODULE_REG, 1 )
#define NS_ERROR_REG_NO_MORE NS_ERROR_GENERATE_SUCCESS( NS_ERROR_MODULE_REG, 2 )
#define NS_ERROR_REG_NOT_FOUND NS_ERROR_GENERATE_FAILURE( NS_ERROR_MODULE_REG, 3 )
#define NS_ERROR_REG_NOFILE NS_ERROR_GENERATE_FAILURE( NS_ERROR_MODULE_REG, 4 )
#define NS_ERROR_REG_BUFFER_TOO_SMALL NS_ERROR_GENERATE_FAILURE( NS_ERROR_MODULE_REG, 5 )
#define NS_ERROR_REG_NAME_TOO_LONG NS_ERROR_GENERATE_FAILURE( NS_ERROR_MODULE_REG, 6 )
#define NS_ERROR_REG_NO_PATH NS_ERROR_GENERATE_FAILURE( NS_ERROR_MODULE_REG, 7 )
#define NS_ERROR_REG_READ_ONLY NS_ERROR_GENERATE_FAILURE( NS_ERROR_MODULE_REG, 8 )
#define NS_ERROR_REG_BAD_UTF8 NS_ERROR_GENERATE_FAILURE( NS_ERROR_MODULE_REG, 9 )
// {5D41A440-8E37-11d2-8059-00600811A9C3}
#define MOZ_IREGISTRY_IID { 0x5d41a440, 0x8e37, 0x11d2, { 0x80, 0x59, 0x0, 0x60, 0x8, 0x11, 0xa9, 0xc3 } }
// {D1B54831-AC07-11d2-805E-00600811A9C3}
#define MOZ_IREGISTRYNODE_IID { 0xd1b54831, 0xac07, 0x11d2, { 0x80, 0x5e, 0x0, 0x60, 0x8, 0x11, 0xa9, 0xc3 } }
// {5316C380-B2F8-11d2-A374-0080C6F80E4B}
#define MOZ_IREGISTRYVALUE_IID { 0x5316c380, 0xb2f8, 0x11d2, { 0xa3, 0x74, 0x0, 0x80, 0xc6, 0xf8, 0xe, 0x4b } }
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,241 @@
/* -*- Mode: C++; tab-width: 8; 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.
*/
#ifndef nsComponentManager_h__
#define nsComponentManager_h__
#include "nsIComponentManager.h"
#include "nsIRegistry.h"
#include "nsHashtable.h"
#include "prtime.h"
#include "prmon.h"
class nsFactoryEntry;
class nsDll;
////////////////////////////////////////////////////////////////////////////////
/*
*** Quick Registration NOT FOR PUBLIC CONSUMPTION ***
*
* Quick Registration
*
* For quick registration, dlls can define
* NSQuickRegisterClassData g_NSQuickRegisterData[];
* and export the symbol "g_NSQuickRegisterData"
*
* Quick registration is tried only if the symbol "NSRegisterSelf"
* is not found. If it is found but fails registration, quick registration
* will not kick in.
*
* The array is terminated by having a NULL last element. Specifically, the
* array will be assumed to end when
* (g_NSQuickRegisterData[i].classIdStr == NULL)
*
*/
#define NS_QUICKREGISTER_DATA_SYMBOL "g_NSQuickRegisterData"
////////////////////////////////////////////////////////////////////////////////
class nsComponentManagerImpl : public nsIComponentManager {
public:
NS_DECL_ISUPPORTS
// nsIComponentManager methods:
NS_IMETHOD FindFactory(const nsCID &aClass,
nsIFactory **aFactory);
// Finds a class ID for a specific Program ID
NS_IMETHOD ProgIDToCLSID(const char *aProgID,
nsCID *aClass);
// Finds a Program ID for a specific class ID
// caller frees the result with delete[]
NS_IMETHOD CLSIDToProgID(nsCID *aClass,
char* *aClassName,
char* *aProgID);
// Creates a class instance for a specific class ID
NS_IMETHOD CreateInstance(const nsCID &aClass,
nsISupports *aDelegate,
const nsIID &aIID,
void **aResult);
// Convenience routine, creates a class instance for a specific ProgID
NS_IMETHOD CreateInstance(const char *aProgID,
nsISupports *aDelegate,
const nsIID &aIID,
void **aResult);
// Manually registry a factory for a class
NS_IMETHOD RegisterFactory(const nsCID &aClass,
const char *aClassName,
const char *aProgID,
nsIFactory *aFactory,
PRBool aReplace);
// Manually register a dynamically loaded component.
NS_IMETHOD RegisterComponent(const nsCID &aClass,
const char *aClassName,
const char *aProgID,
const char *aLibrary,
PRBool aReplace,
PRBool aPersist);
// Manually unregister a factory for a class
NS_IMETHOD UnregisterFactory(const nsCID &aClass,
nsIFactory *aFactory);
// Manually unregister a dynamically loaded component
NS_IMETHOD UnregisterComponent(const nsCID &aClass,
const char *aLibrary);
// Unload dynamically loaded factories that are not in use
NS_IMETHOD FreeLibraries(void);
//////////////////////////////////////////////////////////////////////////////
// DLL registration support
// Autoregistration will try only files with these extensions.
// All extensions are case insensitive.
// ".dll", // Windows
// ".dso", // Unix
// ".so", // Unix
// ".sl", // Unix: HP
// ".shlb", // Mac
// ".dlm", // new for all platforms
//
// Directory and fullname are what NSPR will accept. For eg.
// MAC /Hard drive/mozilla/dist/bin
// WIN y:\Hard drive\mozilla\dist\bin (or) y:/Hard drive/mozilla/dist/bin
// UNIX /Hard drive/mozilla/dist/bin
//
NS_IMETHOD AutoRegister(RegistrationTime when, const char* directory);
NS_IMETHOD AutoRegisterComponent(RegistrationTime when, const char *fullname);
// nsComponentManagerImpl methods:
nsComponentManagerImpl();
virtual ~nsComponentManagerImpl();
static nsComponentManagerImpl* gComponentManager;
nsresult Init(void);
protected:
nsresult LoadFactory(nsFactoryEntry *aEntry, nsIFactory **aFactory);
nsresult SyncComponentsInDir(RegistrationTime when, const char *directory);
nsresult SelfRegisterDll(nsDll *dll);
nsresult SelfUnregisterDll(nsDll *dll);
nsresult HashProgID(const char *aprogID, const nsCID &aClass);
nsresult PlatformVersionCheck();
nsresult PlatformCreateDll(const char *fullname, nsDll* *result);
nsresult PlatformMarkNoComponents(nsDll *dll);
struct QuickRegisterData {
const char *CIDString; // {98765-8776-8958758759-958785}
const char *className; // "Layout Engine"
const char *progID; // "Gecko.LayoutEngine.1"
};
nsresult PlatformRegister(QuickRegisterData* regd, nsDll *dll);
nsresult PlatformUnregister(QuickRegisterData* regd, const char *aLibrary);
nsresult PlatformFind(const nsCID &aCID, nsFactoryEntry* *result);
nsresult PlatformProgIDToCLSID(const char *aProgID, nsCID *aClass);
nsresult PlatformCLSIDToProgID(nsCID *aClass, char* *aClassName, char* *aProgID);
void PlatformGetFileInfo(nsIRegistry::Key Key,PRTime *lastModifiedTime,PRUint32 *fileSize);
protected:
nsHashtable* mFactories;
nsHashtable* mProgIDs;
PRMonitor* mMon;
nsHashtable* mDllStore;
nsIRegistry* mRegistry;
nsIRegistry::Key mXPCOMKey;
nsIRegistry::Key mClassesKey;
};
#define NS_MAX_FILENAME_LEN 1024
#define NS_ERROR_IS_DIR NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_XPCOM, 24)
#ifdef XP_UNIX
/* The default registry on the unix system is $HOME/.mozilla/registry per
* vr_findGlobalRegName(). vr_findRegFile() will create the registry file
* if it doesn't exist. But it wont create directories.
*
* Hence we need to create the directory if it doesn't exist already.
*
* Why create it here as opposed to the app ?
* ------------------------------------------
* The app cannot create the directory in main() as most of the registry
* and initialization happens due to use of static variables.
* And we dont want to be dependent on the order in which
* these static stuff happen.
*
* Permission for the $HOME/.mozilla will be Read,Write,Execute
* for user only. Nothing to group and others.
*/
#define NS_MOZILLA_DIR_NAME ".mozilla"
#define NS_MOZILLA_DIR_PERMISSION 00700
#endif /* XP_UNIX */
/**
* When using the registry we put a version number in it.
* If the version number that is in the registry doesn't match
* the following, we ignore the registry. This lets news versions
* of the software deal with old formats of registry and not
*
* alpha0.20 : First time we did versioning
* alpha0.30 : Changing autoreg to begin registration from ./components on unix
* alpha0.40 : repository -> component manager
* alpha0.50 : using nsIRegistry
*/
#define NS_XPCOM_COMPONENT_MANAGER_VERSION_STRING "alpha0.50"
////////////////////////////////////////////////////////////////////////////////
/**
* Class: nsFactoryEntry()
*
* There are two types of FactoryEntries.
*
* 1. {CID, dll} mapping.
* Factory is a consequence of the dll. These can be either session
* specific or persistent based on whether we write this
* to the registry or not.
*
* 2. {CID, factory} mapping
* These are strictly session specific and in memory only.
*/
class nsFactoryEntry {
public:
nsFactoryEntry();
nsFactoryEntry(const nsCID &aClass, nsIFactory *aFactory);
~nsFactoryEntry();
nsresult Init(nsHashtable* dllHashtable, const nsCID &aClass, const char *aLibrary,
PRTime lastModTime, PRUint32 fileSize);
nsCID cid;
nsIFactory *factory;
// DO NOT DELETE THIS. Many nsFactoryEntry(s) could be sharing the same Dll.
// This gets deleted from the dllStore going away.
nsDll *dll;
};
////////////////////////////////////////////////////////////////////////////////
#endif // nsComponentManager_h__

View File

@@ -0,0 +1,88 @@
/* -*- 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 "nsGenericFactory.h"
nsGenericFactory::nsGenericFactory(ConstructorProcPtr constructor)
: mConstructor(constructor), mDestructor(NULL)
{
NS_INIT_ISUPPORTS();
}
nsGenericFactory::~nsGenericFactory()
{
if (mDestructor != NULL)
(*mDestructor) ();
}
NS_METHOD nsGenericFactory::QueryInterface(const nsIID& aIID, void** aInstancePtr)
{
if (NULL == aInstancePtr) {
return NS_ERROR_NULL_POINTER;
}
if (aIID.Equals(nsIFactory::GetIID()) ||
aIID.Equals(nsIGenericFactory::GetIID()) ||
aIID.Equals(nsISupports::GetIID())) {
*aInstancePtr = (void*) this;
AddRef();
return NS_OK;
}
return NS_NOINTERFACE;
}
NS_IMPL_ADDREF(nsGenericFactory)
NS_IMPL_RELEASE(nsGenericFactory)
NS_IMETHODIMP nsGenericFactory::CreateInstance(nsISupports *aOuter, REFNSIID aIID, void **aResult)
{
return mConstructor(aOuter, aIID, aResult);
}
NS_IMETHODIMP nsGenericFactory::LockFactory(PRBool aLock)
{
return NS_OK;
}
NS_IMETHODIMP nsGenericFactory::SetConstructor(ConstructorProcPtr constructor)
{
mConstructor = constructor;
return NS_OK;
}
NS_IMETHODIMP nsGenericFactory::SetDestructor(DestructorProcPtr destructor)
{
mDestructor = destructor;
return NS_OK;
}
NS_METHOD nsGenericFactory::Create(nsISupports* outer, const nsIID& aIID, void* *aInstancePtr)
{
// sorry, aggregation not spoken here.
nsresult res = NS_ERROR_NO_AGGREGATION;
if (outer == NULL) {
nsGenericFactory* factory = new nsGenericFactory;
if (factory != NULL) {
res = factory->QueryInterface(aIID, aInstancePtr);
if (res != NS_OK)
delete factory;
} else {
res = NS_ERROR_OUT_OF_MEMORY;
}
}
return res;
}

View File

@@ -0,0 +1,60 @@
/* -*- 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.
*/
#ifndef nsGenericFactory_h___
#define nsGenericFactory_h___
#include "nsIGenericFactory.h"
/**
* Most factories follow this simple pattern, so why not just use a function pointer
* for most creation operations?
*/
class nsGenericFactory : public nsIGenericFactory {
public:
static const nsCID& CID() { static nsCID cid = NS_GENERICFACTORY_CID; return cid; }
nsGenericFactory(ConstructorProcPtr constructor = NULL);
virtual ~nsGenericFactory();
NS_DECL_ISUPPORTS
NS_IMETHOD CreateInstance(nsISupports *aOuter, REFNSIID aIID, void **aResult);
NS_IMETHOD LockFactory(PRBool aLock);
/**
* Establishes the generic factory's constructor function, which will be called
* by CreateInstance.
*/
NS_IMETHOD SetConstructor(ConstructorProcPtr constructor);
/**
* Establishes the generic factory's destructor function, which will be called
* whe the generic factory is deleted. This is used to notify the DLL that
* an instance of one of its generic factories is going away.
*/
NS_IMETHOD SetDestructor(DestructorProcPtr destructor);
static NS_METHOD Create(nsISupports* outer, const nsIID& aIID, void* *aInstancePtr);
private:
ConstructorProcPtr mConstructor;
DestructorProcPtr mDestructor;
};
#endif /* nsGenericFactory_h___ */

View File

@@ -0,0 +1,230 @@
/* -*- 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 "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 nsIComponentManager_h__
#define nsIComponentManager_h__
#include "prtypes.h"
#include "nsCom.h"
#include "nsID.h"
#include "nsError.h"
#include "nsISupports.h"
#include "nsIFactory.h"
/*
* Prototypes for dynamic library export functions. Your DLL/DSO needs to export
* these methods to play in the component world.
*/
extern "C" NS_EXPORT nsresult NSGetFactory(nsISupports* aServMgr,
const nsCID &aClass,
const char *aClassName,
const char *aProgID,
nsIFactory **aFactory);
extern "C" NS_EXPORT PRBool NSCanUnload(nsISupports* aServMgr);
extern "C" NS_EXPORT nsresult NSRegisterSelf(nsISupports* aServMgr, const char *fullpath);
extern "C" NS_EXPORT nsresult NSUnregisterSelf(nsISupports* aServMgr, const char *fullpath);
typedef nsresult (*nsFactoryProc)(nsISupports* aServMgr,
const nsCID &aClass,
const char *aClassName,
const char *aProgID,
nsIFactory **aFactory);
typedef PRBool (*nsCanUnloadProc)(nsISupports* aServMgr);
typedef nsresult (*nsRegisterProc)(nsISupports* aServMgr, const char *path);
typedef nsresult (*nsUnregisterProc)(nsISupports* aServMgr, const char *path);
#define NS_ICOMPONENTMANAGER_IID \
{ /* 8458a740-d5dc-11d2-92fb-00e09805570f */ \
0x8458a740, \
0xd5dc, \
0x11d2, \
{0x92, 0xfb, 0x00, 0xe0, 0x98, 0x05, 0x57, 0x0f} \
}
#define NS_COMPONENTMANAGER_CID \
{ /* 91775d60-d5dc-11d2-92fb-00e09805570f */ \
0x91775d60, \
0xd5dc, \
0x11d2, \
{0x92, 0xfb, 0x00, 0xe0, 0x98, 0x05, 0x57, 0x0f} \
}
/*
* nsIComponentManager interface
*/
class nsIComponentManager : public nsISupports {
public:
NS_DEFINE_STATIC_IID_ACCESSOR(NS_ICOMPONENTMANAGER_IID)
NS_IMETHOD FindFactory(const nsCID &aClass,
nsIFactory **aFactory) = 0;
// Finds a class ID for a specific Program ID
NS_IMETHOD ProgIDToCLSID(const char *aProgID,
nsCID *aClass) = 0;
// Finds a Program ID for a specific class ID
// caller frees the result with delete[]
NS_IMETHOD CLSIDToProgID(nsCID *aClass,
char* *aClassName,
char* *aProgID) = 0;
// Creates a class instance for a specific class ID
NS_IMETHOD CreateInstance(const nsCID &aClass,
nsISupports *aDelegate,
const nsIID &aIID,
void **aResult) = 0;
// Convenience routine, creates a class instance for a specific ProgID
NS_IMETHOD CreateInstance(const char *aProgID,
nsISupports *aDelegate,
const nsIID &aIID,
void **aResult) = 0;
// Manually registry a factory for a class
NS_IMETHOD RegisterFactory(const nsCID &aClass,
const char *aClassName,
const char *aProgID,
nsIFactory *aFactory,
PRBool aReplace) = 0;
// Manually register a dynamically loaded component.
NS_IMETHOD RegisterComponent(const nsCID &aClass,
const char *aClassName,
const char *aProgID,
const char *aLibrary,
PRBool aReplace,
PRBool aPersist) = 0;
// Manually unregister a factory for a class
NS_IMETHOD UnregisterFactory(const nsCID &aClass,
nsIFactory *aFactory) = 0;
// Manually unregister a dynamically loaded component
NS_IMETHOD UnregisterComponent(const nsCID &aClass,
const char *aLibrary) = 0;
// Unload dynamically loaded factories that are not in use
NS_IMETHOD FreeLibraries(void) = 0;
//////////////////////////////////////////////////////////////////////////////
// DLL registration support
// Autoregistration will try only files with these extensions.
// All extensions are case insensitive.
// ".dll", // Windows
// ".dso", // Unix
// ".so", // Unix
// ".sl", // Unix: HP
// ".shlb", // Mac
// ".dlm", // new for all platforms
//
// Directory and fullname are what NSPR will accept. For eg.
// MAC /Hard drive/mozilla/dist/bin
// WIN y:\Hard drive\mozilla\dist\bin (or) y:/Hard drive/mozilla/dist/bin
// UNIX /Hard drive/mozilla/dist/bin
//
enum RegistrationTime {
NS_Startup = 0,
NS_Script = 1,
NS_Timer = 2
};
NS_IMETHOD AutoRegister(RegistrationTime when, const char* directory) = 0;
NS_IMETHOD AutoRegisterComponent(RegistrationTime when, const char *fullname) = 0;
};
////////////////////////////////////////////////////////////////////////////////
extern NS_COM nsresult
NS_GetGlobalComponentManager(nsIComponentManager* *result);
////////////////////////////////////////////////////////////////////////////////
// Global Static Component Manager Methods
// (for when you need to link with xpcom)
class NS_COM nsComponentManager {
public:
static nsresult Initialize(void);
// Finds a factory for a specific class ID
static nsresult FindFactory(const nsCID &aClass,
nsIFactory **aFactory);
// Finds a class ID for a specific Program ID
static nsresult ProgIDToCLSID(const char *aProgID,
nsCID *aClass);
// Finds a Program ID for a specific class ID
// caller frees the result with delete[]
static nsresult CLSIDToProgID(nsCID *aClass,
char* *aClassName,
char* *aProgID);
// Creates a class instance for a specific class ID
static nsresult CreateInstance(const nsCID &aClass,
nsISupports *aDelegate,
const nsIID &aIID,
void **aResult);
// Convenience routine, creates a class instance for a specific ProgID
static nsresult CreateInstance(const char *aProgID,
nsISupports *aDelegate,
const nsIID &aIID,
void **aResult);
// Manually registry a factory for a class
static nsresult RegisterFactory(const nsCID &aClass,
const char *aClassName,
const char *aProgID,
nsIFactory *aFactory,
PRBool aReplace);
// Manually register a dynamically loaded component.
static nsresult RegisterComponent(const nsCID &aClass,
const char *aClassName,
const char *aProgID,
const char *aLibrary,
PRBool aReplace,
PRBool aPersist);
// Manually unregister a factory for a class
static nsresult UnregisterFactory(const nsCID &aClass,
nsIFactory *aFactory);
// Manually unregister a dynamically loaded component
static nsresult UnregisterComponent(const nsCID &aClass,
const char *aLibrary);
// Unload dynamically loaded factories that are not in use
static nsresult FreeLibraries(void);
//////////////////////////////////////////////////////////////////////////////
// DLL registration support
static nsresult AutoRegister(nsIComponentManager::RegistrationTime when,
const char* directory);
static nsresult AutoRegisterComponent(nsIComponentManager::RegistrationTime when,
const char *fullname);
};
////////////////////////////////////////////////////////////////////////////////
#endif

View File

@@ -16,41 +16,30 @@
* Reserved.
*/
#ifndef nsWinRegValue_h__
#define nsWinRegValue_h__
#ifndef __nsIFactory_h
#define __nsIFactory_h
#include "prtypes.h"
#include "nsISupports.h"
/*
* nsIFactory interface
*/
PR_BEGIN_EXTERN_C
struct nsWinRegValue {
// {00000001-0000-0000-c000-000000000046}
#define NS_IFACTORY_IID \
{ 0x00000001, 0x0000, 0x0000, \
{ 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46 } }
class nsIFactory: public nsISupports {
public:
static const nsIID& GetIID() { static nsIID iid = NS_IFACTORY_IID; return iid; }
/* Public Fields */
PRInt32 type;
void* data;
PRInt32 data_length;
/* Public Methods */
nsWinRegValue(PRInt32 datatype, void* regdata, PRInt32 len)
{
type = datatype;
data = regdata;
data_length = len;
}
/* should we copy the regdata? */
private:
/* Private Fields */
/* Private Methods */
NS_IMETHOD CreateInstance(nsISupports *aOuter,
REFNSIID aIID,
void **aResult) = 0;
NS_IMETHOD LockFactory(PRBool aLock) = 0;
};
PR_END_EXTERN_C
#endif /* nsWinRegValue_h__ */
#endif

View File

@@ -0,0 +1,57 @@
/* -*- 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.
*/
#ifndef nsIGenericFactory_h___
#define nsIGenericFactory_h___
#include "nsIFactory.h"
// {3bc97f01-ccdf-11d2-bab8-b548654461fc}
#define NS_GENERICFACTORY_CID \
{ 0x3bc97f01, 0xccdf, 0x11d2, { 0xba, 0xb8, 0xb5, 0x48, 0x65, 0x44, 0x61, 0xfc } }
// {3bc97f00-ccdf-11d2-bab8-b548654461fc}
#define NS_IGENERICFACTORY_IID \
{ 0x3bc97f00, 0xccdf, 0x11d2, { 0xba, 0xb8, 0xb5, 0x48, 0x65, 0x44, 0x61, 0xfc } }
/**
* Provides a Generic nsIFactory implementation that can be used by
* DLLs with very simple factory needs.
*/
class nsIGenericFactory : public nsIFactory {
public:
static const nsIID& GetIID() { static nsIID iid = NS_IGENERICFACTORY_IID; return iid; }
typedef NS_CALLBACK(ConstructorProcPtr) (nsISupports *aOuter, REFNSIID aIID, void **aResult);
typedef NS_CALLBACK(DestructorProcPtr) (void);
/**
* Establishes the generic factory's constructor function, which will be called
* by CreateInstance.
*/
NS_IMETHOD SetConstructor(ConstructorProcPtr constructor) = 0;
/**
* Establishes the generic factory's destructor function, which will be called
* whe the generic factory is deleted. This is used to notify the DLL that
* an instance of one of its generic factories is going away.
*/
NS_IMETHOD SetDestructor(DestructorProcPtr destructor) = 0;
};
#endif /* nsIGenericFactory_h___ */

View File

@@ -0,0 +1,350 @@
/* -*- 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 "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 __nsIRegistry_h
#define __nsIRegistry_h
#include "nsISupports.h"
// {5D41A440-8E37-11d2-8059-00600811A9C3}
#define NS_IREGISTRY_IID { 0x5d41a440, 0x8e37, 0x11d2, { 0x80, 0x59, 0x0, 0x60, 0x8, 0x11, 0xa9, 0xc3 } }
#define NS_REGISTRY_PROGID "component://netscape/registry"
#define NS_REGISTRY_CLASSNAME "Mozilla Registry"
// {D1B54831-AC07-11d2-805E-00600811A9C3}
#define NS_IREGISTRYNODE_IID { 0xd1b54831, 0xac07, 0x11d2, { 0x80, 0x5e, 0x0, 0x60, 0x8, 0x11, 0xa9, 0xc3 } }
// {5316C380-B2F8-11d2-A374-0080C6F80E4B}
#define NS_IREGISTRYVALUE_IID { 0x5316c380, 0xb2f8, 0x11d2, { 0xa3, 0x74, 0x0, 0x80, 0xc6, 0xf8, 0xe, 0x4b } }
class nsIEnumerator;
/*-------------------------------- nsIRegistry ---------------------------------
| This interface provides access to a tree of arbitrary values. |
| |
| Each node of the tree contains either a value or a subtree or both. |
| |
| The value at any of these leaf nodes can be any of these "primitive" types: |
| o string (null terminated UTF string) |
| o array of 32-bit integers |
| o arbitrary array of bytes |
| o file identifier |
| Of course, since you can store an arbitrary array of bytes, you can put |
| any data you like into a registry (although you have the burden of |
| encoding/decoding your data in that case). |
| |
| Each branch of the tree is labelled with a string "key." The entire path |
| from a given point of the tree to another point further down can be |
| presented as a single string composed of each branch's label, concatenated |
| to the next, with an intervening forward slash ('/'). The term "key" |
| refers to both specific tree branch labels and to such concatenated paths. |
| |
| The branches from a given node must have unique labels. Distinct nodes can |
| have branches with the same label. |
| |
| For example, here's a small registry tree: |
| | |
| /\ |
| / \ |
| / \ |
| / \ |
| "Classes" "Users" |
| / \ |
| / \ |
| / ["joe"] |
| / / \ |
| | / \ |
| /\ / \ |
| / \ "joe" "bob" |
| / \ / \ |
| / \ |
| "{xxxx-xx-1}" "{xxxx-xx-2}" ["c:/joe"] ["d:/Robert"] |
| | | |
| /\ /\ |
| / \ / \ |
| / \ / \ |
| "Library" "Version" "Library" "Version" |
| / \ / \ |
| ["foo.dll"] 2 ["bar.dll"] 1 |
| |
| In this example, there are 2 keys under the root: "Classes" and "Users". |
| The first denotes a subtree only (which has two subtrees, ...). The second |
| denotes both a value ["joe"] and two subtrees labelled "joe" and "bob". |
| The value at the node "/Users" is ["joe"], at "/Users/bob" is ["d:/Robert"]. |
| The value at "/Classes/{xxxx-xx-1}/Version" is 2. |
| |
| The registry interface provides functions that let you navigate the tree |
| and manipulate it's contents. |
| |
| Please note that the registry itself does not impose any structure or |
| meaning on the contents of the tree. For example, the registry doesn't |
| control whether the value at the key "/Users" is the label for the subtree |
| with information about the last active user. That meaning is applied by |
| the code that stores these values and uses them for that purpose. |
| |
| [Any resemblence between this example and actual contents of any actual |
| registry is purely coincidental.] |
------------------------------------------------------------------------------*/
struct nsIRegistry : public nsISupports {
/*------------------------------ Constants ---------------------------------
| The following enumerated types and values are used by the registry |
| interface. |
--------------------------------------------------------------------------*/
typedef enum {
String = 1,
Int32,
Bytes,
File
} DataType;
/*-------------------------------- Types -----------------------------------
| The following data types are used by this interface. All are basically |
| opaque types. You obtain objects of these types via certain member |
| function calls and re-use them later (without having to know what they |
| contain). |
| |
| Key - Placeholder to represent a particular node in a registry |
| tree. There are 3 enumerated values that correspond to |
| specific nodes: |
| Common - Where most stuff goes. |
| Users - Special subtree to hold info about |
| "users"; if you don't know what goes |
| here, don't mess with it. |
| CurrentUser - Subtree under Users corresponding to |
| whatever user is designed the "current" |
| one; see note above. |
| You can specify any of these enumerated values as "keys" |
| on any member function that takes a nsRegistry::Key. |
| ValueInfo - Structure describing a registry value. |
--------------------------------------------------------------------------*/
typedef uint32 Key;
enum { Users = 1, Common = 2, CurrentUser = 3 };
struct ValueInfo {
DataType type;
uint32 length;
};
static const nsIID& GetIID() { static nsIID iid = NS_IREGISTRY_IID; return iid; }
/*--------------------------- Opening/Closing ------------------------------
| These functions open the specified registry file (Open() with a non-null |
| argument) or the default "standard" registry file (Open() with a null |
| argument or OpenDefault()). |
| |
| Once opened, you can access the registry contents via the read/write |
| or query functions. |
| |
| The registry file will be closed automatically when the registry object |
| is destroyed. You can close the file prior to that by using the |
| Close() function. |
--------------------------------------------------------------------------*/
NS_IMETHOD Open( const char *regFile = 0 ) = 0;
NS_IMETHOD OpenDefault() = 0;
NS_IMETHOD Close() = 0;
/*----------------------- Reading/Writing Values ---------------------------
| These functions read/write the registry values at a given node. |
| |
| All functions require you to specify where in the registry key to |
| get/set the value. The location is specified using two components: |
| o A "base key" indicating where to start from; this is a value of type |
| nsIRegistry::Key. You use either one of the special "root" key |
| values or a subkey obtained via some other member function call. |
| o A "relative path," expressed as a sequence of subtree names |
| separated by forward slashes. This path describes how to get from |
| the base key to the node at which you want to store the data. This |
| component can be a null pointer which means the value goes directly |
| at the node denoted by the base key. |
| |
| When you request a value of a given type, the data stored at the |
| specified node must be of the type requested. If not, an error results. |
| |
| GetString - Obtains a newly allocated copy of a string type value. The |
| caller is obligated to free the returned string using |
| PR_Free. |
| SetString - Stores the argument string at the specified node. |
| GetInt - Obtains an int32 value at the specified node. The result |
| is returned into an int32 location you specify. |
| SetInt - Stores a given int32 value at a node. |
| GetBytes - Obtains a byte array value; this returns both an allocated |
| array of bytes and a length (necessary because there may be |
| embedded null bytes in the array). You must free the |
| resulting array using PR_Free. |
| SetBytes - Stores a given array of bytes; you specify the bytes via a |
| pointer and a length. |
| GetIntArray - Obtains the array of int32 values stored at a given node. |
| The result is composed of two values: a pointer to an |
| array of integer values (which must be freed using |
| PR_Free) and the number of elements in that array. |
| SetIntArray - Stores a set of int32 values at a given node. You must |
| provide a pointer to the array and the number of entries. |
--------------------------------------------------------------------------*/
NS_IMETHOD GetString( Key baseKey, const char *path, char **result ) = 0;
NS_IMETHOD SetString( Key baseKey, const char *path, const char *value ) = 0;
NS_IMETHOD GetInt( Key baseKey, const char *path, int32 *result ) = 0;
NS_IMETHOD SetInt( Key baseKey, const char *path, int32 value ) = 0;
NS_IMETHOD GetBytes( Key baseKey, const char *path, void **result, uint32 *len ) = 0;
NS_IMETHOD SetBytes( Key baseKey, const char *path, void *value, uint32 len ) = 0;
NS_IMETHOD GetIntArray( Key baseKey, const char *path, int32 **result, uint32 *len ) = 0;
NS_IMETHOD SetIntArray( Key baseKey, const char *path, const int32 *value, uint32 len ) = 0;
/*------------------------------ Navigation --------------------------------
| These functions let you navigate through the registry tree, querying |
| its contents. |
| |
| As above, all these functions requires a starting tree location ("base |
| key") specified as a nsIRegistry::Key. Some also require a path |
| name to locate the registry node location relative to this base key. |
| |
| AddSubtree - Adds a new registry subtree at the specified |
| location. Returns the resulting key in |
| the location specified by the third argument |
| (unless that pointer is 0). |
| AddSubtreeRaw - Adds a new registry subtree at the specified |
| location. Returns the resulting key in |
| the location specified by the third argument |
| (unless that pointer is 0). |
| Does not interpret special chars in key names. |
| |
| RemoveSubtree - Removes the specified registry subtree or |
| value at the specified location. |
| RemoveSubtreeRaw - Removes the specified registry subtree or |
| value at the specified location. |
| Does not interpret special chars in key names. |
| |
| GetSubtree - Returns a nsIRegistry::Key that can be used |
| to refer to the specified registry location. |
| GetSubtreeRaw - Returns a nsIRegistry::Key that can be used |
| to refer to the specified registry location. |
| Does not interpret special chars in key names. |
| |
| EnumerateSubtrees - Returns a nsIEnumerator object that you can |
| use to enumerate all the subtrees descending |
| from a specified location. You must free the |
| enumerator via Release() when you're done with |
| it. |
| EnumerateAllSubtrees - Like EnumerateSubtrees, but will recursively |
| enumerate lower-level subtrees, too. |
| GetValueInfo - Returns a uint32 value that designates the type |
| of data stored at this location in the registry; |
| the possible values are defined by the enumerated |
| type nsIRegistry::DataType. |
| GetValueLength - Returns a uint32 value that indicates the length |
| of this registry value; the length is the number |
| of characters (for Strings), the number of bytes |
| (for Bytes), or the number of int32 values (for |
| Int32). |
| EnumerateValues - Returns a nsIEnumerator that you can use to |
| enumerate all the value nodes descending from |
| a specified location. |
--------------------------------------------------------------------------*/
NS_IMETHOD AddSubtree( Key baseKey, const char *path, Key *result ) = 0;
NS_IMETHOD RemoveSubtree( Key baseKey, const char *path ) = 0;
NS_IMETHOD GetSubtree( Key baseKey, const char *path, Key *result ) = 0;
NS_IMETHOD AddSubtreeRaw( Key baseKey, const char *keyname, Key *result ) = 0;
NS_IMETHOD RemoveSubtreeRaw( Key baseKey, const char *keyname ) = 0;
NS_IMETHOD GetSubtreeRaw( Key baseKey, const char *keyname, Key *result ) = 0;
NS_IMETHOD EnumerateSubtrees( Key baseKey, nsIEnumerator **result ) = 0;
NS_IMETHOD EnumerateAllSubtrees( Key baseKey, nsIEnumerator **result ) = 0;
NS_IMETHOD GetValueType( Key baseKey, const char *path, uint32 *result ) = 0;
NS_IMETHOD GetValueLength( Key baseKey, const char *path, uint32 *result ) = 0;
NS_IMETHOD EnumerateValues( Key baseKey, nsIEnumerator **result ) = 0;
/*------------------------------ User Name ---------------------------------
| These functions manipulate the current "user name." This value controls |
| the behavior of certain registry functions (namely, ?). |
| |
| GetCurrentUserName allocates a copy of the current user name (which the |
| caller should free using PR_Free). |
--------------------------------------------------------------------------*/
NS_IMETHOD GetCurrentUserName( char **result ) = 0;
NS_IMETHOD SetCurrentUserName( const char *name ) = 0;
/*------------------------------ Utilities ---------------------------------
| Various utility functions: |
| |
| Pack() is used to compress the contents of an open registry file. |
--------------------------------------------------------------------------*/
NS_IMETHOD Pack() = 0;
}; // nsIRegistry
/*------------------------------ nsIRegistryNode -------------------------------
| This interface is implemented by all the objects obtained from the |
| nsIEnumerators that nsIRegistry provides when you call either of the |
| subtree enumeration functions EnumerateSubtrees or EnumerateAllSubtrees. |
| |
| You can call this function to get the name of this subtree. This is the |
| relative path from the base key from which you got this interface. |
| |
| GetName - Returns the path name of this node; this is the relative path |
| from the base key from which this subtree was obtained. The |
| function allocates a copy of the name; the caller must free it |
| using PR_Free. |
------------------------------------------------------------------------------*/
struct nsIRegistryNode : public nsISupports {
NS_IMETHOD GetName( char **result ) = 0;
}; // nsIRegistryNode
/*------------------------------ nsIRegistryValue ------------------------------
| This interface is implemented by the objects obtained from the |
| nsIEnumerators that nsIRegistry provides when you call the |
| EnumerateValues function. An object supporting this interface is |
| returned when you call the CurrentItem() function on that enumerator. |
| |
| You use the member functions of this interface to obtain information |
| about each registry value. |
| |
| GetName - Returns the path name of this node; this is the relative |
| path\ from the base key from which this value was obtained. |
| The function allocates a copy of the name; the caller must |
| subsequently free it via PR_Free. |
| GetValueType - Returns (into a location provided by the caller) the type |
| of the value; the types are defined by the enumerated |
| type nsIRegistry::DataType. |
| GetValueLength - Returns a uint32 value that indicates the length |
| of this registry value; the length is the number |
| of characters (for Strings), the number of bytes |
| (for Bytes), or the number of int32 values (for |
| Int32). |
------------------------------------------------------------------------------*/
struct nsIRegistryValue : public nsISupports {
NS_IMETHOD GetName( char **result ) = 0;
NS_IMETHOD GetValueType( uint32 *result ) = 0;
NS_IMETHOD GetValueLength( uint32 *result ) = 0;
}; // nsIRegistryEntry
/*------------------------------- Error Codes ----------------------------------
------------------------------------------------------------------------------*/
#define NS_ERROR_REG_BADTYPE NS_ERROR_GENERATE_FAILURE( NS_ERROR_MODULE_REG, 1 )
#define NS_ERROR_REG_NO_MORE NS_ERROR_GENERATE_SUCCESS( NS_ERROR_MODULE_REG, 2 )
#define NS_ERROR_REG_NOT_FOUND NS_ERROR_GENERATE_FAILURE( NS_ERROR_MODULE_REG, 3 )
#define NS_ERROR_REG_NOFILE NS_ERROR_GENERATE_FAILURE( NS_ERROR_MODULE_REG, 4 )
#define NS_ERROR_REG_BUFFER_TOO_SMALL NS_ERROR_GENERATE_FAILURE( NS_ERROR_MODULE_REG, 5 )
#define NS_ERROR_REG_NAME_TOO_LONG NS_ERROR_GENERATE_FAILURE( NS_ERROR_MODULE_REG, 6 )
#define NS_ERROR_REG_NO_PATH NS_ERROR_GENERATE_FAILURE( NS_ERROR_MODULE_REG, 7 )
#define NS_ERROR_REG_READ_ONLY NS_ERROR_GENERATE_FAILURE( NS_ERROR_MODULE_REG, 8 )
#define NS_ERROR_REG_BAD_UTF8 NS_ERROR_GENERATE_FAILURE( NS_ERROR_MODULE_REG, 9 )
#endif

View File

@@ -0,0 +1,327 @@
/* -*- 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 nsIServiceManager_h___
#define nsIServiceManager_h___
#include "nsIComponentManager.h"
#include "nsID.h"
class nsIShutdownListener;
#define NS_ISERVICEMANAGER_IID \
{ /* cf0df3b0-3401-11d2-8163-006008119d7a */ \
0xcf0df3b0, \
0x3401, \
0x11d2, \
{0x81, 0x63, 0x00, 0x60, 0x08, 0x11, 0x9d, 0x7a} \
}
/**
* The nsIServiceManager manager interface provides a means to obtain
* global services in an application. The service manager depends on the
* repository to find and instantiate factories to obtain services.
*
* Users of the service manager must first obtain a pointer to the global
* service manager by calling NS_GetGlobalServiceManager. After that,
* they can request specific services by calling GetService. When they are
* finished with a service the release it by calling ReleaseService (instead
* of releasing the service object directly):
*
* nsICacheManager* cm;
* nsServiceManager::GetService(kCacheManagerCID, kICacheManagerIID, (nsISupports**)&cm);
*
* ... use cm, and then sometime later ...
*
* nsServiceManager::ReleaseService(kCacheManagerCID, cm);
*
* A user of a service may keep references to particular services indefinitely
* and only must call ReleaseService when it shuts down. However if the user
* wishes to voluntarily cooperate with the shutdown of the service it is
* using, it may supply an nsIShutdownListener to provide for asynchronous
* release of the services it is using. The shutdown listener's OnShutdown
* method will be called for a service that is being shut down, and it is
* its responsiblity to release references obtained from that service if at
* all possible.
*
* The process of shutting down a particular service is initiated by calling
* the service manager's ShutdownService method. This will iterate through
* all the registered shutdown listeners for the service being shut down, and
* then will attempt to unload the library associated with the service if
* possible. The status result of ShutdownService indicates whether the
* service was successfully shut down, failed, or was not in service.
*
* XXX QUESTIONS:
* - Should a "service" be more than nsISupports? Should it be a factory
* and/or have Startup(), Shutdown(), etc.
* - If the asynchronous OnShutdown operation gets called, does the user
* of a service still need to call ReleaseService? (Or should they _not_
* call it?)
*/
class nsIServiceManager : public nsISupports {
public:
NS_DEFINE_STATIC_IID_ACCESSOR(NS_ISERVICEMANAGER_IID);
/**
* RegisterService may be called explicitly to register a service
* with the service manager. If a service is not registered explicitly,
* the component manager will be used to create an instance according
* to the class ID specified.
*/
NS_IMETHOD
RegisterService(const nsCID& aClass, nsISupports* aService) = 0;
/**
* Requests a service to be shut down, possibly unloading its DLL.
*
* @returns NS_OK - if shutdown was successful and service was unloaded,
* @returns NS_ERROR_SERVICE_NOT_FOUND - if shutdown failed because
* the service was not currently loaded
* @returns NS_ERROR_SERVICE_IN_USE - if shutdown failed because some
* user of the service wouldn't voluntarily release it by using
* a shutdown listener.
*/
NS_IMETHOD
UnregisterService(const nsCID& aClass) = 0;
NS_IMETHOD
GetService(const nsCID& aClass, const nsIID& aIID,
nsISupports* *result,
nsIShutdownListener* shutdownListener = NULL) = 0;
NS_IMETHOD
ReleaseService(const nsCID& aClass, nsISupports* service,
nsIShutdownListener* shutdownListener = NULL) = 0;
////////////////////////////////////////////////////////////////////////////
// let's do it again, this time with ProgIDs...
NS_IMETHOD
RegisterService(const char* aProgID, nsISupports* aService) = 0;
NS_IMETHOD
UnregisterService(const char* aProgID) = 0;
NS_IMETHOD
GetService(const char* aProgID, const nsIID& aIID,
nsISupports* *result,
nsIShutdownListener* shutdownListener = NULL) = 0;
NS_IMETHOD
ReleaseService(const char* aProgID, nsISupports* service,
nsIShutdownListener* shutdownListener = NULL) = 0;
};
#define NS_ERROR_SERVICE_NOT_FOUND NS_ERROR_GENERATE_SUCCESS(NS_ERROR_MODULE_XPCOM, 22)
#define NS_ERROR_SERVICE_IN_USE NS_ERROR_GENERATE_SUCCESS(NS_ERROR_MODULE_XPCOM, 23)
////////////////////////////////////////////////////////////////////////////////
#define NS_ISHUTDOWNLISTENER_IID \
{ /* 56decae0-3406-11d2-8163-006008119d7a */ \
0x56decae0, \
0x3406, \
0x11d2, \
{0x81, 0x63, 0x00, 0x60, 0x08, 0x11, 0x9d, 0x7a} \
}
class nsIShutdownListener : public nsISupports {
public:
NS_DEFINE_STATIC_IID_ACCESSOR(NS_ISHUTDOWNLISTENER_IID);
NS_IMETHOD
OnShutdown(const nsCID& aClass, nsISupports* service) = 0;
};
////////////////////////////////////////////////////////////////////////////////
// Interface to Global Services
class NS_COM nsServiceManager {
public:
static nsresult
RegisterService(const nsCID& aClass, nsISupports* aService);
static nsresult
UnregisterService(const nsCID& aClass);
static nsresult
GetService(const nsCID& aClass, const nsIID& aIID,
nsISupports* *result,
nsIShutdownListener* shutdownListener = NULL);
static nsresult
ReleaseService(const nsCID& aClass, nsISupports* service,
nsIShutdownListener* shutdownListener = NULL);
////////////////////////////////////////////////////////////////////////////
// let's do it again, this time with ProgIDs...
static nsresult
RegisterService(const char* aProgID, nsISupports* aService);
static nsresult
UnregisterService(const char* aProgID);
static nsresult
GetService(const char* aProgID, const nsIID& aIID,
nsISupports* *result,
nsIShutdownListener* shutdownListener = NULL);
static nsresult
ReleaseService(const char* aProgID, nsISupports* service,
nsIShutdownListener* shutdownListener = NULL);
////////////////////////////////////////////////////////////////////////////
static nsresult GetGlobalServiceManager(nsIServiceManager* *result);
// This method can be called when shutting down the application. It
// releases all the global services, and deletes the global service manager.
static nsresult ShutdownGlobalServiceManager(nsIServiceManager* *result);
static nsIServiceManager* mGlobalServiceManager;
};
////////////////////////////////////////////////////////////////////////////////
// NS_WITH_SERVICE: macro to make using services easier.
// Now you can replace this:
// {
// nsIMyService* service;
// rv = nsServiceManager::GetService(kMyServiceCID, nsIMyService::GetIID(),
// &service);
// if (NS_FAILED(rv)) return rv;
// service->Doit(...); // use my service
// rv = nsServiceManager::ReleaseService(kMyServiceCID, service);
// }
// with this:
// {
// NS_WITH_SERVICE(nsIMyService, service, kMyServiceCID, &rv);
// if (NS_FAILED(rv)) return rv;
// service->Doit(...); // use my service
// }
// and the automatic destructor will take care of releasing the service.
//
// Note that this macro requires you to link with the xpcom DLL to pick up the
// static member functions from nsServiceManager. For situations where you're
// passed an nsISupports that is an nsIComponentManager (such as in a DLL's
// NSRegisterSelf or NSUnregisterSelf entry points) you can use the following
// macro instead:
//
// NSRegisterSelf(nsISupports* servMgr, const char* path) {
// NS_WITH_SERVICE1(nsIComponentManager, compMgr, servMgr,
// kComponentManagerCID, &rv);
// if (NS_FAILED(rv)) return rv;
// compMgr->RegisterComponent(...); // use the service
// }
#define NS_WITH_SERVICE(T, var, cid, rvAddr) \
nsService _serv##var(cid, T::GetIID(), rvAddr); \
T* var = (T*)(nsISupports*)_serv##var;
#define NS_WITH_SERVICE1(T, var, isupports, cid, rvAddr) \
nsService _serv##var(isupports, cid, T::GetIID(), rvAddr); \
T* var = (T*)(nsISupports*)_serv##var;
class nsService {
protected:
nsCID mCID;
nsISupports* mService;
public:
nsService(nsISupports* aServMgr, const nsCID& aClass, const nsIID& aIID, nsresult *rv)
: mCID(aClass), mService(0)
{
nsIServiceManager* servMgr;
*rv = aServMgr->QueryInterface(nsIServiceManager::GetIID(), (void**)&servMgr);
if (NS_SUCCEEDED(*rv)) {
*rv = servMgr->GetService(mCID, aIID, &mService);
NS_RELEASE(servMgr);
}
NS_ASSERTION(NS_SUCCEEDED(*rv), "Couldn't get service.");
}
nsService(nsISupports* aServMgr, const char* aProgID, const nsIID& aIID, nsresult *rv)
: mService(0)
{
*rv = nsComponentManager::ProgIDToCLSID(aProgID, &mCID);
NS_ASSERTION(NS_SUCCEEDED(*rv), "Couldn't get CLSID.");
if (NS_FAILED(*rv)) return;
nsIServiceManager* servMgr;
*rv = aServMgr->QueryInterface(nsIServiceManager::GetIID(), (void**)&servMgr);
if (NS_SUCCEEDED(*rv)) {
*rv = servMgr->GetService(mCID, aIID, &mService);
NS_RELEASE(servMgr);
}
NS_ASSERTION(NS_SUCCEEDED(*rv), "Couldn't get service.");
}
nsService(const nsCID& aClass, const nsIID& aIID, nsresult *rv)
: mCID(aClass), mService(0) {
*rv = nsServiceManager::GetService(aClass, aIID,
(nsISupports**)&mService);
NS_ASSERTION(NS_SUCCEEDED(*rv), "Couldn't get service.");
}
~nsService() {
if (mService) { // mService could be null if the constructor fails
nsresult rv = NS_OK;
rv = nsServiceManager::ReleaseService(mCID, mService);
NS_ASSERTION(NS_SUCCEEDED(rv), "Couldn't release service.");
}
}
nsISupports* operator->() const {
NS_PRECONDITION(mService != 0, "Your code should test the error result from the constructor.");
return mService;
}
PRBool operator==(const nsISupports* other) {
return mService == other;
}
operator nsISupports*() const {
return mService;
}
};
////////////////////////////////////////////////////////////////////////////////
// NS_NewServiceManager: For when you want to create a service manager
// in a given context.
extern NS_COM nsresult
NS_NewServiceManager(nsIServiceManager* *result);
////////////////////////////////////////////////////////////////////////////////
// Initialization of XPCOM. Creates the global ComponentManager, ServiceManager
// and registers xpcom components with the ComponentManager. Should be called
// before any call can be made to XPCOM. Currently we are coping with this
// not being called and internally initializing XPCOM if not already.
extern NS_COM nsresult
NS_InitXPCOM(nsIServiceManager* *result);
////////////////////////////////////////////////////////////////////////////////
#endif /* nsIServiceManager_h___ */

View File

@@ -16,23 +16,16 @@
* Reserved.
*/
#ifndef nsInstallFileOpEnums_h__
#define nsInstallFileOpEnums_h__
#ifndef __nsIServerProvider_h
#define __nsIServerProvider_h
#include "nsISupports.h"
typedef enum nsInstallFileOpEnums {
NS_FOP_DIR_CREATE = 0,
NS_FOP_DIR_REMOVE = 1,
NS_FOP_DIR_RENAME = 2,
NS_FOP_FILE_COPY = 3,
NS_FOP_FILE_DELETE = 4,
NS_FOP_FILE_EXECUTE = 5,
NS_FOP_FILE_MOVE = 6,
NS_FOP_FILE_RENAME = 7,
NS_FOP_WIN_SHORTCUT_CREATE = 8,
NS_FOP_MAC_ALIAS_CREATE = 9,
NS_FOP_UNIX_LINK_CREATE = 10,
NS_FOP_FILE_SET_STAT = 11
typedef nsID nsSID;
#define NSSIDREF const nsSID&
} nsInstallFileOpEnums;
class nsIServiceProvider: public nsISupports {
public:
NS_IMETHOD QueryService(NSSIDREF aSID, NSIIDREF sIID, (void **) pService);
};
#endif /* nsInstallFileOpEnums_h__ */
#endif /* __nsIServerProvider_h */

View File

@@ -0,0 +1,164 @@
/* -*- 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 "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.
*/
#ifdef XP_MAC
#ifdef MOZ_NGLAYOUT
#error "nsMacRepository.h became obsolete when the shared lib conversion was completed."
// The Mac NGLayout is not based on shared libraries yet.
// All the DLLs are built as static libraries and we present them as
// shared libraries by redefining PR_LoadLibrary(), PR_UnloadLibrary()
// and PR_FindSymbol() below.
//
// If you add or remove shared libraries on other platforms, you must
// - Add the library name to the defines below.
// - Rename the "NSGetFactory" and "NSCanUnload" procs for the Mac:
// just append the library name to the function name.
// - Add the library and its procs to the static list below.
typedef struct MacLibrary
{
char * name;
nsFactoryProc factoryProc;
nsCanUnloadProc unloadProc;
} MacLibrary;
// library names
#define WIDGET_DLL "WIDGET_DLL"
#define GFXWIN_DLL "GFXWIN_DLL"
#define VIEW_DLL "VIEW_DLL"
#define WEB_DLL "WEB_DLL"
#define PLUGIN_DLL "PLUGIN_DLL"
#define PREF_DLL "PREF_DLL"
#define PARSER_DLL "PARSER_DLL"
#define DOM_DLL "DOM_DLL"
#define LAYOUT_DLL "LAYOUT_DLL"
#define NETLIB_DLL "NETLIB_DLL"
#define EDITOR_DLL "EDITOR_DLL"
#ifdef IMPL_MAC_REPOSITORY
extern "C" nsresult NSGetFactory_WIDGET_DLL(nsISupports* serviceMgr,
const nsCID &aClass,
const char *aClassName,
const char *aProgID,
nsIFactory **aFactory);
extern "C" nsresult NSGetFactory_GFXWIN_DLL(nsISupports* serviceMgr,
const nsCID &aClass,
const char *aClassName,
const char *aProgID,
nsIFactory **aFactory);
extern "C" nsresult NSGetFactory_VIEW_DLL(nsISupports* serviceMgr,
const nsCID &aClass,
const char *aClassName,
const char *aProgID,
nsIFactory **aFactory);
extern "C" nsresult NSGetFactory_WEB_DLL(nsISupports* serviceMgr,
const nsCID &aClass,
const char *aClassName,
const char *aProgID,
nsIFactory **aFactory);
#if 0
extern "C" nsresult NSGetFactory_PLUGIN_DLL(nsISupports* serviceMgr,
const nsCID &aClass,
const char *aClassName,
const char *aProgID,
nsIFactory **aFactory);
#endif
extern "C" nsresult NSGetFactory_PREF_DLL(nsISupports* serviceMgr,
const nsCID &aClass,
const char *aClassName,
const char *aProgID,
nsIFactory **aFactory);
extern "C" nsresult NSGetFactory_PARSER_DLL(nsISupports* serviceMgr,
const nsCID &aClass,
const char *aClassName,
const char *aProgID,
nsIFactory **aFactory);
extern "C" nsresult NSGetFactory_DOM_DLL(nsISupports* serviceMgr,
const nsCID &aClass,
const char *aClassName,
const char *aProgID,
nsIFactory **aFactory);
extern "C" nsresult NSGetFactory_LAYOUT_DLL(nsISupports* serviceMgr,
const nsCID &aClass,
const char *aClassName,
const char *aProgID,
nsIFactory **aFactory);
extern "C" nsresult NSGetFactory_NETLIB_DLL(nsISupports* serviceMgr,
const nsCID &aClass,
const char *aClassName,
const char *aProgID,
nsIFactory **aFactory);
extern "C" nsresult NSGetFactory_EDITOR_DLL(nsISupports* serviceMgr,
const nsCID &aClass,
const char *aClassName,
const char *aProgID,
nsIFactory **aFactory);
extern "C" PRBool NSCanUnload_PREF_DLL(void);
// library list
static MacLibrary libraries[] = {
#if 0
WIDGET_DLL, NSGetFactory_WIDGET_DLL, NULL,
GFXWIN_DLL, NSGetFactory_GFXWIN_DLL, NULL,
VIEW_DLL, NSGetFactory_VIEW_DLL, NULL,
WEB_DLL, NSGetFactory_WEB_DLL, NULL,
//PLUGIN_DLL, NSGetFactory_PLUGIN_DLL, NULL,
PREF_DLL, NSGetFactory_PREF_DLL, NSCanUnload_PREF_DLL,
PARSER_DLL, NSGetFactory_PARSER_DLL, NULL,
DOM_DLL, NSGetFactory_DOM_DLL, NULL,
LAYOUT_DLL, NSGetFactory_LAYOUT_DLL, NULL,
NETLIB_DLL, NSGetFactory_NETLIB_DLL, NULL,
//EDITOR_DLL, NSGetFactory_EDITOR_DLL, NULL, // FIX ME
#endif
NULL
};
static void* FindMacSymbol(char* libName, const char *symbolName)
{
MacLibrary * macLib;
for (macLib = libraries; ; macLib ++)
{
if (macLib->name == NULL)
return NULL;
if (PL_strcmp(macLib->name, libName) == 0)
break;
}
if (PL_strcmp(symbolName, "NSGetFactory") == 0) {
return macLib->factoryProc;
}
else if (PL_strcmp(symbolName, "NSCanUnload") == 0) {
return macLib->unloadProc;
}
return NULL;
}
#define PR_LoadLibrary(libName) (PRLibrary *)libName
#define PR_UnloadLibrary(lib) lib = NULL
#define PR_FindSymbol(lib, symbolName) FindMacSymbol((char*)lib, symbolName)
#endif // IMPL_MAC_REPOSITORY
#endif // MOZ_NGLAYOUT
#endif // XP_MAC

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,158 @@
/* -*- Mode: C++; tab-width: 8; 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 "nsIComponentManager.h"
nsresult
nsComponentManager::Initialize(void)
{
return NS_OK;
}
nsresult
nsComponentManager::FindFactory(const nsCID &aClass,
nsIFactory **aFactory)
{
nsIComponentManager* cm;
nsresult rv = NS_GetGlobalComponentManager(&cm);
if (NS_FAILED(rv)) return rv;
return cm->FindFactory(aClass, aFactory);
}
nsresult
nsComponentManager::ProgIDToCLSID(const char *aProgID,
nsCID *aClass)
{
nsIComponentManager* cm;
nsresult rv = NS_GetGlobalComponentManager(&cm);
if (NS_FAILED(rv)) return rv;
return cm->ProgIDToCLSID(aProgID, aClass);
}
nsresult
nsComponentManager::CLSIDToProgID(nsCID *aClass,
char* *aClassName,
char* *aProgID)
{
nsIComponentManager* cm;
nsresult rv = NS_GetGlobalComponentManager(&cm);
if (NS_FAILED(rv)) return rv;
return cm->CLSIDToProgID(aClass, aClassName, aProgID);
}
nsresult
nsComponentManager::CreateInstance(const nsCID &aClass,
nsISupports *aDelegate,
const nsIID &aIID,
void **aResult)
{
nsIComponentManager* cm;
nsresult rv = NS_GetGlobalComponentManager(&cm);
if (NS_FAILED(rv)) return rv;
return cm->CreateInstance(aClass, aDelegate, aIID, aResult);
}
nsresult
nsComponentManager::CreateInstance(const char *aProgID,
nsISupports *aDelegate,
const nsIID &aIID,
void **aResult)
{
nsIComponentManager* cm;
nsresult rv = NS_GetGlobalComponentManager(&cm);
if (NS_FAILED(rv)) return rv;
return cm->CreateInstance(aProgID, aDelegate, aIID, aResult);
}
nsresult
nsComponentManager::RegisterFactory(const nsCID &aClass,
const char *aClassName,
const char *aProgID,
nsIFactory *aFactory,
PRBool aReplace)
{
nsIComponentManager* cm;
nsresult rv = NS_GetGlobalComponentManager(&cm);
if (NS_FAILED(rv)) return rv;
return cm->RegisterFactory(aClass, aClassName, aProgID,
aFactory, aReplace);
}
nsresult
nsComponentManager::RegisterComponent(const nsCID &aClass,
const char *aClassName,
const char *aProgID,
const char *aLibrary,
PRBool aReplace,
PRBool aPersist)
{
nsIComponentManager* cm;
nsresult rv = NS_GetGlobalComponentManager(&cm);
if (NS_FAILED(rv)) return rv;
return cm->RegisterComponent(aClass, aClassName, aProgID,
aLibrary, aReplace, aPersist);
}
nsresult
nsComponentManager::UnregisterFactory(const nsCID &aClass,
nsIFactory *aFactory)
{
nsIComponentManager* cm;
nsresult rv = NS_GetGlobalComponentManager(&cm);
if (NS_FAILED(rv)) return rv;
return cm->UnregisterFactory(aClass, aFactory);
}
nsresult
nsComponentManager::UnregisterComponent(const nsCID &aClass,
const char *aLibrary)
{
nsIComponentManager* cm;
nsresult rv = NS_GetGlobalComponentManager(&cm);
if (NS_FAILED(rv)) return rv;
return cm->UnregisterComponent(aClass, aLibrary);
}
nsresult
nsComponentManager::FreeLibraries(void)
{
nsIComponentManager* cm;
nsresult rv = NS_GetGlobalComponentManager(&cm);
if (NS_FAILED(rv)) return rv;
return cm->FreeLibraries();
}
nsresult
nsComponentManager::AutoRegister(nsIComponentManager::RegistrationTime when,
const char* directory)
{
nsIComponentManager* cm;
nsresult rv = NS_GetGlobalComponentManager(&cm);
if (NS_FAILED(rv)) return rv;
return cm->AutoRegister(when, directory);
}
nsresult
nsComponentManager::AutoRegisterComponent(nsIComponentManager::RegistrationTime when,
const char *fullname)
{
nsIComponentManager* cm;
nsresult rv = NS_GetGlobalComponentManager(&cm);
if (NS_FAILED(rv)) return rv;
return cm->AutoRegisterComponent(when, fullname);
}

View File

@@ -1,5 +1,5 @@
/* -*- 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: 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
@@ -16,10 +16,13 @@
* Reserved.
*/
#ifndef __NS_JSWINPROTOTYPE_H__
#define __NS_JSWINPROTOTYPE_H__
#ifndef __nsRespository_h
#define __nsRespository_h
PRInt32
InitWinProfilePrototype(JSContext *jscontext, JSObject *global, JSObject **winRegPrototype);
#include "nsIComponentManager.h"
// XXX nsRepository is obsolete! Use nsComponentManager now!
#define nsRepository nsComponentManager
#endif

View File

@@ -0,0 +1,613 @@
/* -*- 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.
*/
#include "nsIServiceManager.h"
#include "nsVector.h"
#include "nsHashtable.h"
#include "prcmon.h"
#include "prthread.h" /* XXX: only used for the NSPR initialization hack (rick) */
static NS_DEFINE_CID(kComponentManagerCID, NS_COMPONENTMANAGER_CID);
class nsServiceEntry {
public:
nsServiceEntry(const nsCID& cid, nsISupports* service);
~nsServiceEntry();
nsresult AddListener(nsIShutdownListener* listener);
nsresult RemoveListener(nsIShutdownListener* listener);
nsresult NotifyListeners(void);
const nsCID& mClassID;
nsISupports* mService;
nsVector* mListeners; // nsVector<nsIShutdownListener>
PRBool mShuttingDown;
};
nsServiceEntry::nsServiceEntry(const nsCID& cid, nsISupports* service)
: mClassID(cid), mService(service), mListeners(NULL), mShuttingDown(PR_FALSE)
{
}
nsServiceEntry::~nsServiceEntry()
{
if (mListeners) {
NS_ASSERTION(mListeners->GetSize() == 0, "listeners not removed or notified");
#if 0
PRUint32 size = mListeners->GetSize();
for (PRUint32 i = 0; i < size; i++) {
nsIShutdownListener* listener = (nsIShutdownListener*)(*mListeners)[i];
NS_RELEASE(listener);
}
#endif
delete mListeners;
}
}
nsresult
nsServiceEntry::AddListener(nsIShutdownListener* listener)
{
if (listener == NULL)
return NS_OK;
if (mListeners == NULL) {
mListeners = new nsVector();
if (mListeners == NULL)
return NS_ERROR_OUT_OF_MEMORY;
}
PRInt32 rv = mListeners->Add(listener);
NS_ADDREF(listener);
return rv == -1 ? NS_ERROR_FAILURE : NS_OK;
}
nsresult
nsServiceEntry::RemoveListener(nsIShutdownListener* listener)
{
if (listener == NULL)
return NS_OK;
NS_ASSERTION(mListeners, "no listeners added yet");
PRUint32 size = mListeners->GetSize();
for (PRUint32 i = 0; i < size; i++) {
if ((*mListeners)[i] == listener) {
mListeners->Remove(i);
NS_RELEASE(listener);
return NS_OK;
}
}
NS_ASSERTION(0, "unregistered shutdown listener");
return NS_ERROR_FAILURE;
}
nsresult
nsServiceEntry::NotifyListeners(void)
{
if (mListeners) {
PRUint32 size = mListeners->GetSize();
for (PRUint32 i = 0; i < size; i++) {
nsIShutdownListener* listener = (nsIShutdownListener*)(*mListeners)[0];
nsresult rv = listener->OnShutdown(mClassID, mService);
if (NS_FAILED(rv)) return rv;
NS_RELEASE(listener);
mListeners->Remove(0);
}
NS_ASSERTION(mListeners->GetSize() == 0, "failed to notify all listeners");
delete mListeners;
mListeners = NULL;
}
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
class nsServiceManagerImpl : public nsIServiceManager {
public:
NS_IMETHOD
RegisterService(const nsCID& aClass, nsISupports* aService);
NS_IMETHOD
UnregisterService(const nsCID& aClass);
NS_IMETHOD
GetService(const nsCID& aClass, const nsIID& aIID,
nsISupports* *result,
nsIShutdownListener* shutdownListener = NULL);
NS_IMETHOD
ReleaseService(const nsCID& aClass, nsISupports* service,
nsIShutdownListener* shutdownListener = NULL);
NS_IMETHOD
RegisterService(const char* aProgID, nsISupports* aService);
NS_IMETHOD
UnregisterService(const char* aProgID);
NS_IMETHOD
GetService(const char* aProgID, const nsIID& aIID,
nsISupports* *result,
nsIShutdownListener* shutdownListener = NULL);
NS_IMETHOD
ReleaseService(const char* aProgID, nsISupports* service,
nsIShutdownListener* shutdownListener = NULL);
nsServiceManagerImpl(void);
NS_DECL_ISUPPORTS
protected:
virtual ~nsServiceManagerImpl(void);
nsHashtable/*<nsServiceEntry>*/* mServices;
};
nsServiceManagerImpl::nsServiceManagerImpl(void)
{
NS_INIT_REFCNT();
mServices = new nsHashtable(256, PR_TRUE); // Get a threadSafe hashtable
NS_ASSERTION(mServices, "out of memory already?");
}
static PRBool
DeleteEntry(nsHashKey *aKey, void *aData, void* closure)
{
nsServiceEntry* entry = (nsServiceEntry*)aData;
NS_RELEASE(entry->mService);
delete entry;
return PR_TRUE;
}
nsServiceManagerImpl::~nsServiceManagerImpl(void)
{
if (mServices) {
mServices->Enumerate(DeleteEntry);
delete mServices;
}
}
static NS_DEFINE_IID(kIServiceManagerIID, NS_ISERVICEMANAGER_IID);
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
NS_IMPL_ADDREF(nsServiceManagerImpl);
NS_IMPL_RELEASE(nsServiceManagerImpl);
NS_IMETHODIMP
nsServiceManagerImpl::QueryInterface(const nsIID& aIID, void* *aInstancePtr)
{
if (NULL == aInstancePtr) {
return NS_ERROR_NULL_POINTER;
}
*aInstancePtr = NULL;
if (aIID.Equals(kIServiceManagerIID) ||
aIID.Equals(kISupportsIID)) {
*aInstancePtr = (void*) this;
AddRef();
return NS_OK;
}
return NS_NOINTERFACE;
}
NS_IMETHODIMP
nsServiceManagerImpl::GetService(const nsCID& aClass, const nsIID& aIID,
nsISupports* *result,
nsIShutdownListener* shutdownListener)
{
nsresult rv = NS_OK;
/* XXX: This is a hack to force NSPR initialization.. This should be
* removed once PR_CEnterMonitor(...) initializes NSPR... (rick)
*/
(void)PR_GetCurrentThread();
PR_CEnterMonitor(this);
nsIDKey key(aClass);
nsServiceEntry* entry = (nsServiceEntry*)mServices->Get(&key);
if (entry) {
nsISupports* service;
rv = entry->mService->QueryInterface(aIID, (void**)&service);
if (NS_SUCCEEDED(rv)) {
rv = entry->AddListener(shutdownListener);
if (NS_SUCCEEDED(rv)) {
*result = service;
// If someone else requested the service to be shut down,
// and we just asked to get it again before it could be
// released, then cancel their shutdown request:
if (entry->mShuttingDown) {
entry->mShuttingDown = PR_FALSE;
NS_ADDREF(service); // Released in UnregisterService
}
}
}
}
else {
nsISupports* service;
rv = nsComponentManager::CreateInstance(aClass, NULL, aIID, (void**)&service);
if (NS_SUCCEEDED(rv)) {
entry = new nsServiceEntry(aClass, service);
if (entry == NULL) {
NS_RELEASE(service);
rv = NS_ERROR_OUT_OF_MEMORY;
}
else {
rv = entry->AddListener(shutdownListener);
if (NS_SUCCEEDED(rv)) {
mServices->Put(&key, entry);
*result = service;
NS_ADDREF(service); // Released in UnregisterService
}
else {
NS_RELEASE(service);
delete entry;
}
}
}
}
PR_CExitMonitor(this);
return rv;
}
NS_IMETHODIMP
nsServiceManagerImpl::ReleaseService(const nsCID& aClass, nsISupports* service,
nsIShutdownListener* shutdownListener)
{
nsresult rv = NS_OK;
PR_CEnterMonitor(this);
nsIDKey key(aClass);
nsServiceEntry* entry = (nsServiceEntry*)mServices->Get(&key);
NS_ASSERTION(entry, "service not found");
// NS_ASSERTION(entry->mService == service, "service looked failed");
if (entry) {
rv = entry->RemoveListener(shutdownListener);
nsrefcnt cnt;
NS_RELEASE2(service, cnt);
if (NS_SUCCEEDED(rv) && cnt == 0) {
mServices->Remove(&key);
delete entry;
rv = nsComponentManager::FreeLibraries();
}
}
PR_CExitMonitor(this);
return rv;
}
NS_IMETHODIMP
nsServiceManagerImpl::RegisterService(const nsCID& aClass, nsISupports* aService)
{
nsresult rv = NS_OK;
PR_CEnterMonitor(this);
nsIDKey key(aClass);
nsServiceEntry* entry = (nsServiceEntry*)mServices->Get(&key);
if (entry) {
rv = NS_ERROR_FAILURE;
}
else {
nsServiceEntry* entry = new nsServiceEntry(aClass, aService);
if (entry == NULL)
rv = NS_ERROR_OUT_OF_MEMORY;
else {
mServices->Put(&key, entry);
NS_ADDREF(aService); // Released in UnregisterService
}
}
PR_CExitMonitor(this);
return rv;
}
NS_IMETHODIMP
nsServiceManagerImpl::UnregisterService(const nsCID& aClass)
{
nsresult rv = NS_OK;
PR_CEnterMonitor(this);
nsIDKey key(aClass);
nsServiceEntry* entry = (nsServiceEntry*)mServices->Get(&key);
if (entry == NULL) {
rv = NS_ERROR_SERVICE_NOT_FOUND;
}
else {
rv = entry->NotifyListeners(); // break the cycles
entry->mShuttingDown = PR_TRUE;
nsrefcnt cnt;
NS_RELEASE2(entry->mService, cnt); // AddRef in GetService
if (NS_SUCCEEDED(rv) && cnt == 0) {
mServices->Remove(&key);
delete entry;
rv = nsComponentManager::FreeLibraries();
}
else
rv = NS_ERROR_SERVICE_IN_USE;
}
PR_CExitMonitor(this);
return rv;
}
////////////////////////////////////////////////////////////////////////////////
// let's do it again, this time with ProgIDs...
NS_IMETHODIMP
nsServiceManagerImpl::RegisterService(const char* aProgID, nsISupports* aService)
{
nsCID aClass;
nsresult rv;
rv = nsComponentManager::ProgIDToCLSID(aProgID, &aClass);
if (NS_FAILED(rv)) return rv;
return RegisterService(aClass, aService);
}
NS_IMETHODIMP
nsServiceManagerImpl::UnregisterService(const char* aProgID)
{
nsCID aClass;
nsresult rv;
rv = nsComponentManager::ProgIDToCLSID(aProgID, &aClass);
if (NS_FAILED(rv)) return rv;
return UnregisterService(aClass);
}
NS_IMETHODIMP
nsServiceManagerImpl::GetService(const char* aProgID, const nsIID& aIID,
nsISupports* *result,
nsIShutdownListener* shutdownListener)
{
nsCID aClass;
nsresult rv;
rv = nsComponentManager::ProgIDToCLSID(aProgID, &aClass);
if (NS_FAILED(rv)) return rv;
return GetService(aClass, aIID, result, shutdownListener);
}
NS_IMETHODIMP
nsServiceManagerImpl::ReleaseService(const char* aProgID, nsISupports* service,
nsIShutdownListener* shutdownListener)
{
nsCID aClass;
nsresult rv;
rv = nsComponentManager::ProgIDToCLSID(aProgID, &aClass);
if (NS_FAILED(rv)) return rv;
return ReleaseService(aClass, service, shutdownListener);
}
////////////////////////////////////////////////////////////////////////////////
nsresult
NS_NewServiceManager(nsIServiceManager* *result)
{
nsServiceManagerImpl* servMgr = new nsServiceManagerImpl();
if (servMgr == NULL)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(servMgr);
*result = servMgr;
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
// Global service manager interface (see nsIServiceManager.h)
nsresult
nsServiceManager::GetGlobalServiceManager(nsIServiceManager* *result)
{
nsresult rv = NS_OK;
if (mGlobalServiceManager == NULL) {
// XPCOM not initialized yet. Let us do initialization of our module.
rv = NS_InitXPCOM(NULL);
}
// No ADDREF as we are advicing no release of this.
if (NS_SUCCEEDED(rv)) *result = mGlobalServiceManager;
return rv;
}
nsresult
nsServiceManager::ShutdownGlobalServiceManager(nsIServiceManager* *result)
{
if (mGlobalServiceManager != NULL) {
NS_RELEASE(mGlobalServiceManager);
mGlobalServiceManager = NULL;
}
return NS_OK;
}
nsresult
nsServiceManager::GetService(const nsCID& aClass, const nsIID& aIID,
nsISupports* *result,
nsIShutdownListener* shutdownListener)
{
nsIServiceManager* mgr;
nsresult rv = GetGlobalServiceManager(&mgr);
if (NS_FAILED(rv)) return rv;
return mgr->GetService(aClass, aIID, result, shutdownListener);
}
nsresult
nsServiceManager::ReleaseService(const nsCID& aClass, nsISupports* service,
nsIShutdownListener* shutdownListener)
{
nsIServiceManager* mgr;
nsresult rv = GetGlobalServiceManager(&mgr);
if (NS_FAILED(rv)) return rv;
return mgr->ReleaseService(aClass, service, shutdownListener);
}
nsresult
nsServiceManager::RegisterService(const nsCID& aClass, nsISupports* aService)
{
nsIServiceManager* mgr;
nsresult rv = GetGlobalServiceManager(&mgr);
if (NS_FAILED(rv)) return rv;
return mgr->RegisterService(aClass, aService);
}
nsresult
nsServiceManager::UnregisterService(const nsCID& aClass)
{
nsIServiceManager* mgr;
nsresult rv = GetGlobalServiceManager(&mgr);
if (NS_FAILED(rv)) return rv;
return mgr->UnregisterService(aClass);
}
////////////////////////////////////////////////////////////////////////////////
// let's do it again, this time with ProgIDs...
nsresult
nsServiceManager::GetService(const char* aProgID, const nsIID& aIID,
nsISupports* *result,
nsIShutdownListener* shutdownListener)
{
nsIServiceManager* mgr;
nsresult rv = GetGlobalServiceManager(&mgr);
if (NS_FAILED(rv)) return rv;
return mgr->GetService(aProgID, aIID, result, shutdownListener);
}
nsresult
nsServiceManager::ReleaseService(const char* aProgID, nsISupports* service,
nsIShutdownListener* shutdownListener)
{
nsIServiceManager* mgr;
nsresult rv = GetGlobalServiceManager(&mgr);
if (NS_FAILED(rv)) return rv;
return mgr->ReleaseService(aProgID, service, shutdownListener);
}
nsresult
nsServiceManager::RegisterService(const char* aProgID, nsISupports* aService)
{
nsIServiceManager* mgr;
nsresult rv = GetGlobalServiceManager(&mgr);
if (NS_FAILED(rv)) return rv;
return mgr->RegisterService(aProgID, aService);
}
nsresult
nsServiceManager::UnregisterService(const char* aProgID)
{
nsIServiceManager* mgr;
nsresult rv = GetGlobalServiceManager(&mgr);
if (NS_FAILED(rv)) return rv;
return mgr->UnregisterService(aProgID);
}
////////////////////////////////////////////////////////////////////////////////
// XPCOM initialization
//
// To Control the order of initialization of these key components I am putting
// this function.
//
// - nsServiceManager
// - nsComponentManager
// - nsRegistry
//
// Here are key points to remember:
// - A global of all these need to exist. nsServiceManager is an independent object.
// nsComponentManager uses both the globalServiceManager and its own registry.
//
// - A static object of both the nsComponentManager and nsServiceManager
// are in use. Hence InitXPCOM() gets triggered from both
// NS_GetGlobale{Service/Component}Manager() calls.
//
// - There exists no global Registry. Registry can be created from the component manager.
//
#include "nsComponentManager.h"
#include "nsIRegistry.h"
#include "nsXPComCIID.h"
#include "nsAllocator.h"
extern "C" NS_EXPORT nsresult
NS_RegistryGetFactory(nsISupports* servMgr, nsIFactory** aFactory);
nsIServiceManager* nsServiceManager::mGlobalServiceManager = NULL;
nsComponentManagerImpl* nsComponentManagerImpl::gComponentManager = NULL;
nsresult NS_InitXPCOM(nsIServiceManager* *result)
{
nsresult rv = NS_OK;
// 1. Create the Global Service Manager
nsIServiceManager* servMgr = NULL;
if (nsServiceManager::mGlobalServiceManager == NULL)
{
rv = NS_NewServiceManager(&servMgr);
if (NS_FAILED(rv)) return rv;
nsServiceManager::mGlobalServiceManager = servMgr;
NS_ADDREF(servMgr);
if (result) *result = servMgr;
}
// 2. Create the Component Manager and register with global service manager
// It is understood that the component manager can use the global service manager.
nsComponentManagerImpl *compMgr = NULL;
if (nsComponentManagerImpl::gComponentManager == NULL)
{
compMgr = new nsComponentManagerImpl();
if (compMgr == NULL)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(compMgr);
nsresult rv = compMgr->Init();
if (NS_FAILED(rv))
{
NS_RELEASE(compMgr);
return rv;
}
nsComponentManagerImpl::gComponentManager = compMgr;
}
rv = servMgr->RegisterService(kComponentManagerCID, compMgr);
if (NS_FAILED(rv)) return rv;
// 3. Register the RegistryFactory with the component manager so that
// clients can create new registry objects.
nsIFactory *registryFactory = NULL;
rv = NS_RegistryGetFactory(servMgr, &registryFactory);
if (NS_FAILED(rv)) return rv;
NS_DEFINE_CID(kRegistryCID, NS_REGISTRY_CID);
rv = compMgr->RegisterFactory(kRegistryCID, NS_REGISTRY_CLASSNAME,
NS_REGISTRY_PROGID, registryFactory,
PR_TRUE);
NS_RELEASE(registryFactory);
if (NS_FAILED(rv)) return rv;
// Register nsAllocator
nsAllocatorFactory* alloc = new nsAllocatorFactory();
if (alloc == NULL)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(alloc);
static NS_DEFINE_CID(kAllocatorCID, NS_ALLOCATOR_CID);
rv = compMgr->RegisterFactory(kAllocatorCID, "Malloc/Free Allocator",
NULL, alloc, PR_TRUE);
NS_RELEASE(alloc);
if (NS_FAILED(rv)) return rv;
return rv;
}

View File

@@ -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 "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.
*/
#ifndef nsXPComFactory_h__
#define nsXPComFactory_h__
#include "nsIFactory.h"
/*
* This file contains a macro for the implementation of a simple XPCOM factory.
*
* To implement a factory for a given component, you need to declare the
* factory class using the NS_DEF_FACTORY() macro.
*
* The first macro argument is the name for the factory.
*
* The second macro argument is a function (provided by you) which
* can be called by your DLL's NSGetFactory(...) entry point.
*
* Example:
*
* NS_DEF_FACTORY(SomeComponent,SomeComponentImpl)
*
* Declares:
*
* class nsSomeComponentFactory : public nsIFactory {};
*
* NOTE that the NS_DEF_FACTORY takes care of enforcing the "ns" prefix
* and appending the "Factory" suffix to the given name.
*
* To use the new factory:
*
* nsresult NS_New_SomeComponent_Factory(nsIFactory** aResult)
* {
* nsresult rv = NS_OK;
* nsIFactory* inst = new nsSomeComponentFactory;
* if (NULL == inst) {
* rv = NS_ERROR_OUT_OF_MEMORY;
* } else {
* NS_ADDREF(inst);
* }
* *aResult = inst;
* return rv;
* }
*
* NOTE:
* ----
* The factories created by this macro are not thread-safe and do not
* support aggregation.
*
*/
#define NS_DEF_FACTORY(_name,_type) \
class ns##_name##Factory : public nsIFactory \
{ \
public: \
ns##_name##Factory() { NS_INIT_REFCNT(); } \
\
NS_IMETHOD_(nsrefcnt) AddRef (void) \
{ \
return ++mRefCnt; \
} \
\
NS_IMETHOD_(nsrefcnt) Release(void) \
{ \
NS_PRECONDITION(0 != mRefCnt, "dup release"); \
if (--mRefCnt == 0) { \
NS_DELETEXPCOM(this); \
return 0; \
} \
return mRefCnt; \
} \
\
NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr) \
{ \
if (NULL == aInstancePtr) { \
return NS_ERROR_NULL_POINTER; \
} \
\
*aInstancePtr = NULL; \
\
static NS_DEFINE_IID(kIFactoryIID, NS_IFACTORY_IID); \
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID); \
if (aIID.Equals(kIFactoryIID)) { \
*aInstancePtr = (void*) this; \
NS_ADDREF_THIS(); \
return NS_OK; \
} \
if (aIID.Equals(kISupportsIID)) { \
*aInstancePtr = (void*) ((nsISupports*)this); \
NS_ADDREF_THIS(); \
return NS_OK; \
} \
return NS_NOINTERFACE; \
} \
\
NS_IMETHOD CreateInstance(nsISupports *aOuter, \
const nsIID &aIID, \
void **aResult) \
{ \
nsresult rv; \
\
_type * inst; \
\
if (NULL == aResult) { \
rv = NS_ERROR_NULL_POINTER; \
goto done; \
} \
*aResult = NULL; \
if (NULL != aOuter) { \
rv = NS_ERROR_NO_AGGREGATION; \
goto done; \
} \
\
NS_NEWXPCOM(inst, _type); \
if (NULL == inst) { \
rv = NS_ERROR_OUT_OF_MEMORY; \
goto done; \
} \
NS_ADDREF(inst); \
rv = inst->QueryInterface(aIID, aResult); \
NS_RELEASE(inst); \
\
done: \
return rv; \
} \
\
NS_IMETHOD LockFactory(PRBool aLock) \
{ \
return NS_OK; \
} \
\
\
protected: \
virtual ~ns##_name##Factory() \
{ \
NS_ASSERTION(mRefCnt == 0, "non-zero refcnt at destruction"); \
} \
\
nsrefcnt mRefCnt; \
};
#endif /* nsXPComFactory_h__ */

View File

@@ -0,0 +1,171 @@
/* -*- 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 "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.
*/
/* nsDll
*
* Abstraction of a Dll. Stores modifiedTime and size for easy detection of
* change in dll.
*
* dp Suresh <dp@netscape.com>
*/
#include "xcDll.h"
#include "plstr.h" // strdup and strfree
nsDll::nsDll(const char *libFullPath) : m_fullpath(NULL), m_instance(NULL),
m_status(DLL_OK)
{
m_lastModTime = LL_ZERO;
m_size = 0;
if (libFullPath == NULL)
{
m_status = DLL_INVALID_PARAM;
return;
}
m_fullpath = PL_strdup(libFullPath);
if (m_fullpath == NULL)
{
// No more memory
m_status = DLL_NO_MEM;
return;
}
PRFileInfo statinfo;
if (PR_GetFileInfo(m_fullpath, &statinfo) != PR_SUCCESS)
{
// The stat things works only if people pass in the full pathname.
// Even if our stat fails, we could be able to load it because of
// LD_LIBRARY_PATH and other such paths where dlls are searched for
// XXX we need a way of marking this occurance.
// XXX m_status = DLL_STAT_ERROR;
}
else
{
m_size = statinfo.size;
m_lastModTime = statinfo.modifyTime;
if (statinfo.type != PR_FILE_FILE)
{
// Not a file. Cant work with it.
m_status = DLL_NOT_FILE;
return;
}
}
m_status = DLL_OK;
}
nsDll::nsDll(const char *libFullPath, PRTime lastModTime, PRUint32 fileSize)
: m_fullpath(NULL), m_instance(NULL), m_status(DLL_OK)
{
m_lastModTime = lastModTime;
m_size = fileSize;
if (libFullPath == NULL)
{
m_status = DLL_INVALID_PARAM;
return;
}
m_fullpath = PL_strdup(libFullPath);
if (m_fullpath == NULL)
{
// No more memory
m_status = DLL_NO_MEM;
return;
}
m_status = DLL_OK;
}
nsDll::~nsDll(void)
{
if (m_instance != NULL)
Unload();
if (m_fullpath != NULL) PL_strfree(m_fullpath);
m_fullpath = NULL;
}
PRBool nsDll::Load(void)
{
#ifdef XP_MAC
char *macFileName = NULL;
int loop;
#endif
if (m_status != DLL_OK)
{
return (PR_FALSE);
}
if (m_instance != NULL)
{
// Already loaded
return (PR_TRUE);
}
#ifdef XP_MAC
// err = ConvertUnixPathToMacPath(m_fullpath, &macFileName);
if ((macFileName = PL_strdup(m_fullpath)) != NULL)
{
if (macFileName[0] == '/')
{
for (loop=0; loop<PL_strlen(macFileName); loop++)
{
if (macFileName[loop] == '/') macFileName[loop] = ':';
}
m_instance = PR_LoadLibrary(&macFileName[1]); // skip over initial slash
}
else
{
m_instance = PR_LoadLibrary(macFileName);
}
PL_strfree(macFileName);
}
#else
// This is the only right way of doing this...
m_instance = PR_LoadLibrary(m_fullpath);
#endif /* XP_MAC */
return ((m_instance == NULL) ? PR_FALSE : PR_TRUE);
}
PRBool nsDll::Unload(void)
{
if (m_status != DLL_OK || m_instance == NULL)
return (PR_FALSE);
PRStatus ret = PR_UnloadLibrary(m_instance);
if (ret == PR_SUCCESS)
{
m_instance = NULL;
return (PR_TRUE);
}
else
return (PR_FALSE);
}
void * nsDll::FindSymbol(const char *symbol)
{
if (symbol == NULL)
return (NULL);
// If not already loaded, load it now.
if (Load() != PR_TRUE)
return (NULL);
return (PR_FindSymbol(m_instance, symbol));
}

View File

@@ -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 "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.
*/
/* Dll
*
* Programmatic representation of a dll. Stores modifiedTime and size for
* easy detection of change in dll.
*
* dp Suresh <dp@netscape.com>
*/
#include "prio.h"
#include "prlink.h"
typedef enum nsDllStatus
{
DLL_OK = 0,
DLL_NO_MEM = 1,
DLL_STAT_ERROR = 2,
DLL_NOT_FILE = 3,
DLL_INVALID_PARAM = 4
} nsDllStatus;
class nsDll
{
private:
char *m_fullpath; // system format full filename of dll
PRTime m_lastModTime; // last modified time
PRUint32 m_size; // size of the dynamic library
PRLibrary *m_instance; // Load instance
nsDllStatus m_status; // holds current status
public:
nsDll(const char *libFullPath);
nsDll(const char *libFullPath, PRTime lastModTime, PRUint32 fileSize);
~nsDll(void);
// Status checking on operations completed
nsDllStatus GetStatus(void) { return (m_status); }
// Dll Loading
PRBool Load(void);
PRBool Unload(void);
PRBool IsLoaded(void)
{
return ((m_instance != 0) ? PR_TRUE : PR_FALSE);
}
void *FindSymbol(const char *symbol);
const char *GetFullPath(void) { return (m_fullpath); }
PRTime GetLastModifiedTime(void) { return(m_lastModTime); }
PRUint32 GetSize(void) { return(m_size); }
PRLibrary *GetInstance(void) { return (m_instance); }
};

View File

@@ -0,0 +1,88 @@
/* -*- 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 "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 FILE IS OBSOLETE */
/* nsDllStore
*
* Stores dll and their accociated info in a hash keyed on the system format
* full dll path name e.g C:\Program Files\Netscape\Program\raptor.dll
*
* NOTE: dll names are considered to be case sensitive.
*/
#include "xcDllStore.h"
static PR_CALLBACK PRIntn _deleteDllInfo(PLHashEntry *he, PRIntn i, void *arg)
{
delete (nsDll *)he->value;
return (HT_ENUMERATE_NEXT);
}
nsDllStore::nsDllStore(void) : m_dllHashTable(NULL)
{
PRUint32 initSize = 128;
m_dllHashTable = PL_NewHashTable(initSize, PL_HashString,
PL_CompareStrings, PL_CompareValues, NULL, NULL);
}
nsDllStore::~nsDllStore(void)
{
if (m_dllHashTable)
{
// Delete each of the nsDll stored before deleting the Hash Table
PL_HashTableEnumerateEntries(m_dllHashTable, _deleteDllInfo, NULL);
PL_HashTableDestroy(m_dllHashTable);
}
m_dllHashTable = NULL;
}
nsDll* nsDllStore::Get(const char *dll)
{
nsDll *dllInfo = NULL;
if (m_dllHashTable)
{
dllInfo = (nsDll *)PL_HashTableLookup(m_dllHashTable, dll);
}
return (dllInfo);
}
nsDll* nsDllStore::Remove(const char *dll)
{
if (m_dllHashTable == NULL)
{
return (NULL);
}
nsDll *dllInfo = Get(dll);
PL_HashTableRemove(m_dllHashTable, dll);
return (dllInfo);
}
PRBool nsDllStore::Put(const char *dll, nsDll *dllInfo)
{
if (m_dllHashTable == NULL)
return(PR_FALSE);
PLHashEntry *entry =
PL_HashTableAdd(m_dllHashTable, (void *)dll, (void *)dllInfo);
return ((entry != NULL) ? PR_TRUE : PR_FALSE);
}

View File

@@ -0,0 +1,49 @@
/* -*- 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 "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.
*/
/* nsDllStore
*
* Stores dll and their accociated info in a hash keyed on the system format
* full dll path name e.g C:\Program Files\Netscape\Program\raptor.dll
*
* NOTE: dll names are considered to be case sensitive.
*/
#include "plhash.h"
#include "xcDll.h"
class nsDllStore
{
private:
PLHashTable *m_dllHashTable;
public:
// Constructor
nsDllStore(void);
~nsDllStore(void);
// Caller is not expected to delete nsDll returned
// The nsDll returned in NOT removed from the hash
nsDll* Get(const char *filename);
PRBool Put(const char *filename, nsDll *dllInfo);
// The nsDll returned is removed from the hash
// Caller is expected to delete the returned nsDll
nsDll* Remove(const char *filename);
};

View File

@@ -0,0 +1,392 @@
/* -*- 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 "nsIEnumerator.h"
////////////////////////////////////////////////////////////////////////////////
// Intersection Enumerators
////////////////////////////////////////////////////////////////////////////////
class nsConjoiningEnumerator : public nsIBidirectionalEnumerator
{
public:
NS_DECL_ISUPPORTS
// nsIEnumerator methods:
NS_IMETHOD First(void);
NS_IMETHOD Next(void);
NS_IMETHOD CurrentItem(nsISupports **aItem);
NS_IMETHOD IsDone(void);
// nsIBidirectionalEnumerator methods:
NS_IMETHOD Last(void);
NS_IMETHOD Prev(void);
// nsConjoiningEnumerator methods:
nsConjoiningEnumerator(nsIEnumerator* first, nsIEnumerator* second);
virtual ~nsConjoiningEnumerator(void);
protected:
nsIEnumerator* mFirst;
nsIEnumerator* mSecond;
nsIEnumerator* mCurrent;
};
nsConjoiningEnumerator::nsConjoiningEnumerator(nsIEnumerator* first, nsIEnumerator* second)
: mFirst(first), mSecond(second), mCurrent(first)
{
NS_ADDREF(mFirst);
NS_ADDREF(mSecond);
}
nsConjoiningEnumerator::~nsConjoiningEnumerator(void)
{
NS_RELEASE(mFirst);
NS_RELEASE(mSecond);
}
NS_IMPL_ADDREF(nsConjoiningEnumerator);
NS_IMPL_RELEASE(nsConjoiningEnumerator);
NS_IMETHODIMP
nsConjoiningEnumerator::QueryInterface(REFNSIID aIID, void** aInstancePtr)
{
if (NULL == aInstancePtr)
return NS_ERROR_NULL_POINTER;
if (aIID.Equals(nsIBidirectionalEnumerator::GetIID()) ||
aIID.Equals(nsIEnumerator::GetIID()) ||
aIID.Equals(nsISupports::GetIID())) {
*aInstancePtr = (void*) this;
NS_ADDREF_THIS();
return NS_OK;
}
return NS_NOINTERFACE;
}
NS_IMETHODIMP
nsConjoiningEnumerator::First(void)
{
mCurrent = mFirst;
return mCurrent->First();
}
NS_IMETHODIMP
nsConjoiningEnumerator::Next(void)
{
nsresult rv = mCurrent->Next();
if (NS_FAILED(rv) && mCurrent == mFirst) {
mCurrent = mSecond;
rv = mCurrent->First();
}
return rv;
}
NS_IMETHODIMP
nsConjoiningEnumerator::CurrentItem(nsISupports **aItem)
{
return mCurrent->CurrentItem(aItem);
}
NS_IMETHODIMP
nsConjoiningEnumerator::IsDone(void)
{
return (mCurrent == mFirst && mCurrent->IsDone() == NS_OK)
|| (mCurrent == mSecond && mCurrent->IsDone() == NS_OK)
? NS_OK : NS_COMFALSE;
}
////////////////////////////////////////////////////////////////////////////////
NS_IMETHODIMP
nsConjoiningEnumerator::Last(void)
{
nsresult rv;
nsIBidirectionalEnumerator* be;
rv = mSecond->QueryInterface(nsIBidirectionalEnumerator::GetIID(), (void**)&be);
if (NS_FAILED(rv)) return rv;
mCurrent = mSecond;
rv = be->Last();
NS_RELEASE(be);
return rv;
}
NS_IMETHODIMP
nsConjoiningEnumerator::Prev(void)
{
nsresult rv;
nsIBidirectionalEnumerator* be;
rv = mCurrent->QueryInterface(nsIBidirectionalEnumerator::GetIID(), (void**)&be);
if (NS_FAILED(rv)) return rv;
rv = be->Prev();
NS_RELEASE(be);
if (NS_FAILED(rv) && mCurrent == mSecond) {
rv = mFirst->QueryInterface(nsIBidirectionalEnumerator::GetIID(), (void**)&be);
if (NS_FAILED(rv)) return rv;
mCurrent = mFirst;
rv = be->Last();
NS_RELEASE(be);
}
return rv;
}
////////////////////////////////////////////////////////////////////////////////
extern "C" NS_COM nsresult
NS_NewConjoiningEnumerator(nsIEnumerator* first, nsIEnumerator* second,
nsIBidirectionalEnumerator* *aInstancePtrResult)
{
if (aInstancePtrResult == 0)
return NS_ERROR_NULL_POINTER;
nsConjoiningEnumerator* e = new nsConjoiningEnumerator(first, second);
if (e == 0)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(e);
*aInstancePtrResult = e;
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
static nsresult
nsEnumeratorContains(nsIEnumerator* e, nsISupports* item)
{
nsresult rv;
for (e->First(); e->IsDone() != NS_OK; e->Next()) {
nsISupports* other;
rv = e->CurrentItem(&other);
if (NS_FAILED(rv)) return rv;
if (item == other) {
NS_RELEASE(other);
return NS_OK; // true -- exists in enumerator
}
NS_RELEASE(other);
}
return NS_COMFALSE; // false -- doesn't exist
}
////////////////////////////////////////////////////////////////////////////////
// Intersection Enumerators
////////////////////////////////////////////////////////////////////////////////
class nsIntersectionEnumerator : public nsIEnumerator
{
public:
NS_DECL_ISUPPORTS
// nsIEnumerator methods:
NS_IMETHOD First(void);
NS_IMETHOD Next(void);
NS_IMETHOD CurrentItem(nsISupports **aItem);
NS_IMETHOD IsDone(void);
// nsIntersectionEnumerator methods:
nsIntersectionEnumerator(nsIEnumerator* first, nsIEnumerator* second);
virtual ~nsIntersectionEnumerator(void);
protected:
nsIEnumerator* mFirst;
nsIEnumerator* mSecond;
};
nsIntersectionEnumerator::nsIntersectionEnumerator(nsIEnumerator* first, nsIEnumerator* second)
: mFirst(first), mSecond(second)
{
NS_ADDREF(mFirst);
NS_ADDREF(mSecond);
}
nsIntersectionEnumerator::~nsIntersectionEnumerator(void)
{
NS_RELEASE(mFirst);
NS_RELEASE(mSecond);
}
NS_IMPL_ISUPPORTS(nsIntersectionEnumerator, nsIEnumerator::GetIID());
NS_IMETHODIMP
nsIntersectionEnumerator::First(void)
{
nsresult rv = mFirst->First();
if (NS_FAILED(rv)) return rv;
return Next();
}
NS_IMETHODIMP
nsIntersectionEnumerator::Next(void)
{
nsresult rv;
// find the first item that exists in both
for (; mFirst->IsDone() != NS_OK; mFirst->Next()) {
nsISupports* item;
rv = mFirst->CurrentItem(&item);
if (NS_FAILED(rv)) return rv;
// see if it also exists in mSecond
rv = nsEnumeratorContains(mSecond, item);
if (NS_FAILED(rv)) return rv;
NS_RELEASE(item);
if (rv == NS_OK) {
// found in both, so return leaving it as the current item of mFirst
return NS_OK;
}
}
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsIntersectionEnumerator::CurrentItem(nsISupports **aItem)
{
return mFirst->CurrentItem(aItem);
}
NS_IMETHODIMP
nsIntersectionEnumerator::IsDone(void)
{
return mFirst->IsDone();
}
////////////////////////////////////////////////////////////////////////////////
extern "C" NS_COM nsresult
NS_NewIntersectionEnumerator(nsIEnumerator* first, nsIEnumerator* second,
nsIEnumerator* *aInstancePtrResult)
{
if (aInstancePtrResult == 0)
return NS_ERROR_NULL_POINTER;
nsIntersectionEnumerator* e = new nsIntersectionEnumerator(first, second);
if (e == 0)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(e);
*aInstancePtrResult = e;
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
// Union Enumerators
////////////////////////////////////////////////////////////////////////////////
class nsUnionEnumerator : public nsIEnumerator
{
public:
NS_DECL_ISUPPORTS
// nsIEnumerator methods:
NS_IMETHOD First(void);
NS_IMETHOD Next(void);
NS_IMETHOD CurrentItem(nsISupports **aItem);
NS_IMETHOD IsDone(void);
// nsUnionEnumerator methods:
nsUnionEnumerator(nsIEnumerator* first, nsIEnumerator* second);
virtual ~nsUnionEnumerator(void);
protected:
nsIEnumerator* mFirst;
nsIEnumerator* mSecond;
};
nsUnionEnumerator::nsUnionEnumerator(nsIEnumerator* first, nsIEnumerator* second)
: mFirst(first), mSecond(second)
{
NS_ADDREF(mFirst);
NS_ADDREF(mSecond);
}
nsUnionEnumerator::~nsUnionEnumerator(void)
{
NS_RELEASE(mFirst);
NS_RELEASE(mSecond);
}
NS_IMPL_ISUPPORTS(nsUnionEnumerator, nsIEnumerator::GetIID());
NS_IMETHODIMP
nsUnionEnumerator::First(void)
{
nsresult rv = mFirst->First();
if (NS_FAILED(rv)) return rv;
return Next();
}
NS_IMETHODIMP
nsUnionEnumerator::Next(void)
{
nsresult rv;
// find the first item that exists in both
for (; mFirst->IsDone() != NS_OK; mFirst->Next()) {
nsISupports* item;
rv = mFirst->CurrentItem(&item);
if (NS_FAILED(rv)) return rv;
// see if it also exists in mSecond
rv = nsEnumeratorContains(mSecond, item);
if (NS_FAILED(rv)) return rv;
NS_RELEASE(item);
if (rv != NS_OK) {
// if it didn't exist in mSecond, return, making it the current item
return NS_OK;
}
// each time around, make sure that mSecond gets reset to the beginning
// so that when mFirst is done, we'll be ready to enumerate mSecond
rv = mSecond->First();
if (NS_FAILED(rv)) return rv;
}
return mSecond->Next();
}
NS_IMETHODIMP
nsUnionEnumerator::CurrentItem(nsISupports **aItem)
{
if (mFirst->IsDone() != NS_OK)
return mFirst->CurrentItem(aItem);
else
return mSecond->CurrentItem(aItem);
}
NS_IMETHODIMP
nsUnionEnumerator::IsDone(void)
{
return (mFirst->IsDone() == NS_OK && mSecond->IsDone() == NS_OK)
? NS_OK : NS_COMFALSE;
}
////////////////////////////////////////////////////////////////////////////////
extern "C" NS_COM nsresult
NS_NewUnionEnumerator(nsIEnumerator* first, nsIEnumerator* second,
nsIEnumerator* *aInstancePtrResult)
{
if (aInstancePtrResult == 0)
return NS_ERROR_NULL_POINTER;
nsUnionEnumerator* e = new nsUnionEnumerator(first, second);
if (e == 0)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(e);
*aInstancePtrResult = e;
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////

View File

@@ -0,0 +1,77 @@
/* -*- 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.
*/
/*
An empty enumerator.
*/
#include "nsIEnumerator.h"
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
////////////////////////////////////////////////////////////////////////
class EmptyEnumeratorImpl : public nsISimpleEnumerator
{
public:
EmptyEnumeratorImpl(void) {};
virtual ~EmptyEnumeratorImpl(void) {};
// nsISupports interface
NS_IMETHOD_(nsrefcnt) AddRef(void) {
return 2;
}
NS_IMETHOD_(nsrefcnt) Release(void) {
return 1;
}
NS_IMETHOD QueryInterface(REFNSIID iid, void** result) {
if (! result)
return NS_ERROR_NULL_POINTER;
if (iid.Equals(nsISimpleEnumerator::GetIID()) ||
iid.Equals(kISupportsIID)) {
*result = (nsISimpleEnumerator*) this;
NS_ADDREF(this);
return NS_OK;
}
return NS_NOINTERFACE;
}
// nsISimpleEnumerator
NS_IMETHOD HasMoreElements(PRBool* aResult) {
*aResult = PR_FALSE;
return NS_OK;
}
NS_IMETHOD GetNext(nsISupports** aResult) {
return NS_ERROR_UNEXPECTED;
}
};
extern "C" NS_COM nsresult
NS_NewEmptyEnumerator(nsISimpleEnumerator** aResult)
{
static EmptyEnumeratorImpl gEmptyEnumerator;
*aResult = &gEmptyEnumerator;
return NS_OK;
}

View File

@@ -0,0 +1,186 @@
/* -*- 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 "nsEnumeratorUtils.h"
nsArrayEnumerator::nsArrayEnumerator(nsISupportsArray* aValueArray)
: mValueArray(aValueArray),
mIndex(0)
{
NS_INIT_REFCNT();
NS_IF_ADDREF(mValueArray);
}
nsArrayEnumerator::~nsArrayEnumerator(void)
{
NS_IF_RELEASE(mValueArray);
}
NS_IMPL_ISUPPORTS(nsArrayEnumerator, nsISimpleEnumerator::GetIID());
NS_IMETHODIMP
nsArrayEnumerator::HasMoreElements(PRBool* aResult)
{
NS_PRECONDITION(aResult != 0, "null ptr");
if (! aResult)
return NS_ERROR_NULL_POINTER;
*aResult = (mIndex < (PRInt32) mValueArray->Count());
return NS_OK;
}
NS_IMETHODIMP
nsArrayEnumerator::GetNext(nsISupports** aResult)
{
NS_PRECONDITION(aResult != 0, "null ptr");
if (! aResult)
return NS_ERROR_NULL_POINTER;
if (mIndex >= (PRInt32) mValueArray->Count())
return NS_ERROR_UNEXPECTED;
*aResult = mValueArray->ElementAt(mIndex++);
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
nsSingletonEnumerator::nsSingletonEnumerator(nsISupports* aValue)
: mValue(aValue)
{
NS_INIT_REFCNT();
NS_IF_ADDREF(mValue);
mConsumed = (mValue ? PR_FALSE : PR_TRUE);
}
nsSingletonEnumerator::~nsSingletonEnumerator()
{
NS_IF_RELEASE(mValue);
}
NS_IMPL_ISUPPORTS(nsSingletonEnumerator, nsISimpleEnumerator::GetIID());
NS_IMETHODIMP
nsSingletonEnumerator::HasMoreElements(PRBool* aResult)
{
NS_PRECONDITION(aResult != 0, "null ptr");
if (! aResult)
return NS_ERROR_NULL_POINTER;
*aResult = !mConsumed;
return NS_OK;
}
NS_IMETHODIMP
nsSingletonEnumerator::GetNext(nsISupports** aResult)
{
NS_PRECONDITION(aResult != 0, "null ptr");
if (! aResult)
return NS_ERROR_NULL_POINTER;
if (mConsumed)
return NS_ERROR_UNEXPECTED;
mConsumed = PR_TRUE;
NS_ADDREF(mValue);
*aResult = mValue;
return NS_OK;
}
////////////////////////////////////////////////////////////////////////
nsAdapterEnumerator::nsAdapterEnumerator(nsIEnumerator* aEnum)
: mEnum(aEnum), mCurrent(0), mStarted(PR_FALSE)
{
NS_INIT_REFCNT();
NS_ADDREF(mEnum);
}
nsAdapterEnumerator::~nsAdapterEnumerator()
{
NS_RELEASE(mEnum);
NS_IF_RELEASE(mCurrent);
}
NS_IMPL_ISUPPORTS(nsAdapterEnumerator, nsISimpleEnumerator::GetIID());
NS_IMETHODIMP
nsAdapterEnumerator::HasMoreElements(PRBool* aResult)
{
nsresult rv;
if (mCurrent) {
*aResult = PR_TRUE;
return NS_OK;
}
if (! mStarted) {
mStarted = PR_TRUE;
rv = mEnum->First();
if (rv == NS_OK) {
mEnum->CurrentItem(&mCurrent);
*aResult = PR_TRUE;
}
else {
*aResult = PR_FALSE;
}
}
else {
*aResult = PR_FALSE;
rv = mEnum->IsDone();
if (rv != NS_OK) {
// We're not done. Advance to the next one.
rv = mEnum->Next();
if (rv == NS_OK) {
mEnum->CurrentItem(&mCurrent);
*aResult = PR_TRUE;
}
}
}
return NS_OK;
}
NS_IMETHODIMP
nsAdapterEnumerator::GetNext(nsISupports** aResult)
{
nsresult rv;
PRBool hasMore;
rv = HasMoreElements(&hasMore);
if (NS_FAILED(rv)) return rv;
if (! hasMore)
return NS_ERROR_UNEXPECTED;
// No need to addref, we "transfer" the ownership to the caller.
*aResult = mCurrent;
mCurrent = 0;
return NS_OK;
}

View File

@@ -0,0 +1,85 @@
/* -*- 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.
*/
#ifndef nsRDFCursorUtils_h__
#define nsRDFCursorUtils_h__
#include "nsIEnumerator.h"
#include "nsISupportsArray.h"
class NS_COM nsArrayEnumerator : public nsISimpleEnumerator
{
public:
// nsISupports interface
NS_DECL_ISUPPORTS
// nsISimpleEnumerator interface
NS_IMETHOD HasMoreElements(PRBool* aResult);
NS_IMETHOD GetNext(nsISupports** aResult);
// nsRDFArrayEnumerator methods
nsArrayEnumerator(nsISupportsArray* aValueArray);
virtual ~nsArrayEnumerator(void);
protected:
nsISupportsArray* mValueArray;
PRInt32 mIndex;
};
////////////////////////////////////////////////////////////////////////////////
class NS_COM nsSingletonEnumerator : public nsISimpleEnumerator
{
public:
NS_DECL_ISUPPORTS
// nsISimpleEnumerator methods
NS_IMETHOD HasMoreElements(PRBool* aResult);
NS_IMETHOD GetNext(nsISupports** aResult);
nsSingletonEnumerator(nsISupports* aValue);
virtual ~nsSingletonEnumerator();
protected:
nsISupports* mValue;
PRBool mConsumed;
};
////////////////////////////////////////////////////////////////////////////////
class NS_COM nsAdapterEnumerator : public nsISimpleEnumerator
{
public:
NS_DECL_ISUPPORTS
// nsISimpleEnumerator methods
NS_IMETHOD HasMoreElements(PRBool* aResult);
NS_IMETHOD GetNext(nsISupports** aResult);
nsAdapterEnumerator(nsIEnumerator* aEnum);
virtual ~nsAdapterEnumerator();
protected:
nsIEnumerator* mEnum;
nsISupports* mCurrent;
PRBool mStarted;
};
////////////////////////////////////////////////////////////////////////
#endif /* nsRDFCursorUtils_h__ */

View File

@@ -0,0 +1,259 @@
/* -*- 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 "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 "prmem.h"
#include "prlog.h"
#include "nsHashtable.h"
//
// Key operations
//
static PR_CALLBACK PLHashNumber _hashValue(const void *key)
{
return ((const nsHashKey *) key)->HashValue();
}
static PR_CALLBACK PRIntn _hashKeyCompare(const void *key1, const void *key2) {
return ((const nsHashKey *) key1)->Equals((const nsHashKey *) key2);
}
static PR_CALLBACK PRIntn _hashValueCompare(const void *value1,
const void *value2) {
// We're not going to make any assumptions about value equality
return 0;
}
//
// Memory callbacks
//
static PR_CALLBACK void *_hashAllocTable(void *pool, PRSize size) {
return PR_MALLOC(size);
}
static PR_CALLBACK void _hashFreeTable(void *pool, void *item) {
PR_DELETE(item);
}
static PR_CALLBACK PLHashEntry *_hashAllocEntry(void *pool, const void *key) {
return PR_NEW(PLHashEntry);
}
static PR_CALLBACK void _hashFreeEntry(void *pool, PLHashEntry *entry,
PRUintn flag) {
if (flag == HT_FREE_ENTRY) {
delete (nsHashKey *) (entry->key);
PR_DELETE(entry);
}
}
static PLHashAllocOps _hashAllocOps = {
_hashAllocTable, _hashFreeTable,
_hashAllocEntry, _hashFreeEntry
};
//
// Enumerator callback
//
struct _HashEnumerateArgs {
nsHashtableEnumFunc fn;
void* arg;
};
static PR_CALLBACK PRIntn _hashEnumerate(PLHashEntry *he, PRIntn i, void *arg)
{
_HashEnumerateArgs* thunk = (_HashEnumerateArgs*)arg;
return thunk->fn((nsHashKey *) he->key, he->value, thunk->arg)
? HT_ENUMERATE_NEXT
: HT_ENUMERATE_STOP;
}
//
// HashKey
//
nsHashKey::nsHashKey(void)
{
}
nsHashKey::~nsHashKey(void)
{
}
nsHashtable::nsHashtable(PRUint32 aInitSize, PRBool threadSafe)
: mLock(NULL)
{
hashtable = PL_NewHashTable(aInitSize,
_hashValue,
_hashKeyCompare,
_hashValueCompare,
&_hashAllocOps,
NULL);
if (threadSafe == PR_TRUE)
{
mLock = PR_NewLock();
if (mLock == NULL)
{
// Cannot create a lock. If running on a multiprocessing system
// we are sure to die.
PR_ASSERT(mLock != NULL);
}
}
}
nsHashtable::~nsHashtable() {
PL_HashTableDestroy(hashtable);
if (mLock) PR_DestroyLock(mLock);
}
PRBool nsHashtable::Exists(nsHashKey *aKey)
{
PLHashNumber hash = aKey->HashValue();
if (mLock) PR_Lock(mLock);
PLHashEntry **hep = PL_HashTableRawLookup(hashtable, hash, (void *) aKey);
if (mLock) PR_Unlock(mLock);
return *hep != NULL;
}
void *nsHashtable::Put(nsHashKey *aKey, void *aData) {
void *res = NULL;
PLHashNumber hash = aKey->HashValue();
PLHashEntry *he;
if (mLock) PR_Lock(mLock);
PLHashEntry **hep = PL_HashTableRawLookup(hashtable, hash, (void *) aKey);
if ((he = *hep) != NULL) {
res = he->value;
he->value = aData;
} else {
PL_HashTableRawAdd(hashtable, hep, hash,
(void *) aKey->Clone(), aData);
}
if (mLock) PR_Unlock(mLock);
return res;
}
void *nsHashtable::Get(nsHashKey *aKey) {
if (mLock) PR_Lock(mLock);
void *ret = PL_HashTableLookup(hashtable, (void *) aKey);
if (mLock) PR_Unlock(mLock);
return ret;
}
void *nsHashtable::Remove(nsHashKey *aKey) {
PLHashNumber hash = aKey->HashValue();
PLHashEntry *he;
if (mLock) PR_Lock(mLock);
PLHashEntry **hep = PL_HashTableRawLookup(hashtable, hash, (void *) aKey);
void *res = NULL;
if ((he = *hep) != NULL) {
res = he->value;
PL_HashTableRawRemove(hashtable, hep, he);
}
if (mLock) PR_Unlock(mLock);
return res;
}
static PR_CALLBACK PRIntn _hashEnumerateCopy(PLHashEntry *he, PRIntn i, void *arg)
{
nsHashtable *newHashtable = (nsHashtable *)arg;
newHashtable->Put((nsHashKey *) he->key, he->value);
return HT_ENUMERATE_NEXT;
}
nsHashtable * nsHashtable::Clone() {
PRBool threadSafe = PR_FALSE;
if (mLock)
threadSafe = PR_TRUE;
nsHashtable *newHashTable = new nsHashtable(hashtable->nentries, threadSafe);
PL_HashTableEnumerateEntries(hashtable, _hashEnumerateCopy, newHashTable);
return newHashTable;
}
void nsHashtable::Enumerate(nsHashtableEnumFunc aEnumFunc, void* closure) {
_HashEnumerateArgs thunk;
thunk.fn = aEnumFunc;
thunk.arg = closure;
PL_HashTableEnumerateEntries(hashtable, _hashEnumerate, &thunk);
}
static PR_CALLBACK PRIntn _hashEnumerateRemove(PLHashEntry *he, PRIntn i, void *arg)
{
return HT_ENUMERATE_REMOVE;
}
void nsHashtable::Reset() {
PL_HashTableEnumerateEntries(hashtable, _hashEnumerateRemove, NULL);
}
////////////////////////////////////////////////////////////////////////////////
nsCStringKey::nsCStringKey(const char* str)
: mStr(mBuf)
{
PRUint32 len = PL_strlen(str);
if (len >= sizeof(mBuf)) {
mStr = PL_strdup(str);
NS_ASSERTION(mStr, "out of memory");
}
else {
PL_strcpy(mStr, str);
}
}
nsCStringKey::~nsCStringKey(void)
{
if (mStr != mBuf)
PL_strfree(mStr);
}
PRUint32 nsCStringKey::HashValue(void) const
{
return (PRUint32) PL_HashString((const void*) mStr);
}
PRBool nsCStringKey::Equals(const nsHashKey* aKey) const
{
return PL_strcmp( ((nsCStringKey*)aKey)->mStr, mStr ) == 0;
}
nsHashKey* nsCStringKey::Clone() const
{
return new nsCStringKey(mStr);
}
////////////////////////////////////////////////////////////////////////////////

View File

@@ -0,0 +1,168 @@
/* -*- 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 "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 nsHashtable_h__
#define nsHashtable_h__
#include "plhash.h"
#include "prlock.h"
#include "nsCom.h"
class NS_COM nsHashKey {
protected:
nsHashKey(void);
public:
virtual ~nsHashKey(void);
virtual PRUint32 HashValue(void) const = 0;
virtual PRBool Equals(const nsHashKey *aKey) const = 0;
virtual nsHashKey *Clone(void) const = 0;
};
// Enumerator callback function. Use
typedef PRBool (*nsHashtableEnumFunc)(nsHashKey *aKey, void *aData, void* closure);
class NS_COM nsHashtable {
protected:
// members
PLHashTable *hashtable;
PRLock *mLock;
public:
nsHashtable(PRUint32 aSize = 256, PRBool threadSafe = PR_FALSE);
~nsHashtable();
PRInt32 Count(void) { return hashtable->nentries; }
PRBool Exists(nsHashKey *aKey);
void *Put(nsHashKey *aKey, void *aData);
void *Get(nsHashKey *aKey);
void *Remove(nsHashKey *aKey);
nsHashtable *Clone();
void Enumerate(nsHashtableEnumFunc aEnumFunc, void* closure = NULL);
void Reset();
};
////////////////////////////////////////////////////////////////////////////////
// nsISupportsKey: Where keys are nsISupports objects that get refcounted.
#include "nsISupports.h"
class nsISupportsKey : public nsHashKey {
protected:
nsISupports* mKey;
public:
nsISupportsKey(nsISupports* key) {
mKey = key;
NS_IF_ADDREF(mKey);
}
~nsISupportsKey(void) {
NS_IF_RELEASE(mKey);
}
PRUint32 HashValue(void) const {
return (PRUint32)mKey;
}
PRBool Equals(const nsHashKey *aKey) const {
return (mKey == ((nsISupportsKey *) aKey)->mKey);
}
nsHashKey *Clone(void) const {
return new nsISupportsKey(mKey);
}
};
////////////////////////////////////////////////////////////////////////////////
// nsVoidKey: Where keys are void* objects that don't get refcounted.
class nsVoidKey : public nsHashKey {
protected:
const void* mKey;
public:
nsVoidKey(const void* key) {
mKey = key;
}
PRUint32 HashValue(void) const {
return (PRUint32)mKey;
}
PRBool Equals(const nsHashKey *aKey) const {
return (mKey == ((const nsVoidKey *) aKey)->mKey);
}
nsHashKey *Clone(void) const {
return new nsVoidKey(mKey);
}
};
////////////////////////////////////////////////////////////////////////////////
// nsIDKey: Where keys are nsIDs (e.g. nsIID, nsCID).
#include "nsID.h"
class nsIDKey : public nsHashKey {
protected:
nsID mID;
public:
nsIDKey(const nsID &aID) {
mID = aID;
}
PRUint32 HashValue(void) const {
return mID.m0;
}
PRBool Equals(const nsHashKey *aKey) const {
return (mID.Equals(((const nsIDKey *) aKey)->mID));
}
nsHashKey *Clone(void) const {
return new nsIDKey(mID);
}
};
////////////////////////////////////////////////////////////////////////////////
// nsCStringKey: Where keys are char*'s
// Some uses: hashing ProgIDs, filenames, URIs
#include "plstr.h"
class NS_COM nsCStringKey : public nsHashKey {
protected:
char mBuf[64];
char* mStr;
public:
nsCStringKey(const char* str);
~nsCStringKey(void);
PRUint32 HashValue(void) const;
PRBool Equals(const nsHashKey* aKey) const;
nsHashKey* Clone() const;
};
#endif

View File

@@ -0,0 +1,80 @@
/* -*- 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 specifzic 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 nsICollection_h___
#define nsICollection_h___
#include "nsISupports.h"
class nsIEnumerator;
// IID for the nsICollection interface
#define NS_ICOLLECTION_IID \
{ /* 83b6019c-cbc4-11d2-8cca-0060b0fc14a3 */ \
0x83b6019c, \
0xcbc4, \
0x11d2, \
{0x8c, 0xca, 0x00, 0x60, 0xb0, 0xfc, 0x14, 0xa3} \
}
// IID for the nsICollection Factory interface
#define NS_ICOLLECTIONFACTORY_IID \
{ 0xf8052641, 0x8768, 0x11d2, \
{ 0x8f, 0x39, 0x0, 0x60, 0x8, 0x31, 0x1, 0x94 } }
//----------------------------------------------------------------------
/** nsICollection Interface
* this may be ordered or not. a list or array, the implementation is opaque
*/
class nsICollection : public nsISupports {
public:
static const nsIID& GetIID(void) { static nsIID iid = NS_ICOLLECTION_IID; return iid; }
/** Return the count of elements in the collection.
*/
NS_IMETHOD_(PRUint32) Count(void) const = 0;
/**
* AppendElement will take an ISupports and keep track of it
* @param aItem is the Item to be added WILL BE ADDREFFED
* @return NS_OK if successfully added
* @return NS_ERROR_FAILURE otherwise
*/
NS_IMETHOD AppendElement(nsISupports *aItem) = 0;
/** RemoveElement will take an nsISupports and remove it from the collection
* @param aItem is the item to be removed WILL BE RELEASED
* @return NS_OK if successfully added
* @return NS_ERROR_FAILURE otherwise
*/
NS_IMETHOD RemoveElement(nsISupports *aItem) = 0;
/** Return an enumeration for the collection.
*/
NS_IMETHOD Enumerate(nsIEnumerator* *result) = 0;
/** Clear will clear all items from list
*/
NS_IMETHOD Clear(void) = 0;
};
#endif /* nsICollection_h___ */

View File

@@ -0,0 +1,120 @@
/* -*- 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 "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 nsIEnumerator_h___
#define nsIEnumerator_h___
#include "nsISupports.h"
// {D1899240-F9D2-11d2-BDD6-000064657374}
#define NS_ISIMPLEENUMERATOR_IID \
{ 0xd1899240, 0xf9d2, 0x11d2, { 0xbd, 0xd6, 0x0, 0x0, 0x64, 0x65, 0x73, 0x74 } }
class nsISimpleEnumerator : public nsISupports {
public:
static const nsIID& GetIID(void) { static nsIID iid = NS_ISIMPLEENUMERATOR_IID; return iid; }
NS_IMETHOD HasMoreElements(PRBool* aResult) = 0;
NS_IMETHOD GetNext(nsISupports** aResult) = 0;
};
extern "C" NS_COM nsresult
NS_NewEmptyEnumerator(nsISimpleEnumerator** aResult);
#define NS_IENUMERATOR_IID \
{ /* ad385286-cbc4-11d2-8cca-0060b0fc14a3 */ \
0xad385286, \
0xcbc4, \
0x11d2, \
{0x8c, 0xca, 0x00, 0x60, 0xb0, 0xfc, 0x14, 0xa3} \
}
class nsIEnumerator : public nsISupports {
public:
static const nsIID& GetIID(void) { static nsIID iid = NS_IENUMERATOR_IID; return iid; }
/** First will reset the list. will return NS_FAILED if no items
*/
NS_IMETHOD First(void) = 0;
/** Next will advance the list. will return failed if already at end
*/
NS_IMETHOD Next(void) = 0;
/** CurrentItem will return the CurrentItem item it will fail if the list is empty
* @param aItem return value
*/
NS_IMETHOD CurrentItem(nsISupports **aItem) = 0;
/** return if the collection is at the end. that is the beginning following a call to Prev
* and it is the end of the list following a call to next
* @param aItem return value
*/
NS_IMETHOD IsDone(void) = 0;
};
#define NS_IBIDIRECTIONALENUMERATOR_IID \
{ /* 75f158a0-cadd-11d2-8cca-0060b0fc14a3 */ \
0x75f158a0, \
0xcadd, \
0x11d2, \
{0x8c, 0xca, 0x00, 0x60, 0xb0, 0xfc, 0x14, 0xa3} \
}
class nsIBidirectionalEnumerator : public nsIEnumerator {
public:
static const nsIID& GetIID(void) { static nsIID iid = NS_IBIDIRECTIONALENUMERATOR_IID; return iid; }
/** Last will reset the list to the end. will return NS_FAILED if no items
*/
NS_IMETHOD Last(void) = 0;
/** Prev will decrement the list. will return failed if already at beginning
*/
NS_IMETHOD Prev(void) = 0;
};
// Construct and return an implementation of a "conjoining enumerator." This
// enumerator lets you string together two other enumerators into one sequence.
// The result is an nsIBidirectionalEnumerator, but if either input is not
// also bidirectional, the Last and Prev operations will fail.
extern "C" NS_COM nsresult
NS_NewConjoiningEnumerator(nsIEnumerator* first, nsIEnumerator* second,
nsIBidirectionalEnumerator* *aInstancePtrResult);
// Construct and return an implementation of a "union enumerator." This
// enumerator will only return elements that are found in both constituent
// enumerators.
extern "C" NS_COM nsresult
NS_NewUnionEnumerator(nsIEnumerator* first, nsIEnumerator* second,
nsIEnumerator* *aInstancePtrResult);
// Construct and return an implementation of an "intersection enumerator." This
// enumerator will return elements that are found in either constituent
// enumerators, eliminating duplicates.
extern "C" NS_COM nsresult
NS_NewIntersectionEnumerator(nsIEnumerator* first, nsIEnumerator* second,
nsIEnumerator* *aInstancePtrResult);
#endif // __nsIEnumerator_h

View File

@@ -16,9 +16,11 @@
* Reserved.
*/
#include "nsWinRegValue.h"
#ifndef nsISimpleEnumerator_h__
#define nsISimpleEnumerator_h__
PR_BEGIN_EXTERN_C
// This file is needed to pacify the xpidl-generated header files.
#include "nsIEnumerator.h"
#endif // nsISimpleEnumerator_h__
PR_END_EXTERN_C

View File

@@ -0,0 +1,77 @@
/* -*- 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 "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 nsISupportsArray_h___
#define nsISupportsArray_h___
#include "nsCom.h"
#include "nsICollection.h"
class nsIBidirectionalEnumerator;
// {791eafa0-b9e6-11d1-8031-006008159b5a}
#define NS_ISUPPORTSARRAY_IID \
{0x791eafa0, 0xb9e6, 0x11d1, \
{0x80, 0x31, 0x00, 0x60, 0x08, 0x15, 0x9b, 0x5a}}
// Enumerator callback function. Return PR_FALSE to stop
typedef PRBool (*nsISupportsArrayEnumFunc)(nsISupports* aElement, void *aData);
class nsISupportsArray : public nsICollection {
public:
static const nsIID& GetIID() { static nsIID iid = NS_ISUPPORTSARRAY_IID; return iid; }
NS_IMETHOD_(nsISupportsArray&) operator=(const nsISupportsArray& other) = 0;
NS_IMETHOD_(PRBool) operator==(const nsISupportsArray& other) const = 0;
NS_IMETHOD_(PRBool) Equals(const nsISupportsArray* other) const = 0;
NS_IMETHOD_(nsISupports*) ElementAt(PRUint32 aIndex) const = 0;
NS_IMETHOD_(nsISupports*) operator[](PRUint32 aIndex) const = 0;
NS_IMETHOD_(PRInt32) IndexOf(const nsISupports* aPossibleElement, PRUint32 aStartIndex = 0) const = 0;
NS_IMETHOD_(PRInt32) LastIndexOf(const nsISupports* aPossibleElement) const = 0;
NS_IMETHOD_(PRBool) InsertElementAt(nsISupports* aElement, PRUint32 aIndex) = 0;
NS_IMETHOD_(PRBool) ReplaceElementAt(nsISupports* aElement, PRUint32 aIndex) = 0;
NS_IMETHOD_(PRBool) RemoveElementAt(PRUint32 aIndex) = 0;
NS_IMETHOD_(PRBool) RemoveLastElement(const nsISupports* aElement) = 0;
NS_IMETHOD_(PRBool) AppendElements(nsISupportsArray* aElements) = 0;
NS_IMETHOD_(void) Compact(void) = 0;
NS_IMETHOD_(PRBool) EnumerateForwards(nsISupportsArrayEnumFunc aFunc, void* aData) const = 0;
NS_IMETHOD_(PRBool) EnumerateBackwards(nsISupportsArrayEnumFunc aFunc, void* aData) const = 0;
private:
// Copy constructors are not allowed
// XXX test whether this has to be here nsISupportsArray(const nsISupportsArray& other);
};
// Construct and return a default implementation of nsISupportsArray:
extern NS_COM nsresult
NS_NewISupportsArray(nsISupportsArray** aInstancePtrResult);
// Construct and return a default implementation of an enumerator for nsISupportsArrays:
extern NS_COM nsresult
NS_NewISupportsArrayEnumerator(nsISupportsArray* array,
nsIBidirectionalEnumerator* *aInstancePtrResult);
#endif // nsISupportsArray_h___

View File

@@ -0,0 +1,359 @@
/* -*- 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 "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 "nsSupportsArray.h"
#include "nsSupportsArrayEnumerator.h"
static const PRUint32 kGrowArrayBy = 8;
nsSupportsArray::nsSupportsArray()
{
NS_INIT_REFCNT();
mArray = &(mAutoArray[0]);
mArraySize = kAutoArraySize;
mCount = 0;
}
nsSupportsArray::~nsSupportsArray()
{
DeleteArray();
}
NS_IMPL_ISUPPORTS(nsSupportsArray, nsISupportsArray::GetIID());
void nsSupportsArray::DeleteArray(void)
{
Clear();
if (mArray != &(mAutoArray[0])) {
delete[] mArray;
mArray = &(mAutoArray[0]);
mArraySize = kAutoArraySize;
}
}
NS_IMETHODIMP_(nsISupportsArray&)
nsISupportsArray::operator=(const nsISupportsArray& other)
{
NS_ASSERTION(0, "should be an abstract method");
return *this; // bogus
}
NS_IMETHODIMP_(nsISupportsArray&)
nsSupportsArray::operator=(const nsISupportsArray& aOther)
{
PRUint32 otherCount = aOther.Count();
if (otherCount > mArraySize) {
DeleteArray();
mArraySize = otherCount;
mArray = new nsISupports*[mArraySize];
}
else {
Clear();
}
mCount = otherCount;
while (0 < otherCount--) {
mArray[otherCount] = aOther.ElementAt(otherCount);
}
return *this;
}
NS_IMETHODIMP_(PRBool)
nsSupportsArray::Equals(const nsISupportsArray* aOther) const
{
if (0 != aOther) {
const nsSupportsArray* other = (const nsSupportsArray*)aOther;
if (mCount == other->mCount) {
PRUint32 index = mCount;
while (0 < index--) {
if (mArray[index] != other->mArray[index]) {
return PR_FALSE;
}
}
return PR_TRUE;
}
}
return PR_FALSE;
}
NS_IMETHODIMP_(nsISupports*)
nsSupportsArray::ElementAt(PRUint32 aIndex) const
{
if ((0 <= aIndex) && (aIndex < mCount)) {
nsISupports* element = mArray[aIndex];
NS_ADDREF(element);
return element;
}
return 0;
}
NS_IMETHODIMP_(PRInt32)
nsSupportsArray::IndexOf(const nsISupports* aPossibleElement, PRUint32 aStartIndex) const
{
if ((0 <= aStartIndex) && (aStartIndex < mCount)) {
const nsISupports** start = (const nsISupports**)mArray; // work around goofy compiler behavior
const nsISupports** ep = (start + aStartIndex);
const nsISupports** end = (start + mCount);
while (ep < end) {
if (aPossibleElement == *ep) {
return (ep - start);
}
ep++;
}
}
return -1;
}
NS_IMETHODIMP_(PRInt32)
nsSupportsArray::LastIndexOf(const nsISupports* aPossibleElement) const
{
if (0 < mCount) {
const nsISupports** start = (const nsISupports**)mArray; // work around goofy compiler behavior
const nsISupports** ep = (start + mCount);
while (start <= --ep) {
if (aPossibleElement == *ep) {
return (ep - start);
}
}
}
return -1;
}
NS_IMETHODIMP_(PRBool)
nsSupportsArray::InsertElementAt(nsISupports* aElement, PRUint32 aIndex)
{
if ((0 <= aIndex) && (aIndex <= mCount)) {
if (mArraySize < (mCount + 1)) { // need to grow the array
mArraySize += kGrowArrayBy;
nsISupports** oldArray = mArray;
mArray = new nsISupports*[mArraySize];
if (0 == mArray) { // ran out of memory
mArray = oldArray;
mArraySize -= kGrowArrayBy;
return PR_FALSE;
}
if (0 != oldArray) { // need to move old data
if (0 < aIndex) {
::memcpy(mArray, oldArray, aIndex * sizeof(nsISupports*));
}
PRUint32 slide = (mCount - aIndex);
if (0 < slide) {
::memcpy(mArray + aIndex + 1, oldArray + aIndex, slide * sizeof(nsISupports*));
}
if (oldArray != &(mAutoArray[0])) {
delete[] oldArray;
}
}
}
else {
PRUint32 slide = (mCount - aIndex);
if (0 < slide) {
::memmove(mArray + aIndex + 1, mArray + aIndex, slide * sizeof(nsISupports*));
}
}
mArray[aIndex] = aElement;
NS_ADDREF(aElement);
mCount++;
return PR_TRUE;
}
return PR_FALSE;
}
NS_IMETHODIMP_(PRBool)
nsSupportsArray::ReplaceElementAt(nsISupports* aElement, PRUint32 aIndex)
{
if ((0 <= aIndex) && (aIndex < mCount)) {
NS_ADDREF(aElement); // addref first in case it's the same object!
NS_RELEASE(mArray[aIndex]);
mArray[aIndex] = aElement;
return PR_TRUE;
}
return PR_FALSE;
}
NS_IMETHODIMP_(PRBool)
nsSupportsArray::RemoveElementAt(PRUint32 aIndex)
{
if ((0 <= aIndex) && (aIndex < mCount)) {
NS_RELEASE(mArray[aIndex]);
mCount--;
PRInt32 slide = (mCount - aIndex);
if (0 < slide) {
::memmove(mArray + aIndex, mArray + aIndex + 1,
slide * sizeof(nsISupports*));
}
return PR_TRUE;
}
return PR_FALSE;
}
NS_IMETHODIMP_(PRBool)
nsSupportsArray::RemoveElement(const nsISupports* aElement, PRUint32 aStartIndex)
{
if ((0 <= aStartIndex) && (aStartIndex < mCount)) {
nsISupports** ep = mArray;
nsISupports** end = ep + mCount;
while (ep < end) {
if (*ep == aElement) {
return RemoveElementAt(PRUint32(ep - mArray));
}
ep++;
}
}
return PR_FALSE;
}
NS_IMETHODIMP_(PRBool)
nsSupportsArray::RemoveLastElement(const nsISupports* aElement)
{
if (0 < mCount) {
nsISupports** ep = (mArray + mCount);
while (mArray <= --ep) {
if (*ep == aElement) {
return RemoveElementAt(PRUint32(ep - mArray));
}
}
}
return PR_FALSE;
}
NS_IMETHODIMP_(PRBool)
nsSupportsArray::AppendElements(nsISupportsArray* aElements)
{
nsSupportsArray* elements = (nsSupportsArray*)aElements;
if (elements && (0 < elements->mCount)) {
if (mArraySize < (mCount + elements->mCount)) { // need to grow the array
PRUint32 count = mCount + elements->mCount;
PRUint32 oldSize = mArraySize;
while (mArraySize < count) { // ick
mArraySize += kGrowArrayBy;
}
nsISupports** oldArray = mArray;
mArray = new nsISupports*[mArraySize];
if (0 == mArray) { // ran out of memory
mArray = oldArray;
mArraySize = oldSize;
return PR_FALSE;
}
if (0 != oldArray) { // need to move old data
if (0 < mCount) {
::memcpy(mArray, oldArray, mCount);
}
if (oldArray != &(mAutoArray[0])) {
delete[] oldArray;
}
}
}
PRUint32 index = 0;
while (index < elements->mCount) {
NS_ADDREF(elements->mArray[index]);
mArray[mCount++] = elements->mArray[index++];
}
return PR_TRUE;
}
return PR_FALSE;
}
NS_IMETHODIMP
nsSupportsArray::Clear(void)
{
if (0 < mCount) {
do {
--mCount;
NS_RELEASE(mArray[mCount]);
} while (0 != mCount);
}
return NS_OK;
}
NS_IMETHODIMP_(void)
nsSupportsArray::Compact(void)
{
if ((mArraySize != mCount) && (kAutoArraySize < mArraySize)) {
nsISupports** oldArray = mArray;
PRUint32 oldArraySize = mArraySize;
if (mCount <= kAutoArraySize) {
mArray = &(mAutoArray[0]);
mArraySize = kAutoArraySize;
}
else {
mArray = new nsISupports*[mCount];
mArraySize = mCount;
}
if (0 == mArray) {
mArray = oldArray;
mArraySize = oldArraySize;
return;
}
::memcpy(mArray, oldArray, mCount * sizeof(nsISupports*));
delete[] oldArray;
}
}
NS_IMETHODIMP_(PRBool)
nsSupportsArray::EnumerateForwards(nsISupportsArrayEnumFunc aFunc, void* aData) const
{
PRInt32 index = -1;
PRBool running = PR_TRUE;
while (running && (++index < (PRInt32)mCount)) {
running = (*aFunc)(mArray[index], aData);
}
return running;
}
NS_IMETHODIMP_(PRBool)
nsSupportsArray::EnumerateBackwards(nsISupportsArrayEnumFunc aFunc, void* aData) const
{
PRUint32 index = mCount;
PRBool running = PR_TRUE;
while (running && (0 < index--)) {
running = (*aFunc)(mArray[index], aData);
}
return running;
}
NS_IMETHODIMP
nsSupportsArray::Enumerate(nsIEnumerator* *result)
{
nsSupportsArrayEnumerator* e = new nsSupportsArrayEnumerator(this);
if (!e)
return NS_ERROR_OUT_OF_MEMORY;
*result = e;
NS_ADDREF(e);
return NS_OK;
}
NS_COM nsresult
NS_NewISupportsArray(nsISupportsArray** aInstancePtrResult)
{
if (aInstancePtrResult == 0)
return NS_ERROR_NULL_POINTER;
nsSupportsArray *it = new nsSupportsArray();
if (0 == it)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(it);
*aInstancePtrResult = it;
return NS_OK;
}

View File

@@ -0,0 +1,85 @@
/* -*- 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 "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 nsSupportsArray_h__
#define nsSupportsArray_h__
#include "nsISupportsArray.h"
static const PRUint32 kAutoArraySize = 4;
class nsSupportsArray : public nsISupportsArray {
public:
nsSupportsArray(void);
virtual ~nsSupportsArray(void);
NS_DECL_ISUPPORTS
// nsICollection methods:
NS_IMETHOD_(PRUint32) Count(void) const { return mCount; }
NS_IMETHOD AppendElement(nsISupports *aElement) {
// XXX This incorrectly returns a PRBool instead of an nsresult.
return InsertElementAt(aElement, mCount);
}
NS_IMETHOD RemoveElement(nsISupports *aElement) {
// XXX This incorrectly returns a PRBool instead of an nsresult.
return RemoveElement(aElement, 0);
}
NS_IMETHOD Enumerate(nsIEnumerator* *result);
NS_IMETHOD Clear(void);
// nsISupportsArray methods:
NS_IMETHOD_(nsISupportsArray&) operator=(const nsISupportsArray& aOther);
NS_IMETHOD_(PRBool) operator==(const nsISupportsArray& aOther) const { return Equals(&aOther); }
NS_IMETHOD_(PRBool) Equals(const nsISupportsArray* aOther) const;
NS_IMETHOD_(nsISupports*) ElementAt(PRUint32 aIndex) const;
NS_IMETHOD_(nsISupports*) operator[](PRUint32 aIndex) const { return ElementAt(aIndex); }
NS_IMETHOD_(PRInt32) IndexOf(const nsISupports* aPossibleElement, PRUint32 aStartIndex = 0) const;
NS_IMETHOD_(PRInt32) LastIndexOf(const nsISupports* aPossibleElement) const;
NS_IMETHOD_(PRBool) InsertElementAt(nsISupports* aElement, PRUint32 aIndex);
NS_IMETHOD_(PRBool) ReplaceElementAt(nsISupports* aElement, PRUint32 aIndex);
NS_IMETHOD_(PRBool) RemoveElementAt(PRUint32 aIndex);
NS_IMETHOD_(PRBool) RemoveElement(const nsISupports* aElement, PRUint32 aStartIndex = 0);
NS_IMETHOD_(PRBool) RemoveLastElement(const nsISupports* aElement);
NS_IMETHOD_(PRBool) AppendElements(nsISupportsArray* aElements);
NS_IMETHOD_(void) Compact(void);
NS_IMETHOD_(PRBool) EnumerateForwards(nsISupportsArrayEnumFunc aFunc, void* aData) const;
NS_IMETHOD_(PRBool) EnumerateBackwards(nsISupportsArrayEnumFunc aFunc, void* aData) const;
protected:
void DeleteArray(void);
nsISupports** mArray;
PRUint32 mArraySize;
PRUint32 mCount;
nsISupports* mAutoArray[kAutoArraySize];
private:
// Copy constructors are not allowed
nsSupportsArray(const nsISupportsArray& other);
};
#endif // nsSupportsArray_h__

View File

@@ -0,0 +1,133 @@
/* -*- 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 "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 "nsSupportsArrayEnumerator.h"
#include "nsISupportsArray.h"
nsSupportsArrayEnumerator::nsSupportsArrayEnumerator(nsISupportsArray* array)
: mArray(array), mCursor(0)
{
NS_INIT_REFCNT();
NS_ASSERTION(array, "null array");
NS_ADDREF(mArray);
}
nsSupportsArrayEnumerator::~nsSupportsArrayEnumerator()
{
NS_RELEASE(mArray);
}
NS_IMPL_ADDREF(nsSupportsArrayEnumerator);
NS_IMPL_RELEASE(nsSupportsArrayEnumerator);
NS_IMETHODIMP
nsSupportsArrayEnumerator::QueryInterface(REFNSIID aIID, void** aInstancePtr)
{
if (NULL == aInstancePtr)
return NS_ERROR_NULL_POINTER;
if (aIID.Equals(nsIBidirectionalEnumerator::GetIID()) ||
aIID.Equals(nsIEnumerator::GetIID()) ||
aIID.Equals(nsISupports::GetIID())) {
*aInstancePtr = (void*) this;
NS_ADDREF_THIS();
return NS_OK;
}
return NS_NOINTERFACE;
}
NS_IMETHODIMP
nsSupportsArrayEnumerator::First()
{
mCursor = 0;
PRInt32 end = (PRInt32)mArray->Count();
if (mCursor < end)
return NS_OK;
else
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsSupportsArrayEnumerator::Next()
{
PRInt32 end = (PRInt32)mArray->Count();
if (mCursor < end) // don't count upward forever
mCursor++;
if (mCursor < end)
return NS_OK;
else
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsSupportsArrayEnumerator::CurrentItem(nsISupports **aItem)
{
NS_ASSERTION(aItem, "null out parameter");
if (mCursor >= 0 && mCursor < (PRInt32)mArray->Count()) {
*aItem = (*mArray)[mCursor];
NS_IF_ADDREF(*aItem);
return NS_OK;
}
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsSupportsArrayEnumerator::IsDone()
{
return (mCursor >= 0 && mCursor < (PRInt32)mArray->Count())
? NS_COMFALSE : NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
NS_IMETHODIMP
nsSupportsArrayEnumerator::Last()
{
mCursor = mArray->Count() - 1;
return NS_OK;
}
NS_IMETHODIMP
nsSupportsArrayEnumerator::Prev()
{
if (mCursor >= 0)
--mCursor;
if (mCursor >= 0)
return NS_OK;
else
return NS_ERROR_FAILURE;
}
////////////////////////////////////////////////////////////////////////////////
NS_COM nsresult
NS_NewISupportsArrayEnumerator(nsISupportsArray* array,
nsIBidirectionalEnumerator* *aInstancePtrResult)
{
if (aInstancePtrResult == 0)
return NS_ERROR_NULL_POINTER;
nsSupportsArrayEnumerator* e = new nsSupportsArrayEnumerator(array);
if (e == 0)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(e);
*aInstancePtrResult = e;
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////

View File

@@ -0,0 +1,50 @@
/* -*- 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 "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 nsSupportsArrayEnumerator_h___
#define nsSupportsArrayEnumerator_h___
#include "nsIEnumerator.h"
class nsISupportsArray;
class NS_COM nsSupportsArrayEnumerator : public nsIBidirectionalEnumerator {
public:
NS_DECL_ISUPPORTS
nsSupportsArrayEnumerator(nsISupportsArray* array);
virtual ~nsSupportsArrayEnumerator();
// nsIEnumerator methods:
NS_IMETHOD First();
NS_IMETHOD Next();
NS_IMETHOD CurrentItem(nsISupports **aItem);
NS_IMETHOD IsDone();
// nsIBidirectionalEnumerator methods:
NS_IMETHOD Last();
NS_IMETHOD Prev();
protected:
nsISupportsArray* mArray;
PRInt32 mCursor;
};
#endif // __nsSupportsArrayEnumerator_h

View File

@@ -0,0 +1,74 @@
/* -*- 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.
*/
#ifndef nsVector_h__
#define nsVector_h__
#include "plvector.h"
#include "nsCom.h"
class nsVector : public PLVector {
public:
// Construction
nsVector(PRUint32 initialSize = 0, PRInt32 initialGrowBy = 0) {
PL_VectorInitialize(this, initialSize, initialGrowBy);
}
~nsVector(void) { PL_VectorFinalize(this); }
// Attributes
PRUint32 GetSize(void) const { return PL_VectorGetSize(this); }
PRUint32 GetUpperBound(void) const { return GetSize() - 1; }
PRBool SetSize(PRUint32 nNewSize, PRInt32 nGrowBy = PL_VECTOR_GROW_DEFAULT) {
return PL_VectorSetSize(this, nNewSize, nGrowBy);
}
PRBool IsValidIndex(PRUint32 index) { return PL_VectorIsValidIndex(this, index); }
// Operations
// Clean up
void Compact(void) { PL_VectorCompact(this); }
void RemoveAll(void) { SetSize(0); }
void Copy(nsVector* src, PRUint32 len, PRUint32 dstPos = 0, PRUint32 srcPos = 0) {
PL_VectorCopy(this, dstPos, src, srcPos, len);
}
// Accessing elements
void* Get(PRUint32 index) const { return PL_VectorGet(this, index); }
void Set(PRUint32 index, void* newElement) { PL_VectorSet(this, index, newElement); }
void*& ElementAt(PRUint32 index) { return *PL_VectorGetAddr(this, index); }
// Potentially growing the array
PRInt32 Add(void* newElement) { return PL_VectorAdd(this, newElement); }
// overloaded operator helpers
void* operator[](PRUint32 index) const { return Get(index); }
void*& operator[](PRUint32 index) { return ElementAt(index); }
// Operations that move elements around
void Insert(PRUint32 index, void* newElement, PRInt32 count = 1) {
PL_VectorInsert(this, index, newElement, count);
}
void Remove(PRUint32 index, PRInt32 count = 1) {
PL_VectorRemove(this, index, count);
}
#ifdef DEBUG
void AssertValid(void) const { PL_VectorAssertValid((PLVector*)this); }
#endif
};
#endif

View File

@@ -0,0 +1,163 @@
/* -*- 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 "nsDebug.h"
#include "nsIAllocator.h"
#include "nsXPIDLString.h"
#include "plstr.h"
// If the allocator changes, fix it here.
#define XPIDL_STRING_ALLOC(__len) ((PRUnichar*) nsAllocator::Alloc((__len) * sizeof(PRUnichar)))
#define XPIDL_CSTRING_ALLOC(__len) ((char*) nsAllocator::Alloc((__len) * sizeof(char)))
#define XPIDL_FREE(__ptr) (nsAllocator::Free(__ptr))
////////////////////////////////////////////////////////////////////////
// nsXPIDLString
nsXPIDLString::nsXPIDLString()
: mBufOwner(PR_FALSE),
mBuf(0)
{
}
nsXPIDLString::~nsXPIDLString()
{
if (mBufOwner && mBuf)
XPIDL_FREE(mBuf);
}
nsXPIDLString::operator const PRUnichar*()
{
return mBuf;
}
PRUnichar*
nsXPIDLString::Copy(const PRUnichar* aString)
{
NS_ASSERTION(aString, "null ptr");
if (! aString)
return 0;
PRInt32 len = 0;
{
const PRUnichar* p = aString;
while (*p++)
len++;
}
PRUnichar* result = XPIDL_STRING_ALLOC(len + 1);
if (result) {
PRUnichar* q = result;
while (*aString) {
*q = *aString;
q++;
aString++;
}
*q = '\0';
}
return result;
}
PRUnichar**
nsXPIDLString::StartAssignmentByValue()
{
if (mBufOwner && mBuf)
XPIDL_FREE(mBuf);
mBufOwner = PR_TRUE;
return &mBuf;
}
const PRUnichar**
nsXPIDLString::StartAssignmentByReference()
{
if (mBufOwner && mBuf)
XPIDL_FREE(mBuf);
mBufOwner = PR_FALSE;
return (const PRUnichar**) &mBuf;
}
////////////////////////////////////////////////////////////////////////
// nsXPIDLCString
nsXPIDLCString::nsXPIDLCString()
: mBufOwner(PR_FALSE),
mBuf(0)
{
}
nsXPIDLCString::~nsXPIDLCString()
{
if (mBufOwner && mBuf)
XPIDL_FREE(mBuf);
}
nsXPIDLCString::operator const char*()
{
return mBuf;
}
char*
nsXPIDLCString::Copy(const char* aCString)
{
NS_ASSERTION(aCString, "null ptr");
if (! aCString)
return 0;
PRInt32 len = PL_strlen(aCString);
char* result = XPIDL_CSTRING_ALLOC(len + 1);
if (result)
PL_strcpy(result, aCString);
return result;
}
char**
nsXPIDLCString::StartAssignmentByValue()
{
if (mBufOwner && mBuf)
XPIDL_FREE(mBuf);
mBufOwner = PR_TRUE;
return &mBuf;
}
const char**
nsXPIDLCString::StartAssignmentByReference()
{
if (mBufOwner && mBuf)
XPIDL_FREE(mBuf);
mBufOwner = PR_FALSE;
return (const char**) &mBuf;
}

View File

@@ -0,0 +1,294 @@
/* -*- 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.
*/
/*
A set of string wrapper classes that ease transition to use of XPIDL
interfaces. nsXPIDLString and nsXPIDLCString are to XPIDL `wstring'
and `string' out params as nsCOMPtr is to generic XPCOM interface
pointers. They help you deal with object ownership.
Consider the following interface:
interface nsIFoo {
attribute string Bar;
};
This will generated the following C++ header file:
class nsIFoo {
NS_IMETHOD SetBar(const PRUnichar* aValue);
NS_IMETHOD GetBar(PRUnichar* *aValue);
};
The GetBar() method will allocate a copy of the nsIFoo object's
"bar" attribute, and leave you to deal with freeing it:
nsIFoo* aFoo; // assume we get this somehow
PRUnichar* bar;
aFoo->GetFoo(&bar);
// Use bar here...
delete[] bar;
(Strictly speaking, the `delete[] bar' should use the proper XPCOM
de-allocator that; we'll ignore that for now.) This makes your life
harder, because you need to convolute your code to ensure that you
don't leak `bar'.
Enter nsXPIDLString, which manages the ownership of the allocated
string, and automatically destroys it when the nsXPIDLString goes
out of scope:
nsIFoo* aFoo;
nsXPIDLString bar;
aFoo->GetFoo( getter_Copies(bar) );
// Use bar here...
Like nsCOMPtr, nsXPIDLString uses some syntactic sugar to make it
painfully clear exactly what the code expects. You need to wrap an
nsXPIDLString object with either `getter_Copies()' or
`getter_Shares()': these tell the nsXPIDLString how ownership is
being handled. In the case of `getter_Copies()', the callee is
allocating a copy (which is usually the case). In the case of
`getter_Shares()', the callee is returning a const reference to `the
real deal' (this can be done using the [shared] attribute in XPIDL).
*/
#ifndef nsXPIDLString_h__
#define nsXPIDLString_h__
#include "nsCom.h"
#include "prtypes.h"
#ifndef __PRUNICHAR__
#define __PRUNICHAR__
typedef PRUint16 PRUnichar;
#endif /* __PRUNICHAR__ */
////////////////////////////////////////////////////////////////////////
// nsXPIDLString
//
// A wrapper for Unicode strings. With the |getter_Copies()| and
// |getter_Shares()| helper functions, this can be used instead of
// the "naked" |PRUnichar*| interface for |wstring| parameters in
// XPIDL interfaces.
//
class NS_COM nsXPIDLString {
private:
PRUnichar* mBuf;
PRBool mBufOwner;
PRUnichar** StartAssignmentByValue();
const PRUnichar** StartAssignmentByReference();
public:
/**
* Construct a new, uninitialized wrapper for a Unicode string.
*/
nsXPIDLString();
virtual ~nsXPIDLString();
/**
* Return a reference to the immutable Unicode string.
*/
operator const PRUnichar*();
/**
* Make a copy of the Unicode string. Use this function in the
* callee to ensure that the correct memory allocator is used.
*/
static PRUnichar* Copy(const PRUnichar* aString);
// A helper class for assignment-by-value. This class is an
// implementation detail and should not be considered part of the
// public interface.
class NS_COM GetterCopies {
private:
nsXPIDLString& mXPIDLString;
public:
GetterCopies(nsXPIDLString& aXPIDLString)
: mXPIDLString(aXPIDLString) {}
operator PRUnichar**() {
return mXPIDLString.StartAssignmentByValue();
}
friend GetterCopies getter_Copies(nsXPIDLString& aXPIDLString);
};
friend class GetterCopies;
// A helper class for assignment-by-reference. This class is an
// implementation detail and should not be considered part of the
// public interface.
class NS_COM GetterShares {
private:
nsXPIDLString& mXPIDLString;
public:
GetterShares(nsXPIDLString& aXPIDLString)
: mXPIDLString(aXPIDLString) {}
operator const PRUnichar**() {
return mXPIDLString.StartAssignmentByReference();
}
friend GetterShares getter_Shares(nsXPIDLString& aXPIDLString);
};
friend class GetterShares;
private:
// not to be implemented
nsXPIDLString(nsXPIDLString& aXPIDLString) {}
nsXPIDLString& operator =(nsXPIDLString& aXPIDLString) { return *this; }
};
/**
* Use this function to "wrap" the nsXPIDLString object that is to
* receive an |out| value.
*/
inline nsXPIDLString::GetterCopies
getter_Copies(nsXPIDLString& aXPIDLString)
{
return nsXPIDLString::GetterCopies(aXPIDLString);
}
/**
* Use this function to "wrap" the nsXPIDLString object that is to
* receive a |[shared] out| value.
*/
inline nsXPIDLString::GetterShares
getter_Shares(nsXPIDLString& aXPIDLString)
{
return nsXPIDLString::GetterShares(aXPIDLString);
}
////////////////////////////////////////////////////////////////////////
// nsXPIDLCString
//
// A wrapper for Unicode strings. With the |getter_Copies()| and
// |getter_Shares()| helper functions, this can be used instead of
// the "naked" |char*| interface for |string| parameters in XPIDL
// interfaces.
//
class NS_COM nsXPIDLCString {
private:
char* mBuf;
PRBool mBufOwner;
char** StartAssignmentByValue();
const char** StartAssignmentByReference();
public:
/**
* Construct a new, uninitialized wrapper for a single-byte string.
*/
nsXPIDLCString();
virtual ~nsXPIDLCString();
/**
* Return a reference to the immutable single-byte string.
*/
operator const char*();
/**
* Make a copy of the single-byte string. Use this function in the
* callee to ensure that the correct memory allocator is used.
*/
static char* Copy(const char* aString);
// A helper class for assignment-by-value. This class is an
// implementation detail and should not be considered part of the
// public interface.
class NS_COM GetterCopies {
private:
nsXPIDLCString& mXPIDLString;
public:
GetterCopies(nsXPIDLCString& aXPIDLString)
: mXPIDLString(aXPIDLString) {}
operator char**() {
return mXPIDLString.StartAssignmentByValue();
}
friend GetterCopies getter_Copies(nsXPIDLCString& aXPIDLString);
};
friend class GetterCopies;
// A helper class for assignment-by-reference. This class is an
// implementation detail and should not be considered part of the
// public interface.
class NS_COM GetterShares {
private:
nsXPIDLCString& mXPIDLString;
public:
GetterShares(nsXPIDLCString& aXPIDLString)
: mXPIDLString(aXPIDLString) {}
operator const char**() {
return mXPIDLString.StartAssignmentByReference();
}
friend GetterShares getter_Shares(nsXPIDLCString& aXPIDLString);
};
friend class GetterShares;
private:
// not to be implemented
nsXPIDLCString(nsXPIDLCString& aXPIDLString) {}
nsXPIDLCString& operator =(nsXPIDLCString& aXPIDLString) { return *this; }
};
/**
* Use this function to "wrap" the nsXPIDLCString object that is to
* receive an |out| value.
*/
inline nsXPIDLCString::GetterCopies
getter_Copies(nsXPIDLCString& aXPIDLString)
{
return nsXPIDLCString::GetterCopies(aXPIDLString);
}
/**
* Use this function to "wrap" the nsXPIDLCString object that is to
* receive a |[shared] out| value.
*/
inline nsXPIDLCString::GetterShares
getter_Shares(nsXPIDLCString& aXPIDLString)
{
return nsXPIDLCString::GetterShares(aXPIDLString);
}
#endif // nsXPIDLString_h__

318
mozilla/xpcom/ds/plvector.c Normal file
View File

@@ -0,0 +1,318 @@
/* -*- 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 "plvector.h"
#include "prmem.h"
#include <string.h>
#ifdef XP_WIN16
#define SIZE_T_MAX 0xFF80 /* a little less than 64K, the max alloc size on win16. */
#define MAX_ARR_ELEMS SIZE_T_MAX/sizeof(void*)
#endif
PR_IMPLEMENT(PLVector*)
PL_NewVector(PRUint32 initialSize, PRInt32 initialGrowBy)
{
PLVector* v = (PLVector*)PR_Malloc(sizeof(PLVector*));
if (v == NULL)
return NULL;
PL_VectorInitialize(v, initialSize, initialGrowBy);
return v;
}
PR_IMPLEMENT(void)
PL_VectorDestroy(PLVector* v)
{
PL_VectorFinalize(v);
PR_Free(v);
}
/* Initializes an existing vector */
PR_IMPLEMENT(void)
PL_VectorInitialize(PLVector* v, PRUint32 initialSize, PRInt32 initialGrowBy)
{
v->data = NULL;
v->size = v->maxSize = v->growBy = 0;
if (initialSize > 0 || initialGrowBy > 0)
PL_VectorSetSize(v, initialSize, initialGrowBy);
}
/* Destroys the elements, but doesn't free the vector */
PR_IMPLEMENT(void)
PL_VectorFinalize(PLVector* v)
{
/* This implementation doesn't do anything to delete the elements
in the vector -- that's up to the caller. (Don't shoot me,
I just copied the code from libmsg.) */
PR_Free(v->data);
}
PR_IMPLEMENT(PRBool)
PL_VectorSetSize(PLVector* v, PRUint32 newSize, PRInt32 growBy)
{
if (growBy != -1)
v->growBy = growBy; /* set new size */
if (newSize == 0) {
/* shrink to nothing */
PR_Free(v->data);
v->data = NULL;
v->size = v->maxSize = 0;
}
else if (v->data == NULL) {
/* create one with exact size */
#ifdef SIZE_T_MAX
PR_ASSERT(newSize <= SIZE_T_MAX/sizeof(void*)); /* no overflow */
#endif
v->data = (void**)PR_Malloc(newSize * sizeof(void *));
if (v->data == NULL) {
v->size = 0;
return PR_FALSE;
}
memset(v->data, 0, newSize * sizeof(void *)); /* zero fill */
v->size = v->maxSize = newSize;
}
else if (newSize <= v->maxSize) {
/* it fits */
if (newSize > v->size) {
/* initialize the new elements */
memset(&v->data[v->size], 0, (newSize-v->size) * sizeof(void *));
}
v->size = newSize;
}
else {
/* otherwise, grow array */
PRUint32 newMax;
void** newData;
PRInt32 growBy = v->growBy;
if (growBy == 0) {
/* heuristically determine growth when growBy == 0
(this avoids heap fragmentation in many situations) */
growBy = PR_MIN(1024, PR_MAX(4, v->size / 8));
}
#ifdef MAX_ARR_ELEMS
if (v->size + growBy > MAX_ARR_ELEMS)
growBy = MAX_ARR_ELEMS - v->size;
#endif
if (newSize < v->maxSize + growBy)
newMax = v->maxSize + growBy; /* granularity */
else
newMax = newSize; /* no slush */
#ifdef SIZE_T_MAX
if (newMax >= SIZE_T_MAX/sizeof(void*))
return PR_FALSE;
PR_ASSERT(newMax <= SIZE_T_MAX/sizeof(void*)); /* no overflow */
#endif
PR_ASSERT(newMax >= v->maxSize); /* no wrap around */
newData = (void**)PR_Malloc(newMax * sizeof(void*));
if (newData != NULL) {
/* copy new data from old */
memcpy(newData, v->data, v->size * sizeof(void*));
/* construct remaining elements */
PR_ASSERT(newSize > v->size);
memset(&newData[v->size], 0, (newSize-v->size) * sizeof(void*));
/* get rid of old stuff (note: no destructors called) */
PR_Free(v->data);
v->data = newData;
v->size = newSize;
v->maxSize = newMax;
}
else {
return PR_FALSE;
}
}
return PR_TRUE;
}
PR_IMPLEMENT(PRBool)
PL_VectorIsValidIndex(PLVector* v, PRUint32 index)
{
return (index < v->size) ? PR_TRUE : PR_FALSE;
}
PR_IMPLEMENT(void)
PL_VectorCompact(PLVector* v)
{
if (v->size != v->maxSize) {
/* shrink to desired size */
#ifdef SIZE_T_MAX
PR_ASSERT(v->size <= SIZE_T_MAX/sizeof(void *)); /* no overflow */
#endif
void ** newData = NULL;
if (v->size != 0) {
newData = (void **)PR_Malloc(v->size * sizeof(void *));
/* copy new data from old */
memcpy(newData, v->data, v->size * sizeof(void *));
}
/* get rid of old stuff (note: no destructors called) */
PR_Free(v->data);
v->data = newData;
v->maxSize = v->size;
}
}
#if 0 /* becomes Copy */
PR_IMPLEMENT(void)
PL_VectorSplice(PLVector* v, PRUint32 startIndex, PLVector* newVector)
{
PRUint32 i;
PR_ASSERT(newVector != NULL);
if (PL_VectorGetSize(newVector) > 0) {
PL_VectorInsert(v, startIndex, PL_VectorGet(newVector, 0),
PL_VectorGetSize(newVector));
for (i = 0; i < PL_VectorGetSize(newVector); i++)
PL_VectorSet(v, startIndex + i, PL_VectorGet(newVector, i));
}
}
#endif
PR_IMPLEMENT(void)
PL_VectorCopy(PLVector* dstVector, PRUint32 dstPosition,
PLVector* srcVector, PRUint32 srcPosition, PRUint32 length)
{
PR_ASSERT(0); /* XXX not implemented yet */
#if 0
PL_VectorSetSize(dstVector, PR_MAX(PL_VectorGetSize(dstVector),
PL_VectorGetSize(srcVector)),
PL_VECTOR_GROW_DEFAULT);
if (v->data)
PR_Free(v->data);
v->size = oldA->v->size;
v->maxSize = oldA->v->maxSize;
v->growBy = oldA->v->growBy;
v->data = (void**)PR_Malloc(v->size * sizeof(void *));
if (v->data == NULL) {
v->size = 0;
}
else {
memcpy(v->data, oldA->v->data, v->size * sizeof(void *));
}
#endif
}
PR_IMPLEMENT(PLVector*)
PL_VectorClone(PLVector* v)
{
PLVector* newVec = PL_NewVector(v->size, v->growBy);
PL_VectorCopy(newVec, 0, v, 0, v->size);
return newVec;
}
/* Accessing elements */
PR_IMPLEMENT(void)
PL_VectorSet(PLVector* v, PRUint32 index, void* newElement)
{
if (index >= v->size) {
if (!PL_VectorSetSize(v, index+1, PL_VECTOR_GROW_DEFAULT))
return;
}
v->data[index] = newElement;
}
/* Adds at the end */
PR_IMPLEMENT(PRUint32)
PL_VectorAdd(PLVector* v, void* newElement)
{
PRUint32 index = v->size;
#ifdef XP_WIN16
if (index >= SIZE_T_MAX / 4L) {
return -1;
}
#endif
PL_VectorSet(v, index, newElement);
return index;
}
/* Inserts new element count times at index */
PR_IMPLEMENT(void)
PL_VectorInsert(PLVector* v, PRUint32 index, void* newElement, PRUint32 count)
{
PR_ASSERT(count > 0); /* zero or negative size not allowed */
if (index >= v->size) {
/* adding after the end of the array */
if (!PL_VectorSetSize(v, index + count, PL_VECTOR_GROW_DEFAULT))
return; /* grow so index is valid */
}
else {
/* inserting in the middle of the array */
PRUint32 nOldSize = v->size;
if (!PL_VectorSetSize(v, v->size + count, PL_VECTOR_GROW_DEFAULT))
return; /* grow it to new size */
/* shift old data up to fill gap */
memmove(&v->data[index+count], &v->data[index],
(nOldSize-index) * sizeof(void *));
/* re-init slots we copied from */
memset(&v->data[index], 0, count * sizeof(void *));
}
/* insert new value in the gap */
PR_ASSERT(index + count <= v->size);
while (count--)
v->data[index++] = newElement;
}
/* Removes count elements at index */
PR_IMPLEMENT(void)
PL_VectorRemove(PLVector* v, PRUint32 index, PRUint32 count)
{
PRUint32 moveCount;
PR_ASSERT(count >= 0);
PR_ASSERT(index + count <= v->size);
/* just remove a range */
moveCount = v->size - (index + count);
if (moveCount)
memmove(&v->data[index], &v->data[index + count],
moveCount * sizeof(void *));
v->size -= count;
}
#ifdef DEBUG
PR_IMPLEMENT(void)
PL_VectorAssertValid(PLVector* v)
{
if (v->data == NULL) {
PR_ASSERT(v->size == 0);
PR_ASSERT(v->maxSize == 0);
}
else {
PR_ASSERT(v->size >= 0);
PR_ASSERT(v->maxSize >= 0);
PR_ASSERT(v->size <= v->maxSize);
}
}
#endif

100
mozilla/xpcom/ds/plvector.h Normal file
View File

@@ -0,0 +1,100 @@
/* -*- 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.
*/
#ifndef plvector_h__
#define plvector_h__
#include "prtypes.h"
#include "prlog.h"
PR_BEGIN_EXTERN_C
/* Vectors are extensible arrays */
typedef struct PLVector {
void** data; /* the actual array of data */
PRUint32 size; /* # of elements (upperBound - 1) */
PRUint32 maxSize; /* max allocated */
PRInt32 growBy; /* grow amount */
} PLVector;
PR_EXTERN(PLVector*)
PL_NewVector(PRUint32 initialSize, PRInt32 initialGrowBy);
PR_EXTERN(void)
PL_VectorDestroy(PLVector* v);
/* Initializes an existing vector */
PR_EXTERN(void)
PL_VectorInitialize(PLVector* v, PRUint32 initialSize, PRInt32 initialGrowBy);
/* Destroys the elements, but doesn't free the vector */
PR_EXTERN(void)
PL_VectorFinalize(PLVector* v);
#define PL_VectorGetSize(v) ((v)->size)
#define PL_VECTOR_GROW_DEFAULT (-1)
PR_EXTERN(PRBool)
PL_VectorSetSize(PLVector* v, PRUint32 newSize, PRInt32 growBy);
PR_EXTERN(PRBool)
PL_VectorIsValidIndex(PLVector* v, PRUint32 index);
PR_EXTERN(void)
PL_VectorCompact(PLVector* v);
PR_EXTERN(void)
PL_VectorCopy(PLVector* dstVector, PRUint32 dstPosition,
PLVector* srcVector, PRUint32 srcPosition, PRUint32 length);
PR_EXTERN(PLVector*)
PL_VectorClone(PLVector* v);
/* Accessing elements */
#define PL_VectorGetAddr(v, index) (PR_ASSERT((index) < (v)->size), &(v)->data[index])
#define PL_VectorGet(v, index) (*PL_VectorGetAddr(v, index))
PR_EXTERN(void)
PL_VectorSet(PLVector* v, PRUint32 index, void* newElement);
/* Adds at the end */
PR_EXTERN(PRUint32)
PL_VectorAdd(PLVector* v, void* newElement);
/* Inserts new element count times at index */
PR_EXTERN(void)
PL_VectorInsert(PLVector* v, PRUint32 index, void* newElement, PRUint32 count);
/* Removes count elements at index */
PR_EXTERN(void)
PL_VectorRemove(PLVector* v, PRUint32 index, PRUint32 count);
#ifdef DEBUG
PR_EXTERN(void)
PL_VectorAssertValid(PLVector* v);
#endif
PR_END_EXTERN_C
#endif /* plvector_h__ */

View File

@@ -0,0 +1,54 @@
/* -*- 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 "nsCOMPtr.h"
void
nsCOMPtr_base::assign_with_AddRef( nsISupports* rawPtr )
{
if ( rawPtr )
NSCAP_ADDREF(rawPtr);
if ( mRawPtr )
NSCAP_RELEASE(mRawPtr);
mRawPtr = rawPtr;
}
void
nsCOMPtr_base::assign_with_QueryInterface( nsISupports* rawPtr, const nsIID& iid, nsresult* result )
{
nsresult status = NS_OK;
if ( !rawPtr || !NS_SUCCEEDED( status = rawPtr->QueryInterface(iid, NSCAP_REINTERPRET_CAST(void**, &rawPtr)) ) )
rawPtr = 0;
if ( mRawPtr )
NSCAP_RELEASE(mRawPtr);
mRawPtr = rawPtr;
if ( result )
*result = status;
}
void**
nsCOMPtr_base::begin_assignment()
{
if ( mRawPtr )
NSCAP_RELEASE(mRawPtr);
mRawPtr = 0;
return NSCAP_REINTERPRET_CAST(void**, &mRawPtr);
}

View File

@@ -0,0 +1,493 @@
/* -*- 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 nsCOMPtr_h___
#define nsCOMPtr_h___
// Wrapping includes can speed up compiles (see "Large Scale C++ Software Design")
#ifndef nsDebug_h___
#include "nsDebug.h"
// for |NS_PRECONDITION|
#endif
#ifndef nsISupports_h___
#include "nsISupports.h"
// for |nsresult|, |NS_ADDREF|, et al
#endif
/*
Having problems?
See the User Manual at:
<http://www.meer.net/ScottCollins/doc/nsCOMPtr.html>, or
<http://www.mozilla.org/projects/xpcom/nsCOMPtr.html>
*/
/*
TO DO...
+ make StartAssignment optionally inlined
+ make constructor for |nsQueryInterface| explicit (suddenly construct/assign from raw pointer becomes illegal)
+ Improve internal documentation
+ mention *&
+ alternatives for comparison
+ do_QueryInterface
*/
/*
WARNING:
This file defines several macros for internal use only. These macros begin with the
prefix |NSCAP_|. Do not use these macros in your own code. They are for internal use
only for cross-platform compatibility, and are subject to change without notice.
*/
/*
Set up some |#define|s to turn off a couple of troublesome C++ features.
Interestingly, none of the compilers barf on template stuff. These are set up automatically
by the autoconf system for all Unixes. (Temporarily, I hope) I have to define them
myself for Mac and Windows.
*/
// under Metrowerks (Mac), we don't have autoconf yet
#ifdef __MWERKS__
#define HAVE_CPP_USING
#define HAVE_CPP_EXPLICIT
#define HAVE_CPP_NEW_CASTS
#endif
// under VC++ (Windows), we don't have autoconf yet
#ifdef _MSC_VER
#define HAVE_CPP_EXPLICIT
#define HAVE_CPP_USING
#define HAVE_CPP_NEW_CASTS
#if (_MSC_VER<1100)
// before 5.0, VC++ couldn't handle explicit
#undef HAVE_CPP_EXPLICIT
#elif (_MSC_VER==1100)
// VC++5.0 has an internal compiler error (sometimes) without this
#undef HAVE_CPP_USING
#endif
#define NSCAP_FEATURE_INLINE_STARTASSIGNMENT
// under VC++, we win by inlining StartAssignment
#endif
/*
If the compiler doesn't support |explicit|, we'll just make it go away, trusting
that the builds under compilers that do have it will keep us on the straight and narrow.
*/
#ifndef HAVE_CPP_EXPLICIT
#define explicit
#endif
#ifdef HAVE_CPP_NEW_CASTS
#define NSCAP_REINTERPRET_CAST(T,x) reinterpret_cast<T>(x)
#else
#define NSCAP_REINTERPRET_CAST(T,x) ((T)(x))
#endif
#ifdef NSCAP_FEATURE_DEBUG_MACROS
#define NSCAP_ADDREF(ptr) NS_ADDREF(ptr)
#define NSCAP_RELEASE(ptr) NS_RELEASE(ptr)
#else
#define NSCAP_ADDREF(ptr) (ptr)->AddRef()
#define NSCAP_RELEASE(ptr) (ptr)->Release()
#endif
/*
WARNING:
VC++4.2 is very picky. To compile under VC++4.2, the classes must be defined
in an order that satisfies:
nsDerivedSafe < nsCOMPtr
nsDontAddRef < nsCOMPtr
nsCOMPtr < nsGetterAddRefs
The other compilers probably won't complain, so please don't reorder these
classes, on pain of breaking 4.2 compatibility.
*/
template <class T>
class nsDerivedSafe : public T
/*
No client should ever see or have to type the name of this class. It is the
artifact that makes it a compile-time error to call |AddRef| and |Release|
on a |nsCOMPtr|.
See |nsCOMPtr::operator->|, |nsCOMPtr::operator*|, et al.
*/
{
private:
#ifdef HAVE_CPP_USING
using T::AddRef;
using T::Release;
#else
NS_IMETHOD_(nsrefcnt) AddRef(void);
NS_IMETHOD_(nsrefcnt) Release(void);
#endif
void operator delete( void*, size_t ); // NOT TO BE IMPLEMENTED
// declaring |operator delete| private makes calling delete on an interface pointer a compile error
nsDerivedSafe<T>& operator=( const nsDerivedSafe<T>& ); // NOT TO BE IMPLEMENTED
// you may not call |operator=()| through a dereferenced |nsCOMPtr|, because you'd get the wrong one
};
#if !defined(HAVE_CPP_USING) && defined(NEED_CPP_UNUSED_IMPLEMENTATIONS)
template <class T>
nsrefcnt
nsDerivedSafe<T>::AddRef()
{
return 0;
}
template <class T>
nsrefcnt
nsDerivedSafe<T>::Release()
{
return 0;
}
#endif
template <class T>
struct nsDontQueryInterface
/*
...
*/
{
explicit
nsDontQueryInterface( T* aRawPtr )
: mRawPtr(aRawPtr)
{
// nothing else to do here
}
T* mRawPtr;
};
template <class T>
inline
nsDontQueryInterface<T>
dont_QueryInterface( T* aRawPtr )
{
return nsDontQueryInterface<T>(aRawPtr);
}
struct nsQueryInterface
{
explicit
nsQueryInterface( nsISupports* aRawPtr, nsresult* error = 0 )
: mRawPtr(aRawPtr),
mErrorPtr(error)
{
// nothing else to do here
}
nsISupports* mRawPtr;
nsresult* mErrorPtr;
};
inline
nsQueryInterface
do_QueryInterface( nsISupports* aRawPtr, nsresult* error = 0 )
{
return nsQueryInterface(aRawPtr, error);
}
template <class T>
struct nsDontAddRef
/*
...cooperates with |nsCOMPtr| to allow you to assign in a pointer _without_
|AddRef|ing it. You would rarely use this directly, but rather through the
machinery of |getter_AddRefs| in the argument list to functions that |AddRef|
their results before returning them to the caller.
See also |getter_AddRefs()| and |class nsGetterAddRefs|.
*/
{
explicit
nsDontAddRef( T* aRawPtr )
: mRawPtr(aRawPtr)
{
// nothing else to do here
}
T* mRawPtr;
};
// This call is now deprecated. Use |getter_AddRefs()| instead.
template <class T>
inline
nsDontAddRef<T>
dont_AddRef( T* aRawPtr )
/*
...makes typing easier, because it deduces the template type, e.g.,
you write |dont_AddRef(fooP)| instead of |nsDontAddRef<IFoo>(fooP)|.
*/
{
return nsDontAddRef<T>(aRawPtr);
}
template <class T>
inline
nsDontAddRef<T>
getter_AddRefs( T* aRawPtr )
{
return nsDontAddRef<T>(aRawPtr);
}
class nsCOMPtr_base
{
public:
nsCOMPtr_base( nsISupports* rawPtr = 0 )
: mRawPtr(rawPtr)
{
// nothing else to do here
}
~nsCOMPtr_base()
{
if ( mRawPtr )
NSCAP_RELEASE(mRawPtr);
}
NS_EXPORT void assign_with_AddRef( nsISupports* );
NS_EXPORT void assign_with_QueryInterface( nsISupports*, const nsIID&, nsresult* );
NS_EXPORT void** begin_assignment();
protected:
nsISupports* mRawPtr;
};
template <class T>
class nsCOMPtr : private nsCOMPtr_base
/*
...
*/
{
public:
typedef T element_type;
nsCOMPtr()
// : nsCOMPtr_base(0)
{
// nothing else to do here
}
nsCOMPtr( const nsQueryInterface& aSmartPtr )
// : nsCOMPtr_base(0)
{
assign_with_QueryInterface(aSmartPtr.mRawPtr, T::GetIID(), aSmartPtr.mErrorPtr);
}
nsCOMPtr( const nsDontAddRef<T>& aSmartPtr )
: nsCOMPtr_base(aSmartPtr.mRawPtr)
{
// nothing else to do here
}
nsCOMPtr( const nsDontQueryInterface<T>& aSmartPtr )
: nsCOMPtr_base(aSmartPtr.mRawPtr)
{
if ( mRawPtr )
NSCAP_ADDREF(mRawPtr);
}
nsCOMPtr( const nsCOMPtr<T>& aSmartPtr )
: nsCOMPtr_base(aSmartPtr.mRawPtr)
{
if ( mRawPtr )
NSCAP_ADDREF(mRawPtr);
}
nsCOMPtr<T>&
operator=( const nsQueryInterface& rhs )
{
assign_with_QueryInterface(rhs.mRawPtr, T::GetIID(), rhs.mErrorPtr);
return *this;
}
nsCOMPtr<T>&
operator=( const nsDontAddRef<T>& rhs )
{
if ( mRawPtr )
NSCAP_RELEASE(mRawPtr);
mRawPtr = rhs.mRawPtr;
return *this;
}
nsCOMPtr<T>&
operator=( const nsDontQueryInterface<T>& rhs )
{
assign_with_AddRef(rhs.mRawPtr);
return *this;
}
nsCOMPtr<T>&
operator=( const nsCOMPtr<T>& rhs )
{
assign_with_AddRef(rhs.mRawPtr);
return *this;
}
nsDerivedSafe<T>*
get() const
// returns a |nsDerivedSafe<T>*| to deny clients the use of |AddRef| and |Release|
{
return NSCAP_REINTERPRET_CAST(nsDerivedSafe<T>*, mRawPtr);
}
nsDerivedSafe<T>*
operator->() const
// returns a |nsDerivedSafe<T>*| to deny clients the use of |AddRef| and |Release|
{
NS_PRECONDITION(mRawPtr != 0, "You can't dereference a NULL nsCOMPtr with operator->().");
return get();
}
nsDerivedSafe<T>&
operator*() const
// returns a |nsDerivedSafe<T>*| to deny clients the use of |AddRef| and |Release|
{
NS_PRECONDITION(mRawPtr != 0, "You can't dereference a NULL nsCOMPtr with operator*().");
return *get();
}
operator nsDerivedSafe<T>*() const
{
return get();
}
#if 0
private:
friend class nsGetterAddRefs<T>;
/*
In a perfect world, the following member function, |StartAssignment|, would be private.
It is and should be only accessed by the closely related class |nsGetterAddRefs<T>|.
Unfortunately, some compilers---most notably VC++5.0---fail to grok the
friend declaration above or in any alternate acceptable form. So, physically
it will be public (until our compilers get smarter); but it is not to be
considered part of the logical public interface.
*/
#endif
T**
StartAssignment()
{
#ifndef NSCAP_FEATURE_INLINE_STARTASSIGNMENT
return NSCAP_REINTERPRET_CAST(T**, begin_assignment());
#else
if ( mRawPtr )
NSCAP_RELEASE(mRawPtr);
mRawPtr = 0;
return NSCAP_REINTERPRET_CAST(T**, &mRawPtr);
#endif
}
};
template <class T>
class nsGetterAddRefs
/*
...
This class is designed to be used for anonymous temporary objects in the
argument list of calls that return COM interface pointers, e.g.,
nsCOMPtr<IFoo> fooP;
...->QueryInterface(iid, nsGetterAddRefs<IFoo>(fooP))
...->QueryInterface(iid, getter_AddRefs(fooP))
When initialized with a |nsCOMPtr|, as in the example above, it returns
a |void**| (or |T**| if needed) that the outer call (|QueryInterface| in this
case) can fill in.
*/
{
public:
explicit
nsGetterAddRefs( nsCOMPtr<T>& aSmartPtr )
: mTargetSmartPtr(aSmartPtr)
{
// nothing else to do
}
operator void**()
{
// NS_PRECONDITION(mTargetSmartPtr != 0, "getter_AddRefs into no destination");
return NSCAP_REINTERPRET_CAST(void**, mTargetSmartPtr.StartAssignment());
}
T*&
operator*()
{
// NS_PRECONDITION(mTargetSmartPtr != 0, "getter_AddRefs into no destination");
return *(mTargetSmartPtr.StartAssignment());
}
operator T**()
{
// NS_PRECONDITION(mTargetSmartPtr != 0, "getter_AddRefs into no destination");
return mTargetSmartPtr.StartAssignment();
}
private:
nsCOMPtr<T>& mTargetSmartPtr;
};
template <class T>
inline
nsGetterAddRefs<T>
getter_AddRefs( nsCOMPtr<T>& aSmartPtr )
/*
Used around a |nsCOMPtr| when
...makes the class |nsGetterAddRefs<T>| invisible.
*/
{
return nsGetterAddRefs<T>(aSmartPtr);
}
#endif // !defined(nsCOMPtr_h___)

View File

@@ -0,0 +1,178 @@
/* -*- 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 "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 "nsDebug.h"
#include "prlog.h"
#include "prinit.h"
#if defined(XP_UNIX)
/* for abort() */
#include <stdlib.h>
#endif
#if defined(_WIN32)
#include <windows.h>
#elif defined(XP_MAC)
#define TEMP_MAC_HACK
//------------------------
#ifdef TEMP_MAC_HACK
#include <MacTypes.h>
#include <Processes.h>
// TEMPORARY UNTIL WE HAVE MACINTOSH ENVIRONMENT VARIABLES THAT CAN TURN ON
// LOGGING ON MACINTOSH
// At this moment, NSPR's logging is a no-op on Macintosh.
#include <stdarg.h>
#include <stdio.h>
#undef PR_LOG
#define PR_LOG(module,level,args) dprintf args
static void dprintf(const char *format, ...)
{
va_list ap;
Str255 buffer;
va_start(ap, format);
buffer[0] = vsnprintf((char *)buffer + 1, sizeof(buffer) - 1, format, ap);
va_end(ap);
DebugStr(buffer);
}
#endif // TEMP_MAC_HACK
//------------------------
#elif defined(XP_UNIX)
#include<stdlib.h>
#endif
/**
* Implementation of the nsDebug methods. Note that this code is
* always compiled in, in case some other module that uses it is
* compiled with debugging even if this library is not.
*/
static PRLogModuleInfo* gDebugLog;
static void InitLog(void)
{
if (0 == gDebugLog) {
gDebugLog = PR_NewLogModule("nsDebug");
gDebugLog->level = PR_LOG_DEBUG;
}
}
NS_COM void nsDebug::Abort(const char* aFile, PRIntn aLine)
{
InitLog();
PR_LOG(gDebugLog, PR_LOG_ERROR,
("Abort: at file %s, line %d", aFile, aLine));
PR_LogFlush();
#if defined(_WIN32)
long* __p = (long*) 0x7;
*__p = 0x7;
#elif defined(XP_MAC)
ExitToShell();
#elif defined(XP_UNIX)
PR_Abort();
#endif
}
NS_COM void nsDebug::Break(const char* aFile, PRIntn aLine)
{
#ifndef TEMP_MAC_HACK
InitLog();
PR_LOG(gDebugLog, PR_LOG_ERROR,
("Break: at file %s, line %d", aFile, aLine));
PR_LogFlush();
//XXX this works on win32 only for now. For all the other platforms call Abort
#if defined(_WIN32)
::DebugBreak();
#else
Abort(aFile, aLine);
#endif
#endif // TEMP_MAC_HACK
}
NS_COM void nsDebug::PreCondition(const char* aStr, const char* aExpr,
const char* aFile, PRIntn aLine)
{
InitLog();
PR_LOG(gDebugLog, PR_LOG_ERROR,
("PreCondition: \"%s\" (%s) at file %s, line %d", aStr, aExpr,
aFile, aLine));
Break(aFile, aLine);
}
NS_COM void nsDebug::PostCondition(const char* aStr, const char* aExpr,
const char* aFile, PRIntn aLine)
{
InitLog();
PR_LOG(gDebugLog, PR_LOG_ERROR,
("PostCondition: \"%s\" (%s) at file %s, line %d", aStr, aExpr,
aFile, aLine));
Break(aFile, aLine);
}
NS_COM void nsDebug::Assertion(const char* aStr, const char* aExpr,
const char* aFile, PRIntn aLine)
{
InitLog();
PR_LOG(gDebugLog, PR_LOG_ERROR,
("Assertion: \"%s\" (%s) at file %s, line %d", aStr, aExpr,
aFile, aLine));
Break(aFile, aLine);
}
NS_COM void nsDebug::NotYetImplemented(const char* aMessage,
const char* aFile, PRIntn aLine)
{
InitLog();
PR_LOG(gDebugLog, PR_LOG_ERROR,
("NotYetImplemented: \"%s\" at file %s, line %d", aMessage,
aFile, aLine));
Break(aFile, aLine);
}
NS_COM void nsDebug::NotReached(const char* aMessage,
const char* aFile, PRIntn aLine)
{
InitLog();
PR_LOG(gDebugLog, PR_LOG_ERROR,
("NotReached: \"%s\" at file %s, line %d", aMessage, aFile, aLine));
Break(aFile, aLine);
}
NS_COM void nsDebug::Error(const char* aMessage,
const char* aFile, PRIntn aLine)
{
InitLog();
PR_LOG(gDebugLog, PR_LOG_ERROR,
("Error: \"%s\" at file %s, line %d", aMessage, aFile, aLine));
Break(aFile, aLine);
}
NS_COM void nsDebug::Warning(const char* aMessage,
const char* aFile, PRIntn aLine)
{
InitLog();
PR_LOG(gDebugLog, PR_LOG_ERROR,
("Warning: \"%s\" at file %s, line %d", aMessage, aFile, aLine));
PR_LogFlush();
}

View File

@@ -0,0 +1,183 @@
/* -*- 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 "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 nsDebug_h___
#define nsDebug_h___
#include "nsCom.h"
#include "prtypes.h"
#ifdef DEBUG
#define NS_DEBUG
#endif
/**
* Namespace for debugging methods. Note that your code must use the
* macros defined later in this file so that the debug code can be
* conditionally compiled out.
*/
/* in case this is included by a C file */
#ifdef __cplusplus
class nsDebug {
public:
// XXX add in log controls here
// XXX probably want printf type arguments
/**
* Abort the executing program. This works on all architectures.
*/
static NS_COM void Abort(const char* aFile, PRIntn aLine);
/**
* Break the executing program into the debugger.
*/
static NS_COM void Break(const char* aFile, PRIntn aLine);
/**
* Log a pre-condition message to the debug log
*/
static NS_COM void PreCondition(const char* aStr, const char* aExpr,
const char* aFile, PRIntn aLine);
/**
* Log a post-condition message to the debug log
*/
static NS_COM void PostCondition(const char* aStr, const char* aExpr,
const char* aFile, PRIntn aLine);
/**
* Log an assertion message to the debug log
*/
static NS_COM void Assertion(const char* aStr, const char* aExpr,
const char* aFile, PRIntn aLine);
/**
* Log a not-yet-implemented message to the debug log
*/
static NS_COM void NotYetImplemented(const char* aMessage,
const char* aFile, PRIntn aLine);
/**
* Log a not-reached message to the debug log
*/
static NS_COM void NotReached(const char* aMessage,
const char* aFile, PRIntn aLine);
/**
* Log an error message to the debug log. This call returns.
*/
static NS_COM void Error(const char* aMessage,
const char* aFile, PRIntn aLine);
/**
* Log a warning message to the debug log.
*/
static NS_COM void Warning(const char* aMessage,
const char* aFile, PRIntn aLine);
};
#ifdef NS_DEBUG
/**
* Test a precondition for truth. If the expression is not true then
* trigger a program failure.
*/
#define NS_PRECONDITION(expr,str) \
if (!(expr)) \
nsDebug::PreCondition(str, #expr, __FILE__, __LINE__)
/**
* Test an assertion for truth. If the expression is not true then
* trigger a program failure.
*/
#define NS_ASSERTION(expr,str) \
if (!(expr)) \
nsDebug::Assertion(str, #expr, __FILE__, __LINE__)
/**
* Test an assertion for truth. If the expression is not true then
* trigger a program failure. The expression will still be
* executed in release mode.
*/
#define NS_VERIFY(expr,str) \
if (!(expr)) \
nsDebug::Assertion(str, #expr, __FILE__, __LINE__)
/**
* Test a post-condition for truth. If the expression is not true then
* trigger a program failure.
*/
#define NS_POSTCONDITION(expr,str) \
if (!(expr)) \
nsDebug::PostCondition(str, #expr, __FILE__, __LINE__)
/**
* This macros triggers a program failure if executed. It indicates that
* an attempt was made to execute some unimplimented functionality.
*/
#define NS_NOTYETIMPLEMENTED(str) \
nsDebug::NotYetImplemented(str, __FILE__, __LINE__)
/**
* This macros triggers a program failure if executed. It indicates that
* an attempt was made to execute some unimplimented functionality.
*/
#define NS_NOTREACHED(str) \
nsDebug::NotReached(str, __FILE__, __LINE__)
/**
* Log an error message.
*/
#define NS_ERROR(str) \
nsDebug::Error(str, __FILE__, __LINE__)
/**
* Log a warning message.
*/
#define NS_WARNING(str) \
nsDebug::Warning(str, __FILE__, __LINE__)
/**
* Trigger an abort
*/
#define NS_ABORT() \
nsDebug::Abort(__FILE__, __LINE__)
/**
* Cause a break
*/
#define NS_BREAK() \
nsDebug::Break(__FILE__, __LINE__)
#else /* NS_DEBUG */
#define NS_PRECONDITION(expr,str) {}
#define NS_ASSERTION(expr,str) {}
#define NS_VERIFY(expr,str) expr
#define NS_POSTCONDITION(expr,str) {}
#define NS_NOTYETIMPLEMENTED(str) {}
#define NS_NOTREACHED(str) {}
#define NS_ERROR(str) {}
#define NS_WARNING(str) {}
#define NS_ABORT() {}
#define NS_BREAK() {}
#endif /* ! NS_DEBUG */
#endif /* __cplusplus */
#endif /* nsDebug_h___ */

View File

@@ -0,0 +1,88 @@
/* -*- 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 "nsGenericFactory.h"
nsGenericFactory::nsGenericFactory(ConstructorProcPtr constructor)
: mConstructor(constructor), mDestructor(NULL)
{
NS_INIT_ISUPPORTS();
}
nsGenericFactory::~nsGenericFactory()
{
if (mDestructor != NULL)
(*mDestructor) ();
}
NS_METHOD nsGenericFactory::QueryInterface(const nsIID& aIID, void** aInstancePtr)
{
if (NULL == aInstancePtr) {
return NS_ERROR_NULL_POINTER;
}
if (aIID.Equals(nsIFactory::GetIID()) ||
aIID.Equals(nsIGenericFactory::GetIID()) ||
aIID.Equals(nsISupports::GetIID())) {
*aInstancePtr = (void*) this;
AddRef();
return NS_OK;
}
return NS_NOINTERFACE;
}
NS_IMPL_ADDREF(nsGenericFactory)
NS_IMPL_RELEASE(nsGenericFactory)
NS_IMETHODIMP nsGenericFactory::CreateInstance(nsISupports *aOuter, REFNSIID aIID, void **aResult)
{
return mConstructor(aOuter, aIID, aResult);
}
NS_IMETHODIMP nsGenericFactory::LockFactory(PRBool aLock)
{
return NS_OK;
}
NS_IMETHODIMP nsGenericFactory::SetConstructor(ConstructorProcPtr constructor)
{
mConstructor = constructor;
return NS_OK;
}
NS_IMETHODIMP nsGenericFactory::SetDestructor(DestructorProcPtr destructor)
{
mDestructor = destructor;
return NS_OK;
}
NS_METHOD nsGenericFactory::Create(nsISupports* outer, const nsIID& aIID, void* *aInstancePtr)
{
// sorry, aggregation not spoken here.
nsresult res = NS_ERROR_NO_AGGREGATION;
if (outer == NULL) {
nsGenericFactory* factory = new nsGenericFactory;
if (factory != NULL) {
res = factory->QueryInterface(aIID, aInstancePtr);
if (res != NS_OK)
delete factory;
} else {
res = NS_ERROR_OUT_OF_MEMORY;
}
}
return res;
}

View File

@@ -0,0 +1,60 @@
/* -*- 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.
*/
#ifndef nsGenericFactory_h___
#define nsGenericFactory_h___
#include "nsIGenericFactory.h"
/**
* Most factories follow this simple pattern, so why not just use a function pointer
* for most creation operations?
*/
class nsGenericFactory : public nsIGenericFactory {
public:
static const nsCID& CID() { static nsCID cid = NS_GENERICFACTORY_CID; return cid; }
nsGenericFactory(ConstructorProcPtr constructor = NULL);
virtual ~nsGenericFactory();
NS_DECL_ISUPPORTS
NS_IMETHOD CreateInstance(nsISupports *aOuter, REFNSIID aIID, void **aResult);
NS_IMETHOD LockFactory(PRBool aLock);
/**
* Establishes the generic factory's constructor function, which will be called
* by CreateInstance.
*/
NS_IMETHOD SetConstructor(ConstructorProcPtr constructor);
/**
* Establishes the generic factory's destructor function, which will be called
* whe the generic factory is deleted. This is used to notify the DLL that
* an instance of one of its generic factories is going away.
*/
NS_IMETHOD SetDestructor(DestructorProcPtr destructor);
static NS_METHOD Create(nsISupports* outer, const nsIID& aIID, void* *aInstancePtr);
private:
ConstructorProcPtr mConstructor;
DestructorProcPtr mDestructor;
};
#endif /* nsGenericFactory_h___ */

View File

@@ -0,0 +1,57 @@
/* -*- 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.
*/
#ifndef nsIGenericFactory_h___
#define nsIGenericFactory_h___
#include "nsIFactory.h"
// {3bc97f01-ccdf-11d2-bab8-b548654461fc}
#define NS_GENERICFACTORY_CID \
{ 0x3bc97f01, 0xccdf, 0x11d2, { 0xba, 0xb8, 0xb5, 0x48, 0x65, 0x44, 0x61, 0xfc } }
// {3bc97f00-ccdf-11d2-bab8-b548654461fc}
#define NS_IGENERICFACTORY_IID \
{ 0x3bc97f00, 0xccdf, 0x11d2, { 0xba, 0xb8, 0xb5, 0x48, 0x65, 0x44, 0x61, 0xfc } }
/**
* Provides a Generic nsIFactory implementation that can be used by
* DLLs with very simple factory needs.
*/
class nsIGenericFactory : public nsIFactory {
public:
static const nsIID& GetIID() { static nsIID iid = NS_IGENERICFACTORY_IID; return iid; }
typedef NS_CALLBACK(ConstructorProcPtr) (nsISupports *aOuter, REFNSIID aIID, void **aResult);
typedef NS_CALLBACK(DestructorProcPtr) (void);
/**
* Establishes the generic factory's constructor function, which will be called
* by CreateInstance.
*/
NS_IMETHOD SetConstructor(ConstructorProcPtr constructor) = 0;
/**
* Establishes the generic factory's destructor function, which will be called
* whe the generic factory is deleted. This is used to notify the DLL that
* an instance of one of its generic factories is going away.
*/
NS_IMETHOD SetDestructor(DestructorProcPtr destructor) = 0;
};
#endif /* nsIGenericFactory_h___ */

View File

@@ -0,0 +1,557 @@
/* -*- 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.
*/
#ifndef __nsISupportsUtils_h
#define __nsISupportsUtils_h
/**
* A macro to build the static const IID accessor method
*/
#define NS_DEFINE_STATIC_IID_ACCESSOR(the_iid) \
static const nsIID& GetIID() {static nsIID iid = the_iid; return iid;}
/**
* A macro to build the static const CID accessor method
*/
#define NS_DEFINE_STATIC_CID_ACCESSOR(the_cid) \
static const nsID& GetCID() {static nsID cid = the_cid; return cid;}
/**
* Some convenience macros for implementing AddRef and Release
*/
/**
* Declare the reference count variable and the implementations of the
* AddRef and QueryInterface methods.
*/
#define NS_DECL_ISUPPORTS \
public: \
NS_IMETHOD QueryInterface(REFNSIID aIID, \
void** aInstancePtr); \
NS_IMETHOD_(nsrefcnt) AddRef(void); \
NS_IMETHOD_(nsrefcnt) Release(void); \
protected: \
nsrefcnt mRefCnt; \
public:
#define NS_DECL_ISUPPORTS_EXPORTED \
public: \
NS_EXPORT NS_IMETHOD QueryInterface(REFNSIID aIID, \
void** aInstancePtr); \
NS_EXPORT NS_IMETHOD_(nsrefcnt) AddRef(void); \
NS_EXPORT NS_IMETHOD_(nsrefcnt) Release(void); \
protected: \
nsrefcnt mRefCnt; \
public:
////////////////////////////////////////////////////////////////////////////////
/**
* Initialize the reference count variable. Add this to each and every
* constructor you implement.
*/
#define NS_INIT_REFCNT() mRefCnt = 0
#define NS_INIT_ISUPPORTS() NS_INIT_REFCNT() // what it should have been called in the first place
/**
* Use this macro to implement the AddRef method for a given <i>_class</i>
* @param _class The name of the class implementing the method
*/
#define NS_IMPL_ADDREF(_class) \
NS_IMETHODIMP_(nsrefcnt) _class::AddRef(void) \
{ \
NS_PRECONDITION(PRInt32(mRefCnt) >= 0, "illegal refcnt"); \
return ++mRefCnt; \
}
/**
* Use this macro to implement the Release method for a given <i>_class</i>
* @param _class The name of the class implementing the method
*/
#define NS_IMPL_RELEASE(_class) \
NS_IMETHODIMP_(nsrefcnt) _class::Release(void) \
{ \
NS_PRECONDITION(0 != mRefCnt, "dup release"); \
if (--mRefCnt == 0) { \
NS_DELETEXPCOM(this); \
return 0; \
} \
return mRefCnt; \
}
////////////////////////////////////////////////////////////////////////////////
/*
* Some convenience macros for implementing QueryInterface
*/
/**
* This implements query interface with two assumptions: First, the
* class in question implements nsISupports and it's own interface and
* nothing else. Second, the implementation of the class's primary
* inheritance chain leads to it's own interface.
*
* @param _class The name of the class implementing the method
* @param _classiiddef The name of the #define symbol that defines the IID
* for the class (e.g. NS_ISUPPORTS_IID)
*/
#define NS_IMPL_QUERY_INTERFACE(_class,_classiiddef) \
NS_IMETHODIMP _class::QueryInterface(REFNSIID aIID, void** aInstancePtr) \
{ \
if (NULL == aInstancePtr) { \
return NS_ERROR_NULL_POINTER; \
} \
\
*aInstancePtr = NULL; \
\
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID); \
static NS_DEFINE_IID(kClassIID, _classiiddef); \
if (aIID.Equals(kClassIID)) { \
*aInstancePtr = (void*) this; \
NS_ADDREF_THIS(); \
return NS_OK; \
} \
if (aIID.Equals(kISupportsIID)) { \
*aInstancePtr = (void*) ((nsISupports*)this); \
NS_ADDREF_THIS(); \
return NS_OK; \
} \
return NS_NOINTERFACE; \
}
/**
* Convenience macro for implementing all nsISupports methods for
* a simple class.
* @param _class The name of the class implementing the method
* @param _classiiddef The name of the #define symbol that defines the IID
* for the class (e.g. NS_ISUPPORTS_IID)
*/
#define NS_IMPL_ISUPPORTS(_class,_classiiddef) \
NS_IMPL_ADDREF(_class) \
NS_IMPL_RELEASE(_class) \
NS_IMPL_QUERY_INTERFACE(_class,_classiiddef)
////////////////////////////////////////////////////////////////////////////////
/**
* Declare that you're going to inherit from something that already
* implements nsISupports, but also implements an additional interface, thus
* causing an ambiguity. In this case you don't need another mRefCnt, you
* just need to forward the definitions to the appropriate superclass. E.g.
*
* class Bar : public Foo, public nsIBar { // both provide nsISupports
* public:
* NS_DECL_ISUPPORTS_INHERITED
* ...other nsIBar and Bar methods...
* };
*/
#define NS_DECL_ISUPPORTS_INHERITED \
public: \
NS_IMETHOD QueryInterface(REFNSIID aIID, \
void** aInstancePtr); \
NS_IMETHOD_(nsrefcnt) AddRef(void); \
NS_IMETHOD_(nsrefcnt) Release(void); \
/**
* These macros can be used in conjunction with NS_DECL_ISUPPORTS_INHERITED
* to implement the nsISupports methods, forwarding the invocations to a
* superclass that already implements nsISupports.
*
* Note that I didn't make these inlined because they're virtual methods.
*/
#define NS_IMPL_ADDREF_INHERITED(Class, Super) \
NS_IMETHODIMP_(nsrefcnt) Class::AddRef(void) \
{ \
return Super::AddRef(); \
} \
#define NS_IMPL_RELEASE_INHERITED(Class, Super) \
NS_IMETHODIMP_(nsrefcnt) Class::Release(void) \
{ \
return Super::Release(); \
} \
#define NS_IMPL_QUERY_INTERFACE_INHERITED(Class, Super, AdditionalInterface) \
NS_IMETHODIMP Class::QueryInterface(REFNSIID aIID, void** aInstancePtr) \
{ \
if (!aInstancePtr) return NS_ERROR_NULL_POINTER; \
if (aIID.Equals(AdditionalInterface::GetIID())) { \
*aInstancePtr = NS_STATIC_CAST(AdditionalInterface*, this); \
NS_ADDREF_THIS(); \
return NS_OK; \
} \
return Super::QueryInterface(aIID, aInstancePtr); \
} \
#define NS_IMPL_ISUPPORTS_INHERITED(Class, Super, AdditionalInterface) \
NS_IMPL_QUERY_INTERFACE_INHERITED(Class, Super, AdditionalInterface) \
NS_IMPL_ADDREF_INHERITED(Class, Super) \
NS_IMPL_RELEASE_INHERITED(Class, Super) \
////////////////////////////////////////////////////////////////////////////////
/**
*
* Threadsafe implementations of the ISupports convenience macros
*
*/
/**
* IID for the nsIsThreadsafe interface
* {88210890-47a6-11d2-bec3-00805f8a66dc}
*
* This interface is *only* used for debugging purposes to determine if
* a given component is threadsafe.
*/
#define NS_ISTHREADSAFE_IID \
{ 0x88210890, 0x47a6, 0x11d2, \
{0xbe, 0xc3, 0x00, 0x80, 0x5f, 0x8a, 0x66, 0xdc} }
#if defined(NS_MT_SUPPORTED)
#define NS_LOCK_INSTANCE() \
PR_CEnterMonitor((void*)this)
#define NS_UNLOCK_INSTANCE() \
PR_CExitMonitor((void*)this)
/**
* Use this macro to implement the AddRef method for a given <i>_class</i>
* @param _class The name of the class implementing the method
*/
#if defined(XP_PC)
#define NS_IMPL_THREADSAFE_ADDREF(_class) \
NS_IMETHODIMP_(nsrefcnt) _class::AddRef(void) \
{ \
NS_PRECONDITION(PRInt32(mRefCnt) >= 0, "illegal refcnt"); \
return InterlockedIncrement((LONG*)&mRefCnt); \
}
#else /* ! XP_PC */
#define NS_IMPL_THREADSAFE_ADDREF(_class) \
nsrefcnt _class::AddRef(void) \
{ \
nsrefcnt count; \
NS_LOCK_INSTANCE(); \
NS_PRECONDITION(PRInt32(mRefCnt) >= 0, "illegal refcnt"); \
count = ++mRefCnt; \
NS_UNLOCK_INSTANCE(); \
return count; \
}
#endif /* ! XP_PC */
/**
* Use this macro to implement the Release method for a given <i>_class</i>
* @param _class The name of the class implementing the method
*/
#if defined(XP_PC)
#define NS_IMPL_THREADSAFE_RELEASE(_class) \
NS_IMETHODIMP_(nsrefcnt) _class::Release(void) \
{ \
NS_PRECONDITION(0 != mRefCnt, "dup release"); \
if (0 == InterlockedDecrement((LONG*)&mRefCnt)) { \
NS_DELETEXPCOM(this); \
return 0; \
} \
return mRefCnt; /* Not threadsafe but who cares. */ \
}
#else /* ! XP_PC */
#define NS_IMPL_THREADSAFE_RELEASE(_class) \
nsrefcnt _class::Release(void) \
{ \
nsrefcnt count; \
NS_PRECONDITION(0 != mRefCnt, "dup release"); \
NS_LOCK_INSTANCE(); \
count = --mRefCnt; \
NS_UNLOCK_INSTANCE(); \
if (0 == count) { \
NS_DELETEXPCOM(this); \
return 0; \
} \
return count; \
}
#endif /* ! XP_PC */
////////////////////////////////////////////////////////////////////////////////
/*
* Some convenience macros for implementing QueryInterface
*/
/**
* This implements query interface with two assumptions: First, the
* class in question implements nsISupports and it's own interface and
* nothing else. Second, the implementation of the class's primary
* inheritance chain leads to it's own interface.
*
* @param _class The name of the class implementing the method
* @param _classiiddef The name of the #define symbol that defines the IID
* for the class (e.g. NS_ISUPPORTS_IID)
*/
#if defined(NS_DEBUG)
#define NS_VERIFY_THREADSAFE_INTERFACE(_iface) \
if (NULL != (_iface)) { \
nsISupports* tmp; \
static NS_DEFINE_IID(kIsThreadsafeIID, NS_ISTHREADSAFE_IID); \
NS_PRECONDITION((NS_OK == _iface->QueryInterface(kIsThreadsafeIID, \
(void**)&tmp)), \
"Interface is not threadsafe"); \
}
#define NS_IMPL_THREADSAFE_QUERY_INTERFACE(_class,_classiiddef) \
NS_IMETHODIMP _class::QueryInterface(REFNSIID aIID, void** aInstancePtr) \
{ \
if (NULL == aInstancePtr) { \
return NS_ERROR_NULL_POINTER; \
} \
\
*aInstancePtr = NULL; \
\
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID); \
static NS_DEFINE_IID(kIsThreadsafeIID, NS_ISTHREADSAFE_IID); \
static NS_DEFINE_IID(kClassIID, _classiiddef); \
if (aIID.Equals(kClassIID)) { \
*aInstancePtr = (void*) this; \
NS_ADDREF_THIS(); \
return NS_OK; \
} \
if (aIID.Equals(kISupportsIID)) { \
*aInstancePtr = (void*) ((nsISupports*)this); \
NS_ADDREF_THIS(); \
return NS_OK; \
} \
if (aIID.Equals(kIsThreadsafeIID)) { \
return NS_OK; \
} \
return NS_NOINTERFACE; \
}
#else /* !NS_DEBUG */
#define NS_VERIFY_THREADSAFE_INTERFACE(_iface)
#define NS_IMPL_THREADSAFE_QUERY_INTERFACE(_class,_classiiddef) \
NS_IMPL_QUERY_INTERFACE(_class, _classiiddef)
#endif /* !NS_DEBUG */
/**
* Convenience macro for implementing all nsISupports methods for
* a simple class.
* @param _class The name of the class implementing the method
* @param _classiiddef The name of the #define symbol that defines the IID
* for the class (e.g. NS_ISUPPORTS_IID)
*/
#define NS_IMPL_THREADSAFE_ISUPPORTS(_class,_classiiddef) \
NS_IMPL_THREADSAFE_ADDREF(_class) \
NS_IMPL_THREADSAFE_RELEASE(_class) \
NS_IMPL_THREADSAFE_QUERY_INTERFACE(_class,_classiiddef)
#else /* !NS_MT_SUPPORTED */
#define NS_LOCK_INSTANCE()
#define NS_UNLOCK_INSTANCE()
#define NS_IMPL_THREADSAFE_ADDREF(_class) NS_IMPL_ADDREF(_class)
#define NS_IMPL_THREADSAFE_RELEASE(_class) NS_IMPL_RELEASE(_class)
#define NS_VERIFY_THREADSAFE_INTERFACE(_iface)
#define NS_IMPL_THREADSAFE_QUERY_INTERFACE(_class,_classiiddef) \
NS_IMPL_QUERY_INTERFACE(_class, _classiiddef)
#define NS_IMPL_THREADSAFE_ISUPPORTS(_class,_classiiddef) \
NS_IMPL_ADDREF(_class) \
NS_IMPL_RELEASE(_class) \
NS_IMPL_QUERY_INTERFACE(_class,_classiiddef)
#endif /* !NS_MT_SUPPORTED */
////////////////////////////////////////////////////////////////////////////////
// Debugging Macros
////////////////////////////////////////////////////////////////////////////////
/**
* Macro for instantiating a new object that implements nsISupports.
* Use this in your factory methods to allow for refcnt tracing.
* Note that you can only use this if you adhere to the no arguments
* constructor com policy (which you really should!).
* @param _result Where the new instance pointer is stored
* @param _type The type of object to call "new" with.
*/
#ifdef MOZ_TRACE_XPCOM_REFCNT
#define NS_NEWXPCOM(_result,_type) \
PR_BEGIN_MACRO \
_result = new _type(); \
nsTraceRefcnt::Create(_result, #_type, __FILE__, __LINE__); \
PR_END_MACRO
#else
#define NS_NEWXPCOM(_result,_type) \
_result = new _type()
#endif
/**
* Macro for deleting an object that implements nsISupports.
* Use this in your Release methods to allow for refcnt tracing.
* @param _ptr The object to delete.
*/
#ifdef MOZ_TRACE_XPCOM_REFCNT
#define NS_DELETEXPCOM(_ptr) \
PR_BEGIN_MACRO \
nsTraceRefcnt::Destroy((_ptr), __FILE__, __LINE__); \
delete (_ptr); \
PR_END_MACRO
#else
#define NS_DELETEXPCOM(_ptr) \
delete (_ptr)
#endif
/**
* Macro for adding a reference to an interface.
* @param _ptr The interface pointer.
*/
#ifdef MOZ_TRACE_XPCOM_REFCNT
#define NS_ADDREF(_ptr) \
((nsrefcnt) nsTraceRefcnt::AddRef((_ptr), (_ptr)->AddRef(), \
__FILE__, __LINE__))
#else
#define NS_ADDREF(_ptr) \
(_ptr)->AddRef()
#endif
/**
* Macro for adding a reference to this. This macro should be used
* because NS_ADDREF (when tracing) may require an ambiguous cast
* from the pointers primary type to nsISupports. This macro sidesteps
* that entire problem.
*/
#ifdef MOZ_TRACE_XPCOM_REFCNT
#define NS_ADDREF_THIS() \
((nsrefcnt) nsTraceRefcnt::AddRef(this, AddRef(), __FILE__, __LINE__))
#else
#define NS_ADDREF_THIS() \
AddRef()
#endif
/**
* Macro for adding a reference to an interface that checks for NULL.
* @param _ptr The interface pointer.
*/
#ifdef MOZ_TRACE_XPCOM_REFCNT
#define NS_IF_ADDREF(_ptr) \
((0 != (_ptr)) \
? ((nsrefcnt) nsTraceRefcnt::AddRef((_ptr), (_ptr)->AddRef(), __FILE__, \
__LINE__)) \
: 0)
#else
#define NS_IF_ADDREF(_ptr) \
((0 != (_ptr)) ? (_ptr)->AddRef() : 0)
#endif
/**
* Macro for releasing a reference to an interface.
*
* Note that when MOZ_TRACE_XPCOM_REFCNT is defined that the release will
* be done before the trace message is logged. If the reference count
* goes to zero and implementation of Release logs a message, the two
* messages will be logged out of order.
*
* @param _ptr The interface pointer.
*/
#ifdef MOZ_TRACE_XPCOM_REFCNT
#define NS_RELEASE(_ptr) \
PR_BEGIN_MACRO \
nsTraceRefcnt::Release((_ptr), (_ptr)->Release(), __FILE__, __LINE__); \
(_ptr) = 0; \
PR_END_MACRO
#else
#define NS_RELEASE(_ptr) \
PR_BEGIN_MACRO \
(_ptr)->Release(); \
(_ptr) = 0; \
PR_END_MACRO
#endif
/**
* Macro for releasing a reference to an interface, except that this
* macro preserves the return value from the underlying Release call.
* The interface pointer argument will only be NULLed if the reference count
* goes to zero.
*
* Note that when MOZ_TRACE_XPCOM_REFCNT is defined that the release will
* be done before the trace message is logged. If the reference count
* goes to zero and implementation of Release logs a message, the two
* messages will be logged out of order.
*
* @param _ptr The interface pointer.
*/
#ifdef MOZ_TRACE_XPCOM_REFCNT
#define NS_RELEASE2(_ptr, _result) \
PR_BEGIN_MACRO \
_result = ((nsrefcnt) nsTraceRefcnt::Release((_ptr), (_ptr)->Release(), \
__FILE__, __LINE__)); \
if (0 == (_result)) (_ptr) = 0; \
PR_END_MACRO
#else
#define NS_RELEASE2(_ptr, _result) \
PR_BEGIN_MACRO \
_result = (_ptr)->Release(); \
if (0 == (_result)) (_ptr) = 0; \
PR_END_MACRO
#endif
/**
* Macro for releasing a reference to an interface that checks for NULL;
*
* Note that when MOZ_TRACE_XPCOM_REFCNT is defined that the release will
* be done before the trace message is logged. If the reference count
* goes to zero and implementation of Release logs a message, the two
* messages will be logged out of order.
*
* @param _ptr The interface pointer.
*/
#ifdef MOZ_TRACE_XPCOM_REFCNT
#define NS_IF_RELEASE(_ptr) \
PR_BEGIN_MACRO \
((0 != (_ptr)) \
? ((nsrefcnt) nsTraceRefcnt::Release((_ptr), (_ptr)->Release(), \
__FILE__, __LINE__)) \
: 0); \
(_ptr) = 0; \
PR_END_MACRO
#else
#define NS_IF_RELEASE(_ptr) \
PR_BEGIN_MACRO \
((0 != (_ptr)) ? (_ptr)->Release() : 0); \
(_ptr) = 0; \
PR_END_MACRO
#endif
////////////////////////////////////////////////////////////////////////////////
#endif /* __nsISupportsUtils_h */

View File

@@ -0,0 +1,36 @@
#
# This is a list of local files which get copied to the mozilla:dist directory
#
nsCOMPtr.h
nsCom.h
nsAgg.h
nsDebug.h
nsEnumeratorUtils.h
nsError.h
nsHashtable.h
nsID.h
nsIID.h
nsIFactory.h
nsISimpleEnumerator.h
nsISupports.h
nsISupportsUtils.h
nsIPtr.h
nsIRegistry.h
nsIServiceManager.h
nsIComponentManager.h
nsISupportsArray.h
nsRepository.h
nsIEnumerator.h
nsVector.h
nsMacRepository.h
nsTraceRefcnt.h
plvector.h
nsXPComFactory.h
nsXPComCIID.h
nsXPIDLString.h
nsIEventQueueService.h
nsICollection.h
nsIAllocator.h
nsIGenericFactory.h
nsrootidl.h

View File

@@ -1,5 +1,4 @@
#!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
@@ -15,20 +14,50 @@
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
# Reserved.
DEPTH=../..
DEPTH = ../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
include $(topsrcdir)/config/config.mk
MODULE = xpcom
EXPORTS = \
nsCOMPtr.h \
nsCom.h \
nsAgg.h \
nsDebug.h \
nsEnumeratorUtils.h \
nsError.h \
nsHashtable.h \
nsIAllocator.h \
nsICollection.h \
nsID.h \
nsIID.h \
nsIFactory.h \
nsISimpleEnumerator.h \
nsISupports.h \
nsISupportsUtils.h \
nsIPtr.h \
nsIComponentManager.h \
nsRepository.h \
nsIServiceManager.h \
nsISupportsArray.h \
nsProxyEvent.h \
nsIEnumerator.h \
nsTraceRefcnt.h \
nsVector.h \
plvector.h \
nsXPComFactory.h \
nsXPComCIID.h \
nsXPIDLString.h \
nsIEventQueueService.h \
nsIGenericFactory.h \
nsIRegistry.h \
nsrootidl.h \
$(NULL)
EXPORTS := $(addprefix $(srcdir)/, $(EXPORTS))
include $(topsrcdir)/config/rules.mk
EXPORT_RESOURCE_XPINSTALL = \
$(srcdir)/progress.xul \
$(srcdir)/progress.html \
$(srcdir)/progress.css \
$(NULL)
install::
$(INSTALL) $(EXPORT_RESOURCE_XPINSTALL) $(DIST)/bin/res/xpinstall

View File

@@ -0,0 +1,59 @@
#!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.
IGNORE_MANIFEST=1
DEPTH=..\..
EXPORTS = \
nsCOMPtr.h \
nsAgg.h \
nsCom.h \
nsDebug.h \
nsEnumeratorUtils.h \
nsError.h \
nsHashtable.h \
nsICollection.h \
nsID.h \
nsIFactory.h \
nsIID.h \
nsISimpleEnumerator.h \
nsISupports.h \
nsISupportsUtils.h \
nsIPtr.h \
nsIServiceManager.h \
nsISupportsArray.h \
nsIComponentManager.h \
nsRepository.h \
nsProxyEvent.h \
nsIEnumerator.h \
nsTraceRefcnt.h \
nsVector.h \
plvector.h \
nsXPComFactory.h \
nsXPComCIID.h \
nsXPIDLString.h \
nsIEventQueueService.h \
nsIAllocator.h \
nsIRegistry.h \
nsIGenericFactory.h \
nsrootidl.h \
$(NULL)
MODULE = xpcom
include <$(DEPTH)\config\rules.mak>

View File

@@ -0,0 +1,168 @@
/* -*- 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 "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 __mozIClassRegistry_h
#define __mozIClassRegistry_h
#include "nsIComponentManager.h"
/*---------------------------- mozIClassRegistry -------------------------------
| This interface provides access to a mapping from mnemonic interface names |
| to shared libraries where implementations of those interfaces can be located.|
| |
| This interface is designed to provide two things: |
| 1. A means of less static binding between clients and the code that |
| implements the XPCOM interfaces those clients use. This accomplished |
| by the mapping from interface names to nsCID (and the shared libraries |
| that implement those classes). |
| 2. A means of dynamically changing the mapping from interface name to |
| implementation. The canonical example of this is to switch to a |
| "native" widget set versus an "XP" (implemented using gfx) set. |
| |
| The first goal is achieved by storing (in a "Netscape Registry" file, see |
| nsReg.h) information that maps interface/class "names" to information about |
| where to load implementations of those interfaces. That information |
| includes the interface ID, class ID (of the implementation class), and the |
| name of the shared library that contains the implementation. |
| |
| The class registry object will register those classes with the "repository" |
| (see nsComponentManager.h) the first time a request is made to create an |
| instance. Subsequent requests will simply be forwarded to the repository |
| after the appropriate interface and class IDs are determined. |
| |
| The second goal is accomplished by permitting the mnemonic interface |
| "names" to be "overloaded", that is, mapped to distinct implementations |
| by separate class registry objects. Further, class registries can be |
| cascaded: they can be chained together so that when a name is not |
| recognized by one registry, it can pass the request to the next registry in |
| the chain. Users can control resolution by making the request of a |
| registry further up/down the chain. |
| |
| For example, consider the case of "native" vs. "gfx" widgets. This might |
| be structured by a class registry arrangment like this: |
| |
| nativeWidgetRegistry baseWidgetRegistry |
| +----------+ +----------+ |
| | ----+---------------->| | |
| +----------+ +----------+ |
| |toolbar| -+-----+ |toolbar| -+-----+ |
| +----------+ | +----------+ | |
| |button | -+-----+ |button | -+-----+ |
| +----------+ | +----------+ | |
| V V |
| +-----------------+ +-----------------+ |
| | native.dll | | base.dll | |
| +-----------------+ +-----------------+ |
| |
| If a specialized implementation of widgets is present (e.g., native.dll) |
| then a corresponding class registry object is created and added to the |
| head of the registry chain. Object creation requests (normal ones) are |
| resolved to the native implementation. If such a library is not present, |
| then the resolution is to the base implementation. If objects of the |
| base implementation are required, then creation requests can be directed |
| directly to the baseWidgetRegistry object, rather than the head of the |
| registry chain. |
| |
| It is intended that there be a single instance of this interface, accessed |
| via the Service Manager (see nsServiceManager.h). |
------------------------------------------------------------------------------*/
struct mozIClassRegistry : public ISupports {
/*------------------------------ CreateInstance ----------------------------
| Create an instance of the requested class/interface. The interface |
| ID is required to specify how the result will be treated. The class |
| named by aName must support this interface. The result is placed in |
| ncomment aResult (NULL if the request fails). "start" specifies the |
| registry at which the search for an implementation of the named |
| interface should start. It defaults to 0 (indicating to start at the |
| head of the registry chain). |
--------------------------------------------------------------------------*/
NS_IMETHOD CreateInstance( const char *anInterfaceName,
const nsIID &aIID,
void* *aResult,
const char *start = 0 ) = 0;
/*--------------------------- CreateEnumerator -----------------------------
| Creates an nsIEnumerator interface object that can be used to examine |
| the contents of the registry. "pattern" specifies either "*" or the |
| name of a specific interface that you want to query. "result" will |
| be set to point to a new object (which will be freed on the last call |
| to its Release() member). See nsIEnumerator.h for details on how to |
| use the returned interface pointer. |
--------------------------------------------------------------------------*/
NS_IMETHOD CreateEnumerator( const char *pattern,
nsIEnumerator* *result ) = 0;
}; // mozIClassRegistry
/*-------------------------- mozIClassRegistryEntry ----------------------------
| Objects of this class represent the individual elements that comprise a |
| mozIClassRegistry interface. You obtain such objects by applying the |
| CreateEnumerator member function to the class registry and then applying |
| the CurrentItem member function to the resulting nsIEnumerator interface. |
| |
| Each entry can be queried for the following information: |
| o sub-registry name |
| o interface name |
| o Class ID |
| o IIDs implemented |
| |
| The information obtained from the entry (specifically, the const char* |
| strings) remains valid for the life of the entry (i.e., until you |
| Release() it). |
| |
| Here is an example of code that uses this interface to dump the contents |
| of a mozIClassRegistry: |
| |
| mozIClassRegistry *reg = nsServiceManager::GetService( kIDRegistry ); |
| nsIEnumerator *enum; |
| reg->CreateEnumerator( "*", &enum ); |
| for ( enum->First(); !enum->IsDone(); enum->Next(); ) { |
| mozIClassRegistryEntry *entry; |
| enum->CurrentItem( &entry ); |
| const char *subreg; |
| const char *name; |
| nsCID cid; |
| int numIIDs; |
| entry->GetSubRegistryName( &subreg ); |
| entry->GetInterfaceName( &name ); |
| entry->GetClassID( &cid ); |
| entry->GetNumIIDs( &numIIDs ); |
| cout << subreg << "/" << name << " = " << cid.ToString() << endl; |
| for ( int i = 0; i < numIIDs; i++ ) { |
| nsIID iid; |
| entry->GetInterfaceID( i, &iid ); |
| cout << "/tIID[" << i << "] = " << iid.ToString() << endl; |
| } |
| entry->Release(); |
| } |
| enum->Release(); |
------------------------------------------------------------------------------*/
struct mozIClassRegistryEntry : public nsISupports {
NS_IMETHOD GetSubRegistryName( const char **result ) = 0;
NS_IMETHOD GetInterfaceName( const char **result ) = 0;
NS_IMETHOD GetClassID( nsCID *result ) = 0;
NS_IMETHOD GetNumIIDs( int *result ) = 0;
NS_IMETHOD GetInterfaceID( int n, nsIID *result ) = 0;
}; // mozIClassRegistryEntry
// {5D41A440-8E37-11d2-8059-00600811A9C3}
#define MOZ_ICLASSREGISTRY_IID { 0x5d41a440, 0x8e37, 0x11d2, { 0x80, 0x59, 0x0, 0x60, 0x8, 0x11, 0xa9, 0xc3 } }
// {D1B54831-AC07-11d2-805E-00600811A9C3}
#define MOZ_ICLASSREGISTRYENTRY_IID { 0xd1b54831, 0xac07, 0x11d2, { 0x80, 0x5e, 0x0, 0x60, 0x8, 0x11, 0xa9, 0xc3 } }
#endif

View File

@@ -0,0 +1,326 @@
/* -*- 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 "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 __mozIRegistry_h
#define __mozIRegistry_h
#include "nsISupports.h"
class nsIEnumerator;
/*------------------------------- mozIRegistry ---------------------------------
| This interface provides access to a tree of arbitrary values. |
| |
| Each node of the tree contains either a value or a subtree or both. |
| |
| The value at any of these leaf nodes can be any of these "primitive" types: |
| o string (null terminated UTF string) |
| o array of 32-bit integers |
| o arbitrary array of bytes |
| o file identifier |
| Of course, since you can store an arbitrary array of bytes, you can put |
| any data you like into a registry (although you have the burden of |
| encoding/decoding your data in that case). |
| |
| Each branch of the tree is labelled with a string "key." The entire path |
| from a given point of the tree to another point further down can be |
| presented as a single string composed of each branch's label, concatenated |
| to the next, with an intervening forward slash ('/'). The term "key" |
| refers to both specific tree branch labels and to such concatenated paths. |
| |
| The branches from a given node must have unique labels. Distinct nodes can |
| have branches with the same label. |
| |
| For example, here's a small registry tree: |
| | |
| /\ |
| / \ |
| / \ |
| / \ |
| "Classes" "Users" |
| / \ |
| / \ |
| / ["joe"] |
| / / \ |
| | / \ |
| /\ / \ |
| / \ "joe" "bob" |
| / \ / \ |
| / \ |
| "{xxxx-xx-1}" "{xxxx-xx-2}" ["c:/joe"] ["d:/Robert"] |
| | | |
| /\ /\ |
| / \ / \ |
| / \ / \ |
| "Library" "Version" "Library" "Version" |
| / \ / \ |
| ["foo.dll"] 2 ["bar.dll"] 1 |
| |
| In this example, there are 2 keys under the root: "Classes" and "Users". |
| The first denotes a subtree only (which has two subtrees, ...). The second |
| denotes both a value ["joe"] and two subtrees labelled "joe" and "bob". |
| The value at the node "/Users" is ["joe"], at "/Users/bob" is ["d:/Robert"]. |
| The value at "/Classes/{xxxx-xx-1}/Version" is 2. |
| |
| The registry interface provides functions that let you navigate the tree |
| and manipulate it's contents. |
| |
| Please note that the registry itself does not impose any structure or |
| meaning on the contents of the tree. For example, the registry doesn't |
| control whether the value at the key "/Users" is the label for the subtree |
| with information about the last active user. That meaning is applied by |
| the code that stores these values and uses them for that purpose. |
| |
| [Any resemblence between this example and actual contents of any actual |
| registry is purely coincidental.] |
------------------------------------------------------------------------------*/
struct mozIRegistry : public nsISupports {
/*------------------------------ Constants ---------------------------------
| The following enumerated types and values are used by the registry |
| interface. |
--------------------------------------------------------------------------*/
typedef enum {
String = 1,
Int32,
Bytes,
File
} DataType;
/*-------------------------------- Types -----------------------------------
| The following data types are used by this interface. All are basically |
| opaque types. You obtain objects of these types via certain member |
| function calls and re-use them later (without having to know what they |
| contain). |
| |
| Key - Placeholder to represent a particular node in a registry |
| tree. There are 3 enumerated values that correspond to |
| specific nodes: |
| Common - Where most stuff goes. |
| Users - Special subtree to hold info about |
| "users"; if you don't know what goes |
| here, don't mess with it. |
| CurrentUser - Subtree under Users corresponding to |
| whatever user is designed the "current" |
| one; see note above. |
| You can specify any of these enumerated values as "keys" |
| on any member function that takes a mozRegistry::Key. |
| ValueInfo - Structure describing a registry value. |
--------------------------------------------------------------------------*/
typedef uint32 Key;
enum { Users = 1, Common = 2, CurrentUser = 3 };
struct ValueInfo {
DataType type;
uint32 length;
};
/*--------------------------- Opening/Closing ------------------------------
| These functions open the specified registry file (Open() with a non-null |
| argument) or the default "standard" registry file (Open() with a null |
| argument or OpenDefault()). |
| |
| Once opened, you can access the registry contents via the read/write |
| or query functions. |
| |
| The registry file will be closed automatically when the registry object |
| is destroyed. You can close the file prior to that by using the |
| Close() function. |
--------------------------------------------------------------------------*/
NS_IMETHOD Open( const char *regFile = 0 ) = 0;
NS_IMETHOD OpenDefault() = 0;
NS_IMETHOD Close() = 0;
/*----------------------- Reading/Writing Values ---------------------------
| These functions read/write the registry values at a given node. |
| |
| All functions require you to specify where in the registry key to |
| get/set the value. The location is specified using two components: |
| o A "base key" indicating where to start from; this is a value of type |
| mozIRegistry::Key. You use either one of the special "root" key |
| values or a subkey obtained via some other member function call. |
| o A "relative path," expressed as a sequence of subtree names |
| separated by forward slashes. This path describes how to get from |
| the base key to the node at which you want to store the data. This |
| component can be a null pointer which means the value goes directly |
| at the node denoted by the base key. |
| |
| When you request a value of a given type, the data stored at the |
| specified node must be of the type requested. If not, an error results. |
| |
| GetString - Obtains a newly allocated copy of a string type value. The |
| caller is obligated to free the returned string using |
| PR_Free. |
| SetString - Stores the argument string at the specified node. |
| GetInt - Obtains an int32 value at the specified node. The result |
| is returned into an int32 location you specify. |
| SetInt - Stores a given int32 value at a node. |
| GetBytes - Obtains a byte array value; this returns both an allocated |
| array of bytes and a length (necessary because there may be |
| embedded null bytes in the array). You must free the |
| resulting array using PR_Free. |
| SetBytes - Stores a given array of bytes; you specify the bytes via a |
| pointer and a length. |
| GetIntArray - Obtains the array of int32 values stored at a given node. |
| The result is composed of two values: a pointer to an |
| array of integer values (which must be freed using |
| PR_Free) and the number of elements in that array. |
| SetIntArray - Stores a set of int32 values at a given node. You must |
| provide a pointer to the array and the number of entries. |
--------------------------------------------------------------------------*/
NS_IMETHOD GetString( Key baseKey, const char *path, char **result ) = 0;
NS_IMETHOD SetString( Key baseKey, const char *path, const char *value ) = 0;
NS_IMETHOD GetInt( Key baseKey, const char *path, int32 *result ) = 0;
NS_IMETHOD SetInt( Key baseKey, const char *path, int32 value ) = 0;
NS_IMETHOD GetBytes( Key baseKey, const char *path, void **result, uint32 *len ) = 0;
NS_IMETHOD SetBytes( Key baseKey, const char *path, void *value, uint32 len ) = 0;
NS_IMETHOD GetIntArray( Key baseKey, const char *path, int32 **result, uint32 *len ) = 0;
NS_IMETHOD SetIntArray( Key baseKey, const char *path, const int32 *value, uint32 len ) = 0;
/*------------------------------ Navigation --------------------------------
| These functions let you navigate through the registry tree, querying |
| its contents. |
| |
| As above, all these functions requires a starting tree location ("base |
| key") specified as a mozIRegistry::Key. Some also require a path |
| name to locate the registry node location relative to this base key. |
| |
| AddSubtree - Adds a new registry subtree at the specified |
| location. Returns the resulting key in |
| the location specified by the third argument |
| (unless that pointer is 0). |
| RemoveNode - Removes the specified registry subtree or |
| value at the specified location. |
| GetSubtree - Returns a mozIRegistry::Key that can be used |
| to refer to the specified registry location. |
| EnumerateSubtrees - Returns a nsIEnumerator object that you can |
| use to enumerate all the subtrees descending |
| from a specified location. You must free the |
| enumerator via Release() when you're done with |
| it. |
| EnumerateAllSubtrees - Like EnumerateSubtrees, but will recursively |
| enumerate lower-level subtrees, too. |
| GetValueInfo - Returns a uint32 value that designates the type |
| of data stored at this location in the registry; |
| the possible values are defined by the enumerated |
| type mozIRegistry::DataType. |
| GetValueLength - Returns a uint32 value that indicates the length |
| of this registry value; the length is the number |
| of characters (for Strings), the number of bytes |
| (for Bytes), or the number of int32 values (for |
| Int32). |
| EnumerateValues - Returns a nsIEnumerator that you can use to |
| enumerate all the value nodes descending from |
| a specified location. |
--------------------------------------------------------------------------*/
NS_IMETHOD AddSubtree( Key baseKey, const char *path, Key *result ) = 0;
NS_IMETHOD RemoveSubtree( Key baseKey, const char *path ) = 0;
NS_IMETHOD GetSubtree( Key baseKey, const char *path, Key *result ) = 0;
NS_IMETHOD EnumerateSubtrees( Key baseKey, nsIEnumerator **result ) = 0;
NS_IMETHOD EnumerateAllSubtrees( Key baseKey, nsIEnumerator **result ) = 0;
NS_IMETHOD GetValueType( Key baseKey, const char *path, uint32 *result ) = 0;
NS_IMETHOD GetValueLength( Key baseKey, const char *path, uint32 *result ) = 0;
NS_IMETHOD EnumerateValues( Key baseKey, nsIEnumerator **result ) = 0;
/*------------------------------ User Name ---------------------------------
| These functions manipulate the current "user name." This value controls |
| the behavior of certain registry functions (namely, ?). |
| |
| GetCurrentUserName allocates a copy of the current user name (which the |
| caller should free using PR_Free). |
--------------------------------------------------------------------------*/
NS_IMETHOD GetCurrentUserName( char **result ) = 0;
NS_IMETHOD SetCurrentUserName( const char *name ) = 0;
/*------------------------------ Utilities ---------------------------------
| Various utility functions: |
| |
| Pack() is used to compress the contents of an open registry file. |
--------------------------------------------------------------------------*/
NS_IMETHOD Pack() = 0;
}; // mozIRegistry
/*----------------------------- mozIRegistryNode -------------------------------
| This interface is implemented by all the objects obtained from the |
| nsIEnumerators that mozIRegistry provides when you call either of the |
| subtree enumeration functions EnumerateSubtrees or EnumerateAllSubtrees. |
| |
| You can call this function to get the name of this subtree. This is the |
| relative path from the base key from which you got this interface. |
| |
| GetName - Returns the path name of this node; this is the relative path |
| from the base key from which this subtree was obtained. The |
| function allocates a copy of the name; the caller must free it |
| using PR_Free. |
------------------------------------------------------------------------------*/
struct mozIRegistryNode : public nsISupports {
NS_IMETHOD GetName( char **result ) = 0;
}; // mozIRegistryNode
/*----------------------------- mozIRegistryValue ------------------------------
| This interface is implemented by the objects obtained from the |
| nsIEnumerators that mozIRegistry provides when you call the |
| EnumerateValues function. An object supporting this interface is |
| returned when you call the CurrentItem() function on that enumerator. |
| |
| You use the member functions of this interface to obtain information |
| about each registry value. |
| |
| GetName - Returns the path name of this node; this is the relative |
| path\ from the base key from which this value was obtained. |
| The function allocates a copy of the name; the caller must |
| subsequently free it via PR_Free. |
| GetValueType - Returns (into a location provided by the caller) the type |
| of the value; the types are defined by the enumerated |
| type mozIRegistry::DataType. |
| GetValueLength - Returns a uint32 value that indicates the length |
| of this registry value; the length is the number |
| of characters (for Strings), the number of bytes |
| (for Bytes), or the number of int32 values (for |
| Int32). |
------------------------------------------------------------------------------*/
struct mozIRegistryValue : public nsISupports {
NS_IMETHOD GetName( char **result ) = 0;
NS_IMETHOD GetValueType( uint32 *result ) = 0;
NS_IMETHOD GetValueLength( uint32 *result ) = 0;
}; // mozIRegistryEntry
/*------------------------------- Error Codes ----------------------------------
------------------------------------------------------------------------------*/
#define NS_ERROR_REG_BADTYPE NS_ERROR_GENERATE_FAILURE( NS_ERROR_MODULE_REG, 1 )
#define NS_ERROR_REG_NO_MORE NS_ERROR_GENERATE_SUCCESS( NS_ERROR_MODULE_REG, 2 )
#define NS_ERROR_REG_NOT_FOUND NS_ERROR_GENERATE_FAILURE( NS_ERROR_MODULE_REG, 3 )
#define NS_ERROR_REG_NOFILE NS_ERROR_GENERATE_FAILURE( NS_ERROR_MODULE_REG, 4 )
#define NS_ERROR_REG_BUFFER_TOO_SMALL NS_ERROR_GENERATE_FAILURE( NS_ERROR_MODULE_REG, 5 )
#define NS_ERROR_REG_NAME_TOO_LONG NS_ERROR_GENERATE_FAILURE( NS_ERROR_MODULE_REG, 6 )
#define NS_ERROR_REG_NO_PATH NS_ERROR_GENERATE_FAILURE( NS_ERROR_MODULE_REG, 7 )
#define NS_ERROR_REG_READ_ONLY NS_ERROR_GENERATE_FAILURE( NS_ERROR_MODULE_REG, 8 )
#define NS_ERROR_REG_BAD_UTF8 NS_ERROR_GENERATE_FAILURE( NS_ERROR_MODULE_REG, 9 )
// {5D41A440-8E37-11d2-8059-00600811A9C3}
#define MOZ_IREGISTRY_IID { 0x5d41a440, 0x8e37, 0x11d2, { 0x80, 0x59, 0x0, 0x60, 0x8, 0x11, 0xa9, 0xc3 } }
// {D1B54831-AC07-11d2-805E-00600811A9C3}
#define MOZ_IREGISTRYNODE_IID { 0xd1b54831, 0xac07, 0x11d2, { 0x80, 0x5e, 0x0, 0x60, 0x8, 0x11, 0xa9, 0xc3 } }
// {5316C380-B2F8-11d2-A374-0080C6F80E4B}
#define MOZ_IREGISTRYVALUE_IID { 0x5316c380, 0xb2f8, 0x11d2, { 0xa3, 0x74, 0x0, 0x80, 0xc6, 0xf8, 0xe, 0x4b } }
#endif

View File

@@ -0,0 +1,170 @@
/* -*- 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.
*/
#ifndef nsAgg_h___
#define nsAgg_h___
#include "nsISupports.h"
/**
* Outer objects can implement nsIOuter if they choose, allowing them to
* get notification if their inner objects (children) are effectively freed.
* This allows them to reset any state associated with the inner object and
* potentially unload it.
*/
class nsIOuter : public nsISupports {
public:
/**
* This method is called whenever an inner object's refcount is about to
* become zero and the inner object should be released by the outer. This
* allows the outer to clean up any state associated with the inner and
* potentially unload the inner object. This method should call
* inner->Release().
*/
NS_IMETHOD
ReleaseInner(nsISupports* inner) = 0;
};
#define NS_IOUTER_IID \
{ /* ea0bf9f0-3d67-11d2-8163-006008119d7a */ \
0xea0bf9f0, \
0x3d67, \
0x11d2, \
{0x81, 0x63, 0x00, 0x60, 0x08, 0x11, 0x9d, 0x7a} \
}
////////////////////////////////////////////////////////////////////////////////
// Put this in your class's declaration:
#define NS_DECL_AGGREGATED \
NS_DECL_ISUPPORTS \
\
protected: \
\
/* You must implement this operation instead of the nsISupports */ \
/* methods if you inherit from nsAggregated. */ \
NS_IMETHOD \
AggregatedQueryInterface(const nsIID& aIID, void** aInstancePtr); \
\
class Internal : public nsISupports { \
public: \
\
Internal() {} \
\
NS_IMETHOD QueryInterface(const nsIID& aIID, \
void** aInstancePtr); \
NS_IMETHOD_(nsrefcnt) AddRef(void); \
NS_IMETHOD_(nsrefcnt) Release(void); \
\
}; \
\
friend class Internal; \
\
nsISupports* fOuter; \
Internal fAggregated; \
\
nsISupports* GetInner(void) { return &fAggregated; } \
\
public: \
// Put this in your class's constructor:
#define NS_INIT_AGGREGATED(outer) \
PR_BEGIN_MACRO \
NS_INIT_REFCNT(); \
fOuter = outer; \
PR_END_MACRO
// Put this in your class's implementation file:
#define NS_IMPL_AGGREGATED(_class) \
NS_IMETHODIMP \
_class::QueryInterface(const nsIID& aIID, void** aInstancePtr) \
{ \
/* try our own interfaces first before delegating to outer */ \
nsresult rslt = AggregatedQueryInterface(aIID, aInstancePtr); \
if (rslt != NS_OK && fOuter) \
return fOuter->QueryInterface(aIID, aInstancePtr); \
else \
return rslt; \
} \
\
NS_IMETHODIMP_(nsrefcnt) \
_class::AddRef(void) \
{ \
++mRefCnt; /* keep track of our refcount as well as outer's */ \
if (fOuter) \
return NS_ADDREF(fOuter); \
else \
return mRefCnt; \
} \
\
NS_IMETHODIMP_(nsrefcnt) \
_class::Release(void) \
{ \
if (fOuter) { \
nsISupports* outer = fOuter; /* in case we release ourself */ \
nsIOuter* outerIntf; \
static NS_DEFINE_IID(kIOuterIID, NS_IOUTER_IID); \
if (mRefCnt == 1 && \
outer->QueryInterface(kIOuterIID, \
(void**)&outerIntf) == NS_OK) { \
outerIntf->ReleaseInner(GetInner()); \
outerIntf->Release(); \
} \
else \
--mRefCnt; /* keep track of our refcount as well as outer's */ \
return outer->Release(); \
} \
else { \
if (--mRefCnt == 0) { \
delete this; \
return 0; \
} \
return mRefCnt; \
} \
} \
\
NS_IMETHODIMP \
_class::Internal::QueryInterface(const nsIID& aIID, void** aInstancePtr) \
{ \
_class* agg = (_class*)((char*)(this) - offsetof(_class, fAggregated)); \
return agg->AggregatedQueryInterface(aIID, aInstancePtr); \
} \
\
NS_IMETHODIMP_(nsrefcnt) \
_class::Internal::AddRef(void) \
{ \
_class* agg = (_class*)((char*)(this) - offsetof(_class, fAggregated)); \
return ++agg->mRefCnt; \
} \
\
NS_IMETHODIMP_(nsrefcnt) \
_class::Internal::Release(void) \
{ \
_class* agg = (_class*)((char*)(this) - offsetof(_class, fAggregated)); \
if (--agg->mRefCnt == 0) { \
delete agg; \
return 0; \
} \
return agg->mRefCnt; \
} \
#endif /* nsAgg_h___ */

View File

@@ -0,0 +1,493 @@
/* -*- 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 nsCOMPtr_h___
#define nsCOMPtr_h___
// Wrapping includes can speed up compiles (see "Large Scale C++ Software Design")
#ifndef nsDebug_h___
#include "nsDebug.h"
// for |NS_PRECONDITION|
#endif
#ifndef nsISupports_h___
#include "nsISupports.h"
// for |nsresult|, |NS_ADDREF|, et al
#endif
/*
Having problems?
See the User Manual at:
<http://www.meer.net/ScottCollins/doc/nsCOMPtr.html>, or
<http://www.mozilla.org/projects/xpcom/nsCOMPtr.html>
*/
/*
TO DO...
+ make StartAssignment optionally inlined
+ make constructor for |nsQueryInterface| explicit (suddenly construct/assign from raw pointer becomes illegal)
+ Improve internal documentation
+ mention *&
+ alternatives for comparison
+ do_QueryInterface
*/
/*
WARNING:
This file defines several macros for internal use only. These macros begin with the
prefix |NSCAP_|. Do not use these macros in your own code. They are for internal use
only for cross-platform compatibility, and are subject to change without notice.
*/
/*
Set up some |#define|s to turn off a couple of troublesome C++ features.
Interestingly, none of the compilers barf on template stuff. These are set up automatically
by the autoconf system for all Unixes. (Temporarily, I hope) I have to define them
myself for Mac and Windows.
*/
// under Metrowerks (Mac), we don't have autoconf yet
#ifdef __MWERKS__
#define HAVE_CPP_USING
#define HAVE_CPP_EXPLICIT
#define HAVE_CPP_NEW_CASTS
#endif
// under VC++ (Windows), we don't have autoconf yet
#ifdef _MSC_VER
#define HAVE_CPP_EXPLICIT
#define HAVE_CPP_USING
#define HAVE_CPP_NEW_CASTS
#if (_MSC_VER<1100)
// before 5.0, VC++ couldn't handle explicit
#undef HAVE_CPP_EXPLICIT
#elif (_MSC_VER==1100)
// VC++5.0 has an internal compiler error (sometimes) without this
#undef HAVE_CPP_USING
#endif
#define NSCAP_FEATURE_INLINE_STARTASSIGNMENT
// under VC++, we win by inlining StartAssignment
#endif
/*
If the compiler doesn't support |explicit|, we'll just make it go away, trusting
that the builds under compilers that do have it will keep us on the straight and narrow.
*/
#ifndef HAVE_CPP_EXPLICIT
#define explicit
#endif
#ifdef HAVE_CPP_NEW_CASTS
#define NSCAP_REINTERPRET_CAST(T,x) reinterpret_cast<T>(x)
#else
#define NSCAP_REINTERPRET_CAST(T,x) ((T)(x))
#endif
#ifdef NSCAP_FEATURE_DEBUG_MACROS
#define NSCAP_ADDREF(ptr) NS_ADDREF(ptr)
#define NSCAP_RELEASE(ptr) NS_RELEASE(ptr)
#else
#define NSCAP_ADDREF(ptr) (ptr)->AddRef()
#define NSCAP_RELEASE(ptr) (ptr)->Release()
#endif
/*
WARNING:
VC++4.2 is very picky. To compile under VC++4.2, the classes must be defined
in an order that satisfies:
nsDerivedSafe < nsCOMPtr
nsDontAddRef < nsCOMPtr
nsCOMPtr < nsGetterAddRefs
The other compilers probably won't complain, so please don't reorder these
classes, on pain of breaking 4.2 compatibility.
*/
template <class T>
class nsDerivedSafe : public T
/*
No client should ever see or have to type the name of this class. It is the
artifact that makes it a compile-time error to call |AddRef| and |Release|
on a |nsCOMPtr|.
See |nsCOMPtr::operator->|, |nsCOMPtr::operator*|, et al.
*/
{
private:
#ifdef HAVE_CPP_USING
using T::AddRef;
using T::Release;
#else
NS_IMETHOD_(nsrefcnt) AddRef(void);
NS_IMETHOD_(nsrefcnt) Release(void);
#endif
void operator delete( void*, size_t ); // NOT TO BE IMPLEMENTED
// declaring |operator delete| private makes calling delete on an interface pointer a compile error
nsDerivedSafe<T>& operator=( const nsDerivedSafe<T>& ); // NOT TO BE IMPLEMENTED
// you may not call |operator=()| through a dereferenced |nsCOMPtr|, because you'd get the wrong one
};
#if !defined(HAVE_CPP_USING) && defined(NEED_CPP_UNUSED_IMPLEMENTATIONS)
template <class T>
nsrefcnt
nsDerivedSafe<T>::AddRef()
{
return 0;
}
template <class T>
nsrefcnt
nsDerivedSafe<T>::Release()
{
return 0;
}
#endif
template <class T>
struct nsDontQueryInterface
/*
...
*/
{
explicit
nsDontQueryInterface( T* aRawPtr )
: mRawPtr(aRawPtr)
{
// nothing else to do here
}
T* mRawPtr;
};
template <class T>
inline
nsDontQueryInterface<T>
dont_QueryInterface( T* aRawPtr )
{
return nsDontQueryInterface<T>(aRawPtr);
}
struct nsQueryInterface
{
explicit
nsQueryInterface( nsISupports* aRawPtr, nsresult* error = 0 )
: mRawPtr(aRawPtr),
mErrorPtr(error)
{
// nothing else to do here
}
nsISupports* mRawPtr;
nsresult* mErrorPtr;
};
inline
nsQueryInterface
do_QueryInterface( nsISupports* aRawPtr, nsresult* error = 0 )
{
return nsQueryInterface(aRawPtr, error);
}
template <class T>
struct nsDontAddRef
/*
...cooperates with |nsCOMPtr| to allow you to assign in a pointer _without_
|AddRef|ing it. You would rarely use this directly, but rather through the
machinery of |getter_AddRefs| in the argument list to functions that |AddRef|
their results before returning them to the caller.
See also |getter_AddRefs()| and |class nsGetterAddRefs|.
*/
{
explicit
nsDontAddRef( T* aRawPtr )
: mRawPtr(aRawPtr)
{
// nothing else to do here
}
T* mRawPtr;
};
// This call is now deprecated. Use |getter_AddRefs()| instead.
template <class T>
inline
nsDontAddRef<T>
dont_AddRef( T* aRawPtr )
/*
...makes typing easier, because it deduces the template type, e.g.,
you write |dont_AddRef(fooP)| instead of |nsDontAddRef<IFoo>(fooP)|.
*/
{
return nsDontAddRef<T>(aRawPtr);
}
template <class T>
inline
nsDontAddRef<T>
getter_AddRefs( T* aRawPtr )
{
return nsDontAddRef<T>(aRawPtr);
}
class nsCOMPtr_base
{
public:
nsCOMPtr_base( nsISupports* rawPtr = 0 )
: mRawPtr(rawPtr)
{
// nothing else to do here
}
~nsCOMPtr_base()
{
if ( mRawPtr )
NSCAP_RELEASE(mRawPtr);
}
NS_EXPORT void assign_with_AddRef( nsISupports* );
NS_EXPORT void assign_with_QueryInterface( nsISupports*, const nsIID&, nsresult* );
NS_EXPORT void** begin_assignment();
protected:
nsISupports* mRawPtr;
};
template <class T>
class nsCOMPtr : private nsCOMPtr_base
/*
...
*/
{
public:
typedef T element_type;
nsCOMPtr()
// : nsCOMPtr_base(0)
{
// nothing else to do here
}
nsCOMPtr( const nsQueryInterface& aSmartPtr )
// : nsCOMPtr_base(0)
{
assign_with_QueryInterface(aSmartPtr.mRawPtr, T::GetIID(), aSmartPtr.mErrorPtr);
}
nsCOMPtr( const nsDontAddRef<T>& aSmartPtr )
: nsCOMPtr_base(aSmartPtr.mRawPtr)
{
// nothing else to do here
}
nsCOMPtr( const nsDontQueryInterface<T>& aSmartPtr )
: nsCOMPtr_base(aSmartPtr.mRawPtr)
{
if ( mRawPtr )
NSCAP_ADDREF(mRawPtr);
}
nsCOMPtr( const nsCOMPtr<T>& aSmartPtr )
: nsCOMPtr_base(aSmartPtr.mRawPtr)
{
if ( mRawPtr )
NSCAP_ADDREF(mRawPtr);
}
nsCOMPtr<T>&
operator=( const nsQueryInterface& rhs )
{
assign_with_QueryInterface(rhs.mRawPtr, T::GetIID(), rhs.mErrorPtr);
return *this;
}
nsCOMPtr<T>&
operator=( const nsDontAddRef<T>& rhs )
{
if ( mRawPtr )
NSCAP_RELEASE(mRawPtr);
mRawPtr = rhs.mRawPtr;
return *this;
}
nsCOMPtr<T>&
operator=( const nsDontQueryInterface<T>& rhs )
{
assign_with_AddRef(rhs.mRawPtr);
return *this;
}
nsCOMPtr<T>&
operator=( const nsCOMPtr<T>& rhs )
{
assign_with_AddRef(rhs.mRawPtr);
return *this;
}
nsDerivedSafe<T>*
get() const
// returns a |nsDerivedSafe<T>*| to deny clients the use of |AddRef| and |Release|
{
return NSCAP_REINTERPRET_CAST(nsDerivedSafe<T>*, mRawPtr);
}
nsDerivedSafe<T>*
operator->() const
// returns a |nsDerivedSafe<T>*| to deny clients the use of |AddRef| and |Release|
{
NS_PRECONDITION(mRawPtr != 0, "You can't dereference a NULL nsCOMPtr with operator->().");
return get();
}
nsDerivedSafe<T>&
operator*() const
// returns a |nsDerivedSafe<T>*| to deny clients the use of |AddRef| and |Release|
{
NS_PRECONDITION(mRawPtr != 0, "You can't dereference a NULL nsCOMPtr with operator*().");
return *get();
}
operator nsDerivedSafe<T>*() const
{
return get();
}
#if 0
private:
friend class nsGetterAddRefs<T>;
/*
In a perfect world, the following member function, |StartAssignment|, would be private.
It is and should be only accessed by the closely related class |nsGetterAddRefs<T>|.
Unfortunately, some compilers---most notably VC++5.0---fail to grok the
friend declaration above or in any alternate acceptable form. So, physically
it will be public (until our compilers get smarter); but it is not to be
considered part of the logical public interface.
*/
#endif
T**
StartAssignment()
{
#ifndef NSCAP_FEATURE_INLINE_STARTASSIGNMENT
return NSCAP_REINTERPRET_CAST(T**, begin_assignment());
#else
if ( mRawPtr )
NSCAP_RELEASE(mRawPtr);
mRawPtr = 0;
return NSCAP_REINTERPRET_CAST(T**, &mRawPtr);
#endif
}
};
template <class T>
class nsGetterAddRefs
/*
...
This class is designed to be used for anonymous temporary objects in the
argument list of calls that return COM interface pointers, e.g.,
nsCOMPtr<IFoo> fooP;
...->QueryInterface(iid, nsGetterAddRefs<IFoo>(fooP))
...->QueryInterface(iid, getter_AddRefs(fooP))
When initialized with a |nsCOMPtr|, as in the example above, it returns
a |void**| (or |T**| if needed) that the outer call (|QueryInterface| in this
case) can fill in.
*/
{
public:
explicit
nsGetterAddRefs( nsCOMPtr<T>& aSmartPtr )
: mTargetSmartPtr(aSmartPtr)
{
// nothing else to do
}
operator void**()
{
// NS_PRECONDITION(mTargetSmartPtr != 0, "getter_AddRefs into no destination");
return NSCAP_REINTERPRET_CAST(void**, mTargetSmartPtr.StartAssignment());
}
T*&
operator*()
{
// NS_PRECONDITION(mTargetSmartPtr != 0, "getter_AddRefs into no destination");
return *(mTargetSmartPtr.StartAssignment());
}
operator T**()
{
// NS_PRECONDITION(mTargetSmartPtr != 0, "getter_AddRefs into no destination");
return mTargetSmartPtr.StartAssignment();
}
private:
nsCOMPtr<T>& mTargetSmartPtr;
};
template <class T>
inline
nsGetterAddRefs<T>
getter_AddRefs( nsCOMPtr<T>& aSmartPtr )
/*
Used around a |nsCOMPtr| when
...makes the class |nsGetterAddRefs<T>| invisible.
*/
{
return nsGetterAddRefs<T>(aSmartPtr);
}
#endif // !defined(nsCOMPtr_h___)

View File

@@ -0,0 +1,229 @@
/* -*- 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 "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 nsCom_h__
#define nsCom_h__
/*
* API Import/Export macros
*/
#ifdef _IMPL_NS_COM
#ifdef XP_PC
#define NS_COM _declspec(dllexport)
#elif defined(XP_MAC)
#define NS_COM __declspec(export)
#else /* !XP_PC */
#define NS_COM
#endif /* !XP_PC */
#else /* !_IMPL_NS_COM */
#ifdef XP_PC
#define NS_COM _declspec(dllimport)
#else /* !XP_PC */
#define NS_COM
#endif /* !XP_PC */
#endif /* !_IMPL_NS_COM */
/*
* DLL Export macro
*/
#if defined(XP_PC)
#define NS_EXPORT _declspec(dllexport)
#define NS_EXPORT_(type) _declspec(dllexport) type __stdcall
#define NS_IMETHOD_(type) virtual type __stdcall
#define NS_IMETHOD virtual nsresult __stdcall
#define NS_IMETHODIMP_(type) type __stdcall
#define NS_IMETHODIMP nsresult __stdcall
#define NS_METHOD_(type) type __stdcall
#define NS_METHOD nsresult __stdcall
#define NS_CALLBACK_(_type, _name) _type (__stdcall * _name)
#define NS_CALLBACK(_name) nsresult (__stdcall * _name)
#elif defined(XP_MAC)
#define NS_EXPORT __declspec(export)
#define NS_EXPORT_(type) __declspec(export) type
#define NS_IMETHOD_(type) virtual type
#define NS_IMETHOD virtual nsresult
#define NS_IMETHODIMP_(type) type
#define NS_IMETHODIMP nsresult
#define NS_METHOD_(type) type
#define NS_METHOD nsresult
#define NS_CALLBACK_(_type, _name) _type (* _name)
#define NS_CALLBACK(_name) nsresult (* _name)
#else /* !XP_PC && !XP_MAC */
#define NS_EXPORT
#define NS_EXPORT_(type) type
#define NS_IMETHOD_(type) virtual type
#define NS_IMETHOD virtual nsresult
#define NS_IMETHODIMP_(type) type
#define NS_IMETHODIMP nsresult
#define NS_METHOD_(type) type
#define NS_METHOD nsresult
#define NS_CALLBACK_(_type, _name) _type (* _name)
#define NS_CALLBACK(_name) nsresult (* _name)
#endif /* !XP_PC */
/* use these functions to associate get/set methods with a
C++ member variable
*/
#define NS_METHOD_GETTER(_method, _type, _member) \
_method(_type* aResult) \
{\
if (!aResult) return NS_ERROR_NULL_POINTER; \
*aResult = _member; \
return NS_OK; \
}
#define NS_METHOD_SETTER(_method, _type, _member) \
_method(_type aResult) \
{ \
_member = aResult; \
return NS_OK; \
}
/*
* special for strings to get/set char* strings
* using PL_strdup and PR_FREEIF
*/
#define NS_METHOD_GETTER_STR(_method,_member) \
_method(char* *aString)\
{\
if (!aString) return NS_ERROR_NULL_POINTER; \
*aString = PL_strdup(_member); \
return NS_OK; \
}
#define NS_METHOD_SETTER_STR(_method, _member) \
_method(char *aString)\
{\
PR_FREEIF(_member);\
if (aString) _member = PL_strdup(aString); \
else _member = nsnull;\
return NS_OK; \
}
/* Getter/Setter macros.
Usage:
NS_IMPL_[CLASS_]GETTER[_<type>](method, [type,] member);
NS_IMPL_[CLASS_]SETTER[_<type>](method, [type,] member);
NS_IMPL_[CLASS_]GETSET[_<type>]([class, ]postfix, [type,] member);
where:
CLASS_ - implementation is inside a class definition
(otherwise the class name is needed)
Do NOT use in publicly exported header files, because
the implementation may be included many times over.
Instead, use the non-CLASS_ version.
_<type> - For more complex (STR, IFACE) data types
(otherwise the simple data type is needed)
method - name of the method, such as GetWidth or SetColor
type - simple data type if required
member - class member variable such as m_width or mColor
class - the class name, such as Window or MyObject
postfix - Method part after Get/Set such as "Width" for "GetWidth"
Example:
class Window {
public:
NS_IMPL_CLASS_GETSET(Width, int, m_width);
NS_IMPL_CLASS_GETTER_STR(GetColor, m_color);
NS_IMETHOD SetColor(char *color);
private:
int m_width; // read/write
char *m_color; // readonly
};
// defined outside of class
NS_IMPL_SETTER_STR(Window::GetColor, m_color);
Questions/Comments to alecf@netscape.com
*/
/*
* Getter/Setter implementation within a class definition
*/
/* simple data types */
#define NS_IMPL_CLASS_GETTER(_method, _type, _member) \
NS_IMETHOD NS_METHOD_GETTER(_method, _type, _member)
#define NS_IMPL_CLASS_SETTER(_method, _type, _member) \
NS_IMETHOD NS_METHOD_SETTER(_method, _type, _member)
#define NS_IMPL_CLASS_GETSET(_postfix, _type, _member) \
NS_IMPL_CLASS_GETTER(Get##_postfix, _type, _member) \
NS_IMPL_CLASS_SETTER(Set##_postfix, _type, _member)
/* strings */
#define NS_IMPL_CLASS_GETTER_STR(_method, _member) \
NS_IMETHOD NS_METHOD_GETTER_STR(_method, _member)
#define NS_IMPL_CLASS_SETTER_STR(_method, _member) \
NS_IMETHOD NS_METHOD_SETTER_STR(_method, _member)
#define NS_IMPL_CLASS_GETSET_STR(_postfix, _member) \
NS_IMPL_CLASS_GETTER_STR(Get##_postfix, _member) \
NS_IMPL_CLASS_SETTER_STR(Set##_postfix, _member)
/* Getter/Setter implementation outside of a class definition */
/* simple data types */
#define NS_IMPL_GETTER(_method, _type, _member) \
NS_IMETHODIMP NS_METHOD_GETTER(_method, _type, _member)
#define NS_IMPL_SETTER(_method, _type, _member) \
NS_IMETHODIMP NS_METHOD_SETTER(_method, _type, _member)
#define NS_IMPL_GETSET(_class, _postfix, _type, _member) \
NS_IMPL_GETTER(_class::Get##_postfix, _type, _member) \
NS_IMPL_SETTER(_class::Set##_postfix, _type, _member)
/* strings */
#define NS_IMPL_GETTER_STR(_method, _member) \
NS_IMETHODIMP NS_METHOD_GETTER_STR(_method, _member)
#define NS_IMPL_SETTER_STR(_method, _member) \
NS_IMETHODIMP NS_METHOD_SETTER_STR(_method, _member)
#define NS_IMPL_GETSET_STR(_class, _postfix, _member) \
NS_IMPL_GETTER_STR(_class::Get##_postfix, _member) \
NS_IMPL_SETTER_STR(_class::Set##_postfix, _member)
#endif

View File

@@ -0,0 +1,183 @@
/* -*- 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 "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 nsDebug_h___
#define nsDebug_h___
#include "nsCom.h"
#include "prtypes.h"
#ifdef DEBUG
#define NS_DEBUG
#endif
/**
* Namespace for debugging methods. Note that your code must use the
* macros defined later in this file so that the debug code can be
* conditionally compiled out.
*/
/* in case this is included by a C file */
#ifdef __cplusplus
class nsDebug {
public:
// XXX add in log controls here
// XXX probably want printf type arguments
/**
* Abort the executing program. This works on all architectures.
*/
static NS_COM void Abort(const char* aFile, PRIntn aLine);
/**
* Break the executing program into the debugger.
*/
static NS_COM void Break(const char* aFile, PRIntn aLine);
/**
* Log a pre-condition message to the debug log
*/
static NS_COM void PreCondition(const char* aStr, const char* aExpr,
const char* aFile, PRIntn aLine);
/**
* Log a post-condition message to the debug log
*/
static NS_COM void PostCondition(const char* aStr, const char* aExpr,
const char* aFile, PRIntn aLine);
/**
* Log an assertion message to the debug log
*/
static NS_COM void Assertion(const char* aStr, const char* aExpr,
const char* aFile, PRIntn aLine);
/**
* Log a not-yet-implemented message to the debug log
*/
static NS_COM void NotYetImplemented(const char* aMessage,
const char* aFile, PRIntn aLine);
/**
* Log a not-reached message to the debug log
*/
static NS_COM void NotReached(const char* aMessage,
const char* aFile, PRIntn aLine);
/**
* Log an error message to the debug log. This call returns.
*/
static NS_COM void Error(const char* aMessage,
const char* aFile, PRIntn aLine);
/**
* Log a warning message to the debug log.
*/
static NS_COM void Warning(const char* aMessage,
const char* aFile, PRIntn aLine);
};
#ifdef NS_DEBUG
/**
* Test a precondition for truth. If the expression is not true then
* trigger a program failure.
*/
#define NS_PRECONDITION(expr,str) \
if (!(expr)) \
nsDebug::PreCondition(str, #expr, __FILE__, __LINE__)
/**
* Test an assertion for truth. If the expression is not true then
* trigger a program failure.
*/
#define NS_ASSERTION(expr,str) \
if (!(expr)) \
nsDebug::Assertion(str, #expr, __FILE__, __LINE__)
/**
* Test an assertion for truth. If the expression is not true then
* trigger a program failure. The expression will still be
* executed in release mode.
*/
#define NS_VERIFY(expr,str) \
if (!(expr)) \
nsDebug::Assertion(str, #expr, __FILE__, __LINE__)
/**
* Test a post-condition for truth. If the expression is not true then
* trigger a program failure.
*/
#define NS_POSTCONDITION(expr,str) \
if (!(expr)) \
nsDebug::PostCondition(str, #expr, __FILE__, __LINE__)
/**
* This macros triggers a program failure if executed. It indicates that
* an attempt was made to execute some unimplimented functionality.
*/
#define NS_NOTYETIMPLEMENTED(str) \
nsDebug::NotYetImplemented(str, __FILE__, __LINE__)
/**
* This macros triggers a program failure if executed. It indicates that
* an attempt was made to execute some unimplimented functionality.
*/
#define NS_NOTREACHED(str) \
nsDebug::NotReached(str, __FILE__, __LINE__)
/**
* Log an error message.
*/
#define NS_ERROR(str) \
nsDebug::Error(str, __FILE__, __LINE__)
/**
* Log a warning message.
*/
#define NS_WARNING(str) \
nsDebug::Warning(str, __FILE__, __LINE__)
/**
* Trigger an abort
*/
#define NS_ABORT() \
nsDebug::Abort(__FILE__, __LINE__)
/**
* Cause a break
*/
#define NS_BREAK() \
nsDebug::Break(__FILE__, __LINE__)
#else /* NS_DEBUG */
#define NS_PRECONDITION(expr,str) {}
#define NS_ASSERTION(expr,str) {}
#define NS_VERIFY(expr,str) expr
#define NS_POSTCONDITION(expr,str) {}
#define NS_NOTYETIMPLEMENTED(str) {}
#define NS_NOTREACHED(str) {}
#define NS_ERROR(str) {}
#define NS_WARNING(str) {}
#define NS_ABORT() {}
#define NS_BREAK() {}
#endif /* ! NS_DEBUG */
#endif /* __cplusplus */
#endif /* nsDebug_h___ */

View File

@@ -0,0 +1,85 @@
/* -*- 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.
*/
#ifndef nsRDFCursorUtils_h__
#define nsRDFCursorUtils_h__
#include "nsIEnumerator.h"
#include "nsISupportsArray.h"
class NS_COM nsArrayEnumerator : public nsISimpleEnumerator
{
public:
// nsISupports interface
NS_DECL_ISUPPORTS
// nsISimpleEnumerator interface
NS_IMETHOD HasMoreElements(PRBool* aResult);
NS_IMETHOD GetNext(nsISupports** aResult);
// nsRDFArrayEnumerator methods
nsArrayEnumerator(nsISupportsArray* aValueArray);
virtual ~nsArrayEnumerator(void);
protected:
nsISupportsArray* mValueArray;
PRInt32 mIndex;
};
////////////////////////////////////////////////////////////////////////////////
class NS_COM nsSingletonEnumerator : public nsISimpleEnumerator
{
public:
NS_DECL_ISUPPORTS
// nsISimpleEnumerator methods
NS_IMETHOD HasMoreElements(PRBool* aResult);
NS_IMETHOD GetNext(nsISupports** aResult);
nsSingletonEnumerator(nsISupports* aValue);
virtual ~nsSingletonEnumerator();
protected:
nsISupports* mValue;
PRBool mConsumed;
};
////////////////////////////////////////////////////////////////////////////////
class NS_COM nsAdapterEnumerator : public nsISimpleEnumerator
{
public:
NS_DECL_ISUPPORTS
// nsISimpleEnumerator methods
NS_IMETHOD HasMoreElements(PRBool* aResult);
NS_IMETHOD GetNext(nsISupports** aResult);
nsAdapterEnumerator(nsIEnumerator* aEnum);
virtual ~nsAdapterEnumerator();
protected:
nsIEnumerator* mEnum;
nsISupports* mCurrent;
PRBool mStarted;
};
////////////////////////////////////////////////////////////////////////
#endif /* nsRDFCursorUtils_h__ */

View File

@@ -0,0 +1,195 @@
/* -*- 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 "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 nsError_h
#define nsError_h
#ifndef prtypes_h___
#include "prtypes.h"
#endif
/**
* Generic result data type
*/
typedef PRUint32 nsresult;
/*
* To add error code to your module, you need to do the following:
*
* 1) Add a module offset code. Add yours to the bottom of the list
* right below this comment, adding 1.
*
* 2) In your module, define a header file which uses one of the
* NE_ERROR_GENERATExxxxxx macros. Some examples below:
*
* #define NS_ERROR_MYMODULE_MYERROR1 NS_ERROR_GENERATE(NS_ERROR_SEVERITY_ERROR,NS_ERROR_MODULE_MYMODULE,1)
* #define NS_ERROR_MYMODULE_MYERROR2 NS_ERROR_GENERATE_SUCCESS(NS_ERROR_MODULE_MYMODULE,2)
* #define NS_ERROR_MYMODULE_MYERROR3 NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_MYMODULE,3)
*
*/
/**
* @name Standard Module Offset Code. Each Module should identify a unique number
* and then all errors associated with that module become offsets from the
* base associated with that module id. There are 16 bits of code bits for
* each module.
*/
#define NS_ERROR_MODULE_XPCOM 1
#define NS_ERROR_MODULE_BASE 2
#define NS_ERROR_MODULE_GFX 3
#define NS_ERROR_MODULE_WIDGET 4
#define NS_ERROR_MODULE_CALENDAR 5
#define NS_ERROR_MODULE_NETWORK 6
#define NS_ERROR_MODULE_PLUGINS 7
#define NS_ERROR_MODULE_LAYOUT 8
#define NS_ERROR_MODULE_HTMLPARSER 9
#define NS_ERROR_MODULE_RDF 10
#define NS_ERROR_MODULE_UCONV 11
#define NS_ERROR_MODULE_REG 12
#define NS_ERROR_MODULE_FILES 13
#define NS_ERROR_MODULE_MAILNEWS 16
#define NS_ERROR_MODULE_EDITOR 17
/**
* @name Standard Error Handling Macros
*/
#define NS_FAILED(_nsresult) ((_nsresult) & 0x80000000)
#define NS_SUCCEEDED(_nsresult) (!((_nsresult) & 0x80000000))
/**
* @name Severity Code. This flag identifies the level of warning
*/
#define NS_ERROR_SEVERITY_SUCCESS 0
#define NS_ERROR_SEVERITY_ERROR 1
/**
* @name Mozilla Code. This flag separates consumers of mozilla code
* from the native platform
*/
#define NS_ERROR_MODULE_BASE_OFFSET 0x45
/**
* @name Standard Error Generating Macros
*/
#define NS_ERROR_GENERATE(sev,module,code) \
((nsresult) (((PRUint32)(sev)<<31) | ((PRUint32)(module+NS_ERROR_MODULE_BASE_OFFSET)<<16) | ((PRUint32)(code))) )
#define NS_ERROR_GENERATE_SUCCESS(module,code) \
((nsresult) (((PRUint32)(NS_ERROR_SEVERITY_SUCCESS)<<31) | ((PRUint32)(module+NS_ERROR_MODULE_BASE_OFFSET)<<16) | ((PRUint32)(code))) )
#define NS_ERROR_GENERATE_FAILURE(module,code) \
((nsresult) (((PRUint32)(NS_ERROR_SEVERITY_ERROR)<<31) | ((PRUint32)(module+NS_ERROR_MODULE_BASE_OFFSET)<<16) | ((PRUint32)(code))) )
/**
* @name Standard Macros for retrieving error bits
*/
#if PR_BYTES_PER_INT == 4
#define NS_IS_ERROR(err) (((nsresult)(err))<0)
#else
#define NS_IS_ERROR(err) (((((PRUint32)(err)) >> 31) & 0x1) == NS_ERROR_SEVERITY_ERROR)
#endif
#define NS_ERROR_GET_CODE(err) ((err) & 0xffff)
#define NS_ERROR_GET_MODULE(err) (((((err) >> 16) - NS_ERROR_MODULE_BASE_OFFSET) & 0x1fff))
#define NS_ERROR_GET_SEVERITY(err) (((err) >> 31) & 0x1)
/**
* @name Standard return values
*/
/*@{*/
/* Standard "it worked" return value */
#define NS_OK 0
/* The backwards COM false */
#define NS_COMFALSE 1
#define NS_ERROR_BASE ((nsresult) 0xC1F30000)
/* Returned when an instance is not initialized */
#define NS_ERROR_NOT_INITIALIZED (NS_ERROR_BASE + 1)
/* Returned when an instance is already initialized */
#define NS_ERROR_ALREADY_INITIALIZED (NS_ERROR_BASE + 2)
/* Returned by a not implemented function */
#define NS_ERROR_NOT_IMPLEMENTED ((nsresult) 0x80004001L)
/* Returned when a given interface is not supported. */
#define NS_NOINTERFACE ((nsresult) 0x80004002L)
#define NS_ERROR_NO_INTERFACE NS_NOINTERFACE
#define NS_ERROR_INVALID_POINTER ((nsresult) 0x80004003L)
#define NS_ERROR_NULL_POINTER NS_ERROR_INVALID_POINTER
/* Returned when a function aborts */
#define NS_ERROR_ABORT ((nsresult) 0x80004004L)
/* Returned when a function fails */
#define NS_ERROR_FAILURE ((nsresult) 0x80004005L)
/* Returned when an unexpected error occurs */
#define NS_ERROR_UNEXPECTED ((nsresult) 0x8000ffffL)
/* Returned when a memory allocation failes */
#define NS_ERROR_OUT_OF_MEMORY ((nsresult) 0x8007000eL)
/* Returned when an illegal value is passed */
#define NS_ERROR_ILLEGAL_VALUE ((nsresult) 0x80070057L)
#define NS_ERROR_INVALID_ARG NS_ERROR_ILLEGAL_VALUE
/* Returned when a class doesn't allow aggregation */
#define NS_ERROR_NO_AGGREGATION ((nsresult) 0x80040110L)
/* Returned when a class doesn't allow aggregation */
#define NS_ERROR_NOT_AVAILABLE ((nsresult) 0x80040111L)
/* Returned when a class is not registered */
#define NS_ERROR_FACTORY_NOT_REGISTERED ((nsresult) 0x80040154L)
/* Returned when a dynamically loaded factory couldn't be found */
#define NS_ERROR_FACTORY_NOT_LOADED ((nsresult) 0x800401f8L)
/* Returned when a factory doesn't support signatures */
#define NS_ERROR_FACTORY_NO_SIGNATURE_SUPPORT \
(NS_ERROR_BASE + 0x101)
/* Returned when a factory already is registered */
#define NS_ERROR_FACTORY_EXISTS (NS_ERROR_BASE + 0x100)
/*@}*/
////////////////////////////////////////////////////////////////////////////////
#ifdef XP_PC
#pragma warning(disable: 4251) // 'nsCOMPtr<class nsIInputStream>' needs to have dll-interface to be used by clients of class 'nsInputStream'
#pragma warning(disable: 4275) // non dll-interface class 'nsISupports' used as base for dll-interface class 'nsIRDFNode'
#endif
#endif

View File

@@ -0,0 +1,168 @@
/* -*- 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 "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 nsHashtable_h__
#define nsHashtable_h__
#include "plhash.h"
#include "prlock.h"
#include "nsCom.h"
class NS_COM nsHashKey {
protected:
nsHashKey(void);
public:
virtual ~nsHashKey(void);
virtual PRUint32 HashValue(void) const = 0;
virtual PRBool Equals(const nsHashKey *aKey) const = 0;
virtual nsHashKey *Clone(void) const = 0;
};
// Enumerator callback function. Use
typedef PRBool (*nsHashtableEnumFunc)(nsHashKey *aKey, void *aData, void* closure);
class NS_COM nsHashtable {
protected:
// members
PLHashTable *hashtable;
PRLock *mLock;
public:
nsHashtable(PRUint32 aSize = 256, PRBool threadSafe = PR_FALSE);
~nsHashtable();
PRInt32 Count(void) { return hashtable->nentries; }
PRBool Exists(nsHashKey *aKey);
void *Put(nsHashKey *aKey, void *aData);
void *Get(nsHashKey *aKey);
void *Remove(nsHashKey *aKey);
nsHashtable *Clone();
void Enumerate(nsHashtableEnumFunc aEnumFunc, void* closure = NULL);
void Reset();
};
////////////////////////////////////////////////////////////////////////////////
// nsISupportsKey: Where keys are nsISupports objects that get refcounted.
#include "nsISupports.h"
class nsISupportsKey : public nsHashKey {
protected:
nsISupports* mKey;
public:
nsISupportsKey(nsISupports* key) {
mKey = key;
NS_IF_ADDREF(mKey);
}
~nsISupportsKey(void) {
NS_IF_RELEASE(mKey);
}
PRUint32 HashValue(void) const {
return (PRUint32)mKey;
}
PRBool Equals(const nsHashKey *aKey) const {
return (mKey == ((nsISupportsKey *) aKey)->mKey);
}
nsHashKey *Clone(void) const {
return new nsISupportsKey(mKey);
}
};
////////////////////////////////////////////////////////////////////////////////
// nsVoidKey: Where keys are void* objects that don't get refcounted.
class nsVoidKey : public nsHashKey {
protected:
const void* mKey;
public:
nsVoidKey(const void* key) {
mKey = key;
}
PRUint32 HashValue(void) const {
return (PRUint32)mKey;
}
PRBool Equals(const nsHashKey *aKey) const {
return (mKey == ((const nsVoidKey *) aKey)->mKey);
}
nsHashKey *Clone(void) const {
return new nsVoidKey(mKey);
}
};
////////////////////////////////////////////////////////////////////////////////
// nsIDKey: Where keys are nsIDs (e.g. nsIID, nsCID).
#include "nsID.h"
class nsIDKey : public nsHashKey {
protected:
nsID mID;
public:
nsIDKey(const nsID &aID) {
mID = aID;
}
PRUint32 HashValue(void) const {
return mID.m0;
}
PRBool Equals(const nsHashKey *aKey) const {
return (mID.Equals(((const nsIDKey *) aKey)->mID));
}
nsHashKey *Clone(void) const {
return new nsIDKey(mID);
}
};
////////////////////////////////////////////////////////////////////////////////
// nsCStringKey: Where keys are char*'s
// Some uses: hashing ProgIDs, filenames, URIs
#include "plstr.h"
class NS_COM nsCStringKey : public nsHashKey {
protected:
char mBuf[64];
char* mStr;
public:
nsCStringKey(const char* str);
~nsCStringKey(void);
PRUint32 HashValue(void) const;
PRBool Equals(const nsHashKey* aKey) const;
nsHashKey* Clone() const;
};
#endif

View File

@@ -0,0 +1,110 @@
/* -*- 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.
*/
#ifndef nsIAllocator_h___
#define nsIAllocator_h___
#include "nsISupports.h"
/**
* Unlike IMalloc, this interface returns nsresults and doesn't
* implement the problematic GetSize and DidAlloc routines.
*/
#define NS_IALLOCATOR_IID \
{ /* 56def700-b1b9-11d2-8177-006008119d7a */ \
0x56def700, \
0xb1b9, \
0x11d2, \
{0x81, 0x77, 0x00, 0x60, 0x08, 0x11, 0x9d, 0x7a} \
}
class nsIAllocator : public nsISupports {
public:
static const nsIID& GetIID() { static nsIID iid = NS_IALLOCATOR_IID; return iid; }
/**
* Allocates a block of memory of a particular size.
*
* @param size - the size of the block to allocate
* @result the block of memory
*/
NS_IMETHOD_(void*) Alloc(PRUint32 size) = 0;
/**
* Reallocates a block of memory to a new size.
*
* @param ptr - the block of memory to reallocate
* @param size - the new size
* @param oldSize - the current size of the block. If -1 (the default),
* the implementation must be able to determine the block size by
* examining the block pointer.
* @result the rellocated block of memory
*/
NS_IMETHOD_(void*) Realloc(void* ptr, PRUint32 size,
PRInt32 oldSize = -1) = 0;
/**
* Frees a block of memory.
*
* @param ptr - the block of memory to free
* @param size - the size of the block to be freed. If -1 (the default),
* the implementation must be able to determine the block size by
* examining the block pointer.
*/
NS_IMETHOD Free(void* ptr, PRInt32 size = -1) = 0;
/**
* Attempts to shrink the heap.
*/
NS_IMETHOD HeapMinimize(void) = 0;
};
// To get the global memory manager service:
#define NS_ALLOCATOR_CID \
{ /* aafe6770-b1bb-11d2-8177-006008119d7a */ \
0xaafe6770, \
0xb1bb, \
0x11d2, \
{0x81, 0x77, 0x00, 0x60, 0x08, 0x11, 0x9d, 0x7a} \
}
/*
* Public shortcuts to the shared allocator's methods
*/
class nsAllocator
{
public:
static NS_EXPORT void* Alloc(PRUint32 size);
static NS_EXPORT void* Realloc(void* ptr, PRUint32 size);
static NS_EXPORT void Free(void* ptr);
static NS_EXPORT void HeapMinimize();
static NS_EXPORT void* Clone(const void* ptr, PRUint32 size);
private:
nsAllocator(); // not implemented
static PRBool EnsureAllocator() {return mAllocator || FetchAllocator();}
static PRBool FetchAllocator();
static nsIAllocator* mAllocator;
};
////////////////////////////////////////////////////////////////////////////////
#endif /* nsIAllocator_h___ */

View File

@@ -0,0 +1,80 @@
/* -*- 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 specifzic 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 nsICollection_h___
#define nsICollection_h___
#include "nsISupports.h"
class nsIEnumerator;
// IID for the nsICollection interface
#define NS_ICOLLECTION_IID \
{ /* 83b6019c-cbc4-11d2-8cca-0060b0fc14a3 */ \
0x83b6019c, \
0xcbc4, \
0x11d2, \
{0x8c, 0xca, 0x00, 0x60, 0xb0, 0xfc, 0x14, 0xa3} \
}
// IID for the nsICollection Factory interface
#define NS_ICOLLECTIONFACTORY_IID \
{ 0xf8052641, 0x8768, 0x11d2, \
{ 0x8f, 0x39, 0x0, 0x60, 0x8, 0x31, 0x1, 0x94 } }
//----------------------------------------------------------------------
/** nsICollection Interface
* this may be ordered or not. a list or array, the implementation is opaque
*/
class nsICollection : public nsISupports {
public:
static const nsIID& GetIID(void) { static nsIID iid = NS_ICOLLECTION_IID; return iid; }
/** Return the count of elements in the collection.
*/
NS_IMETHOD_(PRUint32) Count(void) const = 0;
/**
* AppendElement will take an ISupports and keep track of it
* @param aItem is the Item to be added WILL BE ADDREFFED
* @return NS_OK if successfully added
* @return NS_ERROR_FAILURE otherwise
*/
NS_IMETHOD AppendElement(nsISupports *aItem) = 0;
/** RemoveElement will take an nsISupports and remove it from the collection
* @param aItem is the item to be removed WILL BE RELEASED
* @return NS_OK if successfully added
* @return NS_ERROR_FAILURE otherwise
*/
NS_IMETHOD RemoveElement(nsISupports *aItem) = 0;
/** Return an enumeration for the collection.
*/
NS_IMETHOD Enumerate(nsIEnumerator* *result) = 0;
/** Clear will clear all items from list
*/
NS_IMETHOD Clear(void) = 0;
};
#endif /* nsICollection_h___ */

View File

@@ -0,0 +1,230 @@
/* -*- 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 "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 nsIComponentManager_h__
#define nsIComponentManager_h__
#include "prtypes.h"
#include "nsCom.h"
#include "nsID.h"
#include "nsError.h"
#include "nsISupports.h"
#include "nsIFactory.h"
/*
* Prototypes for dynamic library export functions. Your DLL/DSO needs to export
* these methods to play in the component world.
*/
extern "C" NS_EXPORT nsresult NSGetFactory(nsISupports* aServMgr,
const nsCID &aClass,
const char *aClassName,
const char *aProgID,
nsIFactory **aFactory);
extern "C" NS_EXPORT PRBool NSCanUnload(nsISupports* aServMgr);
extern "C" NS_EXPORT nsresult NSRegisterSelf(nsISupports* aServMgr, const char *fullpath);
extern "C" NS_EXPORT nsresult NSUnregisterSelf(nsISupports* aServMgr, const char *fullpath);
typedef nsresult (*nsFactoryProc)(nsISupports* aServMgr,
const nsCID &aClass,
const char *aClassName,
const char *aProgID,
nsIFactory **aFactory);
typedef PRBool (*nsCanUnloadProc)(nsISupports* aServMgr);
typedef nsresult (*nsRegisterProc)(nsISupports* aServMgr, const char *path);
typedef nsresult (*nsUnregisterProc)(nsISupports* aServMgr, const char *path);
#define NS_ICOMPONENTMANAGER_IID \
{ /* 8458a740-d5dc-11d2-92fb-00e09805570f */ \
0x8458a740, \
0xd5dc, \
0x11d2, \
{0x92, 0xfb, 0x00, 0xe0, 0x98, 0x05, 0x57, 0x0f} \
}
#define NS_COMPONENTMANAGER_CID \
{ /* 91775d60-d5dc-11d2-92fb-00e09805570f */ \
0x91775d60, \
0xd5dc, \
0x11d2, \
{0x92, 0xfb, 0x00, 0xe0, 0x98, 0x05, 0x57, 0x0f} \
}
/*
* nsIComponentManager interface
*/
class nsIComponentManager : public nsISupports {
public:
NS_DEFINE_STATIC_IID_ACCESSOR(NS_ICOMPONENTMANAGER_IID)
NS_IMETHOD FindFactory(const nsCID &aClass,
nsIFactory **aFactory) = 0;
// Finds a class ID for a specific Program ID
NS_IMETHOD ProgIDToCLSID(const char *aProgID,
nsCID *aClass) = 0;
// Finds a Program ID for a specific class ID
// caller frees the result with delete[]
NS_IMETHOD CLSIDToProgID(nsCID *aClass,
char* *aClassName,
char* *aProgID) = 0;
// Creates a class instance for a specific class ID
NS_IMETHOD CreateInstance(const nsCID &aClass,
nsISupports *aDelegate,
const nsIID &aIID,
void **aResult) = 0;
// Convenience routine, creates a class instance for a specific ProgID
NS_IMETHOD CreateInstance(const char *aProgID,
nsISupports *aDelegate,
const nsIID &aIID,
void **aResult) = 0;
// Manually registry a factory for a class
NS_IMETHOD RegisterFactory(const nsCID &aClass,
const char *aClassName,
const char *aProgID,
nsIFactory *aFactory,
PRBool aReplace) = 0;
// Manually register a dynamically loaded component.
NS_IMETHOD RegisterComponent(const nsCID &aClass,
const char *aClassName,
const char *aProgID,
const char *aLibrary,
PRBool aReplace,
PRBool aPersist) = 0;
// Manually unregister a factory for a class
NS_IMETHOD UnregisterFactory(const nsCID &aClass,
nsIFactory *aFactory) = 0;
// Manually unregister a dynamically loaded component
NS_IMETHOD UnregisterComponent(const nsCID &aClass,
const char *aLibrary) = 0;
// Unload dynamically loaded factories that are not in use
NS_IMETHOD FreeLibraries(void) = 0;
//////////////////////////////////////////////////////////////////////////////
// DLL registration support
// Autoregistration will try only files with these extensions.
// All extensions are case insensitive.
// ".dll", // Windows
// ".dso", // Unix
// ".so", // Unix
// ".sl", // Unix: HP
// ".shlb", // Mac
// ".dlm", // new for all platforms
//
// Directory and fullname are what NSPR will accept. For eg.
// MAC /Hard drive/mozilla/dist/bin
// WIN y:\Hard drive\mozilla\dist\bin (or) y:/Hard drive/mozilla/dist/bin
// UNIX /Hard drive/mozilla/dist/bin
//
enum RegistrationTime {
NS_Startup = 0,
NS_Script = 1,
NS_Timer = 2
};
NS_IMETHOD AutoRegister(RegistrationTime when, const char* directory) = 0;
NS_IMETHOD AutoRegisterComponent(RegistrationTime when, const char *fullname) = 0;
};
////////////////////////////////////////////////////////////////////////////////
extern NS_COM nsresult
NS_GetGlobalComponentManager(nsIComponentManager* *result);
////////////////////////////////////////////////////////////////////////////////
// Global Static Component Manager Methods
// (for when you need to link with xpcom)
class NS_COM nsComponentManager {
public:
static nsresult Initialize(void);
// Finds a factory for a specific class ID
static nsresult FindFactory(const nsCID &aClass,
nsIFactory **aFactory);
// Finds a class ID for a specific Program ID
static nsresult ProgIDToCLSID(const char *aProgID,
nsCID *aClass);
// Finds a Program ID for a specific class ID
// caller frees the result with delete[]
static nsresult CLSIDToProgID(nsCID *aClass,
char* *aClassName,
char* *aProgID);
// Creates a class instance for a specific class ID
static nsresult CreateInstance(const nsCID &aClass,
nsISupports *aDelegate,
const nsIID &aIID,
void **aResult);
// Convenience routine, creates a class instance for a specific ProgID
static nsresult CreateInstance(const char *aProgID,
nsISupports *aDelegate,
const nsIID &aIID,
void **aResult);
// Manually registry a factory for a class
static nsresult RegisterFactory(const nsCID &aClass,
const char *aClassName,
const char *aProgID,
nsIFactory *aFactory,
PRBool aReplace);
// Manually register a dynamically loaded component.
static nsresult RegisterComponent(const nsCID &aClass,
const char *aClassName,
const char *aProgID,
const char *aLibrary,
PRBool aReplace,
PRBool aPersist);
// Manually unregister a factory for a class
static nsresult UnregisterFactory(const nsCID &aClass,
nsIFactory *aFactory);
// Manually unregister a dynamically loaded component
static nsresult UnregisterComponent(const nsCID &aClass,
const char *aLibrary);
// Unload dynamically loaded factories that are not in use
static nsresult FreeLibraries(void);
//////////////////////////////////////////////////////////////////////////////
// DLL registration support
static nsresult AutoRegister(nsIComponentManager::RegistrationTime when,
const char* directory);
static nsresult AutoRegisterComponent(nsIComponentManager::RegistrationTime when,
const char *fullname);
};
////////////////////////////////////////////////////////////////////////////////
#endif

101
mozilla/xpcom/public/nsID.h Normal file
View File

@@ -0,0 +1,101 @@
/* -*- 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 "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 nsID_h__
#define nsID_h__
#include "prtypes.h"
#include "string.h"
#include "nsCom.h"
/**
* A "unique identifier". This is modeled after OSF DCE UUIDs.
*/
struct nsID {
/**
* @name Indentifier values
*/
//@{
PRUint32 m0;
PRUint16 m1;
PRUint16 m2;
PRUint8 m3[8];
//@}
/**
* @name Methods
*/
//@{
/**
* Equivalency method. Compares this nsID with another.
* @return <b>PR_TRUE</b> if they are the same, <b>PR_FALSE</b> if not.
*/
inline PRBool Equals(const nsID& other) const {
return (PRBool)
((((PRUint32*) &m0)[0] == ((PRUint32*) &other.m0)[0]) &&
(((PRUint32*) &m0)[1] == ((PRUint32*) &other.m0)[1]) &&
(((PRUint32*) &m0)[2] == ((PRUint32*) &other.m0)[2]) &&
(((PRUint32*) &m0)[3] == ((PRUint32*) &other.m0)[3]));
}
/**
* nsID Parsing method. Turns a {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}
* string into an nsID
*/
NS_COM PRBool Parse(char *aIDStr);
/**
* nsID string encoder. Returns an allocated string in
* {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} format. Caller should free string.
*/
NS_COM char* ToString() const;
//@}
};
/**
* Declare an ID. If NS_IMPL_IDS is set, a variable <i>_name</i> is declared
* with the given values, otherwise <i>_name</i> is declared as an
* <tt>extern</tt> variable.
*/
#ifdef NS_IMPL_IDS
#define NS_DECLARE_ID(_name,m0,m1,m2,m30,m31,m32,m33,m34,m35,m36,m37) \
extern "C" const nsID _name = {m0,m1,m2,{m30,m31,m32,m33,m34,m35,m36,m37}}
#else
#define NS_DECLARE_ID(_name,m0,m1,m2,m30,m31,m32,m33,m34,m35,m36,m37) \
extern "C" const nsID _name
#endif
/*
* Class IDs
*/
typedef nsID nsCID;
// Define an CID
#define NS_DEFINE_CID(_name, _cidspec) \
const nsCID _name = _cidspec
#define REFNSCID const nsCID&
#endif

View File

@@ -0,0 +1,120 @@
/* -*- 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 "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 nsIEnumerator_h___
#define nsIEnumerator_h___
#include "nsISupports.h"
// {D1899240-F9D2-11d2-BDD6-000064657374}
#define NS_ISIMPLEENUMERATOR_IID \
{ 0xd1899240, 0xf9d2, 0x11d2, { 0xbd, 0xd6, 0x0, 0x0, 0x64, 0x65, 0x73, 0x74 } }
class nsISimpleEnumerator : public nsISupports {
public:
static const nsIID& GetIID(void) { static nsIID iid = NS_ISIMPLEENUMERATOR_IID; return iid; }
NS_IMETHOD HasMoreElements(PRBool* aResult) = 0;
NS_IMETHOD GetNext(nsISupports** aResult) = 0;
};
extern "C" NS_COM nsresult
NS_NewEmptyEnumerator(nsISimpleEnumerator** aResult);
#define NS_IENUMERATOR_IID \
{ /* ad385286-cbc4-11d2-8cca-0060b0fc14a3 */ \
0xad385286, \
0xcbc4, \
0x11d2, \
{0x8c, 0xca, 0x00, 0x60, 0xb0, 0xfc, 0x14, 0xa3} \
}
class nsIEnumerator : public nsISupports {
public:
static const nsIID& GetIID(void) { static nsIID iid = NS_IENUMERATOR_IID; return iid; }
/** First will reset the list. will return NS_FAILED if no items
*/
NS_IMETHOD First(void) = 0;
/** Next will advance the list. will return failed if already at end
*/
NS_IMETHOD Next(void) = 0;
/** CurrentItem will return the CurrentItem item it will fail if the list is empty
* @param aItem return value
*/
NS_IMETHOD CurrentItem(nsISupports **aItem) = 0;
/** return if the collection is at the end. that is the beginning following a call to Prev
* and it is the end of the list following a call to next
* @param aItem return value
*/
NS_IMETHOD IsDone(void) = 0;
};
#define NS_IBIDIRECTIONALENUMERATOR_IID \
{ /* 75f158a0-cadd-11d2-8cca-0060b0fc14a3 */ \
0x75f158a0, \
0xcadd, \
0x11d2, \
{0x8c, 0xca, 0x00, 0x60, 0xb0, 0xfc, 0x14, 0xa3} \
}
class nsIBidirectionalEnumerator : public nsIEnumerator {
public:
static const nsIID& GetIID(void) { static nsIID iid = NS_IBIDIRECTIONALENUMERATOR_IID; return iid; }
/** Last will reset the list to the end. will return NS_FAILED if no items
*/
NS_IMETHOD Last(void) = 0;
/** Prev will decrement the list. will return failed if already at beginning
*/
NS_IMETHOD Prev(void) = 0;
};
// Construct and return an implementation of a "conjoining enumerator." This
// enumerator lets you string together two other enumerators into one sequence.
// The result is an nsIBidirectionalEnumerator, but if either input is not
// also bidirectional, the Last and Prev operations will fail.
extern "C" NS_COM nsresult
NS_NewConjoiningEnumerator(nsIEnumerator* first, nsIEnumerator* second,
nsIBidirectionalEnumerator* *aInstancePtrResult);
// Construct and return an implementation of a "union enumerator." This
// enumerator will only return elements that are found in both constituent
// enumerators.
extern "C" NS_COM nsresult
NS_NewUnionEnumerator(nsIEnumerator* first, nsIEnumerator* second,
nsIEnumerator* *aInstancePtrResult);
// Construct and return an implementation of an "intersection enumerator." This
// enumerator will return elements that are found in either constituent
// enumerators, eliminating duplicates.
extern "C" NS_COM nsresult
NS_NewIntersectionEnumerator(nsIEnumerator* first, nsIEnumerator* second,
nsIEnumerator* *aInstancePtrResult);
#endif // __nsIEnumerator_h

View File

@@ -0,0 +1,47 @@
/* -*- 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 "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.
*/
#ifndef nsIEventQueueService_h__
#define nsIEventQueueService_h__
#include "nsISupports.h"
#include "prthread.h"
#include "plevent.h"
/* a6cf90dc-15b3-11d2-932e-00805f8add32 */
#define NS_IEVENTQUEUESERVICE_IID \
{ 0xa6cf90dc, 0x15b3, 0x11d2, \
{0x93, 0x2e, 0x00, 0x80, 0x5f, 0x8a, 0xdd, 0x32} }
class nsIEventQueueService : public nsISupports
{
public:
NS_IMETHOD CreateThreadEventQueue(void) = 0;
NS_IMETHOD DestroyThreadEventQueue(void) = 0;
NS_IMETHOD GetThreadEventQueue(PRThread* aThread, PLEventQueue** aResult) = 0;
#ifdef XP_MAC
// This is ment to be temporary until something better is worked out
NS_IMETHOD ProcessEvents() = 0;
#endif
};
#endif /* nsIEventQueueService_h___ */

View File

@@ -0,0 +1,45 @@
/* -*- 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 "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 __nsIFactory_h
#define __nsIFactory_h
#include "prtypes.h"
#include "nsISupports.h"
/*
* nsIFactory interface
*/
// {00000001-0000-0000-c000-000000000046}
#define NS_IFACTORY_IID \
{ 0x00000001, 0x0000, 0x0000, \
{ 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46 } }
class nsIFactory: public nsISupports {
public:
static const nsIID& GetIID() { static nsIID iid = NS_IFACTORY_IID; return iid; }
NS_IMETHOD CreateInstance(nsISupports *aOuter,
REFNSIID aIID,
void **aResult) = 0;
NS_IMETHOD LockFactory(PRBool aLock) = 0;
};
#endif

View File

@@ -0,0 +1,57 @@
/* -*- 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.
*/
#ifndef nsIGenericFactory_h___
#define nsIGenericFactory_h___
#include "nsIFactory.h"
// {3bc97f01-ccdf-11d2-bab8-b548654461fc}
#define NS_GENERICFACTORY_CID \
{ 0x3bc97f01, 0xccdf, 0x11d2, { 0xba, 0xb8, 0xb5, 0x48, 0x65, 0x44, 0x61, 0xfc } }
// {3bc97f00-ccdf-11d2-bab8-b548654461fc}
#define NS_IGENERICFACTORY_IID \
{ 0x3bc97f00, 0xccdf, 0x11d2, { 0xba, 0xb8, 0xb5, 0x48, 0x65, 0x44, 0x61, 0xfc } }
/**
* Provides a Generic nsIFactory implementation that can be used by
* DLLs with very simple factory needs.
*/
class nsIGenericFactory : public nsIFactory {
public:
static const nsIID& GetIID() { static nsIID iid = NS_IGENERICFACTORY_IID; return iid; }
typedef NS_CALLBACK(ConstructorProcPtr) (nsISupports *aOuter, REFNSIID aIID, void **aResult);
typedef NS_CALLBACK(DestructorProcPtr) (void);
/**
* Establishes the generic factory's constructor function, which will be called
* by CreateInstance.
*/
NS_IMETHOD SetConstructor(ConstructorProcPtr constructor) = 0;
/**
* Establishes the generic factory's destructor function, which will be called
* whe the generic factory is deleted. This is used to notify the DLL that
* an instance of one of its generic factories is going away.
*/
NS_IMETHOD SetDestructor(DestructorProcPtr destructor) = 0;
};
#endif /* nsIGenericFactory_h___ */

View File

@@ -0,0 +1,44 @@
/* -*- 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.
*/
#ifndef __nsIID_h
#define __nsIID_h
#include "nsID.h"
/**
* An "interface id" which can be used to uniquely identify a given
* interface.
*/
typedef nsID nsIID;
/**
* A macro shorthand for <tt>const nsIID&<tt>
*/
#define REFNSIID const nsIID&
/**
* Define an IID (obsolete)
*/
#define NS_DEFINE_IID(_name, _iidspec) \
const nsIID _name = _iidspec
#endif /* __nsIID_h */

View File

@@ -0,0 +1,142 @@
/* -*- 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 "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 nsIPtr_h___
#define nsIPtr_h___
#include "nsISupports.h"
/*
* nsIPtr is an "auto-release pointer" class for nsISupports based interfaces
*
* It's intent is to be a "set and forget" pointer to help with managing
* active references to nsISupports bases objects.
*
* The pointer object ensures that the underlying pointer is always
* released whenever the value is changed or when the object leaves scope.
*
* Proper care needs to be taken when assigning pointers to a nsIPtr.
* When asigning from a C pointer (nsISupports*), the pointer presumes
* an active reference and subsumes it. When assigning from another nsIPtr,
* a new reference is established.
*
* There are 3 ways to assign a value to a nsIPtr.
* 1) Direct construction or assignment from a C pointer.
* 2) Direct construction or assignment form another nsIPtr.
* 3) Usage of an "out parameter" method.
* a) AssignRef() releases the underlying pointer and returns a reference to it.
* Useful for pointer reference out paramaters.
* b) AssignPtr() releases the underlying pointer and returns a pointer to it.
* c) Query() releases the underlying pointer and returns a (void**) pointer to it.
* Useful for calls to QueryInterface()
* 4) The SetAddRef() method. This is equivalent to an assignment followed by an AddRef().
*
* examples:
*
* class It {
* void NS_NewFoo(nsIFoo** aFoo);
* nsIFoo* GetFoo(void);
* void GetBar(nsIBar*& aBar);
* };
*
* nsIFooPtr foo = it->GetFoo();
* nsIBarPtr bar;
*
* it->NS_NewFoo(foo.AssignPtr());
* it->GetBar(bar.AssignRef());
* it->QueryInterface(kIFooIID, foo.Query());
* bar.SetAddRef(new Bar());
*
* Advantages:
* Set and forget. Once a pointer is assigned to a nsIPtr, it is impossible
* to forget to release it.
* Always pre-initialized. You can't forget to initialize the pointer.
*
* Disadvantages:
* Usage of this class doesn't eliminate the need to think about ref counts
* and assign values properly, AddRef'ing as needed.
* The nsIPtr doesn't typecast exactly like a C pointer. In order to achieve
* typecasting, it may be necessary to first cast to a C pointer of the
* underlying type.
*
*/
#define NS_DEF_PTR(cls) \
class cls##Ptr { \
public: \
cls##Ptr(void) : mPtr(0) {} \
cls##Ptr(const cls##Ptr& aCopy) : mPtr(aCopy.mPtr) \
{ NS_IF_ADDREF(mPtr); } \
cls##Ptr(cls* aInterface) : mPtr(aInterface) {} \
~cls##Ptr(void) { NS_IF_RELEASE(mPtr); } \
cls##Ptr& operator=(const cls##Ptr& aCopy) \
{ if(mPtr == aCopy.mPtr) return *this; \
NS_IF_ADDREF(aCopy.mPtr); \
NS_IF_RELEASE(mPtr); \
mPtr = aCopy.mPtr; return *this; } \
cls##Ptr& operator=(cls* aInterface) \
{ if(mPtr == aInterface) return *this; \
NS_IF_RELEASE(mPtr); mPtr = aInterface; \
return *this; } \
cls##Ptr& operator=(PRInt32 aInt) \
{ NS_IF_RELEASE(mPtr); \
return *this; } \
void SetAddRef(cls* aInterface) \
{ if(aInterface == mPtr) return; \
NS_IF_ADDREF(aInterface); \
NS_IF_RELEASE(mPtr); mPtr = aInterface; } \
cls* AddRef(void) { NS_ADDREF(mPtr); return mPtr; } \
cls* IfAddRef(void) \
{ NS_IF_ADDREF(mPtr); return mPtr; } \
cls*& AssignRef(void) \
{ NS_IF_RELEASE(mPtr); return mPtr; } \
cls** AssignPtr(void) \
{ NS_IF_RELEASE(mPtr); return &mPtr; } \
void** Query(void) \
{ NS_IF_RELEASE(mPtr); return (void**)&mPtr; } \
PRBool IsNull() const \
{ return PRBool(0 == mPtr); } \
PRBool IsNotNull() const \
{ return PRBool(0 != mPtr); } \
PRBool operator==(const cls##Ptr& aCopy) const \
{ return PRBool(mPtr == aCopy.mPtr); } \
PRBool operator==(cls* aInterface) const \
{ return PRBool(mPtr == aInterface); } \
PRBool operator!=(const cls##Ptr& aCopy) const \
{ return PRBool(mPtr != aCopy.mPtr); } \
PRBool operator!=(cls* aInterface) const \
{ return PRBool(mPtr != aInterface); } \
cls* operator->(void) { return mPtr; } \
cls& operator*(void) { return *mPtr; } \
operator cls*(void) { return mPtr; } \
const cls* operator->(void) const { return mPtr; } \
const cls& operator*(void) const { return *mPtr; } \
operator const cls* (void) const { return mPtr; } \
private: \
void* operator new(size_t size) { return 0; } \
void operator delete(void* aPtr) {} \
cls* mPtr; \
public: \
friend inline PRBool operator==(const cls* aInterface, const cls##Ptr& aPtr) \
{ return PRBool(aInterface == aPtr.mPtr); } \
friend inline PRBool operator!=(const cls* aInterface, const cls##Ptr& aPtr) \
{ return PRBool(aInterface != aPtr.mPtr); } \
}
#endif // nsIPtr_h___

View File

@@ -0,0 +1,350 @@
/* -*- 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 "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 __nsIRegistry_h
#define __nsIRegistry_h
#include "nsISupports.h"
// {5D41A440-8E37-11d2-8059-00600811A9C3}
#define NS_IREGISTRY_IID { 0x5d41a440, 0x8e37, 0x11d2, { 0x80, 0x59, 0x0, 0x60, 0x8, 0x11, 0xa9, 0xc3 } }
#define NS_REGISTRY_PROGID "component://netscape/registry"
#define NS_REGISTRY_CLASSNAME "Mozilla Registry"
// {D1B54831-AC07-11d2-805E-00600811A9C3}
#define NS_IREGISTRYNODE_IID { 0xd1b54831, 0xac07, 0x11d2, { 0x80, 0x5e, 0x0, 0x60, 0x8, 0x11, 0xa9, 0xc3 } }
// {5316C380-B2F8-11d2-A374-0080C6F80E4B}
#define NS_IREGISTRYVALUE_IID { 0x5316c380, 0xb2f8, 0x11d2, { 0xa3, 0x74, 0x0, 0x80, 0xc6, 0xf8, 0xe, 0x4b } }
class nsIEnumerator;
/*-------------------------------- nsIRegistry ---------------------------------
| This interface provides access to a tree of arbitrary values. |
| |
| Each node of the tree contains either a value or a subtree or both. |
| |
| The value at any of these leaf nodes can be any of these "primitive" types: |
| o string (null terminated UTF string) |
| o array of 32-bit integers |
| o arbitrary array of bytes |
| o file identifier |
| Of course, since you can store an arbitrary array of bytes, you can put |
| any data you like into a registry (although you have the burden of |
| encoding/decoding your data in that case). |
| |
| Each branch of the tree is labelled with a string "key." The entire path |
| from a given point of the tree to another point further down can be |
| presented as a single string composed of each branch's label, concatenated |
| to the next, with an intervening forward slash ('/'). The term "key" |
| refers to both specific tree branch labels and to such concatenated paths. |
| |
| The branches from a given node must have unique labels. Distinct nodes can |
| have branches with the same label. |
| |
| For example, here's a small registry tree: |
| | |
| /\ |
| / \ |
| / \ |
| / \ |
| "Classes" "Users" |
| / \ |
| / \ |
| / ["joe"] |
| / / \ |
| | / \ |
| /\ / \ |
| / \ "joe" "bob" |
| / \ / \ |
| / \ |
| "{xxxx-xx-1}" "{xxxx-xx-2}" ["c:/joe"] ["d:/Robert"] |
| | | |
| /\ /\ |
| / \ / \ |
| / \ / \ |
| "Library" "Version" "Library" "Version" |
| / \ / \ |
| ["foo.dll"] 2 ["bar.dll"] 1 |
| |
| In this example, there are 2 keys under the root: "Classes" and "Users". |
| The first denotes a subtree only (which has two subtrees, ...). The second |
| denotes both a value ["joe"] and two subtrees labelled "joe" and "bob". |
| The value at the node "/Users" is ["joe"], at "/Users/bob" is ["d:/Robert"]. |
| The value at "/Classes/{xxxx-xx-1}/Version" is 2. |
| |
| The registry interface provides functions that let you navigate the tree |
| and manipulate it's contents. |
| |
| Please note that the registry itself does not impose any structure or |
| meaning on the contents of the tree. For example, the registry doesn't |
| control whether the value at the key "/Users" is the label for the subtree |
| with information about the last active user. That meaning is applied by |
| the code that stores these values and uses them for that purpose. |
| |
| [Any resemblence between this example and actual contents of any actual |
| registry is purely coincidental.] |
------------------------------------------------------------------------------*/
struct nsIRegistry : public nsISupports {
/*------------------------------ Constants ---------------------------------
| The following enumerated types and values are used by the registry |
| interface. |
--------------------------------------------------------------------------*/
typedef enum {
String = 1,
Int32,
Bytes,
File
} DataType;
/*-------------------------------- Types -----------------------------------
| The following data types are used by this interface. All are basically |
| opaque types. You obtain objects of these types via certain member |
| function calls and re-use them later (without having to know what they |
| contain). |
| |
| Key - Placeholder to represent a particular node in a registry |
| tree. There are 3 enumerated values that correspond to |
| specific nodes: |
| Common - Where most stuff goes. |
| Users - Special subtree to hold info about |
| "users"; if you don't know what goes |
| here, don't mess with it. |
| CurrentUser - Subtree under Users corresponding to |
| whatever user is designed the "current" |
| one; see note above. |
| You can specify any of these enumerated values as "keys" |
| on any member function that takes a nsRegistry::Key. |
| ValueInfo - Structure describing a registry value. |
--------------------------------------------------------------------------*/
typedef uint32 Key;
enum { Users = 1, Common = 2, CurrentUser = 3 };
struct ValueInfo {
DataType type;
uint32 length;
};
static const nsIID& GetIID() { static nsIID iid = NS_IREGISTRY_IID; return iid; }
/*--------------------------- Opening/Closing ------------------------------
| These functions open the specified registry file (Open() with a non-null |
| argument) or the default "standard" registry file (Open() with a null |
| argument or OpenDefault()). |
| |
| Once opened, you can access the registry contents via the read/write |
| or query functions. |
| |
| The registry file will be closed automatically when the registry object |
| is destroyed. You can close the file prior to that by using the |
| Close() function. |
--------------------------------------------------------------------------*/
NS_IMETHOD Open( const char *regFile = 0 ) = 0;
NS_IMETHOD OpenDefault() = 0;
NS_IMETHOD Close() = 0;
/*----------------------- Reading/Writing Values ---------------------------
| These functions read/write the registry values at a given node. |
| |
| All functions require you to specify where in the registry key to |
| get/set the value. The location is specified using two components: |
| o A "base key" indicating where to start from; this is a value of type |
| nsIRegistry::Key. You use either one of the special "root" key |
| values or a subkey obtained via some other member function call. |
| o A "relative path," expressed as a sequence of subtree names |
| separated by forward slashes. This path describes how to get from |
| the base key to the node at which you want to store the data. This |
| component can be a null pointer which means the value goes directly |
| at the node denoted by the base key. |
| |
| When you request a value of a given type, the data stored at the |
| specified node must be of the type requested. If not, an error results. |
| |
| GetString - Obtains a newly allocated copy of a string type value. The |
| caller is obligated to free the returned string using |
| PR_Free. |
| SetString - Stores the argument string at the specified node. |
| GetInt - Obtains an int32 value at the specified node. The result |
| is returned into an int32 location you specify. |
| SetInt - Stores a given int32 value at a node. |
| GetBytes - Obtains a byte array value; this returns both an allocated |
| array of bytes and a length (necessary because there may be |
| embedded null bytes in the array). You must free the |
| resulting array using PR_Free. |
| SetBytes - Stores a given array of bytes; you specify the bytes via a |
| pointer and a length. |
| GetIntArray - Obtains the array of int32 values stored at a given node. |
| The result is composed of two values: a pointer to an |
| array of integer values (which must be freed using |
| PR_Free) and the number of elements in that array. |
| SetIntArray - Stores a set of int32 values at a given node. You must |
| provide a pointer to the array and the number of entries. |
--------------------------------------------------------------------------*/
NS_IMETHOD GetString( Key baseKey, const char *path, char **result ) = 0;
NS_IMETHOD SetString( Key baseKey, const char *path, const char *value ) = 0;
NS_IMETHOD GetInt( Key baseKey, const char *path, int32 *result ) = 0;
NS_IMETHOD SetInt( Key baseKey, const char *path, int32 value ) = 0;
NS_IMETHOD GetBytes( Key baseKey, const char *path, void **result, uint32 *len ) = 0;
NS_IMETHOD SetBytes( Key baseKey, const char *path, void *value, uint32 len ) = 0;
NS_IMETHOD GetIntArray( Key baseKey, const char *path, int32 **result, uint32 *len ) = 0;
NS_IMETHOD SetIntArray( Key baseKey, const char *path, const int32 *value, uint32 len ) = 0;
/*------------------------------ Navigation --------------------------------
| These functions let you navigate through the registry tree, querying |
| its contents. |
| |
| As above, all these functions requires a starting tree location ("base |
| key") specified as a nsIRegistry::Key. Some also require a path |
| name to locate the registry node location relative to this base key. |
| |
| AddSubtree - Adds a new registry subtree at the specified |
| location. Returns the resulting key in |
| the location specified by the third argument |
| (unless that pointer is 0). |
| AddSubtreeRaw - Adds a new registry subtree at the specified |
| location. Returns the resulting key in |
| the location specified by the third argument |
| (unless that pointer is 0). |
| Does not interpret special chars in key names. |
| |
| RemoveSubtree - Removes the specified registry subtree or |
| value at the specified location. |
| RemoveSubtreeRaw - Removes the specified registry subtree or |
| value at the specified location. |
| Does not interpret special chars in key names. |
| |
| GetSubtree - Returns a nsIRegistry::Key that can be used |
| to refer to the specified registry location. |
| GetSubtreeRaw - Returns a nsIRegistry::Key that can be used |
| to refer to the specified registry location. |
| Does not interpret special chars in key names. |
| |
| EnumerateSubtrees - Returns a nsIEnumerator object that you can |
| use to enumerate all the subtrees descending |
| from a specified location. You must free the |
| enumerator via Release() when you're done with |
| it. |
| EnumerateAllSubtrees - Like EnumerateSubtrees, but will recursively |
| enumerate lower-level subtrees, too. |
| GetValueInfo - Returns a uint32 value that designates the type |
| of data stored at this location in the registry; |
| the possible values are defined by the enumerated |
| type nsIRegistry::DataType. |
| GetValueLength - Returns a uint32 value that indicates the length |
| of this registry value; the length is the number |
| of characters (for Strings), the number of bytes |
| (for Bytes), or the number of int32 values (for |
| Int32). |
| EnumerateValues - Returns a nsIEnumerator that you can use to |
| enumerate all the value nodes descending from |
| a specified location. |
--------------------------------------------------------------------------*/
NS_IMETHOD AddSubtree( Key baseKey, const char *path, Key *result ) = 0;
NS_IMETHOD RemoveSubtree( Key baseKey, const char *path ) = 0;
NS_IMETHOD GetSubtree( Key baseKey, const char *path, Key *result ) = 0;
NS_IMETHOD AddSubtreeRaw( Key baseKey, const char *keyname, Key *result ) = 0;
NS_IMETHOD RemoveSubtreeRaw( Key baseKey, const char *keyname ) = 0;
NS_IMETHOD GetSubtreeRaw( Key baseKey, const char *keyname, Key *result ) = 0;
NS_IMETHOD EnumerateSubtrees( Key baseKey, nsIEnumerator **result ) = 0;
NS_IMETHOD EnumerateAllSubtrees( Key baseKey, nsIEnumerator **result ) = 0;
NS_IMETHOD GetValueType( Key baseKey, const char *path, uint32 *result ) = 0;
NS_IMETHOD GetValueLength( Key baseKey, const char *path, uint32 *result ) = 0;
NS_IMETHOD EnumerateValues( Key baseKey, nsIEnumerator **result ) = 0;
/*------------------------------ User Name ---------------------------------
| These functions manipulate the current "user name." This value controls |
| the behavior of certain registry functions (namely, ?). |
| |
| GetCurrentUserName allocates a copy of the current user name (which the |
| caller should free using PR_Free). |
--------------------------------------------------------------------------*/
NS_IMETHOD GetCurrentUserName( char **result ) = 0;
NS_IMETHOD SetCurrentUserName( const char *name ) = 0;
/*------------------------------ Utilities ---------------------------------
| Various utility functions: |
| |
| Pack() is used to compress the contents of an open registry file. |
--------------------------------------------------------------------------*/
NS_IMETHOD Pack() = 0;
}; // nsIRegistry
/*------------------------------ nsIRegistryNode -------------------------------
| This interface is implemented by all the objects obtained from the |
| nsIEnumerators that nsIRegistry provides when you call either of the |
| subtree enumeration functions EnumerateSubtrees or EnumerateAllSubtrees. |
| |
| You can call this function to get the name of this subtree. This is the |
| relative path from the base key from which you got this interface. |
| |
| GetName - Returns the path name of this node; this is the relative path |
| from the base key from which this subtree was obtained. The |
| function allocates a copy of the name; the caller must free it |
| using PR_Free. |
------------------------------------------------------------------------------*/
struct nsIRegistryNode : public nsISupports {
NS_IMETHOD GetName( char **result ) = 0;
}; // nsIRegistryNode
/*------------------------------ nsIRegistryValue ------------------------------
| This interface is implemented by the objects obtained from the |
| nsIEnumerators that nsIRegistry provides when you call the |
| EnumerateValues function. An object supporting this interface is |
| returned when you call the CurrentItem() function on that enumerator. |
| |
| You use the member functions of this interface to obtain information |
| about each registry value. |
| |
| GetName - Returns the path name of this node; this is the relative |
| path\ from the base key from which this value was obtained. |
| The function allocates a copy of the name; the caller must |
| subsequently free it via PR_Free. |
| GetValueType - Returns (into a location provided by the caller) the type |
| of the value; the types are defined by the enumerated |
| type nsIRegistry::DataType. |
| GetValueLength - Returns a uint32 value that indicates the length |
| of this registry value; the length is the number |
| of characters (for Strings), the number of bytes |
| (for Bytes), or the number of int32 values (for |
| Int32). |
------------------------------------------------------------------------------*/
struct nsIRegistryValue : public nsISupports {
NS_IMETHOD GetName( char **result ) = 0;
NS_IMETHOD GetValueType( uint32 *result ) = 0;
NS_IMETHOD GetValueLength( uint32 *result ) = 0;
}; // nsIRegistryEntry
/*------------------------------- Error Codes ----------------------------------
------------------------------------------------------------------------------*/
#define NS_ERROR_REG_BADTYPE NS_ERROR_GENERATE_FAILURE( NS_ERROR_MODULE_REG, 1 )
#define NS_ERROR_REG_NO_MORE NS_ERROR_GENERATE_SUCCESS( NS_ERROR_MODULE_REG, 2 )
#define NS_ERROR_REG_NOT_FOUND NS_ERROR_GENERATE_FAILURE( NS_ERROR_MODULE_REG, 3 )
#define NS_ERROR_REG_NOFILE NS_ERROR_GENERATE_FAILURE( NS_ERROR_MODULE_REG, 4 )
#define NS_ERROR_REG_BUFFER_TOO_SMALL NS_ERROR_GENERATE_FAILURE( NS_ERROR_MODULE_REG, 5 )
#define NS_ERROR_REG_NAME_TOO_LONG NS_ERROR_GENERATE_FAILURE( NS_ERROR_MODULE_REG, 6 )
#define NS_ERROR_REG_NO_PATH NS_ERROR_GENERATE_FAILURE( NS_ERROR_MODULE_REG, 7 )
#define NS_ERROR_REG_READ_ONLY NS_ERROR_GENERATE_FAILURE( NS_ERROR_MODULE_REG, 8 )
#define NS_ERROR_REG_BAD_UTF8 NS_ERROR_GENERATE_FAILURE( NS_ERROR_MODULE_REG, 9 )
#endif

View File

@@ -0,0 +1,327 @@
/* -*- 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 nsIServiceManager_h___
#define nsIServiceManager_h___
#include "nsIComponentManager.h"
#include "nsID.h"
class nsIShutdownListener;
#define NS_ISERVICEMANAGER_IID \
{ /* cf0df3b0-3401-11d2-8163-006008119d7a */ \
0xcf0df3b0, \
0x3401, \
0x11d2, \
{0x81, 0x63, 0x00, 0x60, 0x08, 0x11, 0x9d, 0x7a} \
}
/**
* The nsIServiceManager manager interface provides a means to obtain
* global services in an application. The service manager depends on the
* repository to find and instantiate factories to obtain services.
*
* Users of the service manager must first obtain a pointer to the global
* service manager by calling NS_GetGlobalServiceManager. After that,
* they can request specific services by calling GetService. When they are
* finished with a service the release it by calling ReleaseService (instead
* of releasing the service object directly):
*
* nsICacheManager* cm;
* nsServiceManager::GetService(kCacheManagerCID, kICacheManagerIID, (nsISupports**)&cm);
*
* ... use cm, and then sometime later ...
*
* nsServiceManager::ReleaseService(kCacheManagerCID, cm);
*
* A user of a service may keep references to particular services indefinitely
* and only must call ReleaseService when it shuts down. However if the user
* wishes to voluntarily cooperate with the shutdown of the service it is
* using, it may supply an nsIShutdownListener to provide for asynchronous
* release of the services it is using. The shutdown listener's OnShutdown
* method will be called for a service that is being shut down, and it is
* its responsiblity to release references obtained from that service if at
* all possible.
*
* The process of shutting down a particular service is initiated by calling
* the service manager's ShutdownService method. This will iterate through
* all the registered shutdown listeners for the service being shut down, and
* then will attempt to unload the library associated with the service if
* possible. The status result of ShutdownService indicates whether the
* service was successfully shut down, failed, or was not in service.
*
* XXX QUESTIONS:
* - Should a "service" be more than nsISupports? Should it be a factory
* and/or have Startup(), Shutdown(), etc.
* - If the asynchronous OnShutdown operation gets called, does the user
* of a service still need to call ReleaseService? (Or should they _not_
* call it?)
*/
class nsIServiceManager : public nsISupports {
public:
NS_DEFINE_STATIC_IID_ACCESSOR(NS_ISERVICEMANAGER_IID);
/**
* RegisterService may be called explicitly to register a service
* with the service manager. If a service is not registered explicitly,
* the component manager will be used to create an instance according
* to the class ID specified.
*/
NS_IMETHOD
RegisterService(const nsCID& aClass, nsISupports* aService) = 0;
/**
* Requests a service to be shut down, possibly unloading its DLL.
*
* @returns NS_OK - if shutdown was successful and service was unloaded,
* @returns NS_ERROR_SERVICE_NOT_FOUND - if shutdown failed because
* the service was not currently loaded
* @returns NS_ERROR_SERVICE_IN_USE - if shutdown failed because some
* user of the service wouldn't voluntarily release it by using
* a shutdown listener.
*/
NS_IMETHOD
UnregisterService(const nsCID& aClass) = 0;
NS_IMETHOD
GetService(const nsCID& aClass, const nsIID& aIID,
nsISupports* *result,
nsIShutdownListener* shutdownListener = NULL) = 0;
NS_IMETHOD
ReleaseService(const nsCID& aClass, nsISupports* service,
nsIShutdownListener* shutdownListener = NULL) = 0;
////////////////////////////////////////////////////////////////////////////
// let's do it again, this time with ProgIDs...
NS_IMETHOD
RegisterService(const char* aProgID, nsISupports* aService) = 0;
NS_IMETHOD
UnregisterService(const char* aProgID) = 0;
NS_IMETHOD
GetService(const char* aProgID, const nsIID& aIID,
nsISupports* *result,
nsIShutdownListener* shutdownListener = NULL) = 0;
NS_IMETHOD
ReleaseService(const char* aProgID, nsISupports* service,
nsIShutdownListener* shutdownListener = NULL) = 0;
};
#define NS_ERROR_SERVICE_NOT_FOUND NS_ERROR_GENERATE_SUCCESS(NS_ERROR_MODULE_XPCOM, 22)
#define NS_ERROR_SERVICE_IN_USE NS_ERROR_GENERATE_SUCCESS(NS_ERROR_MODULE_XPCOM, 23)
////////////////////////////////////////////////////////////////////////////////
#define NS_ISHUTDOWNLISTENER_IID \
{ /* 56decae0-3406-11d2-8163-006008119d7a */ \
0x56decae0, \
0x3406, \
0x11d2, \
{0x81, 0x63, 0x00, 0x60, 0x08, 0x11, 0x9d, 0x7a} \
}
class nsIShutdownListener : public nsISupports {
public:
NS_DEFINE_STATIC_IID_ACCESSOR(NS_ISHUTDOWNLISTENER_IID);
NS_IMETHOD
OnShutdown(const nsCID& aClass, nsISupports* service) = 0;
};
////////////////////////////////////////////////////////////////////////////////
// Interface to Global Services
class NS_COM nsServiceManager {
public:
static nsresult
RegisterService(const nsCID& aClass, nsISupports* aService);
static nsresult
UnregisterService(const nsCID& aClass);
static nsresult
GetService(const nsCID& aClass, const nsIID& aIID,
nsISupports* *result,
nsIShutdownListener* shutdownListener = NULL);
static nsresult
ReleaseService(const nsCID& aClass, nsISupports* service,
nsIShutdownListener* shutdownListener = NULL);
////////////////////////////////////////////////////////////////////////////
// let's do it again, this time with ProgIDs...
static nsresult
RegisterService(const char* aProgID, nsISupports* aService);
static nsresult
UnregisterService(const char* aProgID);
static nsresult
GetService(const char* aProgID, const nsIID& aIID,
nsISupports* *result,
nsIShutdownListener* shutdownListener = NULL);
static nsresult
ReleaseService(const char* aProgID, nsISupports* service,
nsIShutdownListener* shutdownListener = NULL);
////////////////////////////////////////////////////////////////////////////
static nsresult GetGlobalServiceManager(nsIServiceManager* *result);
// This method can be called when shutting down the application. It
// releases all the global services, and deletes the global service manager.
static nsresult ShutdownGlobalServiceManager(nsIServiceManager* *result);
static nsIServiceManager* mGlobalServiceManager;
};
////////////////////////////////////////////////////////////////////////////////
// NS_WITH_SERVICE: macro to make using services easier.
// Now you can replace this:
// {
// nsIMyService* service;
// rv = nsServiceManager::GetService(kMyServiceCID, nsIMyService::GetIID(),
// &service);
// if (NS_FAILED(rv)) return rv;
// service->Doit(...); // use my service
// rv = nsServiceManager::ReleaseService(kMyServiceCID, service);
// }
// with this:
// {
// NS_WITH_SERVICE(nsIMyService, service, kMyServiceCID, &rv);
// if (NS_FAILED(rv)) return rv;
// service->Doit(...); // use my service
// }
// and the automatic destructor will take care of releasing the service.
//
// Note that this macro requires you to link with the xpcom DLL to pick up the
// static member functions from nsServiceManager. For situations where you're
// passed an nsISupports that is an nsIComponentManager (such as in a DLL's
// NSRegisterSelf or NSUnregisterSelf entry points) you can use the following
// macro instead:
//
// NSRegisterSelf(nsISupports* servMgr, const char* path) {
// NS_WITH_SERVICE1(nsIComponentManager, compMgr, servMgr,
// kComponentManagerCID, &rv);
// if (NS_FAILED(rv)) return rv;
// compMgr->RegisterComponent(...); // use the service
// }
#define NS_WITH_SERVICE(T, var, cid, rvAddr) \
nsService _serv##var(cid, T::GetIID(), rvAddr); \
T* var = (T*)(nsISupports*)_serv##var;
#define NS_WITH_SERVICE1(T, var, isupports, cid, rvAddr) \
nsService _serv##var(isupports, cid, T::GetIID(), rvAddr); \
T* var = (T*)(nsISupports*)_serv##var;
class nsService {
protected:
nsCID mCID;
nsISupports* mService;
public:
nsService(nsISupports* aServMgr, const nsCID& aClass, const nsIID& aIID, nsresult *rv)
: mCID(aClass), mService(0)
{
nsIServiceManager* servMgr;
*rv = aServMgr->QueryInterface(nsIServiceManager::GetIID(), (void**)&servMgr);
if (NS_SUCCEEDED(*rv)) {
*rv = servMgr->GetService(mCID, aIID, &mService);
NS_RELEASE(servMgr);
}
NS_ASSERTION(NS_SUCCEEDED(*rv), "Couldn't get service.");
}
nsService(nsISupports* aServMgr, const char* aProgID, const nsIID& aIID, nsresult *rv)
: mService(0)
{
*rv = nsComponentManager::ProgIDToCLSID(aProgID, &mCID);
NS_ASSERTION(NS_SUCCEEDED(*rv), "Couldn't get CLSID.");
if (NS_FAILED(*rv)) return;
nsIServiceManager* servMgr;
*rv = aServMgr->QueryInterface(nsIServiceManager::GetIID(), (void**)&servMgr);
if (NS_SUCCEEDED(*rv)) {
*rv = servMgr->GetService(mCID, aIID, &mService);
NS_RELEASE(servMgr);
}
NS_ASSERTION(NS_SUCCEEDED(*rv), "Couldn't get service.");
}
nsService(const nsCID& aClass, const nsIID& aIID, nsresult *rv)
: mCID(aClass), mService(0) {
*rv = nsServiceManager::GetService(aClass, aIID,
(nsISupports**)&mService);
NS_ASSERTION(NS_SUCCEEDED(*rv), "Couldn't get service.");
}
~nsService() {
if (mService) { // mService could be null if the constructor fails
nsresult rv = NS_OK;
rv = nsServiceManager::ReleaseService(mCID, mService);
NS_ASSERTION(NS_SUCCEEDED(rv), "Couldn't release service.");
}
}
nsISupports* operator->() const {
NS_PRECONDITION(mService != 0, "Your code should test the error result from the constructor.");
return mService;
}
PRBool operator==(const nsISupports* other) {
return mService == other;
}
operator nsISupports*() const {
return mService;
}
};
////////////////////////////////////////////////////////////////////////////////
// NS_NewServiceManager: For when you want to create a service manager
// in a given context.
extern NS_COM nsresult
NS_NewServiceManager(nsIServiceManager* *result);
////////////////////////////////////////////////////////////////////////////////
// Initialization of XPCOM. Creates the global ComponentManager, ServiceManager
// and registers xpcom components with the ComponentManager. Should be called
// before any call can be made to XPCOM. Currently we are coping with this
// not being called and internally initializing XPCOM if not already.
extern NS_COM nsresult
NS_InitXPCOM(nsIServiceManager* *result);
////////////////////////////////////////////////////////////////////////////////
#endif /* nsIServiceManager_h___ */

View File

@@ -0,0 +1,31 @@
/* -*- 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 "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 __nsIServerProvider_h
#define __nsIServerProvider_h
#include "nsISupports.h"
typedef nsID nsSID;
#define NSSIDREF const nsSID&
class nsIServiceProvider: public nsISupports {
public:
NS_IMETHOD QueryService(NSSIDREF aSID, NSIIDREF sIID, (void **) pService);
};
#endif /* __nsIServerProvider_h */

View File

@@ -1,5 +1,5 @@
/* -*- 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: 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
@@ -16,10 +16,11 @@
* Reserved.
*/
#ifndef __NS_JSWINREG_H__
#define __NS_JSWINREG_H__
#ifndef nsISimpleEnumerator_h__
#define nsISimpleEnumerator_h__
PRInt32
InitWinRegPrototype(JSContext *jscontext, JSObject *global, JSObject **winRegPrototype);
// This file is needed to pacify the xpidl-generated header files.
#include "nsIEnumerator.h"
#endif // nsISimpleEnumerator_h__
#endif

View File

@@ -0,0 +1,132 @@
/* -*- 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 "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 nsISupports_h___
#define nsISupports_h___
#include "nsDebug.h"
#include "nsTraceRefcnt.h"
#include "nsID.h"
#include "nsIID.h"
#include "nsError.h"
#include "nsISupportsUtils.h"
#if defined(NS_MT_SUPPORTED)
#include "prcmon.h"
#endif /* NS_MT_SUPPORTED */
#if defined(XPIDL_JS_STUBS)
struct JSObject;
struct JSContext;
#endif
/*@{*/
////////////////////////////////////////////////////////////////////////////////
/**
* IID for the nsISupports interface
* {00000000-0000-0000-c000-000000000046}
*
* NOTE: NEVER EVER EVER EVER EVER change this IID. Never. Not once.
* No. Don't do it. Stop!
*/
#define NS_ISUPPORTS_IID \
{ 0x00000000, 0x0000, 0x0000, \
{0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46} }
/**
* Reference count values
*/
typedef PRUint32 nsrefcnt;
/**
* Base class for all XPCOM objects to use. This macro forces the C++
* compiler to use a compatible vtable layout for all XPCOM objects.
*/
#ifdef XP_MAC
#define XPCOM_OBJECT : public __comobject
#else
#define XPCOM_OBJECT
#endif
/**
* Basic component object model interface. Objects which implement
* this interface support runtime interface discovery (QueryInterface)
* and a reference counted memory model (AddRef/Release). This is
* modelled after the win32 IUnknown API.
*/
class nsISupports XPCOM_OBJECT {
public:
static const nsIID& GetIID() { static nsIID iid = NS_ISUPPORTS_IID; return iid; }
/**
* @name Methods
*/
//@{
/**
* A run time mechanism for interface discovery.
* @param aIID [in] A requested interface IID
* @param aInstancePtr [out] A pointer to an interface pointer to
* receive the result.
* @return <b>NS_OK</b> if the interface is supported by the associated
* instance, <b>NS_NOINTERFACE</b> if it is not.
* <b>NS_ERROR_INVALID_POINTER</b> if <i>aInstancePtr</i> is <b>NULL</b>.
*/
NS_IMETHOD QueryInterface(REFNSIID aIID,
void** aInstancePtr) = 0;
/**
* Increases the reference count for this interface.
* The associated instance will not be deleted unless
* the reference count is returned to zero.
*
* @return The resulting reference count.
*/
NS_IMETHOD_(nsrefcnt) AddRef(void) = 0;
/**
* Decreases the reference count for this interface.
* Generally, if the reference count returns to zero,
* the associated instance is deleted.
*
* @return The resulting reference count.
*/
NS_IMETHOD_(nsrefcnt) Release(void) = 0;
#if XPIDL_JS_STUBS
// XXX Scriptability hack...
static NS_EXPORT_(JSObject*) InitJSClass(JSContext* cx) {
return 0;
}
static NS_EXPORT_(JSObject*) GetJSObject(JSContext* cx, nsISupports* priv) {
NS_NOTYETIMPLEMENTED("nsISupports isn't XPIDL scriptable yet");
return 0;
}
#endif
//@}
};
////////////////////////////////////////////////////////////////////////////////
/*@}*/
#endif /* nsISupports_h___ */

Some files were not shown because too many files have changed in this diff Show More