Compare commits

..

1 Commits

Author SHA1 Message Date
(no author)
258dc9fead This commit was manufactured by cvs2svn to create branch 'src'.
git-svn-id: svn://10.0.0.236/branches/src@33658 18797224-902f-48f8-a5cc-f745e15eee43
1999-06-03 23:10:01 +00:00
689 changed files with 18421 additions and 198449 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -1,592 +0,0 @@
/* -*- 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.
*/
/******************************************************************************************
MODULE NOTES:
This file contains the nsStr data structure.
This general purpose buffer management class is used as the basis for our strings.
It's benefits include:
1. An efficient set of library style functions for manipulating nsStrs
2. Support for 1 and 2 byte character strings (which can easily be increased to n)
3. Unicode awareness and interoperability.
*******************************************************************************************/
#include "nsStr.h"
#include "bufferRoutines.h"
#include "stdio.h" //only used for printf
#include "nsDeque.h"
#include "nsCRT.h"
static const char* kFoolMsg = "Error: Some fool overwrote the shared buffer.";
//----------------------------------------------------------------------------------------
// The following is a memory agent who knows how to recycled (pool) freed memory...
//----------------------------------------------------------------------------------------
/**************************************************************
Define the char* (pooled) deallocator class...
**************************************************************/
class nsBufferDeallocator: public nsDequeFunctor{
public:
virtual void* operator()(void* anObject) {
char* aCString= (char*)anObject;
delete [] aCString;
return 0;
}
};
/**
*
* @update gess10/30/98
* @param
* @return
*/
class nsPoolingMemoryAgent : public nsMemoryAgent{
public:
nsPoolingMemoryAgent() {
memset(mPools,0,sizeof(mPools));
}
virtual ~nsPoolingMemoryAgent() {
nsBufferDeallocator theDeallocator;
int i=0;
for(i=0;i<10;i++){
if(mPools[i]){
mPools[i]->ForEach(theDeallocator); //now delete the buffers
}
delete mPools[i];
mPools[i]=0;
}
}
virtual PRBool Alloc(nsStr& aDest,PRUint32 aCount) {
//we're given the acount value in charunits; we have to scale up by the charsize.
int theShift=4;
PRUint32 theNewCapacity=eDefaultSize;
while(theNewCapacity<aCount){
theNewCapacity<<=1;
theShift++;
}
aDest.mCapacity=theNewCapacity++;
theShift=(theShift<<aDest.mCharSize)-4;
if((theShift<12) && (mPools[theShift])){
aDest.mStr=(char*)mPools[theShift]->Pop();
}
if(!aDest.mStr) {
//we're given the acount value in charunits; we have to scale up by the charsize.
size_t theSize=(theNewCapacity<<aDest.mCharSize);
aDest.mStr=new char[theSize];
}
aDest.mOwnsBuffer=1;
return PRBool(aDest.mStr!=0);
}
virtual PRBool Free(nsStr& aDest){
if(aDest.mStr){
if(aDest.mOwnsBuffer){
int theShift=1;
unsigned int theValue=1;
while((theValue<<=1)<aDest.mCapacity){
theShift++;
}
theShift-=4;
if(theShift<12){
if(!mPools[theShift]){
mPools[theShift]=new nsDeque(0);
}
mPools[theShift]->Push(aDest.mStr);
}
else delete [] aDest.mStr; //it's too big. Just delete it.
}
aDest.mStr=0;
aDest.mOwnsBuffer=0;
return PR_TRUE;
}
return PR_FALSE;
}
nsDeque* mPools[16];
};
static char* gCommonEmptyBuffer=0;
/**
*
* @update gess10/30/98
* @param
* @return
*/
char* GetSharedEmptyBuffer() {
if(!gCommonEmptyBuffer) {
const size_t theDfltSize=5;
gCommonEmptyBuffer=new char[theDfltSize];
if(gCommonEmptyBuffer){
nsCRT::zero(gCommonEmptyBuffer,theDfltSize);
gCommonEmptyBuffer[0]=0;
}
else {
printf("%s\n","Memory allocation error!");
}
}
return gCommonEmptyBuffer;
}
/**
*
* @update gess10/30/98
* @param
* @return
*/
void nsStr::Initialize(nsStr& aDest,eCharSize aCharSize) {
aDest.mStr=GetSharedEmptyBuffer();
aDest.mLength=0;
aDest.mCapacity=0;
aDest.mCharSize=aCharSize;
aDest.mOwnsBuffer=0;
NS_ASSERTION(gCommonEmptyBuffer[0]==0,kFoolMsg);
}
/**
*
* @update gess10/30/98
* @param
* @return
*/
void nsStr::Initialize(nsStr& aDest,char* aCString,PRUint32 aCapacity,PRUint32 aLength,eCharSize aCharSize,PRBool aOwnsBuffer){
aDest.mStr=(aCString) ? aCString : GetSharedEmptyBuffer();
aDest.mLength=aLength;
aDest.mCapacity=aCapacity;
aDest.mCharSize=aCharSize;
aDest.mOwnsBuffer=aOwnsBuffer;
NS_ASSERTION(gCommonEmptyBuffer[0]==0,kFoolMsg);
}
/**
*
* @update gess10/30/98
* @param
* @return
*/
nsIMemoryAgent* GetDefaultAgent(void){
// static nsPoolingMemoryAgent gDefaultAgent;
static nsMemoryAgent gDefaultAgent;
return (nsIMemoryAgent*)&gDefaultAgent;
}
/**
*
* @update gess10/30/98
* @param
* @return
*/
void nsStr::Destroy(nsStr& aDest,nsIMemoryAgent* anAgent) {
if((aDest.mStr) && (aDest.mStr!=GetSharedEmptyBuffer())) {
if(!anAgent)
anAgent=GetDefaultAgent();
if(anAgent) {
anAgent->Free(aDest);
}
else{
printf("%s\n","Leak occured in nsStr.");
}
}
}
/**
* This method gets called when the internal buffer needs
* to grow to a given size. The original contents are not preserved.
* @update gess 3/30/98
* @param aNewLength -- new capacity of string in charSize units
* @return void
*/
void nsStr::EnsureCapacity(nsStr& aString,PRUint32 aNewLength,nsIMemoryAgent* anAgent) {
if(aNewLength>aString.mCapacity) {
nsIMemoryAgent* theAgent=(anAgent) ? anAgent : GetDefaultAgent();
theAgent->Realloc(aString,aNewLength);
AddNullTerminator(aString);
}
NS_ASSERTION(gCommonEmptyBuffer[0]==0,kFoolMsg);
}
/**
* This method gets called when the internal buffer needs
* to grow to a given size. The original contents ARE preserved.
* @update gess 3/30/98
* @param aNewLength -- new capacity of string in charSize units
* @return void
*/
void nsStr::GrowCapacity(nsStr& aDest,PRUint32 aNewLength,nsIMemoryAgent* anAgent) {
if(aNewLength>aDest.mCapacity) {
nsStr theTempStr;
nsStr::Initialize(theTempStr,aDest.mCharSize);
nsIMemoryAgent* theAgent=(anAgent) ? anAgent : GetDefaultAgent();
EnsureCapacity(theTempStr,aNewLength,theAgent);
if(aDest.mLength) {
Append(theTempStr,aDest,0,aDest.mLength,theAgent);
}
theAgent->Free(aDest);
aDest.mStr = theTempStr.mStr;
theTempStr.mStr=0; //make sure to null this out so that you don't lose the buffer you just stole...
aDest.mLength=theTempStr.mLength;
aDest.mCapacity=theTempStr.mCapacity;
aDest.mOwnsBuffer=theTempStr.mOwnsBuffer;
}
NS_ASSERTION(gCommonEmptyBuffer[0]==0,kFoolMsg);
}
/**
* Replaces the contents of aDest with aSource, up to aCount of chars.
* @update gess10/30/98
* @param aDest is the nsStr that gets changed.
* @param aSource is where chars are copied from
* @param aCount is the number of chars copied from aSource
*/
void nsStr::Assign(nsStr& aDest,const nsStr& aSource,PRUint32 anOffset,PRInt32 aCount,nsIMemoryAgent* anAgent){
if(&aDest!=&aSource){
Truncate(aDest,0,anAgent);
Append(aDest,aSource,anOffset,aCount,anAgent);
}
}
/**
* This method appends the given nsStr to this one. Note that we have to
* pay attention to the underlying char-size of both structs.
* @update gess10/30/98
* @param aDest is the nsStr to be manipulated
* @param aSource is where char are copied from
* @aCount is the number of bytes to be copied
*/
void nsStr::Append(nsStr& aDest,const nsStr& aSource,PRUint32 anOffset,PRInt32 aCount,nsIMemoryAgent* anAgent){
if(anOffset<aSource.mLength){
PRUint32 theRealLen=(aCount<0) ? aSource.mLength : MinInt(aCount,aSource.mLength);
PRUint32 theLength=(anOffset+theRealLen<aSource.mLength) ? theRealLen : (aSource.mLength-anOffset);
if(0<theLength){
if(aDest.mLength+theLength > aDest.mCapacity) {
GrowCapacity(aDest,aDest.mLength+theLength,anAgent);
}
//now append new chars, starting at offset
(*gCopyChars[aSource.mCharSize][aDest.mCharSize])(aDest.mStr,aDest.mLength,aSource.mStr,anOffset,theLength);
aDest.mLength+=theLength;
}
}
AddNullTerminator(aDest);
NS_ASSERTION(gCommonEmptyBuffer[0]==0,kFoolMsg);
}
/**
* This method inserts up to "aCount" chars from a source nsStr into a dest nsStr.
* @update gess10/30/98
* @param aDest is the nsStr that gets changed
* @param aDestOffset is where in aDest the insertion is to occur
* @param aSource is where chars are copied from
* @param aSrcOffset is where in aSource chars are copied from
* @param aCount is the number of chars from aSource to be inserted into aDest
*/
void nsStr::Insert( nsStr& aDest,PRUint32 aDestOffset,const nsStr& aSource,PRUint32 aSrcOffset,PRInt32 aCount,nsIMemoryAgent* anAgent){
//there are a few cases for insert:
// 1. You're inserting chars into an empty string (assign)
// 2. You're inserting onto the end of a string (append)
// 3. You're inserting onto the 1..n-1 pos of a string (the hard case).
if(0<aSource.mLength){
if(aDest.mLength){
if(aDestOffset<aDest.mLength){
PRInt32 theRealLen=(aCount<0) ? aSource.mLength : MinInt(aCount,aSource.mLength);
PRInt32 theLength=(aSrcOffset+theRealLen<aSource.mLength) ? theRealLen : (aSource.mLength-aSrcOffset);
if(aSrcOffset<aSource.mLength) {
//here's the only new case we have to handle.
//chars are really being inserted into our buffer...
GrowCapacity(aDest,aDest.mLength+theLength,anAgent);
//shift the chars right by theDelta...
(*gShiftChars[aDest.mCharSize][KSHIFTRIGHT])(aDest.mStr,aDest.mLength,aDestOffset,theLength);
//now insert new chars, starting at offset
(*gCopyChars[aSource.mCharSize][aDest.mCharSize])(aDest.mStr,aDestOffset,aSource.mStr,aSrcOffset,theLength);
//finally, make sure to update the string length...
aDest.mLength+=theLength;
AddNullTerminator(aDest);
}//if
//else nothing to do!
}
else Append(aDest,aSource,0,aCount,anAgent);
}
else Append(aDest,aSource,0,aCount,anAgent);
}
NS_ASSERTION(gCommonEmptyBuffer[0]==0,kFoolMsg);
}
/**
* This method deletes up to aCount chars from aDest
* @update gess10/30/98
* @param aDest is the nsStr to be manipulated
* @param aDestOffset is where in aDest deletion is to occur
* @param aCount is the number of chars to be deleted in aDest
*/
void nsStr::Delete(nsStr& aDest,PRUint32 aDestOffset,PRUint32 aCount,nsIMemoryAgent* anAgent){
if(aDestOffset<aDest.mLength){
PRUint32 theDelta=aDest.mLength-aDestOffset;
PRUint32 theLength=(theDelta<aCount) ? theDelta : aCount;
if(aDestOffset+theLength<aDest.mLength) {
//if you're here, it means we're cutting chars out of the middle of the string...
//so shift the chars left by theLength...
(*gShiftChars[aDest.mCharSize][KSHIFTLEFT])(aDest.mStr,aDest.mLength,aDestOffset,theLength);
aDest.mLength-=theLength;
}
else Truncate(aDest,aDestOffset,anAgent);
}//if
NS_ASSERTION(gCommonEmptyBuffer[0]==0,kFoolMsg);
}
/**
* This method truncates the given nsStr at given offset
* @update gess10/30/98
* @param aDest is the nsStr to be truncated
* @param aDestOffset is where in aDest truncation is to occur
*/
void nsStr::Truncate(nsStr& aDest,PRUint32 aDestOffset,nsIMemoryAgent* anAgent){
if(aDestOffset<aDest.mLength){
aDest.mLength=aDestOffset;
AddNullTerminator(aDest);
}
NS_ASSERTION(gCommonEmptyBuffer[0]==0,kFoolMsg);
}
/**
*
* @update gess1/7/99
* @param
* @return
*/
void nsStr::ChangeCase(nsStr& aDest,PRBool aToUpper) {
// somehow UnicharUtil return failed, fallback to the old ascii only code
gCaseConverters[aDest.mCharSize](aDest.mStr,aDest.mLength,aToUpper);
NS_ASSERTION(gCommonEmptyBuffer[0]==0,kFoolMsg);
}
/**
*
* @update gess1/7/99
* @param
* @return
*/
void nsStr::StripChars(nsStr& aDest,PRUint32 aDestOffset,PRInt32 aCount,const char* aCharSet){
PRUint32 aNewLen=gStripChars[aDest.mCharSize](aDest.mStr,aDestOffset,aCount,aCharSet);
aDest.mLength=aNewLen;
NS_ASSERTION(gCommonEmptyBuffer[0]==0,kFoolMsg);
}
/**
*
* @update gess1/7/99
* @param
* @return
*/
void nsStr::Trim(nsStr& aDest,const char* aSet,PRBool aEliminateLeading,PRBool aEliminateTrailing){
PRUint32 aNewLen=gTrimChars[aDest.mCharSize](aDest.mStr,aDest.mLength,aSet,aEliminateLeading,aEliminateTrailing);
aDest.mLength=aNewLen;
NS_ASSERTION(gCommonEmptyBuffer[0]==0,kFoolMsg);
}
/**
*
* @update gess1/7/99
* @param
* @return
*/
void nsStr::CompressSet(nsStr& aDest,const char* aSet,PRUint32 aChar,PRBool aEliminateLeading,PRBool aEliminateTrailing){
PRUint32 aNewLen=gCompressChars[aDest.mCharSize](aDest.mStr,aDest.mLength,aSet,aChar,aEliminateLeading,aEliminateTrailing);
aDest.mLength=aNewLen;
NS_ASSERTION(gCommonEmptyBuffer[0]==0,kFoolMsg);
}
/**************************************************************
Searching methods...
**************************************************************/
PRInt32 nsStr::FindSubstr(const nsStr& aDest,const nsStr& aTarget, PRBool aIgnoreCase,PRUint32 anOffset) {
if((aDest.mLength>0) && (aTarget.mLength>0) && (anOffset<aTarget.mLength)){
int32 index=anOffset-1;
int32 theMax=aDest.mLength-aTarget.mLength;
if((aDest.mLength>0) && (aTarget.mLength>0)){
int32 theTargetMax=aTarget.mLength;
while(++index<=theMax) {
int32 theSubIndex=-1;
PRBool matches=PR_TRUE;
while((++theSubIndex<theTargetMax) && (matches)){
PRUnichar theChar=(aIgnoreCase) ? nsCRT::ToLower(GetCharAt(aDest,index+theSubIndex)) : GetCharAt(aDest,index+theSubIndex);
PRUnichar theTargetChar=(aIgnoreCase) ? nsCRT::ToLower(GetCharAt(aTarget,theSubIndex)) : GetCharAt(aTarget,theSubIndex);
matches=PRBool(theChar==theTargetChar);
}
if(matches) {
return index;
}
}
}//if
}
return kNotFound;
}
/**
*
* @update gess1/7/99
* @param
* @return
*/
PRInt32 nsStr::FindChar(const nsStr& aDest,PRUnichar aChar, PRBool aIgnoreCase,PRUint32 anOffset) {
PRInt32 result=gFindChars[aDest.mCharSize](aDest.mStr,aDest.mLength,anOffset,aChar,aIgnoreCase);
return result;
}
/**
*
*
* @update gess 3/25/98
* @param
* @return
*/
PRInt32 nsStr::FindCharInSet(const nsStr& aDest,const nsStr& aSet,PRBool aIgnoreCase,PRUint32 anOffset) {
PRUint32 index=anOffset-1;
PRInt32 thePos;
while(++index<aDest.mLength) {
PRUnichar theChar=GetCharAt(aDest,index);
thePos=gFindChars[aSet.mCharSize](aSet.mStr,aSet.mLength,0,theChar,aIgnoreCase);
if(kNotFound!=thePos)
return index;
} //while
return kNotFound;
}
/**************************************************************
Reverse Searching methods...
**************************************************************/
PRInt32 nsStr::RFindSubstr(const nsStr& aDest,const nsStr& aTarget, PRBool aIgnoreCase,PRUint32 anOffset) {
PRInt32 index=(anOffset ? anOffset : aDest.mLength-aTarget.mLength+1);
PRInt32 result=kNotFound;
if((aDest.mLength>0) && (aTarget.mLength>0)){
nsStr theCopy;
nsStr::Initialize(theCopy,eOneByte);
nsStr::Assign(theCopy,aTarget,0,aTarget.mLength,0);
if(aIgnoreCase){
nsStr::ChangeCase(theCopy,PR_FALSE); //force to lowercase
}
int32 theTargetMax=theCopy.mLength;
while(index--) {
int32 theSubIndex=-1;
PRBool matches=PR_TRUE;
if(anOffset+theCopy.mLength<=aDest.mLength) {
while((++theSubIndex<theTargetMax) && (matches)){
PRUnichar theDestChar=(aIgnoreCase) ? nsCRT::ToLower(GetCharAt(aDest,index+theSubIndex)) : GetCharAt(aDest,index+theSubIndex);
PRUnichar theTargetChar=GetCharAt(theCopy,theSubIndex);
matches=PRBool(theDestChar==theTargetChar);
} //while
} //if
if(matches) {
result=index;
break;
}
} //while
nsStr::Destroy(theCopy,0);
}//if
return result;
}
/**
*
* @update gess1/7/99
* @param
* @return
*/
PRInt32 nsStr::RFindChar(const nsStr& aDest,PRUnichar aChar, PRBool aIgnoreCase,PRUint32 anOffset) {
PRInt32 result=gRFindChars[aDest.mCharSize](aDest.mStr,aDest.mLength,anOffset,aChar,aIgnoreCase);
return result;
}
/**
*
*
* @update gess 3/25/98
* @param
* @return
*/
PRInt32 nsStr::RFindCharInSet(const nsStr& aDest,const nsStr& aSet,PRBool aIgnoreCase,PRUint32 anOffset) {
PRUint32 offset=aDest.mLength-anOffset;
PRInt32 thePos;
while(--offset>=0) {
PRUnichar theChar=GetCharAt(aDest,offset);
thePos=gRFindChars[aSet.mCharSize](aSet.mStr,aSet.mLength,0,theChar,aIgnoreCase);
if(kNotFound!=thePos)
return offset;
} //while
return kNotFound;
}
/**
*
* @update gess11/12/98
* @param
* @return aDest<aSource=-1;aDest==aSource==0;aDest>aSource=1
*/
PRInt32 nsStr::Compare(const nsStr& aDest,const nsStr& aSource,PRInt32 aCount,PRBool aIgnoreCase) {
int minlen=(aSource.mLength<aDest.mLength) ? aSource.mLength : aDest.mLength;
if(0==minlen) {
if ((aDest.mLength == 0) && (aSource.mLength == 0))
return 0;
if (aDest.mLength == 0)
return -1;
return 1;
}
int maxlen=(aSource.mLength<aDest.mLength) ? aDest.mLength : aSource.mLength;
PRInt32 result=(*gCompare[aDest.mCharSize][aSource.mCharSize])(aDest.mStr,aSource.mStr,maxlen,aIgnoreCase);
return result;
}

View File

@@ -1,333 +0,0 @@
/* -*- 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.
*/
/***********************************************************************
MODULE NOTES:
1. There are two philosophies to building string classes:
A. Hide the underlying buffer & offer API's allow indirect iteration
B. Reveal underlying buffer, risk corruption, but gain performance
We chose the option B for performance reasons.
2 Our internal buffer always holds capacity+1 bytes.
The nsStr struct is a simple structure (no methods) that contains
the necessary info to be described as a string. This simple struct
is manipulated by the static methods provided in this class.
(Which effectively makes this a library that works on structs).
There are also object-based versions called nsString and nsAutoString
which use nsStr but makes it look at feel like an object.
***********************************************************************/
#ifndef _nsStr
#define _nsStr
#include "nscore.h"
//----------------------------------------------------------------------------------------
enum eCharSize {eOneByte=0,eTwoByte=1};
#define kDefaultCharSize eTwoByte
const PRInt32 kNotFound = -1;
class nsIMemoryAgent;
//----------------------------------------------------------------------------------------
struct nsStr {
/**
* This method initializes an nsStr for use
*
* @update gess 01/04/99
* @param aString is the nsStr to be initialized
* @param aCharSize tells us the requested char size (1 or 2 bytes)
*/
static void Initialize(nsStr& aDest,eCharSize aCharSize);
/**
* This method initializes an nsStr for use
*
* @update gess 01/04/99
* @param aString is the nsStr to be initialized
* @param aCharSize tells us the requested char size (1 or 2 bytes)
*/
static void Initialize(nsStr& aDest,char* aCString,PRUint32 aCapacity,PRUint32 aLength,eCharSize aCharSize,PRBool aOwnsBuffer);
/**
* This method destroys the given nsStr, and *MAY*
* deallocate it's memory depending on the setting
* of the internal mOwnsBUffer flag.
*
* @update gess 01/04/99
* @param aString is the nsStr to be manipulated
* @param anAgent is the allocator to be used to the nsStr
*/
static void Destroy(nsStr& aDest,nsIMemoryAgent* anAgent=0);
/**
* These methods are where memory allocation/reallocation occur.
*
* @update gess 01/04/99
* @param aString is the nsStr to be manipulated
* @param anAgent is the allocator to be used on the nsStr
* @return
*/
static void EnsureCapacity(nsStr& aString,PRUint32 aNewLength,nsIMemoryAgent* anAgent=0);
static void GrowCapacity(nsStr& aString,PRUint32 aNewLength,nsIMemoryAgent* anAgent=0);
/**
* These methods are used to append content to the given nsStr
*
* @update gess 01/04/99
* @param aDest is the nsStr to be appended to
* @param aSource is the buffer to be copied from
* @param anOffset tells us where in source to start copying
* @param aCount tells us the (max) # of chars to copy
* @param anAgent is the allocator to be used for alloc/free operations
*/
static void Append(nsStr& aDest,const nsStr& aSource,PRUint32 anOffset,PRInt32 aCount,nsIMemoryAgent* anAgent=0);
/**
* These methods are used to assign contents of a source string to dest string
*
* @update gess 01/04/99
* @param aDest is the nsStr to be appended to
* @param aSource is the buffer to be copied from
* @param anOffset tells us where in source to start copying
* @param aCount tells us the (max) # of chars to copy
* @param anAgent is the allocator to be used for alloc/free operations
*/
static void Assign(nsStr& aDest,const nsStr& aSource,PRUint32 anOffset,PRInt32 aCount,nsIMemoryAgent* anAgent=0);
/**
* These methods are used to insert content from source string to the dest nsStr
*
* @update gess 01/04/99
* @param aDest is the nsStr to be appended to
* @param aDestOffset tells us where in dest to start insertion
* @param aSource is the buffer to be copied from
* @param aSrcOffset tells us where in source to start copying
* @param aCount tells us the (max) # of chars to insert
* @param anAgent is the allocator to be used for alloc/free operations
*/
static void Insert( nsStr& aDest,PRUint32 aDestOffset,const nsStr& aSource,PRUint32 aSrcOffset,PRInt32 aCount,nsIMemoryAgent* anAgent=0);
/**
* This method deletes chars from the given str.
* The given allocator may choose to resize the str as well.
*
* @update gess 01/04/99
* @param aDest is the nsStr to be deleted from
* @param aDestOffset tells us where in dest to start deleting
* @param aCount tells us the (max) # of chars to delete
* @param anAgent is the allocator to be used for alloc/free operations
*/
static void Delete(nsStr& aDest,PRUint32 aDestOffset,PRUint32 aCount,nsIMemoryAgent* anAgent=0);
/**
* This method is used to truncate the given string.
* The given allocator may choose to resize the str as well (but it's not likely).
*
* @update gess 01/04/99
* @param aDest is the nsStr to be appended to
* @param aDestOffset tells us where in dest to start insertion
* @param aSource is the buffer to be copied from
* @param aSrcOffset tells us where in source to start copying
* @param anAgent is the allocator to be used for alloc/free operations
*/
static void Truncate(nsStr& aDest,PRUint32 aDestOffset,nsIMemoryAgent* anAgent=0);
/**
* This method is used to perform a case conversion on the given string
*
* @update gess 01/04/99
* @param aDest is the nsStr to be case shifted
* @param toUpper tells us to go upper vs. lower
*/
static void ChangeCase(nsStr& aDest,PRBool aToUpper);
/**
* This method removes chars (given in aSet) from the given buffer
*
* @update gess 01/04/99
* @param aString is the buffer to be manipulated
* @param aDestOffset is starting pos in buffer for manipulation
* @param aCount is the number of chars to compare
* @param aSet tells us which chars to remove from given buffer
*/
static void StripChars(nsStr& aDest,PRUint32 aDestOffset,PRInt32 aCount,const char* aCharSet);
/**
* This method trims chars (given in aSet) from the edges of given buffer
*
* @update gess 01/04/99
* @param aDest is the buffer to be manipulated
* @param aSet tells us which chars to remove from given buffer
* @param aEliminateLeading tells us whether to strip chars from the start of the buffer
* @param aEliminateTrailing tells us whether to strip chars from the start of the buffer
*/
static void Trim(nsStr& aDest,const char* aSet,PRBool aEliminateLeading,PRBool aEliminateTrailing);
/**
* This method compresses duplicate runs of a given char from the given buffer
*
* @update gess 01/04/99
* @param aDest is the buffer to be manipulated
* @param aSet tells us which chars to compress from given buffer
* @param aChar is the replacement char
* @param aEliminateLeading tells us whether to strip chars from the start of the buffer
* @param aEliminateTrailing tells us whether to strip chars from the start of the buffer
*/
static void CompressSet(nsStr& aDest,const char* aSet,PRUint32 aChar,PRBool aEliminateLeading,PRBool aEliminateTrailing);
/**
* This method compares the data bewteen two nsStr's
*
* @update gess 01/04/99
* @param aStr1 is the first buffer to be compared
* @param aStr2 is the 2nd buffer to be compared
* @param aCount is the number of chars to compare
* @param aIgnorecase tells us whether to use a case-sensitive comparison
* @return -1,0,1 depending on <,==,>
*/
static PRInt32 Compare(const nsStr& aDest,const nsStr& aSource,PRInt32 aCount,PRBool aIgnoreCase);
/**
* These methods scan the given string for 1 or more chars in a given direction
*
* @update gess 01/04/99
* @param aDest is the nsStr to be searched to
* @param aSource (or aChar) is the substr we're looking to find
* @param aIgnoreCase tells us whether to search in a case-sensitive manner
* @param anOffset tells us where in the dest string to start searching
* @return the index of the source (substr) in dest, or -1 (kNotFound) if not found.
*/
static PRInt32 FindSubstr(const nsStr& aDest,const nsStr& aSource, PRBool aIgnoreCase,PRUint32 anOffset);
static PRInt32 FindChar(const nsStr& aDest,PRUnichar aChar, PRBool aIgnoreCase,PRUint32 anOffset);
static PRInt32 FindCharInSet(const nsStr& aDest,const nsStr& aSet,PRBool aIgnoreCase,PRUint32 anOffset);
static PRInt32 RFindSubstr(const nsStr& aDest,const nsStr& aSource, PRBool aIgnoreCase,PRUint32 anOffset);
static PRInt32 RFindChar(const nsStr& aDest,PRUnichar aChar, PRBool aIgnoreCase,PRUint32 anOffset);
static PRInt32 RFindCharInSet(const nsStr& aDest,const nsStr& aSet,PRBool aIgnoreCase,PRUint32 anOffset);
PRUint32 mLength;
PRUint32 mCapacity;
eCharSize mCharSize;
PRBool mOwnsBuffer;
union {
char* mStr;
PRUnichar* mUStr;
};
};
/**************************************************************
A couple of tiny helper methods used in the string classes.
**************************************************************/
inline PRInt32 MinInt(PRInt32 anInt1,PRInt32 anInt2){
return (anInt1<anInt2) ? anInt1 : anInt2;
}
inline PRInt32 MaxInt(PRInt32 anInt1,PRInt32 anInt2){
return (anInt1<anInt2) ? anInt2 : anInt1;
}
inline void AddNullTerminator(nsStr& aDest) {
if(eTwoByte==aDest.mCharSize)
aDest.mUStr[aDest.mLength]=0;
else aDest.mStr[aDest.mLength]=0;
}
/**
* This method is used to access a given char in the given string
*
* @update gess 01/04/99
* @param aDest is the nsStr to be appended to
* @param anIndex tells us where in dest to get the char from
* @return the given char, or 0 if anIndex is out of range
*/
inline PRUnichar GetCharAt(const nsStr& aDest,PRUint32 anIndex){
if(anIndex<aDest.mLength) {
return (eTwoByte==aDest.mCharSize) ? aDest.mUStr[anIndex] : aDest.mStr[anIndex];
}//if
return 0;
}
//----------------------------------------------------------------------------------------
class nsIMemoryAgent {
public:
virtual PRBool Alloc(nsStr& aString,PRUint32 aCount)=0;
virtual PRBool Realloc(nsStr& aString,PRUint32 aCount)=0;
virtual PRBool Free(nsStr& aString)=0;
};
class nsMemoryAgent : public nsIMemoryAgent {
protected:
enum eDelta{eDefaultSize=16};
public:
virtual PRBool Alloc(nsStr& aDest,PRUint32 aCount) {
//we're given the acount value in charunits; now scale up to next multiple.
PRUint32 theNewCapacity=eDefaultSize;
while(theNewCapacity<aCount){
theNewCapacity<<=1;
}
aDest.mCapacity=theNewCapacity++;
size_t theSize=(theNewCapacity<<aDest.mCharSize);
aDest.mStr=new char[theSize];
aDest.mOwnsBuffer=1;
return PR_TRUE;
}
virtual PRBool Free(nsStr& aDest){
if(aDest.mStr){
if(aDest.mOwnsBuffer){
delete [] aDest.mStr;
}
aDest.mStr=0;
aDest.mOwnsBuffer=0;
return PR_TRUE;
}
return PR_FALSE;
}
virtual PRBool Realloc(nsStr& aDest,PRUint32 aCount){
Free(aDest);
return Alloc(aDest,aCount);
}
};
char* GetSharedEmptyBuffer();
nsIMemoryAgent* GetDefaultAgent(void);
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -1,819 +0,0 @@
/* -*- 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.
*/
/***********************************************************************
MODULE NOTES:
A. There are two philosophies to building string classes:
1. Hide the underlying buffer & offer API's allow indirect iteration
2. Reveal underlying buffer, risk corruption, but gain performance
We chose the second option for performance reasons.
B Our internal buffer always holds capacity+1 bytes.
***********************************************************************/
#ifndef _nsString1
#define _nsString1
#include "prtypes.h"
#include "nscore.h"
#include "nsIAtom.h"
#include <iostream.h>
#include <stdio.h>
#include "nsStr.h"
#include "nsString2.h" //get new string class
class nsISizeOfHandler;
class NS_COM nsString1 {
public:
/**
* Default constructor. Note that we actually allocate a small buffer
* to begin with. This is because the "philosophy" of the string class
* was to allow developers direct access to the underlying buffer for
* performance reasons.
*/
nsString1();
/**
* This constructor accepts an isolatin string
* @param an ascii is a ptr to a 1-byte cstr
*/
nsString1(const char* aCString);
/**
* This is our copy constructor
* @param reference to another nsString1
*/
nsString1(const nsString1&);
/**
* Constructor from a unicode string
* @param anicodestr pts to a unicode string
*/
nsString1(const PRUnichar* aUnicode);
/**
* Virtual Destructor
*/
virtual ~nsString1();
/**
* Retrieve the length of this string
* @return string length
*/
PRInt32 Length() const { return mLength; }
/**
* Sets the new length of the string.
* @param aLength is new string length.
* @return nada
*/
void SetLength(PRInt32 aLength);
/**
* This method truncates this string to given length.
*
* @param anIndex -- new length of string
* @return nada
*/
void Truncate(PRInt32 anIndex=0);
/**
* This method gets called when the internal buffer needs
* to grow to a given size.
* @param aNewLength -- new capacity of string
* @return void
*/
virtual void EnsureCapacityFor(PRInt32 aNewLength);
/**
*
* @param
*/
virtual void SizeOf(nsISizeOfHandler* aHandler) const;
/**
* Determine whether or not the characters in this
* string are in sorted order.
*
* @return TRUE if ordered.
*/
PRBool IsOrdered(void) const;
/**
* Determine whether or not this string has a length of 0
*
* @return TRUE if empty.
*/
PRBool IsEmpty(void) const {
return PRBool(0==mLength);
}
/**********************************************************************
Accessor methods...
*********************************************************************/
/**
* Retrieve pointer to internal string value
* @return PRUnichar* to internal string
*/
const PRUnichar* GetUnicode(void) const;
/**
*
* @param
* @return
*/
operator const PRUnichar*() const;
/**
* Retrieve unicode char at given index
* @param offset into string
* @return PRUnichar* to internal string
*/
//PRUnichar operator()(PRInt32 anIndex) const;
/**
* Retrieve reference to unicode char at given index
* @param offset into string
* @return PRUnichar& from internal string
*/
PRUnichar& operator[](PRInt32 anIndex) const;
/**
* Retrieve reference to unicode char at given index
* @param offset into string
* @return PRUnichar& from internal string
*/
PRUnichar& CharAt(PRInt32 anIndex) const;
/**
* Retrieve reference to first unicode char in string
* @return PRUnichar from internal string
*/
PRUnichar& First() const;
/**
* Retrieve reference to last unicode char in string
* @return PRUnichar from internal string
*/
PRUnichar& Last() const;
PRBool SetCharAt(PRUnichar aChar,PRInt32 anIndex);
/**********************************************************************
String creation methods...
*********************************************************************/
/**
* Create a new string by appending given string to this
* @param aString -- 2nd string to be appended
* @return new string
*/
nsString1 operator+(const nsString1& aString);
/**
* create a new string by adding this to the given buffer.
* @param aCString is a ptr to cstring to be added to this
* @return newly created string
*/
nsString1 operator+(const char* aCString);
/**
* create a new string by adding this to the given char.
* @param aChar is a char to be added to this
* @return newly created string
*/
nsString1 operator+(char aChar);
/**
* create a new string by adding this to the given buffer.
* @param aStr unichar buffer to be added to this
* @return newly created string
*/
nsString1 operator+(const PRUnichar* aBuffer);
/**
* create a new string by adding this to the given char.
* @param aChar is a unichar to be added to this
* @return newly created string
*/
nsString1 operator+(PRUnichar aChar);
/**
* Converts all chars in internal string to lower
*/
void ToLowerCase();
/**
* Converts all chars in given string to lower
*/
void ToLowerCase(nsString1& aString) const;
/**
* Converts all chars in given string to upper
*/
void ToUpperCase();
/**
* Converts all chars in given string to UCS2
* which ensure that the lower 256 chars are correct.
*/
void ToUCS2(PRInt32 aStartOffset);
/**
* Converts all chars in internal string to upper
*/
void ToUpperCase(nsString1& aString) const;
/**
* Creates a duplicate clone (ptr) of this string.
* @return ptr to clone of this string
*/
nsString1* ToNewString() const;
/**
* Creates an ascii clone of this string
* NOTE: This string is allocated with new; YOU MUST deallocate with delete[]!
* @return ptr to new c-String string
*/
char* ToNewCString() const;
/**
* Copies data from internal buffer onto given char* buffer
* @param aBuf is the buffer where data is stored
* @param aBuflength is the max # of chars to move to buffer
* @return ptr to given buffer
*/
char* ToCString(char* aBuf,PRInt32 aBufLength) const;
/**
* Copies contents of this onto given string.
* @param aString to hold copy of this
* @return nada.
*/
void Copy(nsString1& aString) const;
/**
* Creates an unichar clone of this string
* @return ptr to new unichar string
*/
PRUnichar* ToNewUnicode() const;
/**
* Perform string to float conversion.
* @param aErrorCode will contain error if one occurs
* @return float rep of string value
*/
float ToFloat(PRInt32* aErrorCode) const;
/**
* Perform string to int conversion.
* @param aErrorCode will contain error if one occurs
* @return int rep of string value
*/
PRInt32 ToInteger(PRInt32* aErrorCode,PRInt32 aRadix=10) const;
/**********************************************************************
String manipulation methods...
*********************************************************************/
/**
* assign given PRUnichar* to this string
* @param aStr: buffer to be assigned to this
* @param alength is the length of the given str (or -1)
if you want me to determine its length
* @return this
*/
nsString1& SetString(const PRUnichar* aStr,PRInt32 aLength=-1);
nsString1& SetString(const char* aCString,PRInt32 aLength=-1);
nsString1& SetString(const nsString1& aString);
/**
* assign given string to this one
* @param aString: string to be added to this
* @return this
*/
nsString1& operator=(const nsString1& aString);
/**
* assign given char* to this string
* @param aCString: buffer to be assigned to this
* @return this
*/
nsString1& operator=(const char* aCString);
/**
* assign given char to this string
* @param aChar: char to be assignd to this
* @return this
*/
nsString1& operator=(char aChar);
/**
* assign given unichar* to this string
* @param aBuffer: unichar buffer to be assigned to this
* @return this
*/
nsString1& operator=(const PRUnichar* aBuffer);
/**
* assign given char to this string
* @param aChar: char to be assignd to this
* @return this
*/
nsString1& operator=(PRUnichar aChar);
/**
* append given string to this string
* @param aString : string to be appended to this
* @return this
*/
nsString1& operator+=(const nsString1& aString);
/**
* append given buffer to this string
* @param aCString: buffer to be appended to this
* @return this
*/
nsString1& operator+=(const char* aCString);
/**
* append given buffer to this string
* @param aBuffer: buffer to be appended to this
* @return this
*/
nsString1& operator+=(const PRUnichar* aBuffer);
/**
* append given char to this string
* @param aChar: char to be appended to this
* @return this
*/
nsString1& operator+=(PRUnichar aChar);
/**
* append given string to this string
* @param aString : string to be appended to this
* @param alength is the length of the given str (or -1)
if you want me to determine its length
* @return this
*/
nsString1& Append(const nsString1& aString,PRInt32 aLength=-1);
/**
* append given string to this string
* @param aString : string to be appended to this
* @param alength is the length of the given str (or -1)
if you want me to determine its length
* @return this
*/
nsString1& Append(const char* aCString,PRInt32 aLength=-1);
/**
* append given string to this string
* @param aString : string to be appended to this
* @return this
*/
nsString1& Append(char aChar);
/**
* append given unichar buffer to this string
* @param aString : string to be appended to this
* @param alength is the length of the given str (or -1)
if you want me to determine its length
* @return this
*/
nsString1& Append(const PRUnichar* aBuffer,PRInt32 aLength=-1);
/**
* append given unichar character to this string
* @param aChar is the char to be appended to this
* @return this
*/
nsString1& Append(PRUnichar aChar);
/**
* Append an integer onto this string
* @param aInteger is the int to be appended
* @param aRadix specifies 8,10,16
* @return this
*/
nsString1& Append(PRInt32 aInteger,PRInt32 aRadix); //radix=8,10 or 16
/**
* Append a float value onto this string
* @param aFloat is the float to be appended
* @return this
*/
nsString1& Append(float aFloat);
/*
* Copies n characters from this string to given string,
* starting at the leftmost offset.
*
*
* @param aCopy -- Receiving string
* @param aCount -- number of chars to copy
* @return number of chars copied
*/
PRInt32 Left(nsString1& aCopy,PRInt32 aCount) const;
/*
* Copies n characters from this string to given string,
* starting at the given offset.
*
*
* @param aCopy -- Receiving string
* @param aCount -- number of chars to copy
* @param anOffset -- position where copying begins
* @return number of chars copied
*/
PRInt32 Mid(nsString1& aCopy,PRInt32 anOffset,PRInt32 aCount) const;
/*
* Copies n characters from this string to given string,
* starting at rightmost char.
*
*
* @param aCopy -- Receiving string
* @param aCount -- number of chars to copy
* @return number of chars copied
*/
PRInt32 Right(nsString1& aCopy,PRInt32 aCount) const;
/*
* This method inserts n chars from given string into this
* string at str[anOffset].
*
* @param aCopy -- String to be inserted into this
* @param anOffset -- insertion position within this str
* @param aCount -- number of chars to be copied from aCopy
* @return number of chars inserted into this.
*/
PRInt32 Insert(const nsString1& aCopy,PRInt32 anOffset,PRInt32 aCount=-1);
/**
* Insert a single unicode char into this string at
* a specified offset.
*
* @param aChar char to be inserted into this string
* @param anOffset is insert pos in str
* @return the number of chars inserted into this string
*/
PRInt32 Insert(PRUnichar aChar,PRInt32 anOffset);
/*
* This method is used to cut characters in this string
* starting at anOffset, continuing for aCount chars.
*
* @param anOffset -- start pos for cut operation
* @param aCount -- number of chars to be cut
* @return *this
*/
nsString1& Cut(PRInt32 anOffset,PRInt32 aCount);
/**
* This method is used to remove all occurances of the
* characters found in aSet from this string.
*
* @param aSet -- characters to be cut from this
* @return *this
*/
nsString1& StripChars(const char* aSet);
/**
* This method is used to replace all occurances of the
* given source char with the given dest char
*
* @param
* @return *this
*/
nsString1& ReplaceChar(PRUnichar aSourceChar, PRUnichar aDestChar);
/**
* This method strips whitespace throughout the string
*
* @return this
*/
nsString1& StripWhitespace();
/**
* This method trims characters found in aTrimSet from
* either end of the underlying string.
*
* @param aTrimSet -- contains chars to be trimmed from
* both ends
* @return this
*/
nsString1& Trim(const char* aSet,
PRBool aEliminateLeading=PR_TRUE,
PRBool aEliminateTrailing=PR_TRUE);
/**
* This method strips whitespace from string.
* You can control whether whitespace is yanked from
* start and end of string as well.
*
* @param aEliminateLeading controls stripping of leading ws
* @param aEliminateTrailing controls stripping of trailing ws
* @return this
*/
nsString1& CompressWhitespace( PRBool aEliminateLeading=PR_TRUE,
PRBool aEliminateTrailing=PR_TRUE);
/**
* Determine if given char is a valid space character
*
* @param aChar is character to be tested
* @return TRUE if is valid space char
*/
static PRBool IsSpace(PRUnichar ch);
/**
* Determine if given char in valid alpha range
*
* @param aChar is character to be tested
* @return TRUE if in alpha range
*/
static PRBool IsAlpha(PRUnichar ch);
/**
* Determine if given char is valid digit
*
* @param aChar is character to be tested
* @return TRUE if char is a valid digit
*/
static PRBool IsDigit(PRUnichar ch);
/**********************************************************************
Searching methods...
*********************************************************************/
/**
* Search for given character within this string.
* This method does so by using a binary search,
* so your string HAD BETTER BE ORDERED!
*
* @param aChar is the unicode char to be found
* @return offset in string, or -1 (kNotFound)
*/
PRInt32 BinarySearch(PRUnichar aChar) const;
/**
* Search for given substring within this string
*
* @param aString is substring to be sought in this
* @return offset in string, or -1 (kNotFound)
*/
PRInt32 Find(const char* aString) const;
PRInt32 Find(const PRUnichar* aString) const;
PRInt32 Find(const nsString1& aString) const;
/**
* Search for given char within this string
*
* @param aChar - char to be found
* @return offset in string, or -1 (kNotFound)
*/
PRInt32 Find(PRUnichar aChar,PRInt32 offset=0) const;
/**
* This method searches this string for the first character
* found in the given string
* @param aString contains set of chars to be found
* @param anOffset tells us where to start searching in this
* @return -1 if not found, else the offset in this
*/
PRInt32 FindCharInSet(const char* aString,PRInt32 anOffset=0) const;
PRInt32 FindCharInSet(nsString1& aString,PRInt32 anOffset=0) const;
/**
* This method searches this string for the last character
* found in the given string
* @param aString contains set of chars to be found
* @param anOffset tells us where to start searching in this
* @return -1 if not found, else the offset in this
*/
PRInt32 RFindCharInSet(const char* aString,PRInt32 anOffset=0) const;
PRInt32 RFindCharInSet(nsString1& aString,PRInt32 anOffset=0) const;
/**
* This methods scans the string backwards, looking for the given string
* @param aString is substring to be sought in this
* @param aIgnoreCase tells us whether or not to do caseless compare
* @return offset in string, or -1 (kNotFound)
*/
PRInt32 RFind(const char* aCString,PRBool aIgnoreCase=PR_FALSE) const;
PRInt32 RFind(const PRUnichar* aString,PRBool aIgnoreCase=PR_FALSE) const;
PRInt32 RFind(const nsString1& aString,PRBool aIgnoreCase=PR_FALSE) const;
/**
* This methods scans the string backwards, looking for the given char
* @param char is the char to be sought in this
* @param aIgnoreCase tells us whether or not to do caseless compare
* @return offset in string, or -1 (kNotFound)
*/
PRInt32 RFind(PRUnichar aChar,PRBool aIgnoreCase=PR_FALSE) const;
/**********************************************************************
Comparison methods...
*********************************************************************/
/**
* Compares a given string type to this string.
* @update gess 7/27/98
* @param S is the string to be compared
* @param aIgnoreCase tells us how to treat case
* @return -1,0,1
*/
virtual PRInt32 Compare(const nsString1 &aString,PRBool aIgnoreCase=PR_FALSE) const;
virtual PRInt32 Compare(const char *aString,PRBool aIgnoreCase=PR_FALSE,PRInt32 aLength=-1) const;
virtual PRInt32 Compare(const PRUnichar *aString,PRBool aIgnoreCase=PR_FALSE,PRInt32 aLength=-1) const;
/**
* These methods compare a given string type to this one
* @param aString is the string to be compared to this
* @return TRUE or FALSE
*/
PRBool operator==(const nsString1 &aString) const;
PRBool operator==(const char *aString) const;
PRBool operator==(const PRUnichar* aString) const;
PRBool operator==(PRUnichar* aString) const;
/**
* These methods perform a !compare of a given string type to this
* @param aString is the string to be compared to this
* @return TRUE
*/
PRBool operator!=(const nsString1 &aString) const;
PRBool operator!=(const char *aString) const;
PRBool operator!=(const PRUnichar* aString) const;
/**
* These methods test if a given string is < than this
* @param aString is the string to be compared to this
* @return TRUE or FALSE
*/
PRBool operator<(const nsString1 &aString) const;
PRBool operator<(const char *aString) const;
PRBool operator<(const PRUnichar* aString) const;
/**
* These methods test if a given string is > than this
* @param aString is the string to be compared to this
* @return TRUE or FALSE
*/
PRBool operator>(const nsString1 &S) const;
PRBool operator>(const char *aCString) const;
PRBool operator>(const PRUnichar* aString) const;
/**
* These methods test if a given string is <= than this
* @param aString is the string to be compared to this
* @return TRUE or FALSE
*/
PRBool operator<=(const nsString1 &S) const;
PRBool operator<=(const char *aCString) const;
PRBool operator<=(const PRUnichar* aString) const;
/**
* These methods test if a given string is >= than this
* @param aString is the string to be compared to this
* @return TRUE or FALSE
*/
PRBool operator>=(const nsString1 &S) const;
PRBool operator>=(const char* aCString) const;
PRBool operator>=(const PRUnichar* aString) const;
/**
* Compare this to given string; note that we compare full strings here.
* The optional length argument just lets us know how long the given string is.
* If you provide a length, it is compared to length of this string as an
* optimization.
*
* @param aString -- the string to compare to this
* @param aLength -- optional length of given string.
* @return TRUE if equal
*/
PRBool Equals(const nsString1& aString) const;
PRBool Equals(const char* aString,PRInt32 aLength=-1) const;
PRBool Equals(const nsIAtom *aAtom) const;
/**
* Compares to unichar string ptrs to each other
* @param s1 is a ptr to a unichar buffer
* @param s2 is a ptr to a unichar buffer
* @return TRUE if they match
*/
PRBool Equals(const PRUnichar* s1, const PRUnichar* s2) const;
/**
* Compare this to given string; note that we compare full strings here.
* The optional length argument just lets us know how long the given string is.
* If you provide a length, it is compared to length of this string as an
* optimization.
*
* @param aString -- the string to compare to this
* @param aLength -- optional length of given string.
* @return TRUE if equal
*/
PRBool EqualsIgnoreCase(const nsString1& aString) const;
PRBool EqualsIgnoreCase(const char* aString,PRInt32 aLength=-1) const;
PRBool EqualsIgnoreCase(const nsIAtom *aAtom) const;
/**
* Compares to unichar string ptrs to each other without respect to case
* @param s1 is a ptr to a unichar buffer
* @param s2 is a ptr to a unichar buffer
* @return TRUE if they match
*/
PRBool EqualsIgnoreCase(const PRUnichar* s1, const PRUnichar* s2) const;
static void SelfTest();
virtual void DebugDump(ostream& aStream) const;
protected:
typedef PRUnichar chartype;
chartype* mStr;
PRInt32 mLength;
PRInt32 mCapacity;
#ifdef RICKG_DEBUG
static PRBool mSelfTested;
#endif
};
ostream& operator<<(ostream& os,nsString1& aString);
extern NS_COM int fputs(const nsString1& aString, FILE* out);
//----------------------------------------------------------------------
/**
* A version of nsString1 which is designed to be used as an automatic
* variable. It attempts to operate out of a fixed size internal
* buffer until too much data is added; then a dynamic buffer is
* allocated and grown as necessary.
*/
// XXX template this with a parameter for the size of the buffer?
class NS_COM nsAutoString1 : public nsString1 {
public:
nsAutoString1();
nsAutoString1(const nsString1& other);
nsAutoString1(const nsAutoString1& other);
nsAutoString1(PRUnichar aChar);
nsAutoString1(const char* aCString);
nsAutoString1(const PRUnichar* us, PRInt32 uslen = -1);
virtual ~nsAutoString1();
nsAutoString1& operator=(const nsString1& aString) {nsString1::operator=(aString); return *this;}
nsAutoString1& operator=(const nsAutoString1& aString) {nsString1::operator=(aString); return *this;}
nsAutoString1& operator=(const char* aCString) {nsString1::operator=(aCString); return *this;}
nsAutoString1& operator=(char aChar) {nsString1::operator=(aChar); return *this;}
nsAutoString1& operator=(const PRUnichar* aBuffer) {nsString1::operator=(aBuffer); return *this;}
nsAutoString1& operator=(PRUnichar aChar) {nsString1::operator=(aChar); return *this;}
virtual void SizeOf(nsISizeOfHandler* aHandler) const;
static void SelfTest();
protected:
virtual void EnsureCapacityFor(PRInt32 aNewLength);
chartype mBuf[32];
};
ostream& operator<<(ostream& os,nsAutoString1& aString);
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -1,827 +0,0 @@
/* -*- 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.
*/
/***********************************************************************
MODULE NOTES:
This version of the nsString class offers many improvements over the
original version:
1. Wide and narrow chars
2. Allocators
3. Much smarter autostrings
4. Subsumable strings
5. Memory pools and recycling
***********************************************************************/
#ifndef _nsString2
#define _nsString2
#include "prtypes.h"
#include "nscore.h"
#include <iostream.h>
#include <stdio.h>
#include "nsCRT.h"
#include "nsStr.h"
#include <iostream.h>
#include <stdio.h>
#include "nsIAtom.h"
class nsISizeOfHandler;
#define nsString2 nsString
#define nsAutoString2 nsAutoString
#define kRadix10 (10)
#define kRadix16 (16)
#define kAutoDetect (100)
#define kRadixUnknown (kAutoDetect+1)
class NS_COM nsSubsumeStr;
class NS_COM nsString2 : public nsStr {
public:
/**
* Default constructor. Note that we actually allocate a small buffer
* to begin with. This is because the "philosophy" of the string class
* was to allow developers direct access to the underlying buffer for
* performance reasons.
*/
nsString2(eCharSize aCharSize=kDefaultCharSize,nsIMemoryAgent* anAgent=0);
/**
* This constructor accepts an isolatin string
* @param aCString is a ptr to a 1-byte cstr
*/
nsString2(const char* aCString,eCharSize aCharSize=kDefaultCharSize,nsIMemoryAgent* anAgent=0);
/**
* This constructor accepts a unichar string
* @param aCString is a ptr to a 2-byte cstr
*/
nsString2(const PRUnichar* aString,eCharSize aCharSize=kDefaultCharSize,nsIMemoryAgent* anAgent=0);
/**
* This is a copy constructor that accepts an nsStr
* @param reference to another nsString2
*/
nsString2(const nsStr&,eCharSize aCharSize=kDefaultCharSize,nsIMemoryAgent* anAgent=0);
/**
* This is our copy constructor
* @param reference to another nsString2
*/
nsString2(const nsString2& aString);
/**
* This constructor takes a subsumestr
* @param reference to subsumestr
*/
nsString2(nsSubsumeStr& aSubsumeStr);
/**
* Destructor
*
*/
virtual ~nsString2();
/**
* Retrieve the length of this string
* @return string length
*/
inline PRInt32 Length() const { return (PRInt32)mLength; }
/**
* Retrieve the size of this string
* @return string length
*/
virtual void SizeOf(nsISizeOfHandler* aHandler) const;
/**
* Call this method if you want to force a different string capacity
* @update gess7/30/98
* @param aLength -- contains new length for mStr
* @return
*/
void SetLength(PRUint32 aLength) {
SetCapacity(aLength);
}
/**
* Sets the new length of the string.
* @param aLength is new string length.
* @return nada
*/
void SetCapacity(PRUint32 aLength);
/**
* This method truncates this string to given length.
*
* @param anIndex -- new length of string
* @return nada
*/
void Truncate(PRInt32 anIndex=0);
/**
* Determine whether or not the characters in this
* string are in sorted order.
*
* @return TRUE if ordered.
*/
PRBool IsOrdered(void) const;
/**
* Determine whether or not the characters in this
* string are in store as 1 or 2 byte (unicode) strings.
*
* @return TRUE if ordered.
*/
PRBool IsUnicode(void) const {
PRBool result=PRBool(mCharSize==eTwoByte);
return result;
}
/**
* Determine whether or not this string has a length of 0
*
* @return TRUE if empty.
*/
PRBool IsEmpty(void) const {
return PRBool(0==mLength);
}
/**********************************************************************
Accessor methods...
*********************************************************************/
const char* GetBuffer(void) const;
const PRUnichar* GetUnicode(void) const;
/**
* Get nth character.
*/
PRUnichar operator[](PRUint32 anIndex) const;
PRUnichar CharAt(PRUint32 anIndex) const;
PRUnichar First(void) const;
PRUnichar Last(void) const;
PRBool SetCharAt(PRUnichar aChar,PRUint32 anIndex);
/**********************************************************************
String creation methods...
*********************************************************************/
/**
* Create a new string by appending given string to this
* @param aString -- 2nd string to be appended
* @return new string
*/
nsSubsumeStr operator+(const nsStr& aString);
/**
* Create a new string by appending given string to this
* @param aString -- 2nd string to be appended
* @return new string
*/
nsSubsumeStr operator+(const nsString2& aString);
/**
* create a new string by adding this to the given buffer.
* @param aCString is a ptr to cstring to be added to this
* @return newly created string
*/
nsSubsumeStr operator+(const char* aCString);
/**
* create a new string by adding this to the given wide buffer.
* @param aString is a ptr to UC-string to be added to this
* @return newly created string
*/
nsSubsumeStr operator+(const PRUnichar* aString);
/**
* create a new string by adding this to the given char.
* @param aChar is a char to be added to this
* @return newly created string
*/
nsSubsumeStr operator+(char aChar);
/**
* create a new string by adding this to the given char.
* @param aChar is a unichar to be added to this
* @return newly created string
*/
nsSubsumeStr operator+(PRUnichar aChar);
/**********************************************************************
Lexomorphic transforms...
*********************************************************************/
/**
* Converts all chars in given string to UCS2
* which ensure that the lower 256 chars are correct.
*/
void ToUCS2(PRUint32 aStartOffset);
/**
* Converts chars in this to lowercase
* @update gess 7/27/98
*/
void ToLowerCase();
/**
* Converts chars in this to lowercase, and
* stores them in aOut
* @update gess 7/27/98
* @param aOut is a string to contain result
*/
void ToLowerCase(nsString2& aString) const;
/**
* Converts chars in this to uppercase
* @update gess 7/27/98
*/
void ToUpperCase();
/**
* Converts chars in this to lowercase, and
* stores them in a given output string
* @update gess 7/27/98
* @param aOut is a string to contain result
*/
void ToUpperCase(nsString2& aString) const;
/**
* This method is used to remove all occurances of the
* characters found in aSet from this string.
*
* @param aSet -- characters to be cut from this
* @return *this
*/
nsString2& StripChars(const char* aSet);
/**
* This method strips whitespace throughout the string
*
* @return this
*/
nsString2& StripWhitespace();
/**
* swaps occurence of 1 string for another
*
* @return this
*/
nsString2& ReplaceChar(PRUnichar aSourceChar,PRUnichar aDestChar);
/**
* This method trims characters found in aTrimSet from
* either end of the underlying string.
*
* @param aTrimSet -- contains chars to be trimmed from
* both ends
* @return this
*/
nsString2& Trim(const char* aSet,PRBool aEliminateLeading=PR_TRUE,PRBool aEliminateTrailing=PR_TRUE);
/**
* This method strips whitespace from string.
* You can control whether whitespace is yanked from
* start and end of string as well.
*
* @param aEliminateLeading controls stripping of leading ws
* @param aEliminateTrailing controls stripping of trailing ws
* @return this
*/
nsString2& CompressSet(const char* aSet, char aChar, PRBool aEliminateLeading=PR_TRUE,PRBool aEliminateTrailing=PR_TRUE);
/**
* This method strips whitespace from string.
* You can control whether whitespace is yanked from
* start and end of string as well.
*
* @param aEliminateLeading controls stripping of leading ws
* @param aEliminateTrailing controls stripping of trailing ws
* @return this
*/
nsString2& CompressWhitespace( PRBool aEliminateLeading=PR_TRUE,PRBool aEliminateTrailing=PR_TRUE);
/**********************************************************************
string conversion methods...
*********************************************************************/
/**
* This method constructs a new nsString2 on the stack that is a copy
* of this string.
*
*/
nsString2* ToNewString() const;
/**
* Creates an ISOLatin1 clone of this string
* @return ptr to new isolatin1 string
*/
char* ToNewCString() const;
/**
* Creates a unicode clone of this string
* @return ptr to new unicode string
*/
PRUnichar* ToNewUnicode() const;
/**
* Copies data from internal buffer onto given char* buffer
* @param aBuf is the buffer where data is stored
* @param aBuflength is the max # of chars to move to buffer
* @return ptr to given buffer
*/
char* ToCString(char* aBuf,PRUint32 aBufLength,PRUint32 anOffset=0) const;
/**
* Perform string to float conversion.
* @param aErrorCode will contain error if one occurs
* @return float rep of string value
*/
float ToFloat(PRInt32* aErrorCode) const;
/**
* Try to derive the radix from the value contained in this string
* @return kRadix10, kRadix16 or kAutoDetect (meaning unknown)
*/
PRUint32 DetermineRadix(void);
/**
* Perform string to int conversion.
* @param aErrorCode will contain error if one occurs
* @return int rep of string value
*/
PRInt32 ToInteger(PRInt32* aErrorCode,PRUint32 aRadix=kRadix10) const;
/**********************************************************************
String manipulation methods...
*********************************************************************/
/**
* Functionally equivalent to assign or operator=
*
*/
nsString2& SetString(const char* aString,PRInt32 aLength=-1) {return Assign(aString,aLength);}
nsString2& SetString(const PRUnichar* aString,PRInt32 aLength=-1) {return Assign(aString,aLength);}
nsString2& SetString(const nsString2& aString,PRInt32 aLength=-1) {return Assign(aString,aLength);}
/**
* assign given string to this string
* @param aStr: buffer to be assigned to this
* @param alength is the length of the given str (or -1)
if you want me to determine its length
* @return this
*/
nsString2& Assign(const nsString2& aString,PRInt32 aCount=-1);
nsString2& Assign(const nsStr& aString,PRInt32 aCount=-1);
nsString2& Assign(const char* aString,PRInt32 aCount=-1);
nsString2& Assign(const PRUnichar* aString,PRInt32 aCount=-1);
nsString2& Assign(char aChar);
nsString2& Assign(PRUnichar aChar);
/**
* here come a bunch of assignment operators...
* @param aString: string to be added to this
* @return this
*/
nsString2& operator=(const nsString2& aString) {return Assign(aString);}
nsString2& operator=(const nsStr& aString) {return Assign(aString);}
nsString2& operator=(char aChar) {return Assign(aChar);}
nsString2& operator=(PRUnichar aChar) {return Assign(aChar);}
nsString2& operator=(const char* aCString) {return Assign(aCString);}
nsString2& operator=(const PRUnichar* aString) {return Assign(aString);}
#ifdef AIX
nsString2& operator=(const nsSubsumeStr& aSubsumeString); // AIX requires a const here
#else
nsString2& operator=(nsSubsumeStr& aSubsumeString);
#endif
/**
* Here's a bunch of append mehtods for varying types...
* @param aString : string to be appended to this
* @return this
*/
nsString2& operator+=(const nsStr& aString){return Append(aString,aString.mLength);}
nsString2& operator+=(const nsString2& aString){return Append(aString,aString.mLength);}
nsString2& operator+=(const char* aCString) {return Append(aCString);}
//nsString2& operator+=(char aChar){return Append(aChar);}
nsString2& operator+=(const PRUnichar* aUCString) {return Append(aUCString);}
nsString2& operator+=(PRUnichar aChar){return Append(aChar);}
/*
* Appends n characters from given string to this,
* This version computes the length of your given string
*
* @param aString is the source to be appended to this
* @return number of chars copied
*/
nsString2& Append(const nsStr& aString) {return Append(aString,aString.mLength);}
nsString2& Append(const nsString2& aString) {return Append(aString,aString.mLength);}
/*
* Appends n characters from given string to this,
*
* @param aString is the source to be appended to this
* @param aCount -- number of chars to copy
* @return number of chars copied
*/
nsString2& Append(const nsStr& aString,PRInt32 aCount);
nsString2& Append(const nsString2& aString,PRInt32 aCount);
nsString2& Append(const char* aString,PRInt32 aCount=-1);
nsString2& Append(const PRUnichar* aString,PRInt32 aCount=-1);
nsString2& Append(char aChar);
nsString2& Append(PRUnichar aChar);
nsString2& Append(PRInt32 aInteger,PRInt32 aRadix=10); //radix=8,10 or 16
nsString2& Append(float aFloat);
/*
* Copies n characters from this string to given string,
* starting at the leftmost offset.
*
*
* @param aCopy -- Receiving string
* @param aCount -- number of chars to copy
* @return number of chars copied
*/
PRUint32 Left(nsString2& aCopy,PRInt32 aCount) const;
/*
* Copies n characters from this string to given string,
* starting at the given offset.
*
*
* @param aCopy -- Receiving string
* @param aCount -- number of chars to copy
* @param anOffset -- position where copying begins
* @return number of chars copied
*/
PRUint32 Mid(nsString2& aCopy,PRUint32 anOffset,PRInt32 aCount) const;
/*
* Copies n characters from this string to given string,
* starting at rightmost char.
*
*
* @param aCopy -- Receiving string
* @param aCount -- number of chars to copy
* @return number of chars copied
*/
PRUint32 Right(nsString2& aCopy,PRInt32 aCount) const;
/*
* This method inserts n chars from given string into this
* string at str[anOffset].
*
* @param aCopy -- String to be inserted into this
* @param anOffset -- insertion position within this str
* @param aCount -- number of chars to be copied from aCopy
* @return number of chars inserted into this.
*/
nsString2& Insert(const nsString2& aCopy,PRUint32 anOffset,PRInt32 aCount=-1);
/**
* Insert a given string into this string at
* a specified offset.
*
* @param aString* to be inserted into this string
* @param anOffset is insert pos in str
* @return the number of chars inserted into this string
*/
nsString2& Insert(const char* aChar,PRUint32 anOffset,PRInt32 aCount=-1);
nsString2& Insert(const PRUnichar* aChar,PRUint32 anOffset,PRInt32 aCount=-1);
/**
* Insert a single char into this string at
* a specified offset.
*
* @param character to be inserted into this string
* @param anOffset is insert pos in str
* @return the number of chars inserted into this string
*/
//nsString2& Insert(char aChar,PRUint32 anOffset);
nsString2& Insert(PRUnichar aChar,PRUint32 anOffset);
/*
* This method is used to cut characters in this string
* starting at anOffset, continuing for aCount chars.
*
* @param anOffset -- start pos for cut operation
* @param aCount -- number of chars to be cut
* @return *this
*/
nsString2& Cut(PRUint32 anOffset,PRInt32 aCount);
/**********************************************************************
Searching methods...
*********************************************************************/
/**
* Search for given character within this string.
* This method does so by using a binary search,
* so your string HAD BETTER BE ORDERED!
*
* @param aChar is the unicode char to be found
* @return offset in string, or -1 (kNotFound)
*/
PRInt32 BinarySearch(PRUnichar aChar) const;
/**
* Search for given substring within this string
*
* @param aString is substring to be sought in this
* @return offset in string, or -1 (kNotFound)
*/
PRInt32 Find(const nsString2& aString,PRBool aIgnoreCase=PR_FALSE) const;
PRInt32 Find(const nsStr& aString,PRBool aIgnoreCase=PR_FALSE) const;
PRInt32 Find(const char* aString,PRBool aIgnoreCase=PR_FALSE) const;
PRInt32 Find(const PRUnichar* aString,PRBool aIgnoreCase=PR_FALSE) const;
PRInt32 Find(PRUnichar aChar,PRUint32 offset=0,PRBool aIgnoreCase=PR_FALSE) const;
/**
* This method searches this string for the first character
* found in the given string
* @param aString contains set of chars to be found
* @param anOffset tells us where to start searching in this
* @return -1 if not found, else the offset in this
*/
PRInt32 FindCharInSet(const char* aString,PRUint32 anOffset=0) const;
PRInt32 FindCharInSet(const PRUnichar* aString,PRUint32 anOffset=0) const;
PRInt32 FindCharInSet(const nsString2& aString,PRUint32 anOffset=0) const;
/**
* This method searches this string for the last character
* found in the given string
* @param aString contains set of chars to be found
* @param anOffset tells us where to start searching in this
* @return -1 if not found, else the offset in this
*/
PRInt32 RFindCharInSet(const char* aString,PRUint32 anOffset=0) const;
PRInt32 RFindCharInSet(const PRUnichar* aString,PRUint32 anOffset=0) const;
PRInt32 RFindCharInSet(const nsString2& aString,PRUint32 anOffset=0) const;
/**
* This methods scans the string backwards, looking for the given string
* @param aString is substring to be sought in this
* @param aIgnoreCase tells us whether or not to do caseless compare
* @return offset in string, or -1 (kNotFound)
*/
PRInt32 RFind(const char* aCString,PRBool aIgnoreCase=PR_FALSE) const;
PRInt32 RFind(const nsString2& aString,PRBool aIgnoreCase=PR_FALSE) const;
PRInt32 RFind(const nsStr& aString,PRBool aIgnoreCase=PR_FALSE) const;
PRInt32 RFind(const PRUnichar* aString,PRBool aIgnoreCase=PR_FALSE) const;
PRInt32 RFind(PRUnichar aChar,PRUint32 offset=0,PRBool aIgnoreCase=PR_FALSE) const;
/**********************************************************************
Comparison methods...
*********************************************************************/
/**
* Compares a given string type to this string.
* @update gess 7/27/98
* @param S is the string to be compared
* @param aIgnoreCase tells us how to treat case
* @return -1,0,1
*/
virtual PRInt32 Compare(const nsString2& aString,PRBool aIgnoreCase=PR_FALSE,PRInt32 aLength=-1) const;
virtual PRInt32 Compare(const nsStr &aString,PRBool aIgnoreCase=PR_FALSE,PRInt32 aLength=-1) const;
virtual PRInt32 Compare(const char* aString,PRBool aIgnoreCase=PR_FALSE,PRInt32 aLength=-1) const;
virtual PRInt32 Compare(const PRUnichar* aString,PRBool aIgnoreCase=PR_FALSE,PRInt32 aLength=-1) const;
/**
* These methods compare a given string type to this one
* @param aString is the string to be compared to this
* @return TRUE or FALSE
*/
PRBool operator==(const nsString2 &aString) const;
PRBool operator==(const nsStr &aString) const;
PRBool operator==(const char *aString) const;
PRBool operator==(const PRUnichar* aString) const;
/**
* These methods perform a !compare of a given string type to this
* @param aString is the string to be compared to this
* @return TRUE
*/
PRBool operator!=(const nsString2 &aString) const;
PRBool operator!=(const nsStr &aString) const;
PRBool operator!=(const char* aString) const;
PRBool operator!=(const PRUnichar* aString) const;
/**
* These methods test if a given string is < than this
* @param aString is the string to be compared to this
* @return TRUE or FALSE
*/
PRBool operator<(const nsString2 &aString) const;
PRBool operator<(const nsStr &aString) const;
PRBool operator<(const char* aString) const;
PRBool operator<(const PRUnichar* aString) const;
/**
* These methods test if a given string is > than this
* @param aString is the string to be compared to this
* @return TRUE or FALSE
*/
PRBool operator>(const nsString2 &aString) const;
PRBool operator>(const nsStr &S) const;
PRBool operator>(const char* aString) const;
PRBool operator>(const PRUnichar* aString) const;
/**
* These methods test if a given string is <= than this
* @param aString is the string to be compared to this
* @return TRUE or FALSE
*/
PRBool operator<=(const nsString2 &aString) const;
PRBool operator<=(const nsStr &S) const;
PRBool operator<=(const char* aString) const;
PRBool operator<=(const PRUnichar* aString) const;
/**
* These methods test if a given string is >= than this
* @param aString is the string to be compared to this
* @return TRUE or FALSE
*/
PRBool operator>=(const nsString2 &aString) const;
PRBool operator>=(const nsStr &S) const;
PRBool operator>=(const char* aString) const;
PRBool operator>=(const PRUnichar* aString) const;
/**
* Compare this to given string; note that we compare full strings here.
* The optional length argument just lets us know how long the given string is.
* If you provide a length, it is compared to length of this string as an
* optimization.
*
* @param aString -- the string to compare to this
* @param aLength -- optional length of given string.
* @return TRUE if equal
*/
PRBool Equals(const nsString2 &aString,PRBool aIgnoreCase=PR_FALSE) const;
PRBool Equals(const nsStr& aString,PRBool aIgnoreCase=PR_FALSE) const;
PRBool Equals(const char* aString,PRBool aIgnoreCase=PR_FALSE) const;
PRBool Equals(const char* aString,PRUint32 aCount,PRBool aIgnoreCase) const;
PRBool Equals(const PRUnichar* aString,PRBool aIgnoreCase=PR_FALSE) const;
PRBool Equals(const PRUnichar* aString,PRUint32 aCount,PRBool aIgnoreCase) const;
PRBool Equals(const nsIAtom* anAtom,PRBool aIgnoreCase) const;
PRBool Equals(const PRUnichar* s1, const PRUnichar* s2,PRBool aIgnoreCase=PR_FALSE) const;
PRBool EqualsIgnoreCase(const nsString2& aString) const;
PRBool EqualsIgnoreCase(const char* aString,PRInt32 aLength=-1) const;
PRBool EqualsIgnoreCase(const nsIAtom *aAtom) const;
PRBool EqualsIgnoreCase(const PRUnichar* s1, const PRUnichar* s2) const;
/**
* Determine if given char is a valid space character
*
* @param aChar is character to be tested
* @return TRUE if is valid space char
*/
static PRBool IsSpace(PRUnichar ch);
/**
* Determine if given char in valid alpha range
*
* @param aChar is character to be tested
* @return TRUE if in alpha range
*/
static PRBool IsAlpha(PRUnichar ch);
/**
* Determine if given char is valid digit
*
* @param aChar is character to be tested
* @return TRUE if char is a valid digit
*/
static PRBool IsDigit(PRUnichar ch);
static void Recycle(nsString2* aString);
static nsString2* CreateString(eCharSize aCharSize=eTwoByte);
virtual void DebugDump(ostream& aStream) const;
nsIMemoryAgent* mAgent;
};
extern NS_COM int fputs(const nsString2& aString, FILE* out);
ostream& operator<<(ostream& aStream,const nsString2& aString);
/**************************************************************
Here comes the AutoString class which uses internal memory
(typically found on the stack) for its default buffer.
If the buffer needs to grow, it gets reallocated on the heap.
**************************************************************/
class NS_COM nsAutoString2 : public nsString2 {
public:
nsAutoString2(eCharSize aCharSize=kDefaultCharSize);
nsAutoString2(nsStr& anExtBuffer,const char* aCString);
nsAutoString2(const char* aCString,eCharSize aCharSize=kDefaultCharSize);
nsAutoString2(char* aCString,PRInt32 aCapacity=-1,eCharSize aCharSize=kDefaultCharSize,PRBool assumeOwnership=PR_FALSE);
nsAutoString2(const PRUnichar* aString,eCharSize aCharSize=kDefaultCharSize);
nsAutoString2(PRUnichar* aString,PRInt32 aCapacity=-1,eCharSize aCharSize=kDefaultCharSize,PRBool assumeOwnership=PR_FALSE);
nsAutoString2(const nsStr& aString,eCharSize aCharSize=kDefaultCharSize);
nsAutoString2(const nsString2& aString,eCharSize aCharSize=kDefaultCharSize);
nsAutoString2(const nsAutoString2& aString,eCharSize aCharSize=kDefaultCharSize);
#ifdef AIX
nsAutoString2(const nsSubsumeStr& aSubsumeStr); // AIX requires a const
#else
nsAutoString2(nsSubsumeStr& aSubsumeStr);
#endif // AIX
nsAutoString2(PRUnichar aChar,eCharSize aCharSize=kDefaultCharSize);
virtual ~nsAutoString2();
nsAutoString2& operator=(const nsString2& aString) {nsString2::operator=(aString); return *this;}
nsAutoString2& operator=(const nsStr& aString) {nsString2::Assign(aString); return *this;}
nsAutoString2& operator=(const nsAutoString2& aString) {nsString2::operator=(aString); return *this;}
nsAutoString2& operator=(const char* aCString) {nsString2::operator=(aCString); return *this;}
nsAutoString2& operator=(char aChar) {nsString2::operator=(aChar); return *this;}
nsAutoString2& operator=(const PRUnichar* aBuffer) {nsString2::operator=(aBuffer); return *this;}
nsAutoString2& operator=(PRUnichar aChar) {nsString2::operator=(aChar); return *this;}
/**
* Retrieve the size of this string
* @return string length
*/
virtual void SizeOf(nsISizeOfHandler* aHandler) const;
char mBuffer[32];
};
/***************************************************************
The subsumestr class is very unusual.
It differs from a normal string in that it doesn't use normal
copy semantics when another string is assign to this.
Instead, it "steals" the contents of the source string.
This is very handy for returning nsString classes as part of
an operator+(...) for example, in that it cuts down the number
of copy operations that must occur.
You should probably not use this class unless you really know
what you're doing.
***************************************************************/
class NS_COM nsSubsumeStr : public nsString2 {
public:
nsSubsumeStr(nsString2& aString);
nsSubsumeStr(nsStr& aString);
nsSubsumeStr(PRUnichar* aString,PRBool assumeOwnership,PRInt32 aLength=-1);
nsSubsumeStr(char* aString,PRBool assumeOwnership,PRInt32 aLength=-1);
};
/***************************************************************
***************************************************************/
class NS_COM nsCAutoString: public nsAutoString{
public:
nsCAutoString(const nsString2& aString);
operator const char*() const;
};
#endif

View File

@@ -1,167 +0,0 @@
/* -*- 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);
mBuf = 0;
mBufOwner = PR_TRUE;
return &mBuf;
}
const PRUnichar**
nsXPIDLString::StartAssignmentByReference()
{
if (mBufOwner && mBuf)
XPIDL_FREE(mBuf);
mBuf = 0;
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);
mBuf = 0;
mBufOwner = PR_TRUE;
return &mBuf;
}
const char**
nsXPIDLCString::StartAssignmentByReference()
{
if (mBufOwner && mBuf)
XPIDL_FREE(mBuf);
mBuf = 0;
mBufOwner = PR_FALSE;
return (const char**) &mBuf;
}

View File

@@ -1,300 +0,0 @@
/* -*- 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 generate 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...
printf("bar is %s!\n", bar);
delete[] bar;
(Strictly speaking, the `delete[] bar' should use the proper XPCOM
de-allocator; 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...
printf("bar is %s!\n", (const char*) bar);
// no need to remember to delete[].
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()' before passing it to a getter: 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& /* aXPIDLCString */) { 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__

View File

@@ -1,41 +0,0 @@
#!gmake
# The contents of this file are subject to the Netscape Public License
# Version 1.0 (the "NPL"); you may not use this file except in
# compliance with the NPL. You may obtain a copy of the NPL at
# http://www.mozilla.org/NPL/
#
# Software distributed under the NPL is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
# for the specific language governing rights and limitations under the
# NPL.
#
# The Initial Developer of this code under the NPL is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
# Reserved.
DEPTH = ..
topsrcdir = @top_srcdir@
VPATH = @srcdir@
srcdir = @srcdir@
include $(DEPTH)/config/autoconf.mk
DIRS= typelib \
base \
ds \
io \
components \
threads \
reflect \
proxy \
build \
tools \
sample \
$(NULL)
ifdef ENABLE_TESTS
DIRS += tests
endif
include $(topsrcdir)/config/rules.mk

File diff suppressed because it is too large Load Diff

View File

@@ -1,12 +0,0 @@
nsAgg.h
nsIAllocator.h
nsCOMPtr.h
nsCom.h
nsDebug.h
nsError.h
nsID.h
nsIID.h
nsIPtr.h
nsISupportsUtils.h
nsTraceRefcnt.h
nscore.h

View File

@@ -1,2 +0,0 @@
nsISupports.idl
nsrootidl.idl

View File

@@ -1,73 +0,0 @@
#!gmake
#
# The contents of this file are subject to the Netscape Public License
# Version 1.0 (the "NPL"); you may not use this file except in
# compliance with the NPL. You may obtain a copy of the NPL at
# http://www.mozilla.org/NPL/
#
# Software distributed under the NPL is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
# for the specific language governing rights and limitations under the
# NPL.
#
# The Initial Developer of this code under the NPL is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
# Reserved.
DEPTH=../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
include $(topsrcdir)/config/config.mk
LIBRARY_NAME = xpcombase_s
MODULE = xpcom
XPIDL_MODULE = xpcom_base
XPIDLSRCS = \
nsrootidl.idl \
nsISupports.idl \
$(NULL)
CPPSRCS = \
nsAllocator.cpp \
nsDebug.cpp \
nsTraceRefcnt.cpp \
nsCOMPtr.cpp \
nsID.cpp \
$(NULL)
EXPORTS = \
nsAgg.h \
nsIAllocator.h \
nsCOMPtr.h \
nsCom.h \
nsDebug.h \
nsError.h \
nsID.h \
nsIID.h \
nsIPtr.h \
nsISupportsUtils.h \
nsTraceRefcnt.h \
nscore.h \
$(NULL)
EXPORTS := $(addprefix $(srcdir)/, $(EXPORTS))
DEFINES += -D_IMPL_NS_COM
REQUIRES = xpcom
MKSHLIB :=
# we don't want the shared lib, but we want to force the creation of a static lib.
override NO_SHARED_LIB=1
override NO_STATIC_LIB=
include $(topsrcdir)/config/rules.mk

View File

@@ -1,81 +0,0 @@
#!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=..\..
MODULE = xpcom
################################################################################
## exports
EXPORTS = \
nsAgg.h \
nsIAllocator.h \
nsCOMPtr.h \
nsCom.h \
nsDebug.h \
nsError.h \
nsID.h \
nsIID.h \
nsIPtr.h \
nsISupportsUtils.h \
nsTraceRefcnt.h \
nscore.h \
$(NULL)
XPIDL_MODULE = xpcom_base
XPIDLSRCS = \
.\nsrootidl.idl \
.\nsISupports.idl \
$(NULL)
################################################################################
## library
#MAKE_OBJ_TYPE = DLL
#LIBNAME = .\$(OBJDIR)\xpcombase
#DLL = $(LIBNAME).dll
LIBRARY_NAME=xpcombase_s
LINCS = \
-I$(PUBLIC)\xpcom \
$(NULL)
LCFLAGS = -D_IMPL_NS_COM -DWIN32_LEAN_AND_MEAN
CPP_OBJS = \
.\$(OBJDIR)\nsDebug.obj \
.\$(OBJDIR)\nsAllocator.obj \
.\$(OBJDIR)\nsCOMPtr.obj \
.\$(OBJDIR)\nsID.obj \
.\$(OBJDIR)\nsTraceRefcnt.obj \
$(NULL)
include <$(DEPTH)\config\rules.mak>
#libs:: $(DLL)
# $(MAKE_INSTALL) $(LIBNAME).$(DLL_SUFFIX) $(DIST)\bin
# $(MAKE_INSTALL) $(LIBNAME).$(LIB_SUFFIX) $(DIST)\lib
libs:: $(LIBRARY)
$(MAKE_INSTALL) $(LIBRARY) $(DIST)\lib
clobber::
rm -f $(DIST)\lib\$(LIBRARY_NAME).lib

View File

@@ -1,170 +0,0 @@
/* -*- 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

@@ -1,179 +0,0 @@
/* -*- 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 */
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(nsIAllocator::GetIID()) ||
aIID.Equals(nsCOMTypeInfo<nsISupports>::GetIID())) {
*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(nsCOMTypeInfo<nsISupports>::GetIID()))
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(nsCOMTypeInfo<nsISupports>::GetIID()))
*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)
{
return PR_Realloc(ptr, size);
}
NS_METHOD
nsAllocatorImpl::Free(void* ptr)
{
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;
}
////////////////////////////////////////////////////////////////////////////////
#if 0
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?
}
#endif
////////////////////////////////////////////////////////////////////////////////
/*
* 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()
{
nsAllocatorImpl::Create(NULL, nsIAllocator::GetIID(), (void**)&mAllocator);
NS_ASSERTION(mAllocator, "failed to get Allocator!");
return (PRBool) mAllocator;
}

View File

@@ -1,92 +0,0 @@
/* -*- 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
* @result the rellocated block of memory
*/
NS_IMETHOD_(void*) Realloc(void* ptr, PRUint32 size);
/**
* Frees a block of memory.
*
* @param ptr - the block of memory to free
*/
NS_IMETHOD Free(void* ptr);
/**
* 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);
};
////////////////////////////////////////////////////////////////////////////////
#if 0
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
////////////////////////////////////////////////////////////////////////////////
#endif // nsAllocator_h__

View File

@@ -1,65 +0,0 @@
/* -*- 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"
#ifdef NSCAP_FEATURE_FACTOR_DESTRUCTOR
nsCOMPtr_base::~nsCOMPtr_base()
{
if ( mRawPtr )
NSCAP_RELEASE(mRawPtr);
}
#endif
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_ERROR_NULL_POINTER;
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

@@ -1,732 +0,0 @@
/* -*- 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
/*
Public things defined in this file:
T* rawTptr;
class nsCOMPtr<T> nsCOMPtr<T> smartTptr;
null_nsCOMPtr() smartTptr = null_nsCOMPtr();
do_QueryInterface( nsISupports* ) smartTptr = do_QueryInterface(other_ptr);
do_QueryInterface( nsISupports*, nsresult* ) smartTptr = do_QueryInterface(other_ptr, &status);
dont_QueryInterface( T* ) smartTptr = dont_QueryInterface(rawTptr);
getter_AddRefs( nsCOMPtr<T>& )
getter_AddRefs( T* )
dont_AddRef( T* )
CallQueryInterface( nsISupports*, T** )
CallQueryInterface( nsISupports*, nsCOMPtr<T>* )
*/
/*
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...
+ 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
#define HAVE_CPP_BOOL
#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
#define NSCAP_FEATURE_ALLOW_RAW_POINTERS
#define NSCAP_FEATURE_ALLOW_COMPARISONS
#define NSCAP_FEATURE_FACTOR_DESTRUCTOR
#ifdef NS_DEBUG
#define NSCAP_FEATURE_TEST_DONTQUERY_CASES
#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_BOOL
typedef bool NSCAP_BOOL;
#else
typedef PRBool NSCAP_BOOL;
#endif
#ifdef HAVE_CPP_NEW_CASTS
#define NSCAP_STATIC_CAST(T,x) static_cast<T>(x)
#define NSCAP_REINTERPRET_CAST(T,x) reinterpret_cast<T>(x)
#else
#define NSCAP_STATIC_CAST(T,x) ((T)(x))
#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|. DO NOT USE THIS TYPE DIRECTLY IN YOUR CODE.
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
/*
...
DO NOT USE THIS TYPE DIRECTLY IN YOUR CODE. Use |dont_QueryInterface()| instead.
*/
{
explicit
nsDontQueryInterface( T* aRawPtr )
: mRawPtr(aRawPtr)
{
// nothing else to do here
}
T* mRawPtr;
};
template <class T>
inline
const nsDontQueryInterface<T>
dont_QueryInterface( T* aRawPtr )
{
return nsDontQueryInterface<T>(aRawPtr);
}
struct nsQueryInterface
/*
...
DO NOT USE THIS TYPE DIRECTLY IN YOUR CODE. Use |do_QueryInterface()| instead.
*/
{
explicit
nsQueryInterface( nsISupports* aRawPtr, nsresult* error = 0 )
: mRawPtr(aRawPtr),
mErrorPtr(error)
{
// nothing else to do here
}
nsISupports* mRawPtr;
nsresult* mErrorPtr;
};
inline
const nsQueryInterface
do_QueryInterface( nsISupports* aRawPtr, nsresult* error = 0 )
{
return nsQueryInterface(aRawPtr, error);
}
#ifdef NSCAP_FEATURE_ALLOW_RAW_POINTERS
#define null_nsCOMPtr() (0)
#else
inline
const nsQueryInterface
null_nsCOMPtr()
/*
You can use this to assign |NULL| into an |nsCOMPtr|, e.g.,
myPtr = null_nsCOMPtr();
*/
{
typedef nsISupports* nsISupports_Ptr;
return nsQueryInterface(nsISupports_Ptr(0));
}
#endif
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.
DO NOT USE THIS TYPE DIRECTLY IN YOUR CODE. Use |getter_AddRefs()| or
|dont_AddRef()| instead.
See also |getter_AddRefs()|, |dont_AddRef()|, and |class nsGetterAddRefs|.
*/
{
explicit
nsDontAddRef( T* aRawPtr )
: mRawPtr(aRawPtr)
{
// nothing else to do here
}
T* mRawPtr;
};
template <class T>
inline
const nsDontAddRef<T>
getter_AddRefs( 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
const nsDontAddRef<T>
dont_AddRef( T* aRawPtr )
{
return nsDontAddRef<T>(aRawPtr);
}
class nsCOMPtr_base
/*
...factors implementation for all template versions of |nsCOMPtr|.
*/
{
public:
nsCOMPtr_base( nsISupports* rawPtr = 0 )
: mRawPtr(rawPtr)
{
// nothing else to do here
}
#ifdef NSCAP_FEATURE_FACTOR_DESTRUCTOR
NS_EXPORT ~nsCOMPtr_base();
#endif
#if 0
~nsCOMPtr_base()
{
if ( mRawPtr )
NSCAP_RELEASE(mRawPtr);
}
#endif
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;
#if 0
typedef nsDerivedSafe<T>* safe_ptr_t;
typedef T* safe_ptr_t;
#endif
#ifndef NSCAP_FEATURE_FACTOR_DESTRUCTOR
~nsCOMPtr()
{
if ( mRawPtr )
NSCAP_RELEASE(mRawPtr);
}
#endif
nsCOMPtr()
// : nsCOMPtr_base(0)
{
// nothing else to do here
}
nsCOMPtr( const nsQueryInterface& aSmartPtr )
// : nsCOMPtr_base(0)
{
assign_with_QueryInterface(aSmartPtr.mRawPtr, nsCOMTypeInfo<T>::GetIID(), aSmartPtr.mErrorPtr);
}
#ifdef NSCAP_FEATURE_TEST_DONTQUERY_CASES
void
Assert_NoQueryNeeded()
{
if ( !mRawPtr )
return;
T* query_result = 0;
nsresult status = CallQueryInterface(mRawPtr, &query_result);
NS_ASSERTION(query_result == mRawPtr, "QueryInterface needed");
if ( NS_SUCCEEDED(status) )
NSCAP_RELEASE(query_result);
}
#endif
nsCOMPtr( const nsDontAddRef<T>& aSmartPtr )
: nsCOMPtr_base(aSmartPtr.mRawPtr)
{
#ifdef NSCAP_FEATURE_TEST_DONTQUERY_CASES
Assert_NoQueryNeeded();
#endif
}
nsCOMPtr( const nsDontQueryInterface<T>& aSmartPtr )
: nsCOMPtr_base(aSmartPtr.mRawPtr)
{
if ( mRawPtr )
NSCAP_ADDREF(mRawPtr);
#ifdef NSCAP_FEATURE_TEST_DONTQUERY_CASES
Assert_NoQueryNeeded();
#endif
}
nsCOMPtr( const nsCOMPtr<T>& aSmartPtr )
: nsCOMPtr_base(aSmartPtr.mRawPtr)
{
if ( mRawPtr )
NSCAP_ADDREF(mRawPtr);
}
#ifdef NSCAP_FEATURE_ALLOW_RAW_POINTERS
nsCOMPtr( T* aRawPtr )
: nsCOMPtr_base(aRawPtr)
{
if ( mRawPtr )
NSCAP_ADDREF(mRawPtr);
#ifdef NSCAP_FEATURE_TEST_DONTQUERY_CASES
Assert_NoQueryNeeded();
#endif
}
nsCOMPtr<T>&
operator=( T* rhs )
{
assign_with_AddRef(rhs);
#ifdef NSCAP_FEATURE_TEST_DONTQUERY_CASES
Assert_NoQueryNeeded();
#endif
return *this;
}
#endif
nsCOMPtr<T>&
operator=( const nsQueryInterface& rhs )
{
assign_with_QueryInterface(rhs.mRawPtr, nsCOMTypeInfo<T>::GetIID(), rhs.mErrorPtr);
return *this;
}
nsCOMPtr<T>&
operator=( const nsDontAddRef<T>& rhs )
{
if ( mRawPtr )
NSCAP_RELEASE(mRawPtr);
mRawPtr = rhs.mRawPtr;
#ifdef NSCAP_FEATURE_TEST_DONTQUERY_CASES
Assert_NoQueryNeeded();
#endif
return *this;
}
nsCOMPtr<T>&
operator=( const nsDontQueryInterface<T>& rhs )
{
assign_with_AddRef(rhs.mRawPtr);
#ifdef NSCAP_FEATURE_TEST_DONTQUERY_CASES
Assert_NoQueryNeeded();
#endif
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, getter_AddRefs(fooP))
DO NOT USE THIS TYPE DIRECTLY IN YOUR CODE. Use |getter_AddRefs()| instead.
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**()
{
return NSCAP_REINTERPRET_CAST(void**, mTargetSmartPtr.StartAssignment());
}
T*&
operator*()
{
return *(mTargetSmartPtr.StartAssignment());
}
operator T**()
{
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);
}
#ifdef NSCAP_FEATURE_ALLOW_COMPARISONS
class NSCAP_Zero;
template <class T, class U>
inline
NSCAP_BOOL
operator==( const nsCOMPtr<T>& lhs, const nsCOMPtr<U>& rhs )
{
return NSCAP_STATIC_CAST(const void*, lhs.get()) == NSCAP_STATIC_CAST(const void*, rhs.get());
}
template <class T, class U>
inline
NSCAP_BOOL
operator==( const nsCOMPtr<T>& lhs, const U* rhs )
{
return NSCAP_STATIC_CAST(const void*, lhs.get()) == NSCAP_STATIC_CAST(const void*, rhs);
}
template <class T, class U>
inline
NSCAP_BOOL
operator==( const U* lhs, const nsCOMPtr<T>& rhs )
{
return NSCAP_STATIC_CAST(const void*, lhs) == NSCAP_STATIC_CAST(const void*, rhs.get());
}
template <class T>
inline
NSCAP_BOOL
operator==( const nsCOMPtr<T>& lhs, NSCAP_Zero* rhs )
// specifically to allow |smartPtr == 0|
{
return NSCAP_STATIC_CAST(const void*, lhs.get()) == NSCAP_REINTERPRET_CAST(const void*, rhs);
}
template <class T>
inline
NSCAP_BOOL
operator==( NSCAP_Zero* lhs, const nsCOMPtr<T>& rhs )
// specifically to allow |0 == smartPtr|
{
return NSCAP_REINTERPRET_CAST(const void*, lhs) == NSCAP_STATIC_CAST(const void*, rhs.get());
}
template <class T, class U>
inline
NSCAP_BOOL
operator!=( const nsCOMPtr<T>& lhs, const nsCOMPtr<U>& rhs )
{
return NSCAP_STATIC_CAST(const void*, lhs.get()) != NSCAP_STATIC_CAST(const void*, rhs.get());
}
template <class T, class U>
inline
NSCAP_BOOL
operator!=( const nsCOMPtr<T>& lhs, const U* rhs )
{
return NSCAP_STATIC_CAST(const void*, lhs.get()) != NSCAP_STATIC_CAST(const void*, rhs);
}
template <class T, class U>
inline
NSCAP_BOOL
operator!=( const U* lhs, const nsCOMPtr<T>& rhs )
{
return NSCAP_STATIC_CAST(const void*, lhs) != NSCAP_STATIC_CAST(const void*, rhs.get());
}
template <class T>
inline
NSCAP_BOOL
operator!=( const nsCOMPtr<T>& lhs, NSCAP_Zero* rhs )
// specifically to allow |smartPtr != 0|
{
return NSCAP_STATIC_CAST(const void*, lhs.get()) != NSCAP_REINTERPRET_CAST(const void*, rhs);
}
template <class T>
inline
NSCAP_BOOL
operator!=( NSCAP_Zero* lhs, const nsCOMPtr<T>& rhs )
// specifically to allow |0 != smartPtr|
{
return NSCAP_REINTERPRET_CAST(const void*, lhs) != NSCAP_STATIC_CAST(const void*, rhs.get());
}
inline
NSCAP_BOOL
SameCOMIdentity( nsISupports* lhs, nsISupports* rhs )
{
return nsCOMPtr<nsISupports>( do_QueryInterface(lhs) ) == nsCOMPtr<nsISupports>( do_QueryInterface(rhs) );
}
#endif // defined(NSCAP_FEATURE_ALLOW_COMPARISONS)
template <class DestinationType>
inline
nsresult
CallQueryInterface( nsISupports* aSource, nsCOMPtr<DestinationType>* aDestination )
// a type-safe shortcut for calling the |QueryInterface()| member function
{
return CallQueryInterface(aSource, getter_AddRefs(*aDestination));
// this calls the _other_ |CallQueryInterface|
}
#endif // !defined(nsCOMPtr_h___)

View File

@@ -1,229 +0,0 @@
/* -*- 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

@@ -1,205 +0,0 @@
/* -*- 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_BEOS)
/* For DEBUGGER macros */
#include <Debug.h>
#endif
#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>
#include <string.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
#undef PR_LogFlush
#define PR_LOG(module,level,args) dprintf args
#define PR_LogFlush()
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);
if (strstr(format, "Warning: ") == format)
printf("¥¥¥%s\n", (char*)buffer + 1);
else
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();
#elif defined(XP_BEOS)
{
char buf[2000];
sprintf(buf, "Abort: at file %s, line %d", aFile, aLine);
DEBUGGER(buf);
}
#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();
#if defined(_WIN32)
::DebugBreak();
#elif defined(XP_UNIX) && !defined(UNIX_CRASH_ON_ASSERT)
fprintf(stderr, "\07"); fflush(stderr);
#elif defined(XP_BEOS)
{
char buf[2000];
sprintf(buf, "Break: at file %s, line %d", aFile, aLine);
DEBUGGER(buf);
}
#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));
#if defined(XP_UNIX)
fprintf(stderr, "Assertion: \"%s\" (%s) at file %s, line %d\n", aStr, aExpr,
aFile, aLine);
#endif
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

@@ -1,183 +0,0 @@
/* -*- 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

@@ -1,189 +0,0 @@
/* -*- 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
*/
#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

@@ -1,108 +0,0 @@
/* -*- 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} \
}
#define NS_ALLOCATOR_PROGID "component://netscape/allocator"
#define NS_ALLOCATOR_CLASSNAME "Allocator"
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
* @result the rellocated block of memory
*/
NS_IMETHOD_(void*) Realloc(void* ptr, PRUint32 size) = 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) = 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

@@ -1,73 +0,0 @@
/* -*- 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;
}

View File

@@ -1,107 +0,0 @@
/* -*- 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 <string.h>
#ifndef prtypes_h___
#include "prtypes.h"
#endif
#ifndef nsCom_h__
#include "nsCom.h"
#endif
/**
* 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

@@ -1,46 +0,0 @@
/* -*- 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
#ifndef nsID_h__
#include "nsID.h"
#endif
/**
* 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

@@ -1,142 +0,0 @@
/* -*- 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

@@ -1,56 +0,0 @@
/* -*- Mode: IDL; 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.
*/
/* The mother of all xpcom interfaces. */
/* In order to get both the right typelib and the right header we force
* the 'real' output from xpidl to be commentout out in the generated header
* and includes a copy of the original nsISUpports.h. This is all just to deal
* with the Mac specific ": public __comobject" thing.
*/
#include "nsrootidl.idl"
%{C++
/*
* Start commenting out the C++ versions of the below in the output header
*/
#if 0
%}
[scriptable, uuid(00000000-0000-0000-c000-000000000046)]
interface nsISupports {
void QueryInterface(in nsIIDRef uuid,
[iid_is(uuid),retval] out nsQIResult result);
[noscript, notxpcom] nsrefcnt AddRef();
[noscript, notxpcom] nsrefcnt Release();
};
%{C++
/*
* End commenting out the C++ versions of the above in the output header
*/
#endif
%}
%{C++
#include "nsISupportsUtils.h"
%}

View File

@@ -1,756 +0,0 @@
/* -*- 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
/***************************************************************************/
/* this section copied from the hand written nsISupports.h */
#include "nsDebug.h"
#include "nsID.h"
#include "nsIID.h"
#include "nsError.h"
#if defined(NS_MT_SUPPORTED)
#include "prcmon.h"
#endif /* NS_MT_SUPPORTED */
#if defined(XPIDL_JS_STUBS)
struct JSObject;
struct JSContext;
#endif
// under Metrowerks (Mac), we don't have autoconf yet
#ifdef __MWERKS__
#define HAVE_CPP_SPECIALIZATION
#endif
// under VC++ (Windows), we don't have autoconf yet
#if defined(_MSC_VER) && (_MSC_VER>=1100)
// VC++ 5.0 and greater implement template specialization, 4.2 is unknown
#define HAVE_CPP_SPECIALIZATION
#endif
#ifdef HAVE_CPP_SPECIALIZATION
#define NSCAP_FEATURE_HIDE_NSISUPPORTS_GETIID
#endif
/*@{*/
////////////////////////////////////////////////////////////////////////////////
/**
* IID for the nsISupports interface
* {00000000-0000-0000-c000-000000000046}
*
* To maintain binary compatibility with COM's nsIUnknown, we define the IID
* of nsISupports to be the same as that of COM's nsIUnknown.
*/
#define NS_ISUPPORTS_IID \
{ 0x00000000, 0x0000, 0x0000, \
{0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46} }
/**
* Reference count values
*
* This is type of return value from Addref() and Release() in nsISupports.
* nsIUnknown of COM returns a unsigned long from equivalent functions.
* To maintain binary compatibility of nsISupports with nsIUnknown, we are
* doing this ifdeffing.
*/
#if defined(XP_PC) && PR_BYTES_PER_LONG == 4
typedef unsigned long nsrefcnt;
#else
typedef PRUint32 nsrefcnt;
#endif
#include "nsTraceRefcnt.h"
/**
* 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:
#ifndef NSCAP_FEATURE_HIDE_NSISUPPORTS_GETIID
static const nsIID& GetIID() { static nsIID iid = NS_ISUPPORTS_IID; return iid; }
#endif
/**
* @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;
//@}
};
/*@}*/
/***************************************************************************/
/**
* 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"); \
++mRefCnt; \
NS_LOG_ADDREF(this, mRefCnt, __FILE__, __LINE__); \
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"); \
--mRefCnt; \
NS_LOG_RELEASE(this, mRefCnt, __FILE__, __LINE__); \
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(kClassIID, _classiiddef); \
if (aIID.Equals(kClassIID)) { \
*aInstancePtr = (void*) this; \
NS_ADDREF_THIS(); \
return NS_OK; \
} \
if (aIID.Equals(nsCOMTypeInfo<nsISupports>::GetIID())) { \
*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.
*
* 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_THIS() \
nsTraceRefcnt::Release(this, Release(), __FILE__, __LINE__)
#else
#define NS_RELEASE_THIS() \
Release()
#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
#ifdef MOZ_LOG_REFCNT
#define NS_LOG_ADDREF(_ptr, _refcnt, _file, _line) \
nsTraceRefcnt::LogAddRef((_ptr), (_refcnt), (_file), (_line))
#define NS_LOG_RELEASE(_ptr, _refcnt, _file, _line) \
nsTraceRefcnt::LogRelease((_ptr), (_refcnt), (_file), (_line))
#else
#define NS_LOG_ADDREF(_file, _line, _ptr, _refcnt)
#define NS_LOG_RELEASE(_file, _line, _ptr, _refcnt)
#endif
////////////////////////////////////////////////////////////////////////////////
// A type-safe interface for calling |QueryInterface()|. A similar implementation
// exists in "nsCOMPtr.h" for use with |nsCOMPtr|s.
extern "C++" {
// ...because some one is accidentally including this file inside an |extern "C"|
class nsISupports;
template <class T>
struct nsCOMTypeInfo
{
static const nsIID& GetIID() { return T::GetIID(); }
};
#ifdef NSCAP_FEATURE_HIDE_NSISUPPORTS_GETIID
template <>
struct nsCOMTypeInfo<nsISupports>
{
static const nsIID& GetIID() { static nsIID iid = NS_ISUPPORTS_IID; return iid; }
};
#endif
#define NS_GET_IID(T) nsCOMTypeInfo<T>::GetIID()
template <class DestinationType>
inline
nsresult
CallQueryInterface( nsISupports* aSource, DestinationType** aDestination )
// a type-safe shortcut for calling the |QueryInterface()| member function
{
NS_PRECONDITION(aSource, "null parameter");
NS_PRECONDITION(aDestination, "null parameter");
return aSource->QueryInterface(nsCOMTypeInfo<DestinationType>::GetIID(), (void**)aDestination);
}
} // extern "C++"
////////////////////////////////////////////////////////////////////////////////
#endif /* __nsISupportsUtils_h */

View File

@@ -1,486 +0,0 @@
/* -*- 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>
#elif defined(linux) && defined(__GLIBC__) && defined(__i386)
#include <setjmp.h>
//
// On glibc 2.1, the Dl_info api defined in <dlfcn.h> is only exposed
// if __USE_GNU is defined. I suppose its some kind of standards
// adherence thing.
//
#if (__GLIBC_MINOR__ >= 1)
#define __USE_GNU
#endif
#include <dlfcn.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 */
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 */
}
}
int nsIToA16(PRUint32 aNumber, char* aBuffer)
{
static char kHex[] = "0123456789abcdef";
if (aNumber == 0) {
*aBuffer = '0';
return 1;
}
char buf[8];
PRInt32 count = 0;
while (aNumber != 0) {
PRUint32 nibble = aNumber & 0xf;
buf[count++] = kHex[nibble];
aNumber >>= 4;
}
for (PRInt32 i = count - 1; i >= 0; --i)
*aBuffer++ = buf[i];
return count;
}
#if defined(_WIN32) // WIN32 stack walking code
#include "imagehlp.h"
#include <stdio.h>
// Define these as static pointers so that we can load the DLL on the
// fly (and not introduce a link-time dependency on it). Tip o' the
// hat to Matt Pietrick for this idea. See:
//
// http://msdn.microsoft.com/library/periodic/period97/F1/D3/S245C6.htm
//
typedef BOOL (__stdcall *SYMINITIALIZEPROC)(HANDLE, LPSTR, BOOL);
static SYMINITIALIZEPROC _SymInitialize;
typedef BOOL (__stdcall *SYMCLEANUPPROC)(HANDLE);
static SYMCLEANUPPROC _SymCleanup;
typedef BOOL (__stdcall *STACKWALKPROC)(DWORD,
HANDLE,
HANDLE,
LPSTACKFRAME,
LPVOID,
PREAD_PROCESS_MEMORY_ROUTINE,
PFUNCTION_TABLE_ACCESS_ROUTINE,
PGET_MODULE_BASE_ROUTINE,
PTRANSLATE_ADDRESS_ROUTINE);
static STACKWALKPROC _StackWalk;
typedef LPVOID (__stdcall *SYMFUNCTIONTABLEACCESSPROC)(HANDLE, DWORD);
static SYMFUNCTIONTABLEACCESSPROC _SymFunctionTableAccess;
typedef DWORD (__stdcall *SYMGETMODULEBASEPROC)(HANDLE, DWORD);
static SYMGETMODULEBASEPROC _SymGetModuleBase;
typedef BOOL (__stdcall *SYMGETSYMFROMADDRPROC)(HANDLE, DWORD, PDWORD, PIMAGEHLP_SYMBOL);
static SYMGETSYMFROMADDRPROC _SymGetSymFromAddr;
static PRBool
EnsureSymInitialized()
{
PRBool gInitialized = PR_FALSE;
if (! gInitialized) {
HMODULE module = ::LoadLibrary("IMAGEHLP.DLL");
if (!module) return PR_FALSE;
_SymInitialize = (SYMINITIALIZEPROC) ::GetProcAddress(module, "SymInitialize");
if (!_SymInitialize) return PR_FALSE;
_SymCleanup = (SYMCLEANUPPROC)GetProcAddress(module, "SymCleanup");
if (!_SymCleanup) return PR_FALSE;
_StackWalk = (STACKWALKPROC)GetProcAddress(module, "StackWalk");
if (!_StackWalk) return PR_FALSE;
_SymFunctionTableAccess = (SYMFUNCTIONTABLEACCESSPROC) GetProcAddress(module, "SymFunctionTableAccess");
if (!_SymFunctionTableAccess) return PR_FALSE;
_SymGetModuleBase = (SYMGETMODULEBASEPROC)GetProcAddress(module, "SymGetModuleBase");
if (!_SymGetModuleBase) return PR_FALSE;
_SymGetSymFromAddr = (SYMGETSYMFROMADDRPROC)GetProcAddress(module, "SymGetSymFromAddr");
if (!_SymGetSymFromAddr) return PR_FALSE;
gInitialized = _SymInitialize(GetCurrentProcess(), 0, TRUE);
}
return gInitialized;
}
/**
* 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)
{
aBuffer[0] = '\0';
aBufLen--; // leave room for nul
HANDLE myProcess = ::GetCurrentProcess();
HANDLE myThread = ::GetCurrentThread();
BOOL ok;
ok = EnsureSymInitialized();
if (! ok)
return;
// 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 context;
context.ContextFlags = CONTEXT_FULL;
ok = GetThreadContext(myThread, &context);
if (! ok)
return;
// Setup initial stack frame to walk from
STACKFRAME frame;
memset(&frame, 0, sizeof(frame));
frame.AddrPC.Offset = context.Eip;
frame.AddrPC.Mode = AddrModeFlat;
frame.AddrStack.Offset = context.Esp;
frame.AddrStack.Mode = AddrModeFlat;
frame.AddrFrame.Offset = context.Ebp;
frame.AddrFrame.Mode = AddrModeFlat;
// Now walk the stack and map the pc's to symbol names that we stuff
// append to *cp.
char* cp = aBuffer;
int skip = 2;
while (aBufLen > 0) {
ok = _StackWalk(IMAGE_FILE_MACHINE_I386,
myProcess,
myThread,
&frame,
&context,
0, // read process memory routine
_SymFunctionTableAccess, // function table access routine
_SymGetModuleBase, // module base routine
0); // translate address routine
if (!ok || frame.AddrPC.Offset == 0)
break;
if (skip-- > 0)
continue;
char buf[sizeof(IMAGEHLP_SYMBOL) + 512];
PIMAGEHLP_SYMBOL symbol = (PIMAGEHLP_SYMBOL) buf;
symbol->SizeOfStruct = sizeof(buf);
symbol->MaxNameLength = 512;
DWORD displacement;
ok = _SymGetSymFromAddr(myProcess,
frame.AddrPC.Offset,
&displacement,
symbol);
if (ok) {
int nameLen = strlen(symbol->Name);
if (nameLen + 12 > aBufLen) { // 12 == strlen("+0x12345678 ")
break;
}
char* cp2 = symbol->Name;
while (*cp2) {
if (*cp2 == ' ') *cp2 = '_'; // replace spaces with underscores
*cp++ = *cp2++;
}
aBufLen -= nameLen;
*cp++ = '+';
*cp++ = '0';
*cp++ = 'x';
PRInt32 len = nsIToA16(displacement, cp);
cp += len;
*cp++ = ' ';
aBufLen -= nameLen + len + 4;
}
else {
if (11 > aBufLen) { // 11 == strlen("0x12345678 ")
break;
}
*cp++ = '0';
*cp++ = 'x';
PRInt32 len = nsIToA16(frame.AddrPC.Offset, cp);
cp += len;
*cp++ = ' ';
aBufLen -= len + 3;
}
}
*cp = 0;
}
/* _WIN32 */
#elif defined(linux) && defined(__GLIBC__) && defined(__i386) // i386 Linux stackwalking code
void
nsTraceRefcnt::WalkTheStack(char* aBuffer, int aBufLen)
{
aBuffer[0] = '\0';
aBufLen--; // leave room for nul
char* cp = aBuffer;
jmp_buf jb;
setjmp(jb);
// Stack walking code courtesy Kipp's "leaky".
u_long* bp = (u_long*) (jb[0].__jmpbuf[JB_BP]);
int skip = 2;
for (;;) {
u_long* nextbp = (u_long*) *bp++;
u_long pc = *bp;
if ((pc < 0x08000000) || (pc > 0x7fffffff) || (nextbp < bp)) {
break;
}
if (--skip <= 0) {
Dl_info info;
int ok = dladdr((void*) pc, &info);
if (ok < 0)
break;
int len = strlen(info.dli_sname);
if (! len)
break; // XXX Lazy. We could look at the filename or something.
if (len + 12 >= aBufLen) // 12 == strlen("+0x12345678 ")
break;
strcpy(cp, info.dli_sname);
cp += len;
*cp++ = '+';
*cp++ = '0';
*cp++ = 'x';
PRUint32 off = (char*)pc - (char*)info.dli_saddr;
PRInt32 addrStrLen = nsIToA16(off, cp);
cp += addrStrLen;
*cp++ = ' ';
aBufLen -= addrStrLen + 4;
}
bp = nextbp;
}
*cp = '\0';
}
#else // unsupported platform.
NS_COM void
nsTraceRefcnt::WalkTheStack(char* aBuffer, int aBufLen)
{
// Write me!!!
*aBuffer = '\0';
}
#endif
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
}
NS_COM void
nsTraceRefcnt::LogAddRef(void* aPtr,
nsrefcnt aRefCnt,
const char* aFile,
int aLine)
{
InitTraceLog();
if (PR_LOG_TEST(gTraceRefcntLog, PR_LOG_DEBUG)) {
char sb[16384];
WalkTheStack(sb, sizeof(sb));
// Can't use PR_LOG(), b/c it truncates the line
printf("%s(%d) %p AddRef %d %s\n", aFile, aLine, aPtr, aRefCnt, sb);
}
}
NS_COM void
nsTraceRefcnt::LogRelease(void* aPtr,
nsrefcnt aRefCnt,
const char* aFile,
int aLine)
{
InitTraceLog();
if (PR_LOG_TEST(gTraceRefcntLog, PR_LOG_DEBUG)) {
char sb[16384];
WalkTheStack(sb, sizeof(sb));
// Can't use PR_LOG(), b/c it truncates the line
printf("%s(%d) %p Release %d %s\n", aFile, aLine, aPtr, aRefCnt, sb);
}
}

View File

@@ -1,72 +0,0 @@
/* -*- 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);
static NS_COM void LogAddRef(void* aPtr,
nsrefcnt aRefCnt,
const char* aFile,
int aLine);
static NS_COM void LogRelease(void* aPtr,
nsrefcnt aRefCnt,
const char* aFile,
int aLine);
};
#endif /* nsTraceRefcnt_h___ */

View File

@@ -1,486 +0,0 @@
/* -*- 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>
#elif defined(linux) && defined(__GLIBC__) && defined(__i386)
#include <setjmp.h>
//
// On glibc 2.1, the Dl_info api defined in <dlfcn.h> is only exposed
// if __USE_GNU is defined. I suppose its some kind of standards
// adherence thing.
//
#if (__GLIBC_MINOR__ >= 1)
#define __USE_GNU
#endif
#include <dlfcn.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 */
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 */
}
}
int nsIToA16(PRUint32 aNumber, char* aBuffer)
{
static char kHex[] = "0123456789abcdef";
if (aNumber == 0) {
*aBuffer = '0';
return 1;
}
char buf[8];
PRInt32 count = 0;
while (aNumber != 0) {
PRUint32 nibble = aNumber & 0xf;
buf[count++] = kHex[nibble];
aNumber >>= 4;
}
for (PRInt32 i = count - 1; i >= 0; --i)
*aBuffer++ = buf[i];
return count;
}
#if defined(_WIN32) // WIN32 stack walking code
#include "imagehlp.h"
#include <stdio.h>
// Define these as static pointers so that we can load the DLL on the
// fly (and not introduce a link-time dependency on it). Tip o' the
// hat to Matt Pietrick for this idea. See:
//
// http://msdn.microsoft.com/library/periodic/period97/F1/D3/S245C6.htm
//
typedef BOOL (__stdcall *SYMINITIALIZEPROC)(HANDLE, LPSTR, BOOL);
static SYMINITIALIZEPROC _SymInitialize;
typedef BOOL (__stdcall *SYMCLEANUPPROC)(HANDLE);
static SYMCLEANUPPROC _SymCleanup;
typedef BOOL (__stdcall *STACKWALKPROC)(DWORD,
HANDLE,
HANDLE,
LPSTACKFRAME,
LPVOID,
PREAD_PROCESS_MEMORY_ROUTINE,
PFUNCTION_TABLE_ACCESS_ROUTINE,
PGET_MODULE_BASE_ROUTINE,
PTRANSLATE_ADDRESS_ROUTINE);
static STACKWALKPROC _StackWalk;
typedef LPVOID (__stdcall *SYMFUNCTIONTABLEACCESSPROC)(HANDLE, DWORD);
static SYMFUNCTIONTABLEACCESSPROC _SymFunctionTableAccess;
typedef DWORD (__stdcall *SYMGETMODULEBASEPROC)(HANDLE, DWORD);
static SYMGETMODULEBASEPROC _SymGetModuleBase;
typedef BOOL (__stdcall *SYMGETSYMFROMADDRPROC)(HANDLE, DWORD, PDWORD, PIMAGEHLP_SYMBOL);
static SYMGETSYMFROMADDRPROC _SymGetSymFromAddr;
static PRBool
EnsureSymInitialized()
{
PRBool gInitialized = PR_FALSE;
if (! gInitialized) {
HMODULE module = ::LoadLibrary("IMAGEHLP.DLL");
if (!module) return PR_FALSE;
_SymInitialize = (SYMINITIALIZEPROC) ::GetProcAddress(module, "SymInitialize");
if (!_SymInitialize) return PR_FALSE;
_SymCleanup = (SYMCLEANUPPROC)GetProcAddress(module, "SymCleanup");
if (!_SymCleanup) return PR_FALSE;
_StackWalk = (STACKWALKPROC)GetProcAddress(module, "StackWalk");
if (!_StackWalk) return PR_FALSE;
_SymFunctionTableAccess = (SYMFUNCTIONTABLEACCESSPROC) GetProcAddress(module, "SymFunctionTableAccess");
if (!_SymFunctionTableAccess) return PR_FALSE;
_SymGetModuleBase = (SYMGETMODULEBASEPROC)GetProcAddress(module, "SymGetModuleBase");
if (!_SymGetModuleBase) return PR_FALSE;
_SymGetSymFromAddr = (SYMGETSYMFROMADDRPROC)GetProcAddress(module, "SymGetSymFromAddr");
if (!_SymGetSymFromAddr) return PR_FALSE;
gInitialized = _SymInitialize(GetCurrentProcess(), 0, TRUE);
}
return gInitialized;
}
/**
* 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)
{
aBuffer[0] = '\0';
aBufLen--; // leave room for nul
HANDLE myProcess = ::GetCurrentProcess();
HANDLE myThread = ::GetCurrentThread();
BOOL ok;
ok = EnsureSymInitialized();
if (! ok)
return;
// 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 context;
context.ContextFlags = CONTEXT_FULL;
ok = GetThreadContext(myThread, &context);
if (! ok)
return;
// Setup initial stack frame to walk from
STACKFRAME frame;
memset(&frame, 0, sizeof(frame));
frame.AddrPC.Offset = context.Eip;
frame.AddrPC.Mode = AddrModeFlat;
frame.AddrStack.Offset = context.Esp;
frame.AddrStack.Mode = AddrModeFlat;
frame.AddrFrame.Offset = context.Ebp;
frame.AddrFrame.Mode = AddrModeFlat;
// Now walk the stack and map the pc's to symbol names that we stuff
// append to *cp.
char* cp = aBuffer;
int skip = 2;
while (aBufLen > 0) {
ok = _StackWalk(IMAGE_FILE_MACHINE_I386,
myProcess,
myThread,
&frame,
&context,
0, // read process memory routine
_SymFunctionTableAccess, // function table access routine
_SymGetModuleBase, // module base routine
0); // translate address routine
if (!ok || frame.AddrPC.Offset == 0)
break;
if (skip-- > 0)
continue;
char buf[sizeof(IMAGEHLP_SYMBOL) + 512];
PIMAGEHLP_SYMBOL symbol = (PIMAGEHLP_SYMBOL) buf;
symbol->SizeOfStruct = sizeof(buf);
symbol->MaxNameLength = 512;
DWORD displacement;
ok = _SymGetSymFromAddr(myProcess,
frame.AddrPC.Offset,
&displacement,
symbol);
if (ok) {
int nameLen = strlen(symbol->Name);
if (nameLen + 12 > aBufLen) { // 12 == strlen("+0x12345678 ")
break;
}
char* cp2 = symbol->Name;
while (*cp2) {
if (*cp2 == ' ') *cp2 = '_'; // replace spaces with underscores
*cp++ = *cp2++;
}
aBufLen -= nameLen;
*cp++ = '+';
*cp++ = '0';
*cp++ = 'x';
PRInt32 len = nsIToA16(displacement, cp);
cp += len;
*cp++ = ' ';
aBufLen -= nameLen + len + 4;
}
else {
if (11 > aBufLen) { // 11 == strlen("0x12345678 ")
break;
}
*cp++ = '0';
*cp++ = 'x';
PRInt32 len = nsIToA16(frame.AddrPC.Offset, cp);
cp += len;
*cp++ = ' ';
aBufLen -= len + 3;
}
}
*cp = 0;
}
/* _WIN32 */
#elif defined(linux) && defined(__GLIBC__) && defined(__i386) // i386 Linux stackwalking code
void
nsTraceRefcnt::WalkTheStack(char* aBuffer, int aBufLen)
{
aBuffer[0] = '\0';
aBufLen--; // leave room for nul
char* cp = aBuffer;
jmp_buf jb;
setjmp(jb);
// Stack walking code courtesy Kipp's "leaky".
u_long* bp = (u_long*) (jb[0].__jmpbuf[JB_BP]);
int skip = 2;
for (;;) {
u_long* nextbp = (u_long*) *bp++;
u_long pc = *bp;
if ((pc < 0x08000000) || (pc > 0x7fffffff) || (nextbp < bp)) {
break;
}
if (--skip <= 0) {
Dl_info info;
int ok = dladdr((void*) pc, &info);
if (ok < 0)
break;
int len = strlen(info.dli_sname);
if (! len)
break; // XXX Lazy. We could look at the filename or something.
if (len + 12 >= aBufLen) // 12 == strlen("+0x12345678 ")
break;
strcpy(cp, info.dli_sname);
cp += len;
*cp++ = '+';
*cp++ = '0';
*cp++ = 'x';
PRUint32 off = (char*)pc - (char*)info.dli_saddr;
PRInt32 addrStrLen = nsIToA16(off, cp);
cp += addrStrLen;
*cp++ = ' ';
aBufLen -= addrStrLen + 4;
}
bp = nextbp;
}
*cp = '\0';
}
#else // unsupported platform.
NS_COM void
nsTraceRefcnt::WalkTheStack(char* aBuffer, int aBufLen)
{
// Write me!!!
*aBuffer = '\0';
}
#endif
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
}
NS_COM void
nsTraceRefcnt::LogAddRef(void* aPtr,
nsrefcnt aRefCnt,
const char* aFile,
int aLine)
{
InitTraceLog();
if (PR_LOG_TEST(gTraceRefcntLog, PR_LOG_DEBUG)) {
char sb[16384];
WalkTheStack(sb, sizeof(sb));
// Can't use PR_LOG(), b/c it truncates the line
printf("%s(%d) %p AddRef %d %s\n", aFile, aLine, aPtr, aRefCnt, sb);
}
}
NS_COM void
nsTraceRefcnt::LogRelease(void* aPtr,
nsrefcnt aRefCnt,
const char* aFile,
int aLine)
{
InitTraceLog();
if (PR_LOG_TEST(gTraceRefcntLog, PR_LOG_DEBUG)) {
char sb[16384];
WalkTheStack(sb, sizeof(sb));
// Can't use PR_LOG(), b/c it truncates the line
printf("%s(%d) %p Release %d %s\n", aFile, aLine, aPtr, aRefCnt, sb);
}
}

View File

@@ -1,72 +0,0 @@
/* -*- 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);
static NS_COM void LogAddRef(void* aPtr,
nsrefcnt aRefCnt,
const char* aFile,
int aLine);
static NS_COM void LogRelease(void* aPtr,
nsrefcnt aRefCnt,
const char* aFile,
int aLine);
};
#endif /* nsTraceRefcnt_h___ */

View File

@@ -1,164 +0,0 @@
/* -*- 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 nscore_h___
#define nscore_h___
#ifdef _WIN32
#define NS_WIN32 1
#endif
#if defined(__unix)
#define NS_UNIX 1
#endif
#include "prtypes.h"
#ifdef __cplusplus
#include "nsDebug.h"
#endif
#ifndef __PRUNICHAR__
#define __PRUNICHAR__
typedef PRUint16 PRUnichar;
#endif
/* The preferred symbol for null. */
#define nsnull 0
/* Define brackets for protecting C code from C++ */
#ifdef __cplusplus
#define NS_BEGIN_EXTERN_C extern "C" {
#define NS_END_EXTERN_C }
#else
#define NS_BEGIN_EXTERN_C
#define NS_END_EXTERN_C
#endif
/*----------------------------------------------------------------------*/
/* Import/export defines */
#ifdef NS_WIN32
#define NS_IMPORT _declspec(dllimport)
#define NS_IMPORT_(type) type _declspec(dllimport) __stdcall
#define NS_EXPORT _declspec(dllexport)
/* XXX NS_EXPORT_ defined in nsCOm.h (xpcom) differs in where the __declspec
is placed. It needs to be done this way to make the 4.x compiler happy... */
#undef NS_EXPORT_
#define NS_EXPORT_(type) type _declspec(dllexport) __stdcall
#elif defined(XP_MAC)
#define NS_IMPORT
#define NS_IMPORT_(type) type
/* XXX NS_EXPORT_ defined in nsCom.h actually does an export. Here it's just sugar. */
#undef NS_EXPORT
#undef NS_EXPORT_
#define NS_EXPORT __declspec(export)
#define NS_EXPORT_(type) __declspec(export) type
#else
/* XXX do something useful? */
#define NS_IMPORT
#define NS_IMPORT_(type) type
#define NS_EXPORT
#define NS_EXPORT_(type) type
#endif
#ifdef _IMPL_NS_BASE
#define NS_BASE NS_EXPORT
#else
#define NS_BASE NS_IMPORT
#endif
#ifdef _IMPL_NS_NET
#define NS_NET NS_EXPORT
#else
#define NS_NET NS_IMPORT
#endif
#ifdef _IMPL_NS_DOM
#define NS_DOM NS_EXPORT
#else
#define NS_DOM NS_IMPORT
#endif
#ifdef _IMPL_NS_WIDGET
#define NS_WIDGET NS_EXPORT
#else
#define NS_WIDGET NS_IMPORT
#endif
#ifdef _IMPL_NS_VIEW
#define NS_VIEW NS_EXPORT
#else
#define NS_VIEW NS_IMPORT
#endif
#ifdef _IMPL_NS_GFXNONXP
#define NS_GFXNONXP NS_EXPORT
#define NS_GFXNONXP_(type) NS_EXPORT_(type)
#else
#define NS_GFXNONXP NS_IMPORT
#define NS_GFXNONXP_(type) NS_IMPORT_(type)
#endif
#ifdef _IMPL_NS_GFX
#define NS_GFX NS_EXPORT
#define NS_GFX_(type) NS_EXPORT_(type)
#else
#define NS_GFX NS_IMPORT
#define NS_GFX_(type) NS_IMPORT_(type)
#endif
#ifdef _IMPL_NS_PLUGIN
#define NS_PLUGIN NS_EXPORT
#else
#define NS_PLUGIN NS_IMPORT
#endif
#ifdef _IMPL_NS_APPSHELL
#define NS_APPSHELL NS_EXPORT
#else
#define NS_APPSHELL NS_IMPORT
#endif
/* ------------------------------------------------------------------------ */
/* Casting macros for hiding C++ features from older compilers */
/* unix now determines this automatically */
#ifndef XP_UNIX
#define HAVE_CPP_NEW_CASTS /* we'll be optimistic. */
#endif
#if defined(HAVE_CPP_NEW_CASTS)
#define NS_STATIC_CAST(__type, __ptr) static_cast<__type>(__ptr)
#define NS_CONST_CAST(__type, __ptr) const_cast<__type>(__ptr)
#define NS_REINTERPRET_CAST(__type, __ptr) reinterpret_cast<__type>(__ptr)
#else
#define NS_STATIC_CAST(__type, __ptr) ((__type)(__ptr))
#define NS_CONST_CAST(__type, __ptr) ((__type)(__ptr))
#define NS_REINTERPRET_CAST(__type, __ptr) ((__type)(__ptr))
#endif
/* No sense in making an NS_DYNAMIC_CAST() macro: you can't duplicate
the semantics. So if you want to dynamic_cast, then just use it
"straight", no macro. */
#endif /* nscore_h___ */

View File

@@ -1,63 +0,0 @@
/* -*- Mode: IDL; 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.
*/
/* Root idl declarations to be used by all. */
%{C++
#include "nscore.h"
#include "prtime.h"
/*
* Start commenting out the C++ versions of the below in the output header
*/
#if 0
%}
typedef boolean PRBool ;
typedef octet PRUint8 ;
typedef unsigned short PRUint16 ;
typedef unsigned long PRUint32 ;
typedef unsigned long long PRUint64 ;
typedef unsigned long long PRTime ;
typedef short PRInt16 ;
typedef long PRInt32 ;
typedef long long PRInt64 ;
typedef unsigned long nsrefcnt ;
typedef unsigned long nsresult ;
[ptr] native voidStar(void);
[ptr] native charStar(char);
[ref, nsid] native nsIDRef(nsID);
[ref, nsid] native nsIIDRef(nsIID);
[ref, nsid] native nsCIDRef(nsCID);
[ptr, nsid] native nsIDPtr(nsID);
[ptr, nsid] native nsIIDPtr(nsIID);
[ptr, nsid] native nsCIDPtr(nsCID);
[ptr] native nsQIResult(void);
%{C++
/*
* End commenting out the C++ versions of the above in the output header
*/
#endif
%}

View File

@@ -1,84 +0,0 @@
#
# The contents of this file are subject to the Netscape Public License
# Version 1.0 (the "NPL"); you may not use this file except in
# compliance with the NPL. You may obtain a copy of the NPL at
# http://www.mozilla.org/NPL/
#
# Software distributed under the NPL is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
# for the specific language governing rights and limitations under the
# NPL.
#
# The Initial Developer of this code under the NPL is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
# Reserved.
#
DEPTH = ../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
LIBRARY_NAME = xpcom
MODULE = xpcom
CPPSRCS = nsXPComInit.cpp
REQUIRES = xpcom
include $(topsrcdir)/config/config.mk
LOCAL_INCLUDES += \
-I$(srcdir)/../base \
-I$(srcdir)/../ds \
-I$(srcdir)/../io \
-I$(srcdir)/../components \
-I$(srcdir)/../threads \
-I$(srcdir)/../proxy/src \
$(NULL)
DEFINES += -D_IMPL_NS_COM -D_IMPL_NS_BASE
SHARED_LIBRARY_LIBS = \
$(DIST)/lib/libxpcomds_s.a \
$(DIST)/lib/libxpcomio_s.a \
$(DIST)/lib/libxpcomcomponents_s.a \
$(DIST)/lib/libxpcomthreads_s.a \
$(DIST)/lib/libxpcomproxy_s.a \
$(DIST)/lib/libxpcombase_s.a \
$(DIST)/lib/libxptcall.a \
$(DIST)/lib/libxptinfo.a \
$(DIST)/lib/libxpt.a \
$(DIST)/lib/libxptcmd.a \
$(DIST)/lib/libreg.a \
$(NULL)
ifeq ($(OS_ARCH),HP-UX)
EXTRA_DSO_LDOPTS = -c objs/objslist
else
EXTRA_DSO_LDOPTS = \
$(MKSHLIB_FORCE_ALL) \
$(SHARED_LIBRARY_LIBS) \
$(MKSHLIB_UNFORCE_ALL)
endif
ifeq ($(OS_ARCH),BeOS)
EXTRA_DSO_LDOPTS += -lbe
endif
include $(topsrcdir)/config/rules.mk
ifeq ($(OS_ARCH),HP-UX)
shared_library_objs: $(SHARED_LIBRARY_LIBS)
rm -rf objs
mkdir objs
(cd objs; for lib in $(SHARED_LIBRARY_LIBS); do ar xv ../$$lib; done) \
| awk '{ print "objs/"$$3 }' > objs/objslist
$(LIBRARY) $(SHARED_LIBRARY): shared_library_objs Makefile
else
$(LIBRARY) $(SHARED_LIBRARY): $(SHARED_LIBRARY_LIBS) Makefile
endif

View File

@@ -1,83 +0,0 @@
/* -*- 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.
*/
// Force references to all of the symbols that we want exported from
// the dll that are located in the .lib files we link with
#include "nsVoidArray.h"
#include "nsIAtom.h"
#include "nsFileSpec.h"
#include "nsIBuffer.h"
//#include "nsIByteBufferInputStream.h"
#include "nsFileStream.h"
#include "nsFileSpecStreaming.h"
#include "nsSpecialSystemDirectory.h"
#include "nsIThread.h"
#include "nsDeque.h"
#include "nsObserver.h"
#include "nsTraceRefcnt.h"
#include "nsXPIDLString.h"
#include "nsIEnumerator.h"
#include "nsEnumeratorUtils.h"
#include "nsQuickSort.h"
#include "nsString2.h"
#include "nsProxyEventPrivate.h"
#include "xpt_xdr.h"
#include "nsInterfaceInfo.h"
#include "xptcall.h"
#include "nsIFileSpec.h"
#include "nsIGenericFactory.h"
void XXXNeverCalled()
{
nsVoidArray();
NS_GetNumberOfAtoms();
nsFileURL(NULL);
NS_NewPipe(NULL, NULL, 0, 0, 0, NULL);
nsFileSpec s;
NS_NewIOFileStream(NULL, s, 0, 0);
nsInputFileStream(s, 0, 0);
nsPersistentFileDescriptor d;
ReadDescriptor(NULL, d);
new nsSpecialSystemDirectory(nsSpecialSystemDirectory::OS_DriveDirectory);
nsIThread::GetCurrent(NULL);
nsDeque(NULL);
NS_NewObserver(NULL, NULL);
nsTraceRefcnt::AddRef(NULL, 0, NULL, 0);
nsXPIDLCString::Copy(NULL);
NS_NewEmptyEnumerator(NULL);
nsArrayEnumerator(NULL);
NS_NewIntersectionEnumerator(NULL, NULL, NULL);
NS_QuickSort(NULL, 0, 0, NULL, NULL);
nsString2();
nsProxyObject();
XPT_DoString(NULL, NULL);
XPT_DoHeader(NULL, NULL);
nsInterfaceInfo* info = NULL;
info->GetName(NULL);
#ifdef DEBUG
info->print(NULL);
#endif
XPTC_InvokeByIndex(NULL, 0, 0, NULL);
NS_NewFileSpec(NULL);
xptc_dummy();
xptc_dummy2();
XPTI_GetInterfaceInfoManager();
NS_NewGenericFactory(NULL, NULL, NULL);
}

View File

@@ -1,86 +0,0 @@
#!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=..\..
MODULE = xpcom
LIBNAME = .\$(OBJDIR)\xpcom
DLL = $(LIBNAME).dll
LINCS = \
-I$(PUBLIC)\xpcom \
-I..\base \
-I..\ds \
-I..\io \
-I..\components \
-I..\threads \
-I..\reflect\xptinfo\src \
-I..\proxy\src \
$(NULL)
LCFLAGS=-D_IMPL_NS_COM \
-D_IMPL_NS_BASE \
-DWIN32_LEAN_AND_MEAN \
-DEXPORT_XPT_API \
-DEXPORT_XPTC_API \
-DEXPORT_XPTI_API
CPP_OBJS = \
.\$(OBJDIR)\nsXPComInit.obj \
.\$(OBJDIR)\dlldeps.obj \
$(NULL)
!ifndef BUILD_OPT
#CPP_OBJS = $(CPP_OBJS) .\$(OBJDIR)\nsConstructorPattern.obj
!endif
OURLIBS = \
$(LIBNSPR) \
$(DIST)\lib\plc3.lib \
$(DIST)\lib\xpcombase_s.lib \
$(DIST)\lib\xpcomds_s.lib \
$(DIST)\lib\xpcomio_s.lib \
$(DIST)\lib\xpcomcomp_s.lib \
$(DIST)\lib\xpcomthreads_s.lib \
$(DIST)\lib\xpcomxpt_s.lib \
$(DIST)\lib\xpcomxptcall_s.lib \
$(DIST)\lib\xpcomxptcmd_s.lib \
$(DIST)\lib\xpcomxptinfo_s.lib \
$(DIST)\lib\xpcomproxy_s.lib \
$(DIST)\lib\libreg32.lib \
$(NULL)
LLIBS = \
$(OURLIBS) \
shell32.lib \
!if "$(MOZ_BITS)"=="32" && defined(MOZ_DEBUG) && defined(GLOWCODE)
$(GLOWDIR)\glowcode.lib \
!endif
!if defined(MOZ_TRACE_XPCOM_REFCNT)
imagehlp.lib \
!endif
$(NULL)
MISCDEP=$(OURLIBS)
include <$(DEPTH)\config\rules.mak>
libs:: $(DLL)
$(MAKE_INSTALL) $(LIBNAME).$(DLL_SUFFIX) $(DIST)\bin
$(MAKE_INSTALL) $(LIBNAME).$(LIB_SUFFIX) $(DIST)\lib

View File

@@ -1,243 +0,0 @@
/* -*- 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 "nsISupports.h"
////////////////////////////////////////////////////////////////////////////////
// nsIFoo.h
////////////////////////////////////////////////////////////////////////////////
// Here's an interface that we're going to work with. Normally it would be
// defined in nsIFoo.h:
#define NS_IFOO_IID \
{ /* f981ba10-1547-11d3-9337-00104ba0fd40 */ \
0xf981ba10, \
0x1547, \
0x11d3, \
{0x93, 0x37, 0x00, 0x10, 0x4b, 0xa0, 0xfd, 0x40} \
}
#define NS_FOO_CID \
{ /* fe1a5870-1547-11d3-9337-00104ba0fd40 */ \
0xfe1a5870, \
0x1547, \
0x11d3, \
{0x93, 0x37, 0x00, 0x10, 0x4b, 0xa0, 0xfd, 0x40} \
}
class nsIFoo : public nsISupports {
public:
NS_DEFINE_STATIC_IID_ACCESSOR(NS_IFOO_IID);
NS_IMETHOD Init(const char* name) = 0;
NS_IMETHOD Doit(int x) = 0;
};
// Define a global constructor function if you really need one. Otherwise
// you can always use nsIComponentManager::CreateInstance.
PR_EXTERN(nsresult)
NS_NewFoo(nsIFoo* *result, const char* name);
////////////////////////////////////////////////////////////////////////////////
// nsFoo.h
////////////////////////////////////////////////////////////////////////////////
// Here's the implementation class definition. Put this in an nsFoo.h (and don't
// export it to dist).
//#include "nsIFoo.h"
class nsFoo : public nsIFoo {
public:
// Define the constructor, but don't give it arguments that are needed
// for initialization that can fail:
nsFoo();
// Always make the destructor virtual:
virtual ~nsFoo();
// Define a Create method to be used with a factory:
static NS_METHOD
Create(nsISupports* aOuter, const nsIID& aIID, void* *aResult);
// from nsIFoo:
NS_IMETHOD Init(const char* name);
NS_IMETHOD Doit(int x);
// from nsISupports:
NS_DECL_ISUPPORTS
protected:
// instance variables:
char* mName;
};
////////////////////////////////////////////////////////////////////////////////
// nsFoo.cpp
////////////////////////////////////////////////////////////////////////////////
// Here's the implementation. Put this in an nsFoo.cpp.
//#include "nsFoo.h"
#include "nsCRT.h"
#include <stdio.h>
// Don't do anything in the constructor that can fail. Just initialize all
// the instance variables and get out:
nsFoo::nsFoo()
: mName(NULL)
{
NS_INIT_REFCNT();
}
// Do anything that can fail in the Init method. It's a good idea to provide
// one so that in the future if someone adds something that can fail they'll
// be encouraged to do it right:
NS_IMETHODIMP
nsFoo::Init(const char* name)
{
mName = nsCRT::strdup(name);
if (mName == NULL)
return NS_ERROR_OUT_OF_MEMORY;
return NS_OK;
}
// Destroy and release things as usual in the destructor:
nsFoo::~nsFoo()
{
if (mName)
nsCRT::free(mName);
}
// Provide a Create method that can be called by a factory constructor:
NS_METHOD
nsFoo::Create(nsISupports* aOuter, const nsIID& aIID, void* *aResult)
{
if (aOuter)
return NS_ERROR_NO_AGGREGATION;
nsFoo* foo = new nsFoo();
if (foo == NULL)
return NS_ERROR_OUT_OF_MEMORY;
// Note that Create doesn't initialize the instance -- that has to
// be done by the caller since the initialization args aren't passed
// in here.
// AddRef before calling QI -- this makes it easier to handle the QI
// failure case because we'll always just Release and return
NS_ADDREF(foo);
nsresult rv = foo->QueryInterface(aIID, aResult);
// This will free it if QI failed:
NS_RELEASE(foo);
return rv;
}
// Implement the nsISupports methods:
NS_IMPL_ISUPPORTS(nsFoo, nsIFoo::GetIID());
// Implement the method(s) of the interface:
NS_IMETHODIMP
nsFoo::Doit(int x)
{
printf("%s %d\n", mName, x);
return NS_OK;
}
// Finally, (if you really need one) implement a global constructor function
// for this class:
PR_IMPLEMENT(nsresult)
NS_NewFoo(nsIFoo* *result, const char* name)
{
// Use the constructor method to create this. Don't duplicate work.
nsresult rv = nsFoo::Create(NULL, nsIFoo::GetIID(),
(void**)result);
if (NS_SUCCEEDED(rv)) {
// Only initialize if the constructor succeeded:
rv = (*result)->Init(name);
}
return rv;
}
////////////////////////////////////////////////////////////////////////////////
// nsFooModuleFactory.cpp
////////////////////////////////////////////////////////////////////////////////
// This file defines the factory that instantiates nsFoo and any other classes
// in the same component. It also defines the component's NSGetFactory,
// NSRegisterSelf and NSUnregisterSelf entry points:
// Include nsFoo.h to get the nsFoo::Create method:
//#include "nsFoo.h"
#include "nsIComponentManager.h"
#include "nsIServiceManager.h"
// Include the generic factory stuff. It's the easiest and smallest way to
// work with factories:
#include "nsGenericFactory.h"
static NS_DEFINE_CID(kFooCID, NS_FOO_CID);
static NS_DEFINE_CID(kComponentManagerCID, NS_COMPONENTMANAGER_CID);
extern "C" PR_IMPLEMENT(nsresult)
NSGetFactory(nsISupports* aServMgr,
const nsCID &aClass,
const char *aClassName,
const char *aProgID,
nsIFactory **aFactory)
{
nsresult rv;
nsIGenericFactory* fact;
if (aClass.Equals(kFooCID))
rv = NS_NewGenericFactory(&fact, nsFoo::Create);
else
rv = NS_ERROR_FAILURE;
if (NS_SUCCEEDED(rv))
*aFactory = fact;
return rv;
}
extern "C" PR_IMPLEMENT(nsresult)
NSRegisterSelf(nsISupports* aServMgr , const char* aPath)
{
nsresult rv;
NS_WITH_SERVICE1(nsIComponentManager, compMgr,
aServMgr, kComponentManagerCID, &rv);
if (NS_FAILED(rv)) return rv;
rv = compMgr->RegisterComponent(kFooCID, "Foo", NULL,
aPath, PR_TRUE, PR_TRUE);
return rv;
}
extern "C" PR_IMPLEMENT(nsresult)
NSUnregisterSelf(nsISupports* aServMgr, const char* aPath)
{
nsresult rv;
NS_WITH_SERVICE1(nsIComponentManager, compMgr,
aServMgr, kComponentManagerCID, &rv);
if (NS_FAILED(rv)) return rv;
rv = compMgr->UnregisterComponent(kFooCID, aPath);
return rv;
}
////////////////////////////////////////////////////////////////////////////////

View File

@@ -1,263 +0,0 @@
/* -*- 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 "nsIRegistry.h"
#include "nscore.h"
#include "nsCOMPtr.h"
#include "nsObserverService.h"
#include "nsObserver.h"
#include "nsProperties.h"
#include "nsAllocator.h"
#include "nsArena.h"
#include "nsBuffer.h"
#include "nsByteBuffer.h"
#include "nsPageMgr.h"
#include "nsSupportsArray.h"
#include "nsUnicharBuffer.h"
#include "nsComponentManager.h"
#include "nsIServiceManager.h"
#include "nsGenericFactory.h"
#include "nsEventQueueService.h"
#include "nsEventQueue.h"
#include "nsProxyObjectManager.h"
#include "nsProxyEventPrivate.h" // access to the impl of nsProxyObjectManager for the generic factory registration.
#include "nsFileSpecImpl.h"
// base
static NS_DEFINE_CID(kAllocatorCID, NS_ALLOCATOR_CID);
// ds
static NS_DEFINE_CID(kArenaCID, NS_ARENA_CID);
static NS_DEFINE_CID(kBufferCID, NS_BUFFER_CID);
static NS_DEFINE_CID(kByteBufferCID, NS_BYTEBUFFER_CID);
static NS_DEFINE_CID(kPageManagerCID, NS_PAGEMANAGER_CID);
static NS_DEFINE_CID(kPropertiesCID, NS_PROPERTIES_CID);
static NS_DEFINE_CID(kSupportsArrayCID, NS_SUPPORTSARRAY_CID);
static NS_DEFINE_CID(kUnicharBufferCID, NS_UNICHARBUFFER_CID);
// io
static NS_DEFINE_CID(kFileSpecCID, NS_FILESPEC_CID);
static NS_DEFINE_CID(kDirectoryIteratorCID, NS_DIRECTORYITERATOR_CID);
// components
static NS_DEFINE_CID(kComponentManagerCID, NS_COMPONENTMANAGER_CID);
static NS_DEFINE_CID(kGenericFactoryCID, NS_GENERICFACTORY_CID);
// threads
static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID);
static NS_DEFINE_CID(kEventQueueCID, NS_EVENTQUEUE_CID);
// proxy
static NS_DEFINE_CID(kProxyObjectManagerCID, NS_PROXYEVENT_MANAGER_CID);
////////////////////////////////////////////////////////////////////////////////
// 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.
//
static nsresult
RegisterGenericFactory(nsIComponentManager* compMgr, const nsCID& cid, const char* className,
const char *progid, nsIGenericFactory::ConstructorProcPtr constr)
{
nsresult rv;
nsIGenericFactory* fact;
rv = NS_NewGenericFactory(&fact, constr);
if (NS_FAILED(rv)) return rv;
rv = compMgr->RegisterFactory(cid, className, progid, fact, PR_TRUE);
NS_RELEASE(fact);
return rv;
}
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;
if (result)
{
NS_ADDREF(servMgr);
*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);
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 global services with the component manager so that
// clients can create new objects.
// Registry
nsIFactory *registryFactory = NULL;
rv = NS_RegistryGetFactory(&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;
rv = RegisterGenericFactory(compMgr, kAllocatorCID,
NS_ALLOCATOR_CLASSNAME,
NS_ALLOCATOR_PROGID,
nsAllocatorImpl::Create);
if (NS_FAILED(rv)) return rv;
rv = RegisterGenericFactory(compMgr, kArenaCID,
NS_ARENA_CLASSNAME,
NS_ARENA_PROGID,
ArenaImpl::Create);
if (NS_FAILED(rv)) return rv;
rv = RegisterGenericFactory(compMgr, kBufferCID,
NS_BUFFER_CLASSNAME,
NS_BUFFER_PROGID,
nsBuffer::Create);
if (NS_FAILED(rv)) return rv;
rv = RegisterGenericFactory(compMgr, kByteBufferCID,
NS_BYTEBUFFER_CLASSNAME,
NS_BYTEBUFFER_PROGID,
ByteBufferImpl::Create);
if (NS_FAILED(rv)) return rv;
rv = RegisterGenericFactory(compMgr, kFileSpecCID,
NS_FILESPEC_CLASSNAME,
NS_FILESPEC_PROGID,
nsFileSpecImpl::Create);
if (NS_FAILED(rv)) return rv;
rv = RegisterGenericFactory(compMgr, kDirectoryIteratorCID,
NS_DIRECTORYITERATOR_CLASSNAME,
NS_DIRECTORYITERATOR_PROGID,
nsDirectoryIteratorImpl::Create);
if (NS_FAILED(rv)) return rv;
rv = RegisterGenericFactory(compMgr, kPageManagerCID,
NS_PAGEMANAGER_CLASSNAME,
NS_PAGEMANAGER_PROGID,
nsPageMgr::Create);
if (NS_FAILED(rv)) return rv;
rv = RegisterGenericFactory(compMgr, kPropertiesCID,
NS_PROPERTIES_CLASSNAME,
NS_PROPERTIES_PROGID,
nsProperties::Create);
if (NS_FAILED(rv)) return rv;
rv = RegisterGenericFactory(compMgr, kPersistentPropertiesCID,
NS_PERSISTENTPROPERTIES_CLASSNAME,
NS_PERSISTENTPROPERTIES_PROGID,
nsPersistentProperties::Create);
if (NS_FAILED(rv)) return rv;
rv = RegisterGenericFactory(compMgr, kSupportsArrayCID,
NS_SUPPORTSARRAY_CLASSNAME,
NS_SUPPORTSARRAY_PROGID,
nsSupportsArray::Create);
if (NS_FAILED(rv)) return rv;
rv = RegisterGenericFactory(compMgr, nsObserver::GetCID(),
NS_OBSERVER_CLASSNAME,
NS_OBSERVER_PROGID,
nsObserver::Create);
if (NS_FAILED(rv)) return rv;
rv = RegisterGenericFactory(compMgr, nsObserverService::GetCID(),
NS_OBSERVERSERVICE_CLASSNAME,
NS_OBSERVERSERVICE_PROGID,
nsObserverService::Create);
if (NS_FAILED(rv)) return rv;
rv = RegisterGenericFactory(compMgr, kGenericFactoryCID,
NS_GENERICFACTORY_CLASSNAME,
NS_GENERICFACTORY_PROGID,
nsGenericFactory::Create);
if (NS_FAILED(rv)) return rv;
rv = RegisterGenericFactory(compMgr, kEventQueueServiceCID,
NS_EVENTQUEUESERVICE_CLASSNAME,
NS_EVENTQUEUESERVICE_PROGID,
nsEventQueueServiceImpl::Create);
if (NS_FAILED(rv)) return rv;
rv = RegisterGenericFactory(compMgr, kEventQueueCID,
NS_EVENTQUEUE_CLASSNAME,
NS_EVENTQUEUE_PROGID,
nsEventQueueImpl::Create);
if (NS_FAILED(rv)) return rv;
rv = RegisterGenericFactory(compMgr,
kProxyObjectManagerCID,
NS_XPCOMPROXY_CLASSNAME,
NS_XPCOMPROXY_PROGID,
nsProxyObjectManager::Create);
// Prepopulate registry for performance
nsComponentManagerImpl::gComponentManager->PlatformPrePopulateRegistry();
return rv;
}
////////////////////////////////////////////////////////////////////////////////

View File

@@ -1,8 +0,0 @@
nsIComponentManager.h
nsIFactory.h
nsIGenericFactory.h
nsIRegistry.h
nsIServiceManager.h
nsIServiceProvider.h
nsRepository.h
nsXPComFactory.h

View File

@@ -1,72 +0,0 @@
#!gmake
#
# The contents of this file are subject to the Netscape Public License
# Version 1.0 (the "NPL"); you may not use this file except in
# compliance with the NPL. You may obtain a copy of the NPL at
# http://www.mozilla.org/NPL/
#
# Software distributed under the NPL is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
# for the specific language governing rights and limitations under the
# NPL.
#
# The Initial Developer of this code under the NPL is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
# Reserved.
DEPTH=../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
include $(topsrcdir)/config/config.mk
LIBRARY_NAME = xpcomcomponents_s
MODULE = xpcom
XPIDLSRCS = \
$(NULL)
CPPSRCS = \
nsComponentManager.cpp \
nsGenericFactory.cpp \
nsRegistry.cpp \
nsRepository.cpp \
nsServiceManager.cpp \
xcDll.cpp \
$(NULL)
EXPORTS = \
nsIComponentManager.h \
nsIFactory.h \
nsIGenericFactory.h \
nsIRegistry.h \
nsIServiceManager.h \
nsIServiceProvider.h \
nsRepository.h \
nsXPComFactory.h \
$(NULL)
EXPORTS := $(addprefix $(srcdir)/, $(EXPORTS))
DEFINES += -DUSE_NSREG -D_IMPL_NS_COM -D_IMPL_NS_BASE
REQUIRES = xpcom libreg
LOCAL_INCLUDES += \
-I$(srcdir)/../base \
-I$(srcdir)/../thread \
$(NULL)
MKSHLIB :=
# we don't want the shared lib, but we want to force the creation of a static lib.
override NO_SHARED_LIB=1
override NO_STATIC_LIB=
include $(topsrcdir)/config/rules.mk

View File

@@ -1,69 +0,0 @@
#!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=..\..
MODULE = xpcom
################################################################################
## exports
EXPORTS = \
nsIComponentManager.h \
nsIFactory.h \
nsIGenericFactory.h \
nsIRegistry.h \
nsIServiceManager.h \
nsIServiceProvider.h \
nsRepository.h \
nsXPComFactory.h \
$(NULL)
XPIDLSRCS = \
$(NULL)
################################################################################
## library
LIBRARY_NAME=xpcomcomp_s
LINCS = \
-I$(PUBLIC)\xpcom \
-I$(PUBLIC)\libreg \
-I..\base \
-I..\threads \
$(NULL)
LCFLAGS = -DUSE_NSREG -D_IMPL_NS_COM -D_IMPL_NS_BASE -DWIN32_LEAN_AND_MEAN
CPP_OBJS = \
.\$(OBJDIR)\nsComponentManager.obj \
.\$(OBJDIR)\nsGenericFactory.obj \
.\$(OBJDIR)\nsRegistry.obj \
.\$(OBJDIR)\nsRepository.obj \
.\$(OBJDIR)\nsServiceManager.obj \
.\$(OBJDIR)\xcDll.obj \
$(NULL)
include <$(DEPTH)\config\rules.mak>
libs:: $(LIBRARY)
$(MAKE_INSTALL) $(LIBRARY) $(DIST)\lib
clobber::
rm -f $(DIST)\lib\$(LIBRARY_NAME).lib

View File

@@ -1,168 +0,0 @@
/* -*- 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

@@ -1,326 +0,0 @@
/* -*- 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

@@ -1,260 +0,0 @@
/* -*- 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;
// Registry Factory creation function defined in nsRegistry.cpp
// We hook into this function locally to create and register the registry
// Since noone outside xpcom needs to know about this and nsRegistry.cpp
// does not have a local include file, we are putting this definition
// here rather than in nsIRegistry.h
extern "C" NS_EXPORT nsresult NS_RegistryGetFactory(nsIFactory** aFactory);
////////////////////////////////////////////////////////////////////////////////
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.
// The libraryPersistentDescriptor is what gets passed to the library
// self register function from ComponentManager. The format of this string
// is the same as nsIFileSpec::GetPersistentDescriptorString()
//
// This function will go away in favour of RegisterComponentSpec. In fact,
// it internally turns around and calls RegisterComponentSpec.
NS_IMETHOD RegisterComponent(const nsCID &aClass,
const char *aClassName,
const char *aProgID,
const char *aLibraryPersistentDescriptor,
PRBool aReplace,
PRBool aPersist);
// Register a component using its FileSpec as its identification
// This is the more prevalent use.
NS_IMETHOD RegisterComponentSpec(const nsCID &aClass,
const char *aClassName,
const char *aProgID,
nsIFileSpec *aLibrary,
PRBool aReplace,
PRBool aPersist);
// Register a component using its dllName. This could be a dll name with
// no path so that LD_LIBRARY_PATH on unix or PATH on win can load it. Or
// this could be a code fragment name on the Mac.
NS_IMETHOD RegisterComponentLib(const nsCID &aClass,
const char *aClassName,
const char *aProgID,
const char *adllName,
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
//
//
NS_IMETHOD AutoRegister(RegistrationTime when, nsIFileSpec *directory);
NS_IMETHOD AutoRegisterComponent(RegistrationTime when, nsIFileSpec *component);
// nsComponentManagerImpl methods:
nsComponentManagerImpl();
virtual ~nsComponentManagerImpl();
static nsComponentManagerImpl* gComponentManager;
nsresult Init(void);
nsresult PlatformPrePopulateRegistry();
protected:
nsresult LoadFactory(nsFactoryEntry *aEntry, nsIFactory **aFactory);
nsFactoryEntry *GetFactoryEntry(const nsCID &aClass, PRBool checkRegistry);
nsresult SyncComponentsInDir(RegistrationTime when, nsIFileSpec *dirSpec);
nsresult SelfRegisterDll(nsDll *dll);
nsresult SelfUnregisterDll(nsDll *dll);
nsresult HashProgID(const char *aprogID, const nsCID &aClass);
nsDll *CreateCachedDll(const char *persistentDescriptor, PRUint32 modDate, PRUint32 size);
nsDll *CreateCachedDll(nsIFileSpec *dllSpec);
nsDll *CreateCachedDllName(const char *dllName);
// The following functions are the only ones that operate on the persistent
// registry
nsresult PlatformInit(void);
nsresult PlatformVersionCheck();
nsresult PlatformCreateDll(const char *fullname, nsDll* *result);
nsresult PlatformMarkNoComponents(nsDll *dll);
nsresult PlatformRegister(const char *cidString, const char *className, const char *progID, nsDll *dll);
nsresult PlatformUnregister(const char *cidString, 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, PRUint32 *lastModifiedTime, PRUint32 *fileSize);
void PlatformSetFileInfo(nsIRegistry::Key Key, PRUint32 lastModifiedTime, PRUint32 fileSize);
protected:
nsHashtable* mFactories;
nsHashtable* mProgIDs;
PRMonitor* mMon;
nsHashtable* mDllStore;
nsIRegistry* mRegistry;
nsIRegistry::Key mXPCOMKey;
nsIRegistry::Key mClassesKey;
nsIRegistry::Key mCLSIDKey;
};
#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 */
#ifdef XP_BEOS
#define NS_MOZILLA_DIR_NAME "mozilla"
#define NS_MOZILLA_DIR_PERMISSION 00700
#endif /* XP_BEOS */
/**
* 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
* alpha0.60 : xpcom 2.0 landing
* alpha0.70 : using nsIFileSpec. PRTime -> PRUint32
*/
#define NS_XPCOM_COMPONENT_MANAGER_VERSION_STRING "alpha0.70"
////////////////////////////////////////////////////////////////////////////////
/**
* 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(const nsCID &aClass, nsDll *dll);
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

@@ -1,110 +0,0 @@
/* -*- 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(nsIGenericFactory::GetIID()) ||
aIID.Equals(nsIFactory::GetIID()) ||
aIID.Equals(nsCOMTypeInfo<nsISupports>::GetIID())) {
*aInstancePtr = (nsIGenericFactory*) this;
NS_ADDREF_THIS();
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;
}
NS_COM nsresult
NS_NewGenericFactory(nsIGenericFactory* *result,
nsIGenericFactory::ConstructorProcPtr constructor,
nsIGenericFactory::DestructorProcPtr destructor)
{
nsresult rv;
nsIGenericFactory* fact;
rv = nsGenericFactory::Create(NULL, nsIGenericFactory::GetIID(), (void**)&fact);
if (NS_FAILED(rv)) return rv;
rv = fact->SetConstructor(constructor);
if (NS_FAILED(rv)) goto error;
rv = fact->SetDestructor(destructor);
if (NS_FAILED(rv)) goto error;
*result = fact;
return rv;
error:
NS_RELEASE(fact);
return rv;
}

View File

@@ -1,60 +0,0 @@
/* -*- 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

@@ -1,286 +0,0 @@
/* -*- 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"
#include "nsIFileSpec.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.
// The libraryPersistentDescriptor is what gets passed to the library
// self register function from ComponentManager. The format of this string
// is the same as nsIFileSpec::GetPersistentDescriptorString()
//
// This function will go away in favour of RegisterComponentSpec. In fact,
// it internally turns around and calls RegisterComponentSpec.
NS_IMETHOD RegisterComponent(const nsCID &aClass,
const char *aClassName,
const char *aProgID,
const char *aLibraryPersistentDescriptor,
PRBool aReplace,
PRBool aPersist) = 0;
// Register a component using its FileSpec as its identification
// This is the more prevalent use.
NS_IMETHOD RegisterComponentSpec(const nsCID &aClass,
const char *aClassName,
const char *aProgID,
nsIFileSpec *aLibrary,
PRBool aReplace,
PRBool aPersist) = 0;
// Register a component using its dllName. This could be a dll name with
// no path so that LD_LIBRARY_PATH on unix or PATH on win can load it. Or
// this could be a code fragment name on the Mac.
NS_IMETHOD RegisterComponentLib(const nsCID &aClass,
const char *aClassName,
const char *aProgID,
const char *adllName,
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, nsIFileSpec* directory) = 0;
NS_IMETHOD AutoRegisterComponent(RegistrationTime when, nsIFileSpec *component) = 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.
// The libraryPersistentDescriptor is what gets passed to the library
// self register function from ComponentManager. The format of this string
// is the same as nsIFileSpec::GetPersistentDescriptorString()
//
// This function will go away in favour of RegisterComponentSpec. In fact,
// it internally turns around and calls RegisterComponentSpec.
static nsresult RegisterComponent(const nsCID &aClass,
const char *aClassName,
const char *aProgID,
const char *aLibraryPersistentDescriptor,
PRBool aReplace,
PRBool aPersist);
// Register a component using its FileSpec as its identification
// This is the more prevalent use.
static nsresult RegisterComponentSpec(const nsCID &aClass,
const char *aClassName,
const char *aProgID,
nsIFileSpec *aLibrary,
PRBool aReplace,
PRBool aPersist);
// Register a component using its dllName. This could be a dll name with
// no path so that LD_LIBRARY_PATH on unix or PATH on win can load it. Or
// this could be a code fragment name on the Mac.
static nsresult RegisterComponentLib(const nsCID &aClass,
const char *aClassName,
const char *aProgID,
const char *adllName,
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
// If directory is NULL, then AutoRegister will try registering components
// in the default components directory which is got by
// nsSpecialSystemDirectory(XPCOM_CurrentProcessComponentDirectory)
static nsresult AutoRegister(nsIComponentManager::RegistrationTime when,
nsIFileSpec* directory);
static nsresult AutoRegisterComponent(nsIComponentManager::RegistrationTime when,
nsIFileSpec *component);
};
////////////////////////////////////////////////////////////////////////////////
#endif

View File

@@ -1,39 +0,0 @@
/*
* DO NOT EDIT. THIS FILE IS GENERATED FROM nsIFactory.idl
*/
#ifndef __gen_nsIFactory_h__
#define __gen_nsIFactory_h__
#include "nsISupports.h" /* interface nsISupports */
#include "nsrootidl.h" /* interface nsrootidl */
#ifdef XPIDL_JS_STUBS
#include "jsapi.h"
#endif
/* starting interface: nsIFactory */
/* {00000001-0000-0000-c000-000000000046} */
#define NS_IFACTORY_IID_STR "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:
NS_DEFINE_STATIC_IID_ACCESSOR(NS_IFACTORY_IID)
/* voidStar CreateInstance (in nsISupports aOuter, in nsIIDRef iid); */
NS_IMETHOD CreateInstance(nsISupports *aOuter, const nsIID & iid, void * *_retval) = 0;
/* void LockFactory (in PRBool lock); */
NS_IMETHOD LockFactory(PRBool lock) = 0;
#ifdef XPIDL_JS_STUBS
static NS_EXPORT_(JSObject *) InitJSClass(JSContext *cx);
static NS_EXPORT_(JSObject *) GetJSObject(JSContext *cx, nsIFactory *priv);
#endif
};
#endif /* __gen_nsIFactory_h__ */

View File

@@ -1,29 +0,0 @@
/* -*- Mode: IDL; 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 "nsISupports.idl"
[object, uuid(00000001-0000-0000-c000-000000000046)]
interface nsIFactory : nsISupports {
voidStar CreateInstance(in nsISupports aOuter,
in nsIIDRef iid);
void LockFactory(in PRBool lock);
};

View File

@@ -1,95 +0,0 @@
/* -*- 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 } }
#define NS_GENERICFACTORY_PROGID "component:/netscape/generic-factory"
#define NS_GENERICFACTORY_CLASSNAME "Generic Factory"
/**
* 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;
};
extern NS_COM nsresult
NS_NewGenericFactory(nsIGenericFactory* *result,
nsIGenericFactory::ConstructorProcPtr constructor,
nsIGenericFactory::DestructorProcPtr destructor = NULL);
#define NS_GENERIC_FACTORY_CONSTRUCTOR(_InstanceClass) \
static nsresult \
_InstanceClass##Constructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) \
{ \
nsresult rv; \
\
_InstanceClass * 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, _InstanceClass); \
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; \
}
#endif /* nsIGenericFactory_h___ */

View File

@@ -1,363 +0,0 @@
/* -*- 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 } }
/* be761f00-a3b0-11d2-996c-0080c7cb1081 */
#define NS_REGISTRY_CID \
{ 0xbe761f00, 0xa3b0, 0x11d2, \
{0x99, 0x6c, 0x00, 0x80, 0xc7, 0xcb, 0x10, 0x81} }
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 WellKnownKeys { Users = 1, Common = 2, CurrentUser = 3 };
enum WellKnownRegistry {
ApplicationComponentRegistry = 1
};
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 OpenWellKnownRegistry( uint32 regid ) = 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_DEFINE_STATIC_IID_ACCESSOR(NS_IREGISTRYNODE_IID)
NS_IMETHOD GetName( char **result ) = 0;
NS_IMETHOD GetKey( nsIRegistry::Key *r_key ) = 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

@@ -1,343 +0,0 @@
/* -*- 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 = nsnull) = 0;
NS_IMETHOD
ReleaseService(const nsCID& aClass, nsISupports* service,
nsIShutdownListener* shutdownListener = nsnull) = 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 = nsnull) = 0;
NS_IMETHOD
ReleaseService(const char* aProgID, nsISupports* service,
nsIShutdownListener* shutdownListener = nsnull) = 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 = nsnull);
static nsresult
ReleaseService(const nsCID& aClass, nsISupports* service,
nsIShutdownListener* shutdownListener = nsnull);
////////////////////////////////////////////////////////////////////////////
// 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 = nsnull);
static nsresult
ReleaseService(const char* aProgID, nsISupports* service,
nsIShutdownListener* shutdownListener = nsnull);
////////////////////////////////////////////////////////////////////////////
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
// }
//
// Note that both NS_WITH_SERVICE and NS_WITH_SERVICE1 can be used with a
// "progid" as well as a "clsid"; for example,
//
// nsresult rv;
// NS_WITH_SERVICE(nsIObserverService,
// observer,
// "component://netscape/observer-service", /* or NS_OBSERVERSERVICE_PROGID */
// &rv);
//
#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);
}
}
nsService(nsISupports* aServMgr, const char* aProgID, const nsIID& aIID, nsresult *rv)
: mService(0)
{
*rv = nsComponentManager::ProgIDToCLSID(aProgID, &mCID);
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);
}
}
nsService(const nsCID& aClass, const nsIID& aIID, nsresult *rv)
: mCID(aClass), mService(0) {
*rv = nsServiceManager::GetService(aClass, aIID,
(nsISupports**)&mService);
}
nsService(const char* aProgID, const nsIID& aIID, nsresult *rv)
: mService(0)
{
*rv = nsComponentManager::ProgIDToCLSID(aProgID, &mCID);
if (NS_FAILED(*rv)) return;
*rv = nsServiceManager::GetService(mCID, aIID,
(nsISupports**)&mService);
}
~nsService() {
if (mService) { // mService could be null if the constructor fails
nsresult rv = NS_OK;
rv = nsServiceManager::ReleaseService(mCID, mService);
}
}
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

@@ -1,164 +0,0 @@
/* -*- 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

@@ -1,188 +0,0 @@
/* -*- 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 *aLibraryPersistentDescriptor,
PRBool aReplace,
PRBool aPersist)
{
nsIComponentManager* cm;
nsresult rv = NS_GetGlobalComponentManager(&cm);
if (NS_FAILED(rv)) return rv;
return cm->RegisterComponent(aClass, aClassName, aProgID,
aLibraryPersistentDescriptor, aReplace, aPersist);
}
nsresult
nsComponentManager::RegisterComponentSpec(const nsCID &aClass,
const char *aClassName,
const char *aProgID,
nsIFileSpec *aLibrary,
PRBool aReplace,
PRBool aPersist)
{
nsIComponentManager* cm;
nsresult rv = NS_GetGlobalComponentManager(&cm);
if (NS_FAILED(rv)) return rv;
return cm->RegisterComponentSpec(aClass, aClassName, aProgID,
aLibrary, aReplace, aPersist);
}
nsresult
nsComponentManager::RegisterComponentLib(const nsCID &aClass,
const char *aClassName,
const char *aProgID,
const char *adllName,
PRBool aReplace,
PRBool aPersist)
{
nsIComponentManager* cm;
nsresult rv = NS_GetGlobalComponentManager(&cm);
if (NS_FAILED(rv)) return rv;
return cm->RegisterComponentLib(aClass, aClassName, aProgID,
adllName, 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,
nsIFileSpec *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,
nsIFileSpec *fullname)
{
nsIComponentManager* cm;
nsresult rv = NS_GetGlobalComponentManager(&cm);
if (NS_FAILED(rv)) return rv;
return cm->AutoRegisterComponent(when, fullname);
}

View File

@@ -1,518 +0,0 @@
/* -*- 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 {
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);
}
////////////////////////////////////////////////////////////////////////////////

View File

@@ -1,158 +0,0 @@
/* -*- 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

@@ -1,273 +0,0 @@
/* -*- 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
#include "nsIComponentManager.h"
// MAC ONLY
nsDll::nsDll(const char *codeDllName, int type)
: m_dllName(NULL), m_dllSpec(NULL), m_modDate(0), m_size(0),
m_instance(NULL), m_status(DLL_OK)
{
if (!codeDllName || !*codeDllName)
{
m_status = DLL_INVALID_PARAM;
return;
}
m_dllName = PL_strdup(codeDllName);
if (!m_dllName)
{
m_status = DLL_NO_MEM;
return;
}
}
nsDll::nsDll(nsIFileSpec *dllSpec)
: m_dllName(NULL), m_dllSpec(dllSpec), m_modDate(0), m_size(0),
m_instance(NULL), m_status(DLL_OK)
{
Init(dllSpec);
}
nsDll::nsDll(const char *libPersistentDescriptor)
: m_dllName(NULL), m_dllSpec(NULL), m_modDate(0), m_size(0),
m_instance(NULL), m_status(DLL_OK)
{
Init(libPersistentDescriptor);
}
nsDll::nsDll(const char *libPersistentDescriptor, PRUint32 modDate, PRUint32 fileSize)
: m_dllName(NULL), m_dllSpec(NULL), m_modDate(0), m_size(0),
m_instance(NULL), m_status(DLL_OK)
{
Init(libPersistentDescriptor);
// and overwrite the modData and fileSize
m_modDate = modDate;
m_size = fileSize;
}
void
nsDll::Init(nsIFileSpec *dllSpec)
{
// Addref the m_dllSpec
m_dllSpec = dllSpec;
NS_ADDREF(m_dllSpec);
// Make sure we are dealing with a file
PRBool isFile = PR_FALSE;
nsresult rv = m_dllSpec->isFile(&isFile);
if (NS_FAILED(rv))
{
m_status = DLL_INVALID_PARAM;
return;
}
if (isFile == PR_FALSE)
{
// Not a file. Cant work with it.
m_status = DLL_NOT_FILE;
return;
}
// Populate m_modDate and m_size
if (NS_FAILED(m_dllSpec->GetModDate(&m_modDate)) ||
NS_FAILED(m_dllSpec->GetFileSize(&m_size)))
{
m_status = DLL_INVALID_PARAM;
return;
}
m_status = DLL_OK;
}
void
nsDll::Init(const char *libPersistentDescriptor)
{
nsresult rv;
m_modDate = 0;
m_size = 0;
if (libPersistentDescriptor == NULL)
{
m_status = DLL_INVALID_PARAM;
return;
}
// Create a FileSpec from the persistentDescriptor
nsIFileSpec *dllSpec = NULL;
NS_DEFINE_IID(kFileSpecIID, NS_IFILESPEC_IID);
rv = nsComponentManager::CreateInstance(NS_FILESPEC_PROGID, NULL, kFileSpecIID, (void **) &dllSpec);
if (NS_FAILED(rv))
{
m_status = DLL_INVALID_PARAM;
return;
}
rv = dllSpec->SetPersistentDescriptorString((char *)libPersistentDescriptor);
if (NS_FAILED(rv))
{
m_status = DLL_INVALID_PARAM;
return;
}
Init(dllSpec);
}
nsDll::~nsDll(void)
{
if (m_instance != NULL)
Unload();
if (m_dllSpec)
NS_RELEASE(m_dllSpec);
if (m_dllName)
PL_strfree(m_dllName);
}
const char *
nsDll::GetNativePath()
{
if (m_dllName)
return m_dllName;
char *nativePath = NULL;
m_dllSpec->GetNativePath(&nativePath);
return nativePath;
}
const char *
nsDll::GetPersistentDescriptorString()
{
if (m_dllName)
return m_dllName;
char *persistentDescriptor = NULL;
m_dllSpec->GetPersistentDescriptorString(&persistentDescriptor);
return persistentDescriptor;
}
PRBool
nsDll::HasChanged()
{
if (m_dllName)
return PR_FALSE;
// If mod date has changed, then dll has changed
PRBool modDateChanged = PR_FALSE;
nsresult rv = m_dllSpec->modDateChanged(m_modDate, &modDateChanged);
if (NS_FAILED(rv) || modDateChanged == PR_TRUE)
return PR_TRUE;
// If size has changed, then dll has changed
PRUint32 aSize = 0;
rv = m_dllSpec->GetFileSize(&aSize);
if (NS_FAILED(rv) || aSize != m_size)
return PR_TRUE;
return PR_FALSE;
}
PRBool nsDll::Load(void)
{
if (m_status != DLL_OK)
{
return (PR_FALSE);
}
if (m_instance != NULL)
{
// Already loaded
return (PR_TRUE);
}
if (m_dllName)
{
m_instance = PR_LoadLibrary(m_dllName);
}
else
{
char *nsprPath = NULL;
nsresult rv = m_dllSpec->GetNSPRPath(&nsprPath);
if (NS_FAILED(rv)) return PR_FALSE;
#ifdef XP_MAC
// NSPR path is / separated. This works for all NSPR functions
// except Load Library. Translate to something NSPR can accepts.
char *macFileName = PL_strdup(nsprPath);
if (macFileName != NULL)
{
if (macFileName[0] == '/')
{
// convert '/' to ':'
int c;
char* str = macFileName;
while ((c = *str++) != 0)
{
if (c == '/')
str[-1] = ':';
}
m_instance = PR_LoadLibrary(&macFileName[1]); // skip over initial slash
}
else
{
m_instance = PR_LoadLibrary(macFileName);
}
PL_strfree(macFileName);
}
#else
m_instance = PR_LoadLibrary(nsprPath);
#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

@@ -1,82 +0,0 @@
/* -*- 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"
#include "nsIFileSpec.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_dllName; // Mac only. Stores the dllName to load.
nsIFileSpec *m_dllSpec; // Filespec representing the component
PRUint32 m_modDate; // last modified time at creation of this object
PRUint32 m_size; // size of the dynamic library at creation of this object
PRLibrary *m_instance; // Load instance
nsDllStatus m_status; // holds current status
void Init(nsIFileSpec *dllSpec);
void Init(const char *persistentDescriptor);
public:
nsDll(nsIFileSpec *dllSpec);
nsDll(const char *persistentDescriptor);
nsDll(const char *persistentDescriptor, PRUint32 modDate, PRUint32 fileSize);
nsDll(const char *dll, int type /* dummy */);
~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);
PRBool HasChanged(void);
const char *GetNativePath(void);
const char *GetPersistentDescriptorString(void);
PRUint32 GetLastModifiedTime(void) { return(m_modDate); }
PRUint32 GetSize(void) { return(m_size); }
PRLibrary *GetInstance(void) { return (m_instance); }
};

View File

@@ -1,88 +0,0 @@
/* -*- 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

@@ -1,49 +0,0 @@
/* -*- 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

@@ -1,117 +0,0 @@
<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
<META NAME="Author" CONTENT="Kipp E.B. Hickman">
<META NAME="GENERATOR" CONTENT="Mozilla/4.04 [en] (WinNT; I) [Netscape]">
<TITLE>Gemini Object Model</TITLE>
</HEAD>
<BODY>
<H1>
Gemini Object Model</H1>
The gemini object model is a cross platform component object model modelled
after win32's IUnknown and COM. We do not support a C API to gemini at
this time.
<H2>
nsID</H2>
Like OSF's DCE, we use an "interface id" which is a unique identifer which
names the interface. The nsID and be used as a key into a cross platform
registry service to discover an implementation of an interface. Here is
the declaration of nsID:
<UL><TT>struct nsID {</TT>
<BR><TT>&nbsp; PRUint32 m0;</TT>
<BR><TT>&nbsp; PRUint16 m1, m2;</TT>
<BR><TT>&nbsp; PRUint8 m3[8];</TT>
<P><TT>&nbsp; inline nsbool Equals(const nsID&amp; other) const {</TT>
<BR><TT>&nbsp;&nbsp;&nbsp; return</TT>
<BR><TT>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (((PRUint32*) &amp;m0)[0] == ((PRUint32*)
&amp;other.m0)[0]) &amp;&amp;</TT>
<BR><TT>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (((PRUint32*) &amp;m0)[1] == ((PRUint32*)
&amp;other.m0)[1]) &amp;&amp;</TT>
<BR><TT>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (((PRUint32*) &amp;m0)[2] == ((PRUint32*)
&amp;other.m0)[2]) &amp;&amp;</TT>
<BR><TT>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (((PRUint32*) &amp;m0)[3] == ((PRUint32*)
&amp;other.m0)[3]);</TT>
<BR><TT>&nbsp; }</TT>
<BR><TT>};</TT></UL>
On windows, the "uuidgen" program (provided with Visual C++) can be used
to generate these identifiers.
<H2>
nsISupports</H2>
This is the base class for all component objects. Not all objects are component
objects; these rules apply to objects which expose an interface which is
shared across dll/exe boundaries. Here is nsISupports:
<UL><TT>typedef nsID nsIID;</TT>
<BR><TT>class nsISupports {</TT>
<BR><TT>public:</TT>
<BR><TT>&nbsp; virtual nsqresult QueryInterface(const nsIID&amp; aIID,</TT>
<BR><TT>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
void** aInstancePtr) = 0;</TT>
<BR><TT>&nbsp; virtual nsrefcnt AddRef() = 0;</TT>
<BR><TT>&nbsp; virtual nsrefcnt Release() = 0;</TT>
<BR><TT>};</TT></UL>
The semantics of this interface are identical to win32's "COM" IUnknown
interface. In addition, the types are carefully mapped and the names are
the same so that if necessary we can "flip a switch" and have the windows
version (or any other platform that embraces COM) use the native COM IUnknown
without source code modification.
<H2>
Factory Procedures</H2>
Factory procedures use this design pattern
<UL><TT>nsqresult NS_NewFoo(nsIFoo** aInstancePtr, nsISupports* aOuter,
...);</TT></UL>
The return value is a status value (see nsISupports.h for the legal return
values); the first argument is a pointer to a cell which will hold the
new instance pointer if the factory procedure succeeds. The second argument
is a pointer to a containing component object that wishes to aggregate
in the Foo object. This pointer will be null if no aggregation is requested.
If the factory procedure cannot support aggregation of the Foo type then
it fails and returns an error if aggregation is requested.
<P>The following symbols are defined for standard error return values from
<TT>QueryInterface</TT> and from factory procedures:
<UL><TT>#define NS_FAILED(_nsresult) ((_nsresult) &lt; 0)</TT>
<BR><TT>#define NS_SUCCEEDED(_nsresult) ((_nsresult) >= 0)</TT>
<P><TT>// Standard "it worked" return value</TT>
<BR><TT>#define NS_OK 0</TT>
<P><TT>// Some standard error codes we use</TT>
<BR><TT>#define NS_ERROR_BASE ((nsresult) 0xC1F30000)</TT>
<BR><TT>#define NS_ERROR_OUT_OF_MEMORY (NS_ERROR_BASE + 0)</TT>
<BR><TT>#define NS_ERROR_NO_AGGREGATION (NS_ERROR_BASE + 1)</TT>
<BR><TT>#define NS_NOINTERFACE ((nqresult) 0x80004002L)</TT></UL>
<H2>
nsIFactory</H2>
Factory classes should eventually replace factory procedures for major
classes. They provide an easy mechanism for placing code in DLLs. The nsIFactory
class is as follows:
<BR>&nbsp;
<UL><TT>class nsIFactory: public nsISupports {</TT>
<BR><TT>public:</TT>
<UL><TT>virtual nsresult CreateInstance(const nsIID &amp;aIID,</TT>
<BR><TT>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
nsISupports *aOuter,</TT>
<BR><TT>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
void **aResult) = 0;</TT>
<BR><TT>virtual void LockFactory(PRBool aLock) = 0;</TT></UL>
<TT>};</TT></UL>
This interface is again identical to the COM version. More on registering
factories shortly.
<H2>
Error Handling</H2>
Because no exceptions are returned, error handling is done in the traditional
"error status value" method.
<H2>
Cross Platform Registry</H2>
A cross platform registry was written for the SmartUpdate feature of Communicator.
We will investigate it's usefulness for our purposes.
<H2>
Library Management</H2>
NSPR 2.x provides the cross platform mechanism for loading and unloading
libraries, and run time linking.
<BR>&nbsp;
</BODY>
</HTML>

View File

@@ -1,254 +0,0 @@
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="GENERATOR" content="Mozilla/4.51 [en] (WinNT; U) [Netscape]">
<meta name="Author" content="Suresh Duddi">
<title>TODO List for XPCOM</title>
</head>
<body>
<center>
<h1>
TODO List for XPCOM</h1></center>
<center>Last updated: 25 March 1999
<br><a href="mailto:dp@netscape.com">Suresh Duddi</a></center>
<table BORDER WIDTH="100%" NOSAVE >
<tr NOSAVE>
<th NOSAVE>Task</th>
<th NOSAVE><a href="http://bugzilla.mozilla.org/bug_status.html#priority">Priority</a></th>
<th NOSAVE>Owner</th>
<th NOSAVE>MileStone complete/Status</th>
</tr>
<tr BGCOLOR="#33CCFF" NOSAVE>
<td NOSAVE>Move xpcom from using NR_*() functions (modules/libreg) to nsIRegistry
(xpcom/src/nsRegistry.cpp)
<ul>
<li>
Mainly you want to change all the Platform*() functions in nsComponentManager.cpp</li>
<li>
Now we open/close the registry all the time. I want to keep the registry
open all the time. That would get performance up.</li>
<li>
Platform*() functions use the NR_*Raw() functions in some places. I wonder
if the nsRegistry has a equivalent. If not we need to create them.</li>
</ul>
Mostly, there is equivalence between NR_*() calls and nsRegistry calls.&nbsp;</td>
<td>P2</td>
<td>Nick Ambrose &lt;<a href="mailto:nicka87@hotmail.com">nicka87@hotmail.com</a>></td>
<td>3/22/1999 started
<br>3/27/1999 Patch submitted
<br>3/30/1999 landing
<br><b>DONE</b></td>
</tr>
<tr BGCOLOR="#33CCFF">
<td>RegisterFactory() and RegisterComponent(..persist=0) ignoring PROGID.
Needs Fix.</td>
<td>P1</td>
<td>Nick Ambrose &lt;<a href="mailto:nicka87@hotmail.com">nicka87@hotmail.com</a>></td>
<td>4/6/1999 started
<br>4/7/1999 Patch submitted
<br>4/12/1999 Patch Checked in
<br><b>DONE</b></td>
</tr>
<tr>
<td>Startup components: Some components need to be created at startup.
Have a framework for them.</td>
<td>P1</td>
<td><a href="mailto:dp@netscape.com">Suresh Duddi</a></td>
<td></td>
</tr>
<tr>
<td>nsIRegistry access via Javascript.</td>
<td>P1</td>
<td></td>
<td>IDL of nsIRegistry will fix this says <a href="mailto:jband@netscape.com">John
Bandhauer</a></td>
</tr>
<tr BGCOLOR="#33CCFF" NOSAVE>
<td NOSAVE>API changes: Remove all pathlist. XPCOM should support only
paths.</td>
<td>P1</td>
<td><a href="mailto:dp@netscape.com">Suresh Duddi</a></td>
<td>4/2/1999 Checked in
<br><b>DONE</b></td>
</tr>
<tr>
<td>Fix xpcom from being initialized before main from static variables.</td>
<td>P1</td>
<td><a href="mailto:dp@netscape.com">Suresh Duddi</a></td>
<td>3/22/1999 Started.
<br>- checked in a fixed xpcom initialization sequence.
<br>- Now got to fix all code statically calling it. I know Netlib does.
<br>- 4/1/1999 Fixed netlib on unix from static intialization. WIN is left.</td>
</tr>
<tr>
<td>Path handling: Use nsFileSpec instead of file path names. Char * pathnames
are not intl, and cannot be stored in the registry. Plus that wont support
mac aliases.
<ul>
<li>
Possibly move autoreg out of xpcom</li>
</ul>
</td>
<td>P1</td>
<td><a href="mailto:dp@netscape.com">Suresh Duddi</a>
<br><a href="mailto:rjc@netscape.com">Robert Churchill</a></td>
<td>3/24/1999 started
<br><b>Blocked </b>on deciding which solution to pick.</td>
</tr>
<tr>
<td>Registry dump utility (regExport exists on windows) and about:registry
(or) better yet an rdf data source for the registry.</td>
<td>P3</td>
<td><a href="mailto:dp@netscape.com">Suresh Duddi</a></td>
<td>4/5/1999 Fixed regExport to accurately dump the registry on win and
unix.
<br>- regExport needs to be compiled on the mac.</td>
</tr>
<tr>
<td>Replace use of nsVector (PL_Vector) with nsISupportsArray</td>
<td>P3</td>
<td></td>
<td></td>
</tr>
<tr>
<td>PATH argument to NSRegisterSelf() and NSUnregisterSelf() to be a nsISupports</td>
<td>P1</td>
<td></td>
<td></td>
</tr>
<tr BGCOLOR="#33CCFF" NOSAVE>
<td NOSAVE>Code Cleanup:
<ul>
<li>
Registry path strings in nsComponentManager.cpp #defined</li>
</ul>
</td>
<td>P3</td>
<td>Nick Ambrose &lt;<a href="mailto:nicka87@hotmail.com">nicka87@hotmail.com</a>></td>
<td>4/1/1999 started
<br>4/5/1999 Patch submitted and checked in
<br><b>DONE</b></td>
</tr>
<tr BGCOLOR="#33CCFF">
<td>Performance
<ul>
<li>
Cache commonly used registry keys</li>
</ul>
</td>
<td>P1</td>
<td>Nick Ambrose &lt;<a href="mailto:nicka87@hotmail.com">nicka87@hotmail.com</a>></td>
<td>4/1/1999 started
<br>4/5/1999 Patch submitted and checked in
<br><b>DONE</b></td>
</tr>
<tr>
<td>Factories: Use previously created factories for object creation instead
of creating the factory everytime the object needs to be created.
<ul>
<li>
This is very tricky as the factory is owned by the component and when it
decides to unload itself on a CanUnload() call, the factory will be released.
Got to make sure that the component manager gets notified of this if it
caches the factory.</li>
</ul>
</td>
<td>P2</td>
<td></td>
<td></td>
</tr>
<tr BGCOLOR="#33CCFF" NOSAVE>
<td NOSAVE>nsIAllocator: wrap it in a static api</td>
<td>P2</td>
<td><a href="mailto:jband@netscape.com">John Bandhauer</a></td>
<td NOSAVE>3/31/1999 started
<br>4/2/1999 Check in
<br><b>DONE</b></td>
</tr>
</table>
<h2>
Documentation on XPCOM</h2>
<ul>
<li>
<a href="TODO.html">TODO List</a> &lt;<i>this page></i></li>
<li>
XPCOM main page : <a href="http://www.mozilla.org/projects/xpcom">http://www.mozilla.org/projects/xpcom</a></li>
<li>
<a href="xpcom-code-faq.html">Code FAQ</a></li>
<li>
<a href="xpcom-component-registration.html">Component Registration</a></li>
</ul>
<hr WIDTH="100%">
</body>
</html>

View File

@@ -1,93 +0,0 @@
<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
<META NAME="Author" CONTENT="Kipp E.B. Hickman">
<META NAME="GENERATOR" CONTENT="Mozilla/4.04 [en] (WinNT; U) [Netscape]">
<TITLE>C++ Tips</TITLE>
</HEAD>
<BODY>
<H1>
C++ Tips</H1>
This is a compilation of tips on how to write cross-platform C++ code that
compiles everywhere.
<H2>
General</H2>
<UL>
<LI>
Always use the nspr types for intrinsic integer types. The only exception
to this rule is when writing machine dependent code that is called from
xp code. In this case you will probably need to bridge the type systems
and cast from an nspr type to a native type. The other exception is floating
point; nspr defines PRFloat as a double (!).</LI>
<LI>
Exceptions do not work everywhere so don't use them anywhere except in
machine specific code, and then if you do use them in machine specific
code you must catch all exceptions there because you can't throw the exception
across xp code.</LI>
<LI>
Templates do not work everywhere so don't use them anywhere.</LI>
<LI>
Do not wrap include statements with an #ifdef. The reason is that when
the symbol is not defined, other compiler symbols will not be defined and
it will be hard to test the code on all platforms. An example of what <B>not</B>
to do:</LI>
<BR>&nbsp;
<UL><TT>#ifdef X</TT>
<BR><TT>#include "foo.h"</TT>
<BR><TT>#endif</TT>
<BR><TT></TT>&nbsp;</UL>
<LI>
For types that do not need operator= or a copy constructor, declare them
yourselves and make them private. Example:</LI>
<BR>&nbsp;
<UL><TT>class foo {</TT>
<BR><TT>...</TT>
<BR><TT>private:</TT>
<BR><TT>&nbsp; // These are not supported and are not implemented!</TT>
<BR><TT>&nbsp; foo(const foo&amp; x);</TT>
<BR><TT>&nbsp; foo&amp; operator=(const foo&amp; x);</TT>
<BR><TT>};</TT></UL>
<LI>
</LI>
</UL>
<H2>
Windows Compatability</H2>
<H2>
Metroworks Compatability</H2>
<UL>
<LI>
MAC compilers do not handle #include path names in the same manner as other
systems. Consequently #include statements should not contain path names,
just simple file names. An example of what <B>not</B> to do:</LI>
<BR>&nbsp;
<UL>#include "gemini/nsICSSParser.h"
<BR>&nbsp;</UL>
<LI>
</LI>
</UL>
<H2>
G++ Compatability</H2>
<UL>
<LI>
Use void in argument lists for functions that have no arguments (this works
around a bug in g++ 2.6.3)</LI>
</UL>
</BODY>
</HTML>

View File

@@ -1,279 +0,0 @@
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="GENERATOR" content="Mozilla/4.51 [en] (WinNT; U) [Netscape]">
<meta name="Author" content="Suresh Duddi">
<title>XPCOM Code FAQ</title>
</head>
<body>
<h2>
XPCOM Code FAQ</h2>
Suresh Duddi &lt;<a href="mailto:dp@netscape.com">dp@netscape.com</a>>
<br>Last Modified: April 2 1999
<br>
<hr WIDTH="100%">
<br>I am documenting things randomly as I am replying to people's questions.
So this looks more like an FAQ.
<h3>
Table of Contents</h3>
<ol>
<li>
<a href="#What are the Global Objects that XPCOM maintains">What are the
Global Objects that XPCOM maintains</a></li>
<li>
<a href="#What are the static classes that XPCOM maintains">What are the
static classes that XPCOM maintains</a></li>
<li>
<a href="#Is there any restriction on which static class I should call fi">Is
there any restriction on which static class I should call first</a></li>
<li>
<a href="#What is the order of creation of the ServiceManager, ComponentM">What
is the order of creation of the ServiceManager, ComponentManager and Registry</a></li>
<li>
<a href="#Is there a global Registry being maintained">Is there a global
Registry being maintained</a></li>
<li>
<font color="#000000"><a href="#ComponentManager Vs ServiceManager">ComponentManager
Vs ServiceManager</a></font></li>
<li>
<a href="#ProgID Vs CLSID">ProgID Vs CLSID</a></li>
<li>
<a href="#How to debug components ?">How to debug components ?</a></li>
</ol>
<hr WIDTH="100%">
<h4>
<a NAME="What are the Global Objects that XPCOM maintains"></a>What are
the Global Objects that XPCOM maintains</h4>
<ul>mGlobalServiceManager
<br>mGlobalComponentManager</ul>
<h4>
<a NAME="What are the static classes that XPCOM maintains"></a>What are
the static classes that XPCOM maintains</h4>
<blockquote>nsComponentManager
<br>nsServiceManager</blockquote>
<h4>
<a NAME="Is there any restriction on which static class I should call fi"></a>Is
there any restriction on which static class I should call first</h4>
<blockquote>No restrictions. You can call any function from the static
classes nsComponentManager and nsServiceManager. XPCOM will do the right
thing to initialize itself at both places.
<p>Autoregistration() can happen only after Init_XPCOM() is called since
the registy might be required by SelfRegister() functions of the dlls and
it is only in Init_XPCOM() do we create register the RegistryFactory()
with the ComponentManager.</blockquote>
<h4>
<a NAME="What is the order of creation of the ServiceManager, ComponentM"></a>What
is the order of creation of the ServiceManager, ComponentManager and Registry</h4>
<blockquote>Init_XPCOM()
<blockquote>
<li>
create the global service manager</li>
<li>
create the global component manager and register as service with the global
service manager</li>
<li>
RegisterFactory(...RegistryFactory...)&nbsp; Register the RegistryFactory
with the component manager so that new registry objects can be created.</li>
</blockquote>
Now the hard problem is when to trigger Init_XPCOM() There are two static
objects nsComponentManager and nsServiceManager. Any function in either
of them can be called first. Today nsServiceManager::GetService() is the
first one that gets called. All the members of the static nsServiceManager
use the NS_GetGlobalServiceManager() to get to the global service manager.
All members of the static nsComponentManager use the NS_GetGlobalComponentManager()
to get to the global component manager. Hence if we trigger Init_XPCOM()
from both NS_GetGlobalComponentManager() and NS_GetGlobalServiceManager()
we will be safe.</blockquote>
<h4>
<a NAME="Is there a global Registry being maintained"></a>Is there a global
Registry being maintained</h4>
<blockquote>No. The nsIRegistry is designed to be lightweight access to
the registry. Consumers who need to access the registry should use the
component manager to create the their own registry access object. This
is required because the open() call is supported by the nsIRegistry() and
if we maintain a global registry arbitrating which registry file is opened
is going to be a major headach.
<p>The ProgID for the registry will be <font color="#990000">component://netscape/registry</font>
<br>&nbsp;</blockquote>
<h4>
<a NAME="ComponentManager Vs ServiceManager"></a><font color="#000000">ComponentManager
Vs ServiceManager</font></h4>
<blockquote><font color="#000000">ComponentManager is the only way for
component creation. ComponentManager always uses the component's factory
to create the component instance. Clients (code that calls CreateInstance()
to create and use a component) call the ComponentManager to create instances.
Components (the code that implemented NSRegisterSelf()) calls the ComponentManager
to register itself and gets called when a Client wants to instantiate a
component.</font>
<p><font color="#000000">ServiceManager is a convinience for getting singleton
components, components for which only one instance stays alive for the
entire application e.g Netlib. It enforces only one of a kind of a component
to exist. Hence the notion of getting a service not creating one. (as opposed
to the notion of Creating instances with the componentManager). ServiceManager
is a convenience because components can technically force singletonism
by making their factory return the same instance if one was created already.
The other big use of ServiceManager is the (still unimplemented) notion
of Shutting down a service.</font>
<p><b><i><font color="#000000">Client</font></i></b>
<ul>
<li>
<i><font color="#000000">When does a client use the service manager vs
component manager</font></i></li>
<br><font color="#000000">When a client knows that the component that they
are trying to instantiate is a singleton, they need to call service manager
instead of component manager. Clients dont have to worry about calling
the ComponentManager at all in this case. The ServiceManager will take
care of creating the instance if the first one doesn't exist already.</font>
<br>&nbsp;
<li>
<i><font color="#000000">When does a client use the Component Manager as
opposed to Service Manager</font></i></li>
<br><font color="#000000">When a client wants a private instance of a component,
they call the Component Manager. From the Clients point of view, a new
xpcom object creation happens everytime they call CreateInstance() Anything
else is an implementation detail that the Client need not worry about.</font>
<br>&nbsp;
<li>
<i><font color="#000000">How does a Client know that they have to instantiate
a singleton</font></i></li>
<br><font color="#000000">For now, the Client just has to know. There is
no way of telling which component is a Service and which isn't. In fact,
in todays xpcom (Mar 1999) any component can be accessed as a Service.
Use your judgement until there is a proper method or service manager is
eliminated. There is nothing even in the code that detects Services from
Instances.</font>
<p><b><font color="#CC0000">Need a solution for this. Email suggestion
to <a href="mailto:warren@netscape.com,dp@netscape.com">warren@netscape.com,
dp@netscape.com</a></font></b>
<br>&nbsp;</ul>
<b><i><font color="#000000">Component</font></i></b>
<ul>
<li>
<i><font color="#000000">Can a component enforce use only as a Service</font></i></li>
<br><font color="#000000">No. The notion of the ServiceManager is available
only to Clients.</font>
<p><font color="#000000">Note that at some points when a component wants
another component, it actually behaves as a client and hence follows the
rules of the Client above to either CreateInstance() or GetService() the
needed component.</font>
<p><b><tt><font color="#990000">Workaround:</font></tt></b><font color="#000000">
If however a component wants only one of its instances to exist and cannot
ensure that Clients understand well enough only to use the Service Manager
to get it, it can implement singletonism in its factory. Basically the
factory on first instance creation should hang on to the instance. On subsequence
instance creations, addref the instance it is holding to and return that
instead creating a new one.</font>
<ul>&nbsp;
<br><font color="#000000">E.g preferences does this.</font> Code sample
at
<a href="http://lxr.mozilla.org/seamonkey/source/modules/libpref/src/nsPref.cpp#621">nsPref.cpp
nsPrefFactory::CreateInstance()</a> and&nbsp; <a href="http://lxr.mozilla.org/seamonkey/source/modules/libpref/src/nsPref.cpp#227">nsPref.cpp
nsPref::GetInstance()</a> With this implementation, whether Clients get
to it by calling nsIServiceManager::GetService() or nsIComponentManager::CreateInstance(),
the same object will be returned hence guaranteeing singletonism.</ul>
<li>
<i><font color="#000000">Should a component do anything at creation to
become a Service</font></i></li>
<br><font color="#000000">No. Again, the notion of a ServiceManager is
available only to Clients.</font>
<br>&nbsp;
<li>
<i><font color="#000000">Can a component advertise that it is a service
so clients can use it as one</font></i></li>
<br>No. There isn't a way other than a comment in the interface of the
header file.</ul>
</blockquote>
<h4>
<a NAME="ProgID Vs CLSID"></a>ProgID Vs CLSID</h4>
<blockquote>ClassID or CLSID is the unique indentification of a component.
It is a structure of huge numbers generated by using uuidgen on a windows
box. It is represented as a string in documentation as {108d75a0-bab5-11d2-96c4-0060b0fb9956}
<p>ProgID is the string identification of an implementation of a component
the client is looking for. The representation takes a URI syntax. Eg. <i>component://netscape/network/protocol?name=http;description=Http%20Protocol%20Handler</i>
<br>Some simplify this to, ProgID is a more readable string form of a CLSID.
That is acceptable on the periphery. The ProgID is a Client thing. Components
register with component manager to claim that they are the implementation
for a ProgID. A component can register to be the implementation for multiple
ProgIDs (not implemented yet).
<p><b><i>Client</i></b>
<ul>
<li>
<i>Should CreateInstance() calls use ProgID or CLSID</i></li>
<br>ProgID is what Clients should use to CreateInstances. Clients should
not even know about the CLSID unless they are hell bent on creating a particular
implementation of a component.
<br>&nbsp;</ul>
<b><i>Component</i></b>
<ul>
<li>
<i>Should Components register with both a CID and ProgID</i></li>
<br>Absolutely.</ul>
</blockquote>
<h4>
<a NAME="How to debug components ?"></a>How to debug components ?</h4>
<blockquote>XPCOM provides log output. To enable the logging:
<blockquote><tt>setenv NSPR_LOG_MODULES nsComponentManager:5</tt>
<br><tt>setenv NSPR_LOG_FILE xpcom.log</tt></blockquote>
Start your application after setting the above environment variables. Debug
log from xpcom would be in the file <tt>xpcom.log</tt>
<p>Since components are dynamically loaded only on demand, debugging them
could be a hard. Here are some tips to debugging components.
<p><b><i>Windows: VC5.0 VC6.0</i></b>
<ul>Include your component library in the Project->Settings, Additional
Dll. drop down. After that breakpoints can be enabled.</ul>
<b><i>Unix: gdb</i></b>
<blockquote>Let the program run until you are sure that your component
is loaded. Type Control-C. Now all symbols from your component will be
available in gdb. Put your breakpoints and restart the app. Gdb will complain
that it cannot set the breakpoint, and that it is temporarily disabling
it, but when the *.so is loaded, the breakpoint is enabled automatically.
- &lt;<a href="mailto:erik@netscape.com">Eric Van Der Poel</a>>
<p>I think typing "dir components" (assuming you're in dist/bin) will also
allow you to see the symbols in your stack the first time. - &lt;<a href="mailto:alecf@netscape.com">Alec
Flett</a>></blockquote>
<b><i>Mac: Codewarrior</i></b>
<blockquote>Just open the appropriate .xSYM file in the debugger; the debugger
will target the library when the application is run. - &lt;<a href="mailto:sfraser@netscape.com">Simon
Fraser</a>></blockquote>
</blockquote>
<hr WIDTH="100%">
</body>
</html>

View File

@@ -1,543 +0,0 @@
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="Author" content="Suresh Duddi">
<meta name="GENERATOR" content="Mozilla/4.51 [en] (X11; U; Linux 2.0.36 i686) [Netscape]">
<title>XPCOM Dynamic Component Registration</title>
</head>
<body>
<center>
<h2>
XPCOM Dynamic Component Registration</h2></center>
<center>Suresh Duddi &lt;<a href="mailto:dp@netscape.com">dp@netscape.com</a>>
<hr WIDTH="100%"></center>
<p>Dynamic object registration in XPCOM is achieved by interaction of the
following components:
<ul>
<li>
The Component Registry</li>
<li>
The Repository</li>
<li>
The Service Manager</li>
<li>
Component dll implementing <tt>NSRegisterSelf()</tt></li>
</ul>
The registration mechanism for XPCOM components is similar in many ways
to that of COM. The XPCOM component dlls will have the opportunity to register
themselves with the registry. The exact time of installation would be either
at install time or as a result of <b>autodetection</b> by the Repository
Manager at runtime.
<br>
<hr WIDTH="100%">
<h3>
<a NAME="The Registry: XPCOM Hierarchy"></a>The Component Registry</h3>
There are three types of Component Registries:
<ol>
<li>
<b>App-Component-Registry<br>
</b>Each application has its own Component Registry that lives along with
the app in its &lt;exe-dir>/components directory. The Component Registry
is created on installation or first run. It is be used read-only by XPCOM</li>
<li>
<b>User-Component-Registry</b></li>
<br>Each user can install additional components under their user home directory.
These components will be shared across all XPCOM applications that the
user runs.
<li>
<b>Meta-Component-Registry</b></li>
<br>Sharing Components between application: This can happen in two ways.
The installer of an application can find the other application's components
by looking for the application specifically and registering them with this
app's component registry. The second and more preferable approach is to
keep a machine wide Meta-Components-Registry that would aggregate all the
app component registries.</ol>
The difference component registries will be searched in the following order:
<ol>
<li>
User Components Registry</li>
<li>
App Component Registry</li>
<li>
Meta Component Registry</li>
</ol>
The user component registry is the only one that will be updated on the
fly by XPCOM. JS will be given the option to update either the App-Component-Registry
or the User-Component-Registry and this may succeed fail based on write
permission, although the general guideline is to update the User-Component-Registry.
JS will have to do special things to update the App-Component-Registry.
<p>Profiles are a notion of the app (navigator) and xpcom has nothing to
do with it. The app will store app specific data in a Data-Registry that
will be stored under the user's home directory.
<h4>
How does this Solve our problems</h4>
<ol>
<li>
Multiple installations of mozilla and xpcom based apps</li>
<br>Since each installation is going run with their own App-Component-Registry,
basically both apps will work. No inter process locking is essential. Since
both processes will operate on the User-Component-Registry, inter process
locking of the User-Component-Registry will be required.
<li>
Third Party components installation</li>
<br>Third parties can install components in their own directories and update
the App-Component-Registry (preferable) or User-Component-Registry depending
on if the sharing of component needs to be specific to the user or for
all users. Facilities for updating the registry would be to use JS or write
XPCOM code in their installer. The other option would be to add their components
in their own directory, create a App-Component-Registry of their own in
their directory and reference it in the Global Meta-Components-Registry.
This will get their components used by all applications.
<li>
Registry used to store app specific data</li>
<br>This is a totally separate registry: the Data-Registry. The theory
is that this will reside in the user's home directory. The registry hierarchy
is app specific.
<li>
User Specific components</li>
<br>This is basically the User-Component-Registry. Inter process locking
is required as all processes with XPCOM will access the same User-Component-Registry.
<li>
Embedding</li>
<br>This is requires more thought. The fact is when say Gecko is embedded
into an application, Gecko is running most probably in the process space
of that application and hence the XPCOM used will look for components in
this embedding applications directory. The embedding procedure should create
a App-Component-Reqistry for the embedding application that should contain
all the components from different apps this app would like to use. This
is however not required, if the Meta-Component-Registry exists.
<li>
User not having permission to the place where the global registry lives,
if there is one.</li>
<br>First the App-Component-Registry is written to only when there is a
new component or a component has gone away. New components come with installers
or the user calls regFactory.exe with the dll as an argument or clicks
on a button that says "refresh my user components" which will cause autoregistration
of user components. For deleted app components, annotations will be made
in the User-Component-Registry. Deleted user components is a non-issue.
<li>
NFS mounted home directories and app directories</li>
<br>NFS mounted home directories requires inter-machine locking of the
User-Component-Registry.&nbsp; NFS mounted app directories dont have a
problem as the App-Component-Registry is&nbsp; only used read-only by XPCOM.</ol>
So in summary,
<ul>
<li>
App-Component-Registry pretty much solves the top problem of Multiple applications.
With some help from the installer, Third party components will also be
solved.</li>
<li>
User-Component-Registry solves the User Specific Components problem.</li>
<li>
Meta-Component-Registry enables the dynamic sharing of components between
apps which eases embedding.</li>
</ul>
As a first cut, I am going to implement the App-Component-Registry for
M8.
<h4>
Hierarchy Used by Component Registry</h4>
XPCOM uses the nsRegistry to store mappings between CLSIDs and their implementations.
The Registry provides persistent storage of hierarchical keys and name-value
pairs associated with each key. Each key also keeps a default value.
<p>XPCOM will use the following registry hierarchy:
<blockquote><tt>ROOTKEY_COMMON</tt>
<br><tt>&nbsp;&nbsp;&nbsp; Common</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Classes</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
CLSID</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<b><font color="#CC0000">{108d75a0-bab5-11d2-96c4-0060b0fb9956}</font></b></tt>
<br><tt><nobr>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
InprocServer (S)&nbsp; = <font color="#CC0000">/home/dp/dist/bin/components/libnfs-protocol.so</font></nobr></tt>
<br><tt><nobr>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
ProgID&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (S)&nbsp; = <b><font color="#CC0000">component://netscape/network-protocol&amp;type=nfs</font></b></nobr></tt>
<br><tt><nobr>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
ClassName&nbsp;&nbsp;&nbsp; (S)&nbsp; = <b><font color="#CC0000">NFS Protocol
Handler</font></b></nobr></tt>
<p><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font color="#CC0000">component://netscape/network-protocol&amp;type=nfs</font></tt>
<br><tt><nobr>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
CLSID&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (S)&nbsp; = <font color="#CC0000">{108d75a0-bab5-11d2-96c4-0060b0fb9956}</font></nobr></tt>
<p><tt><i>&nbsp;&nbsp;&nbsp; </i>Software</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Netscape</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
XPCOM</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
VersionString&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (S)&nbsp;
= <font color="#CC0000">alpha0.20</font></tt>
<p><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<font color="#CC0000">/home/dp/dist/bin/components/libnfs-protocol.so</font></tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
ComponentsCount&nbsp;&nbsp;&nbsp; (Int)&nbsp; = <font color="#CC0000">1</font></tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
FileSize&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (Int)&nbsp;
= <font color="#CC0000">78965</font></tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
LastModTimeStamp&nbsp;&nbsp; (S)&nbsp;&nbsp;&nbsp; = <font color="#CC0000">Wed
Feb 24 11:24:06 PST 1999</font></tt>
<p><tt><font color="#CC0000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</font><font color="#000000">Events</font></tt>
<br><tt><font color="#000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
Startup</font></tt>
<br><tt><font color="#000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</font><font color="#CC0000">{108d75a0-bab5-11d2-96c4-0060b0fb9956}</font></tt>
<br><tt><font color="#CC0000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
{17894983-ab78-8d75-a0bb-511d296c4006}</font></tt>
<p><tt><font color="#000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
Shutdown</font></tt>
<br><tt><font color="#000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</font><font color="#CC0000">{748958ea-abab-511d-296c-40060b0fb995}</font></tt>
<br><tt><font color="#CC0000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
{45617894-983a-b788-d75a-0bab11d296c4}</font></tt>
<br>&nbsp;</blockquote>
<h3>
<hr WIDTH="100%"><a NAME="The Repository: Object instance creation"></a>The
Repository: Object instance creation</h3>
All object creation happens via The Repository.&nbsp; <tt>nsIRepository::CreateInstance()</tt>
will be the primary way of creation of object instances. The steps in instantiation
of an object that implements the IID interface and of class CLSID is as
follows:
<ol>
<li>
The CLSID of the component that would need to create the object instance
is identified.</li>
<ol>Callers use <tt>nsIRepository::ProgIDToCLSID()</tt> to convert the
ProgID string to the CLSID.</ol>
<li>
Load the dll associated with the CLSID after consulting the Registry</li>
<li>
Instantiate the class factory by calling a globally exported dll function
<tt>NSGetFactory()</tt>.
This returns an instance of the class factory that implements the <tt>nsIFactory</tt>
interface.</li>
<li>
The actual object creation is delegated to this <tt>nsIFactory</tt> instance
with a call to <tt>nsIFactory::CreateInstance()</tt>.</li>
</ol>
<h3>
<hr WIDTH="100%"><a NAME="The Service Manager"></a>The Service Manager</h3>
All globally created system services are available via the <tt>nsIServiceManager</tt>,
including the <tt>nsIRepository</tt> and <tt>nsIRegistry</tt>. Although
the <tt>nsIServiceManager</tt> uses the Registry and Repository in the
creation and maintenance of other services, the circular dependency is
broken by not letting the <tt>nsIServiceManager</tt> create the <tt>nsIRepository</tt>
and <tt>nsIRegistry</tt> instance and registering them specially with the
<tt>nsIServiceManager</tt>.
The nsIServiceManager is passed into NSGetFactory() for assisting the DLL
in the Factory creation process.
<h3>
<hr WIDTH="100%"><a NAME="Component Registration"></a>Component Registration</h3>
Either at installation time of the Component or at times when the XPCOM
library autodetect new/changed dlls, component registration is activated.
The autodetection happens at startup time of the navigator or via a javascript
trigger <tt>navigator.repository.autodetect()</tt>. The steps in component
registration would be:
<ol>
<li>
The dll is loaded</li>
<li>
The component is allowed to self register by a call to a globally exported
dll function <tt>NSRegisterSelf()</tt>. The <tt>nsIServiceManager</tt>
and the fullpath of the dll are passed in to assist in the registration
process. The dll is expected to create/modify its entries in the Registry
according to the guidelines of the <a href="#The Registry: XPCOM Hierarchy">XPCOM
hierarchy</a> in the registry. <tt>nsIRepository</tt>, which can be queried
from the <tt>nsIServiceManager</tt>, has useful registration functions
that would easen the process.</li>
<li>
The dll is unloaded</li>
</ol>
<h3>
<hr WIDTH="100%"><a NAME="Autodetection of Components"></a>Autodetection
of Components</h3>
Autodetection of changed dlls happened by storing the dll's last modified
time and its size in the Registry automatically. If either the last modified
time stamp or the filesize differs from that stored in the Registry for
the dll, re-registration takes place. Before re-registration, the existing
instances of the objects created by the classes in the dll are not freed
because the <tt>nsIRepository</tt> has no list of them. The <tt>NSCanUnload()</tt>
will be called with input parameter <i>force</i> set to <tt>true</tt>.
The dll has to prepare for getting unloaded. After this call returns, the
dll <b>will</b> be unloaded if the return value is <tt>true</tt>. If the
dll detects that it cannot properly prepare for unloading, then it can
return <tt>false</tt>. XPCOM will not let the re-registration of the modified
dll proceed in this case. There is nothing much that XPCOM library can
do to salvage this situation other than warning the user of possible instability
and advice a restart upon which the re-registration will happen.
<h3>
<hr WIDTH="100%"><a NAME="ProgID Spec"></a>ProgID Spec</h3>
The general format of ProgIDs is <i><b><font color="#990000">component://</font></b>netscape<b><font color="#990000">/</font></b>compname<b><font color="#990000">?</font></b>var<b><font color="#990000">=</font></b>value<b><font color="#990000">;</font></b>var<b><font color="#990000">=</font></b>value<b><font color="#990000">;</font></b>var<b><font color="#990000">=</font></b>value...</i>
<p>Let us consider some more examples:
<ol>
<li>
A pluggable protocol that implementes the nfs protocol</li>
<li>
A converter that can handle application/x-zip</li>
<li>
A plugin that can handle image/gif</li>
<li>
A widget that can do a toolbar</li>
<li>
A datasource that can handle mail</li>
<li>
A helperapp that deals with application/postscript</li>
</ol>
All the above have what type they are and one or more arguments on what
they particularly do.
<p>The ProgID for these would look like
<ol>
<li>
<tt>component://netscape/network-protocol?type=nfs</tt></li>
<li>
<tt>component://netscape/data-converter?type=application/x-zip</tt></li>
<li>
<tt>component://netscape/plugin?type=image/gif;name=ImageMedia%20Gif%20Image%20Plugin;Description=Renders%20GIF%20Images....</tt></li>
<li>
<tt>component://netscape/widget?type=toolbar</tt></li>
<li>
<tt>component://netscape/rdf/datsource?type=mail</tt></li>
<li>
<tt>component://netscape/helperapp?type=application/postscript</tt></li>
</ol>
{Assume proper escaping of all above URI}
<p>The above semantics would let ProgID be an extensible mechanism that
could be searched on multiple ways. And
<br>query on a progid should match only whatever was passed in. So a query
for
<br>component://netscape/plugin?type=image/gif should pass for the progid
specified above. We could extend this
<br>mechanism with wildcards, but I dont want to go there yet... :-)
<br>&nbsp;
<h3>
<hr WIDTH="100%"><a NAME="Startup Components"></a>Components created on
events</h3>
<b><font color="#990000">NOTE: THIS IS NOT BEING DONE. We are going to
expect the apps to this themselves by using the registry.</font></b>
<p>Some dlls have components that want to be created on certain events
namely Startup, Shutdown (for now). Example is xpinstall.
<blockquote>RegisterComponentForEvent(..., RegisterationTime when, ...)
<br>RegisterFactoryForEvent(..., RegistrationTime when,...)</blockquote>
exists for this purpose. When an application wants to Fire the particular
event, it calls
<blockquote>nsComponentManager::FireEvent(RegistrationTime when)</blockquote>
ComponentManager will look for components that are registered to be created
on these events and do the following for each of the components:
<ol>
<li>
CreateInstance(...,CID, knsIStartupComponentIID, &amp;obj);</li>
<br>For a shutdown event, knsIShutdownComponentIID would be used.
<br>&nbsp;
<li>
obj->Release();</li>
<br>The component needs to take adequate measures to keep itself alive
and figure out how it would delete the object, since a Release() happens
immediately after a CreateInstace()</ol>
<b><i>Warning: </i></b>Order of creation of multiple components registered
on the same event is not defined. Component dependencies aren't thought
of yet.
<br>&nbsp;
<h3>
<hr WIDTH="100%"><a NAME="How will all this help me"></a>How will all this
help me</h3>
For Component Developers:
<ul>
<li>
Component dlls developed could be dropped into a directory, a JS function
called after which your component is in business without even a restart
of the browser. Of course, there needs to be someone accessing it.</li>
<li>
No need to export you CLSID or run around finding where to advertise your
CLSID</li>
</ul>
For Component Users:
<blockquote>
<li>
No more hacking in calls to <tt>nsIRepository::RegisterFactory()</tt></li>
<li>
No need to know the CLSID of components that you want to instantiate. Component
creation can happen like this</li>
<br><tt>nsIRepository::CreateInstance(<b>"<font color="#CC0000">component://netscape/network-protocol&amp;type=nfs</font>"</b>,
NULL, kProtocolIID, &amp;result);</tt>
<br>instead of
<br><strike>nsIRepository::CreateInstance(NFS_PROTOCOL_CID, NULL, domIID,
&amp;result);</strike></blockquote>
<h3>
<hr WIDTH="100%"><a NAME="What has happened so far"></a>What has happened
so far</h3>
<ul>
<li>
Autoregistration implemented to grovel for components from the current
directory</li>
<li>
nsRepository is a global object. Not nsIRepository exists.</li>
<li>
nsRepository::ProgIDToCLSID() implemented</li>
</ul>
<h3>
<hr WIDTH="100%"><a NAME="Changes to XPCOM happening"></a>Changes to XPCOM
happening</h3>
<ul>
<li>
API changes to get ProgID in entire registration process for factories
and components</li>
<li>
ProgID cache to improve performance of ProgID queries</li>
<li>
Notion of Component dlls living in a <b>Components directory </b>and autoregistration
will load/manage only these components. Other components that are linked
in to the app need to call <tt>nsRepository::RegisterFactory()</tt> from
the app. <b>To make this happen we need a list of these.</b></li>
<li>
<b>nsRegistry:</b> Enabling the new nsRegistry developed by Bill Law &lt;law@netscape.com></li>
<li>
Service Manager and Repository: Merge them</li>
<li>
Convenience function to createIntance(progid)</li>
<li>
Base ProgID in the interface ID header file</li>
</ul>
<h3>
<hr WIDTH="100%"><a NAME="What should I do"></a>What should I do</h3>
<ul><b><font color="#CC0000">Component Developers</font></b>
<ul>
<li>
<font color="#000000">Implement <tt>NSRegisterSelf()</tt> for your component
dlls. Sample implementation that perf</font> <a href="http://cvs-mirror.mozilla.org/webtools/lxr/source/modules/libpref/src/nsPref.cpp#608">http://cvs-mirror.mozilla.org/webtools/lxr/source/modules/libpref/src/nsPref.cpp#608</a></li>
<li>
Use <tt>nsRepository::RegisterComponent()</tt> instead of <tt>nsRepository::RegisterFactory()</tt>
if your component lives in a DLL</li>
<li>
<b>Dont use static constructors in loadable components</b></li>
</ul>
<p><br><b><font color="#CC0000">Component Users</font></b>
<ul>
<li>
Create all your components using ProgID rather than CID</li>
<li>
If you were thinking of managing creation of components yourself, think
again. The repository may be already doing that.</li>
</ul>
</ul>
<h3>
<hr WIDTH="100%"><a NAME="Issues"></a>Issues</h3>
<ul>
<li>
Need support for questions like:</li>
<ol>
<li>
Enumerate all CLSIDs that implement a particular interface.</li>
<li>
Let a particular CLSID be the preferable implementation for an interface.</li>
<br>I dont know how this a XPCOM component user could use it unless there
could be a call like:
<br><tt>nsIRepository::CreateInstance(<b>NULL</b>, NULL, nsWidgetIID, &amp;result);</tt>
<li>
Enumerate all interfaces supported by a CLSID</li>
</ol>
<li>
Resolving naming conflicts between ProgID</li>
<li>
Store component specific name-values under <tt>ROOTKEY_COMMON\\<i>component.class.version\\</i></tt></li>
<li>
Add a registry entry under <tt>ROOTKEY_COMMON\\<i>component.class.version\\</i></tt>to
indicate the willingness for a CLSID to behave as a Service.</li>
<li>
Add quick registration support functions in <tt>nsIRepository</tt> for
components to use.</li>
<li>
Is the hierarchy <tt>ROOTKEY_COMMON\\<b>Classes</b>\\CLSID </tt>acceptable.</li>
<li>
Should we have a nsIRepository. JS needs it so that they can reflect it
in javascript. Remove &amp;'s in the API.</li>
</ul>
<hr WIDTH="100%">
<br><i><font size=-1>Last Modified: 28 Jan 1998</font></i>
<br><font size=-1><i>Feedback to: </i><a href="news:netscape.public.mozilla.xpcom">netscape.public.mozilla.xpcom</a></font>
</body>
</html>

View File

@@ -1,161 +0,0 @@
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="Author" content="pnunn">
<meta name="GENERATOR" content="Mozilla/4.5 [en]C-NSCP (WinNT; U) [Netscape]">
<title>xpCom FAQ</title>
</head>
<body>
<b><font size=+3>XPCOM FAQ</font></b>
<p>Get out your decoder rings kids!
<p>Having a basic understanding of COM is only the first
<br>step. To get CMonkey code to build and run,
<br>you&nbsp; need to translate your COM ideas into Netscape
<br>speak.
<p>Feel free to add to this document or change incorrect info.
<br>Hopefully more info and more examples will help new
<br>people reach XPCOM nirvana more quickly.
<p><b>To mentally translate XPCOM to COM.</b>
<br>&nbsp;
<table BORDER COLS=2 WIDTH="100%" >
<tr>
<td BGCOLOR="#CCCCCC"><b>vanilla COM</b></td>
<td BGCOLOR="#FFCCCC"><b>XPCOM</b></td>
</tr>
<tr>
<td BGCOLOR="#CCCCCC">&nbsp;IUnknown</td>
<td BGCOLOR="#FFCCCC">nsISupports</td>
</tr>
<tr>
<td BGCOLOR="#CCCCCC">IClassFactory</td>
<td BGCOLOR="#FFCCCC">nsIFactory</td>
</tr>
<tr>
<td BGCOLOR="#CCCCCC">virtual void _stdcall</td>
<td BGCOLOR="#FFCCCC">NS_IMETHOD</td>
</tr>
<tr>
<td BGCOLOR="#CCCCCC">interface ID = IID</td>
<td BGCOLOR="#FFCCCC">nsID = nsIID = IID</td>
</tr>
<tr>
<td BGCOLOR="#CCCCCC">class ID = CLSID&nbsp;</td>
<td BGCOLOR="#FFCCCC">nsCID = CID</td>
</tr>
</table>
<p>Not too difficult.
<br>But wait. There's more.
<br><b>-------------------------------------------</b>
<p><b><font size=+1>Why don't those classes have AddRef?</font></b>
<p>Actually, those classes do have AddRef. It is hidden
<br>in a macro. There are alot of&nbsp; macros that are alot of&nbsp; help
<br>once you know :
<br>&nbsp;&nbsp;&nbsp; 1) They exist.
<p>&nbsp;&nbsp;&nbsp; 2) Where they are defined. (They aren't always mnemonic
or onomatipeic.
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
You might want to print them out.)
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mozilla/xpcom/public/nsCom.h
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mozilla/xpcom/public/nsISupports.h
<p>&nbsp;&nbsp;&nbsp; 3)What they are
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
Here's a short list to give you an idea of what you've been missing.
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
The include files listed above are the real reference.
<p>&nbsp;&nbsp;&nbsp; 4) A quick way to expand pesky macros:
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
For macros in&nbsp; foo.cpp,&nbsp; 'make foo.i'
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; This
will pump the foo.cpp file through C preprocessing
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
and expand all the macros for you.&nbsp; The output can be
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
hard to read, but if you search for&nbsp; unique strings
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
in the area you aredebugging, you can navigate
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
the file pretty easily.
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
(thanks to hshaw@netscape.com)
<br>&nbsp;
<br>&nbsp;
<br>&nbsp;
<table BORDER COLS=2 WIDTH="100%" BGCOLOR="#CCCCCC" >
<tr>
<td BGCOLOR="#FFCCCC"><b><font size=+1>Netscape MACRO</font></b></td>
<td><b><font size=+1>Expansion of macro</font></b></td>
</tr>
<tr>
<td BGCOLOR="#FFCCCC">NSADDREF(factoryinstname)</td>
<td>Factory->AddRef();</td>
</tr>
<tr>
<td BGCOLOR="#FFCCCC">NS_IMETHOD</td>
<td>virtual nsresult __stdcall</td>
</tr>
<tr>
<td BGCOLOR="#FFCCCC">NS_INIT_REFCNT()</td>
<td>mRefCnt = 0</td>
</tr>
<tr>
<td BGCOLOR="#FFCCCC">NS_INIT_ISUPPORTS()</td>
<td>NS_INIT_REFCNT()</td>
</tr>
<tr>
<td BGCOLOR="#FFCCCC">NS_DECL_ISUPPORTS</td>
<td>public:
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NS_IMETHOD QueryInterface(REFNSIID
aIID,
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
void** aInstancePtr);
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NS_IMETHOD_(nsrefcnt)
AddRef(void);
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NS_IMETHOD_(nsrefcnt)
Release(void);
<br>&nbsp;&nbsp;&nbsp; protected:
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; nsrefcnt mRefCnt;</td>
</tr>
</table>
<p>&nbsp;<font size=+1>Useful Links to COM Documents:</font>
<p><a href="http://www.mozilla.org/projects/xpcom/">XPCOM&nbsp; Page</a>
<br><a href="http://www.mozilla.org/projects/xpcom/nsCOMPtr.html">nsCOMPtr</a>
<br><a href="http://warp.netscape.com/client/raptor/codingconventions.html">Coding
Conventions</a>
<br><a href="http://warp/client/bam/eng/howto.html">Getting BAMmed</a>
<br><a href="http://warp/client/bam/eng/comdoc.html">How to COM</a>
<br><a href="http://www.mozilla.org/docs/tplist/catFlow/modunote.htm">Modularization
Techniques</a>
<br><a href="http://www.mozilla.org/docs/tplist/catBuild/portable-cpp.html">C++
Portability Guide</a>
<br><a href="http://www.mozilla.org/newlayout/">NGLayout</a>
<br>&nbsp;
<br>&nbsp;
<br>&nbsp;
</body>
</html>

View File

@@ -1,28 +0,0 @@
nsBTree.h
nsCRT.h
nsDeque.h
nsEnumeratorUtils.h
nsHashtable.h
nsIArena.h
nsIAtom.h
nsIBuffer.h
nsIByteBuffer.h
nsIObserverList.h
nsIPageManager.h
nsIProperties.h
nsISimpleEnumerator.h
nsISizeOfHandler.h
nsIUnicharBuffer.h
nsIVariant.h
nsInt64.h
nsQuickSort.h
nsRBTree.h
nsStr.h
nsString.h
nsString2.h
nsTime.h
nsUnitConversion.h
nsVector.h
nsVoidArray.h
nsXPIDLString.h
plvector.h

View File

@@ -1,5 +0,0 @@
nsICollection.idl
nsIEnumerator.idl
nsIObserver.idl
nsIObserverService.idl
nsISupportsArray.idl

View File

@@ -1,117 +0,0 @@
#!gmake
#
# The contents of this file are subject to the Netscape Public License
# Version 1.0 (the "NPL"); you may not use this file except in
# compliance with the NPL. You may obtain a copy of the NPL at
# http://www.mozilla.org/NPL/
#
# Software distributed under the NPL is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
# for the specific language governing rights and limitations under the
# NPL.
#
# The Initial Developer of this code under the NPL is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
# Reserved.
DEPTH=../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
include $(topsrcdir)/config/config.mk
LIBRARY_NAME = xpcomds_s
MODULE = xpcom
XPIDL_MODULE = xpcom_ds
XPIDLSRCS = \
nsICollection.idl \
nsIEnumerator.idl \
nsIObserver.idl \
nsIObserverService.idl \
nsISupportsArray.idl \
$(NULL)
CPPSRCS = \
nsArena.cpp \
nsAtomTable.cpp \
nsBTree.cpp \
nsBuffer.cpp \
nsByteBuffer.cpp \
nsCRT.cpp \
nsConjoiningEnumerator.cpp \
nsDeque.cpp \
nsEmptyEnumerator.cpp \
nsEnumeratorUtils.cpp \
nsHashtable.cpp \
nsObserver.cpp \
nsObserverList.cpp \
nsObserverService.cpp \
nsPageMgr.cpp \
nsProperties.cpp \
nsQuickSort.cpp \
nsRBTree.cpp \
nsSizeOfHandler.cpp \
nsStr.cpp \
nsString.cpp \
nsString2.cpp \
nsSupportsArray.cpp \
nsSupportsArrayEnumerator.cpp \
nsUnicharBuffer.cpp \
nsVariant.cpp \
nsVoidArray.cpp \
nsXPIDLString.cpp \
plvector.cpp \
$(NULL)
EXPORTS = \
nsBTree.h \
nsCRT.h \
nsDeque.h \
nsEnumeratorUtils.h \
nsHashtable.h \
nsIArena.h \
nsIAtom.h \
nsIBuffer.h \
nsIByteBuffer.h \
nsIObserverList.h \
nsIPageManager.h \
nsIProperties.h \
nsISimpleEnumerator.h \
nsISizeOfHandler.h \
nsIUnicharBuffer.h \
nsIVariant.h \
nsInt64.h \
nsQuickSort.h \
nsRBTree.h \
nsStr.h \
nsString.h \
nsString2.h \
nsTime.h \
nsUnitConversion.h \
nsVector.h \
nsVoidArray.h \
nsXPIDLString.h \
plvector.h \
$(NULL)
EXPORTS := $(addprefix $(srcdir)/, $(EXPORTS))
DEFINES = -D_IMPL_NS_COM -D_IMPL_NS_BASE
REQUIRES = xpcom uconv unicharutil
MKSHLIB :=
# we don't want the shared lib, but we want to force the creation of a static lib.
override NO_SHARED_LIB=1
override NO_STATIC_LIB=
include $(topsrcdir)/config/rules.mk

View File

@@ -1,896 +0,0 @@
/* -*- 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.
*/
/******************************************************************************************
MODULE NOTES:
This file contains the workhorse copy and shift functions used in nsStrStruct.
Ultimately, I plan to make the function pointers in this system available for
use by external modules. They'll be able to install their own "handlers".
Not so, today though.
*******************************************************************************************/
#ifndef _BUFFERROUTINES_H
#define _BUFFERROUTINES_H
#include "nsCRT.h"
#ifndef RICKG_TESTBED
#include "nsUnicharUtilCIID.h"
#include "nsIServiceManager.h"
#include "nsICaseConversion.h"
#endif
#define KSHIFTLEFT (0)
#define KSHIFTRIGHT (1)
inline PRUnichar GetUnicharAt(const char* aString,PRUint32 anIndex) {
return ((PRUnichar*)aString)[anIndex];
}
inline PRUnichar GetCharAt(const char* aString,PRUint32 anIndex) {
return (PRUnichar)aString[anIndex];
}
//----------------------------------------------------------------------------------------
//
// This set of methods is used to shift the contents of a char buffer.
// The functions are differentiated by shift direction and the underlying charsize.
//
/**
* This method shifts single byte characters left by a given amount from an given offset.
* @update gess 01/04/99
* @param aDest is a ptr to a cstring where left-shift is to be performed
* @param aLength is the known length of aDest
* @param anOffset is the index into aDest where shifting shall begin
* @param aCount is the number of chars to be "cut"
*/
void ShiftCharsLeft(char* aDest,PRUint32 aLength,PRUint32 anOffset,PRUint32 aCount) {
PRUint32 theMax=aLength-anOffset;
PRUint32 theLength=(theMax<aCount) ? theMax : aCount;
char* first= aDest+anOffset+aCount;
char* last = aDest+aLength;
char* to = aDest+anOffset;
//now loop over characters, shifting them left...
while(first<=last) {
*to=*first;
to++;
first++;
}
}
/**
* This method shifts single byte characters right by a given amount from an given offset.
* @update gess 01/04/99
* @param aDest is a ptr to a cstring where the shift is to be performed
* @param aLength is the known length of aDest
* @param anOffset is the index into aDest where shifting shall begin
* @param aCount is the number of chars to be "inserted"
*/
void ShiftCharsRight(char* aDest,PRUint32 aLength,PRUint32 anOffset,PRUint32 aCount) {
char* last = aDest+aLength;
char* first= aDest+anOffset-1;
char* to = aDest+aLength+aCount;
//Copy rightmost chars, up to offset+theDelta...
while(first<=last) {
*to=*last;
to--;
last--;
}
}
/**
* This method shifts unicode characters by a given amount from an given offset.
* @update gess 01/04/99
* @param aDest is a ptr to a cstring where the shift is to be performed
* @param aLength is the known length of aDest
* @param anOffset is the index into aDest where shifting shall begin
* @param aCount is the number of chars to be "cut"
*/
void ShiftDoubleCharsLeft(char* aDest,PRUint32 aLength,PRUint32 anOffset,PRUint32 aCount) {
PRUint32 theMax=aLength-anOffset;
PRUint32 theLength=(theMax<aCount) ? theMax : aCount;
PRUnichar* theBuf=(PRUnichar*)aDest;
PRUnichar* first= theBuf+anOffset+aCount;
PRUnichar* last = theBuf+aLength;
PRUnichar* to = theBuf+anOffset;
//now loop over characters, shifting them left...
while(first<=last) {
*to=*first;
to++;
first++;
}
}
/**
* This method shifts unicode characters by a given amount from an given offset.
* @update gess 01/04/99
* @param aDest is a ptr to a cstring where the shift is to be performed
* @param aLength is the known length of aDest
* @param anOffset is the index into aDest where shifting shall begin
* @param aCount is the number of chars to be "inserted"
*/
void ShiftDoubleCharsRight(char* aDest,PRUint32 aLength,PRUint32 anOffset,PRUint32 aCount) {
PRUnichar* theBuf=(PRUnichar*)aDest;
PRUnichar* last = theBuf+aLength;
PRUnichar* first= theBuf+anOffset-1;
PRUnichar* to = theBuf+aLength+aCount;
//Copy rightmost chars, up to offset+theDelta...
while(first<=last) {
*to=*last;
to--;
last--;
}
}
typedef void (*ShiftChars)(char* aDest,PRUint32 aLength,PRUint32 anOffset,PRUint32 aCount);
ShiftChars gShiftChars[2][2]= {
{&ShiftCharsLeft,&ShiftCharsRight},
{&ShiftDoubleCharsLeft,&ShiftDoubleCharsRight}
};
//----------------------------------------------------------------------------------------
//
// This set of methods is used to copy one buffer onto another.
// The functions are differentiated by the size of source and dest character sizes.
// WARNING: Your destination buffer MUST be big enough to hold all the source bytes.
// We don't validate these ranges here (this should be done in higher level routines).
//
/**
* Going 1 to 1 is easy, since we assume ascii. No conversions are necessary.
* @update gess 01/04/99
* @param aDest is the destination buffer
* @param aDestOffset is the pos to start copy to in the dest buffer
* @param aSource is the source buffer
* @param anOffset is the offset to start copying from in the source buffer
* @param aCount is the (max) number of chars to copy
*/
void CopyChars1To1(char* aDest,PRInt32 anDestOffset,const char* aSource,PRUint32 anOffset,PRUint32 aCount) {
char* to = aDest+anDestOffset;
const char* first= aSource+anOffset;
const char* last = first+aCount;
//now loop over characters, shifting them left...
while(first<last) {
*to=*first;
to++;
first++;
}
}
/**
* Going 1 to 2 requires a conversion from ascii to unicode. This can be expensive.
* @param aDest is the destination buffer
* @param aDestOffset is the pos to start copy to in the dest buffer
* @param aSource is the source buffer
* @param anOffset is the offset to start copying from in the source buffer
* @param aCount is the (max) number of chars to copy
*/
void CopyChars1To2(char* aDest,PRInt32 anDestOffset,const char* aSource,PRUint32 anOffset,PRUint32 aCount) {
PRUnichar* theDest=(PRUnichar*)aDest;
PRUnichar* to = theDest+anDestOffset;
const unsigned char* first= (const unsigned char*)aSource+anOffset;
const unsigned char* last = first+aCount;
//now loop over characters, shifting them left...
while(first<last) {
*to=(PRUnichar)(*first);
to++;
first++;
}
}
/**
* Going 2 to 1 requires a conversion from unicode down to ascii. This can be lossy.
* @update gess 01/04/99
* @param aDest is the destination buffer
* @param aDestOffset is the pos to start copy to in the dest buffer
* @param aSource is the source buffer
* @param anOffset is the offset to start copying from in the source buffer
* @param aCount is the (max) number of chars to copy
*/
void CopyChars2To1(char* aDest,PRInt32 anDestOffset,const char* aSource,PRUint32 anOffset,PRUint32 aCount) {
char* to = aDest+anDestOffset;
PRUnichar* theSource=(PRUnichar*)aSource;
const PRUnichar* first= theSource+anOffset;
const PRUnichar* last = first+aCount;
//now loop over characters, shifting them left...
while(first<last) {
if(*first<256)
*to=(char)*first;
else *to='.';
to++;
first++;
}
}
/**
* Going 2 to 2 is fast and efficient.
* @update gess 01/04/99
* @param aDest is the destination buffer
* @param aDestOffset is the pos to start copy to in the dest buffer
* @param aSource is the source buffer
* @param anOffset is the offset to start copying from in the source buffer
* @param aCount is the (max) number of chars to copy
*/
void CopyChars2To2(char* aDest,PRInt32 anDestOffset,const char* aSource,PRUint32 anOffset,PRUint32 aCount) {
PRUnichar* theDest=(PRUnichar*)aDest;
PRUnichar* to = theDest+anDestOffset;
PRUnichar* theSource=(PRUnichar*)aSource;
PRUnichar* from= theSource+anOffset;
memcpy((void*)to,(void*)from,aCount*2);
}
//--------------------------------------------------------------------------------------
typedef void (*CopyChars)(char* aDest,PRInt32 anDestOffset,const char* aSource,PRUint32 anOffset,PRUint32 aCount);
CopyChars gCopyChars[2][2]={
{&CopyChars1To1,&CopyChars1To2},
{&CopyChars2To1,&CopyChars2To2}
};
//----------------------------------------------------------------------------------------
//
// This set of methods is used to search a buffer looking for a char.
//
/**
* This methods cans the given buffer for the given char
*
* @update gess 3/25/98
* @param aDest is the buffer to be searched
* @param aLength is the size (in char-units, not bytes) of the buffer
* @param anOffset is the start pos to begin searching
* @param aChar is the target character we're looking for
* @param aIgnorecase tells us whether to use a case sensitive search
* @return index of pos if found, else -1 (kNotFound)
*/
inline PRInt32 FindChar1(const char* aDest,PRUint32 aLength,PRUint32 anOffset,const PRUnichar aChar,PRBool aIgnoreCase) {
PRUnichar theCmpChar=(aIgnoreCase ? nsCRT::ToUpper(aChar) : aChar);
PRInt32 theIndex=0;
PRInt32 theLength=(PRInt32)aLength;
for(theIndex=(PRInt32)anOffset;theIndex<theLength;theIndex++){
PRUnichar theChar=GetCharAt(aDest,theIndex);
if(aIgnoreCase)
theChar=nsCRT::ToUpper(theChar);
if(theChar==theCmpChar)
return theIndex;
}
return kNotFound;
}
/**
* This methods cans the given buffer for the given char
*
* @update gess 3/25/98
* @param aDest is the buffer to be searched
* @param aLength is the size (in char-units, not bytes) of the buffer
* @param anOffset is the start pos to begin searching
* @param aChar is the target character we're looking for
* @param aIgnorecase tells us whether to use a case sensitive search
* @return index of pos if found, else -1 (kNotFound)
*/
inline PRInt32 FindChar2(const char* aDest,PRUint32 aLength,PRUint32 anOffset,const PRUnichar aChar,PRBool aIgnoreCase) {
PRUnichar theCmpChar=(aIgnoreCase ? nsCRT::ToUpper(aChar) : aChar);
PRInt32 theIndex=0;
PRInt32 theLength=(PRInt32)aLength;
for(theIndex=(PRInt32)anOffset;theIndex<theLength;theIndex++){
PRUnichar theChar=GetUnicharAt(aDest,theIndex);
if(aIgnoreCase)
theChar=nsCRT::ToUpper(theChar);
if(theChar==theCmpChar)
return theIndex;
}
return kNotFound;
}
/**
* This methods cans the given buffer (in reverse) for the given char
*
* @update gess 3/25/98
* @param aDest is the buffer to be searched
* @param aLength is the size (in char-units, not bytes) of the buffer
* @param anOffset is the start pos to begin searching
* @param aChar is the target character we're looking for
* @param aIgnorecase tells us whether to use a case sensitive search
* @return index of pos if found, else -1 (kNotFound)
*/
inline PRInt32 RFindChar1(const char* aDest,PRUint32 aLength,PRUint32 anOffset,const PRUnichar aChar,PRBool aIgnoreCase) {
PRUnichar theCmpChar=(aIgnoreCase ? nsCRT::ToUpper(aChar) : aChar);
PRInt32 theIndex=0;
PRInt32 thePos=(PRInt32)aLength-anOffset-1;
for(theIndex=thePos;theIndex>=0;theIndex--){
PRUnichar theChar=GetCharAt(aDest,theIndex);
if(aIgnoreCase)
theChar=nsCRT::ToUpper(theChar);
if(theChar==theCmpChar)
return theIndex;
}
return kNotFound;
}
/**
* This methods cans the given buffer for the given char
*
* @update gess 3/25/98
* @param aDest is the buffer to be searched
* @param aLength is the size (in char-units, not bytes) of the buffer
* @param anOffset is the start pos to begin searching
* @param aChar is the target character we're looking for
* @param aIgnorecase tells us whether to use a case sensitive search
* @return index of pos if found, else -1 (kNotFound)
*/
inline PRInt32 RFindChar2(const char* aDest,PRUint32 aLength,PRUint32 anOffset,const PRUnichar aChar,PRBool aIgnoreCase) {
PRUnichar theCmpChar=(aIgnoreCase ? nsCRT::ToUpper(aChar) : aChar);
PRInt32 theIndex=0;
PRInt32 thePos=(PRInt32)aLength-anOffset-1;
for(theIndex=thePos;theIndex>=0;theIndex--){
PRUnichar theChar=GetUnicharAt(aDest,theIndex);
if(aIgnoreCase)
theChar=nsCRT::ToUpper(theChar);
if(theChar==theCmpChar)
return theIndex;
}
return kNotFound;
}
typedef PRInt32 (*FindChars)(const char* aDest,PRUint32 aLength,PRUint32 anOffset,const PRUnichar aChar,PRBool aIgnoreCase);
FindChars gFindChars[]={&FindChar1,&FindChar2};
FindChars gRFindChars[]={&RFindChar1,&RFindChar2};
//----------------------------------------------------------------------------------------
//
// This set of methods is used to compare one buffer onto another.
// The functions are differentiated by the size of source and dest character sizes.
// WARNING: Your destination buffer MUST be big enough to hold all the source bytes.
// We don't validate these ranges here (this should be done in higher level routines).
//
/**
* This method compares the data in one buffer with another
* @update gess 01/04/99
* @param aStr1 is the first buffer to be compared
* @param aStr2 is the 2nd buffer to be compared
* @param aCount is the number of chars to compare
* @param aIgnorecase tells us whether to use a case-sensitive comparison
* @return -1,0,1 depending on <,==,>
*/
PRInt32 Compare1To1(const char* aStr1,const char* aStr2,PRUint32 aCount,PRBool aIgnoreCase){
PRInt32 result=0;
if(aIgnoreCase)
result=nsCRT::strncasecmp(aStr1,aStr2,aCount);
else result=strncmp(aStr1,aStr2,aCount);
return result;
}
/**
* This method compares the data in one buffer with another
* @update gess 01/04/99
* @param aStr1 is the first buffer to be compared
* @param aStr2 is the 2nd buffer to be compared
* @param aCount is the number of chars to compare
* @param aIgnorecase tells us whether to use a case-sensitive comparison
* @return -1,0,1 depending on <,==,>
*/
PRInt32 Compare2To2(const char* aStr1,const char* aStr2,PRUint32 aCount,PRBool aIgnoreCase){
PRInt32 result=0;
if(aIgnoreCase)
result=nsCRT::strncasecmp((PRUnichar*)aStr1,(PRUnichar*)aStr2,aCount);
else result=nsCRT::strncmp((PRUnichar*)aStr1,(PRUnichar*)aStr2,aCount);
return result;
}
/**
* This method compares the data in one buffer with another
* @update gess 01/04/99
* @param aStr1 is the first buffer to be compared
* @param aStr2 is the 2nd buffer to be compared
* @param aCount is the number of chars to compare
* @param aIgnorecase tells us whether to use a case-sensitive comparison
* @return -1,0,1 depending on <,==,>
*/
PRInt32 Compare2To1(const char* aStr1,const char* aStr2,PRUint32 aCount,PRBool aIgnoreCase){
PRInt32 result;
if(aIgnoreCase)
result=nsCRT::strncasecmp((PRUnichar*)aStr1,aStr2,aCount);
else result=nsCRT::strncmp((PRUnichar*)aStr1,aStr2,aCount);
return result;
}
/**
* This method compares the data in one buffer with another
* @update gess 01/04/99
* @param aStr1 is the first buffer to be compared
* @param aStr2 is the 2nd buffer to be compared
* @param aCount is the number of chars to compare
* @param aIgnorecase tells us whether to use a case-sensitive comparison
* @return -1,0,1 depending on <,==,>
*/
PRInt32 Compare1To2(const char* aStr1,const char* aStr2,PRUint32 aCount,PRBool aIgnoreCase){
PRInt32 result;
if(aIgnoreCase)
result=nsCRT::strncasecmp((PRUnichar*)aStr2,aStr1,aCount)*-1;
else result=nsCRT::strncmp((PRUnichar*)aStr2,aStr1,aCount)*-1;
return result;
}
typedef PRInt32 (*CompareChars)(const char* aStr1,const char* aStr2,PRUint32 aCount,PRBool aIgnoreCase);
CompareChars gCompare[2][2]={
{&Compare1To1,&Compare1To2},
{&Compare2To1,&Compare2To2},
};
//----------------------------------------------------------------------------------------
//
// This set of methods is used to convert the case of strings...
//
/**
* This method performs a case conversion the data in the given buffer
*
* @update gess 01/04/99
* @param aString is the buffer to be case shifted
* @param aCount is the number of chars to compare
* @param aToUpper tells us whether to convert to upper or lower
* @return 0
*/
PRInt32 ConvertCase1(char* aString,PRUint32 aCount,PRBool aToUpper){
PRInt32 result=0;
typedef char chartype;
chartype* cp = (chartype*)aString;
chartype* end = cp + aCount-1;
while (cp <= end) {
chartype ch = *cp;
if(aToUpper) {
if ((ch >= 'a') && (ch <= 'z')) {
*cp = 'A' + (ch - 'a');
}
}
else {
if ((ch >= 'A') && (ch <= 'Z')) {
*cp = 'a' + (ch - 'A');
}
}
cp++;
}
return result;
}
//----------------------------------------------------------------------------------------
#ifndef RICKG_TESTBED
class HandleCaseConversionShutdown3 : public nsIShutdownListener {
public :
NS_IMETHOD OnShutdown(const nsCID& cid, nsISupports* service);
HandleCaseConversionShutdown3(void) { NS_INIT_REFCNT(); }
virtual ~HandleCaseConversionShutdown3(void) {}
NS_DECL_ISUPPORTS
};
static NS_DEFINE_CID(kUnicharUtilCID, NS_UNICHARUTIL_CID);
static NS_DEFINE_IID(kICaseConversionIID, NS_ICASECONVERSION_IID);
static NS_DEFINE_IID(kIShutdownListenerIID, NS_ISHUTDOWNLISTENER_IID);
static nsICaseConversion * gCaseConv = 0;
NS_IMPL_ISUPPORTS(HandleCaseConversionShutdown3, kIShutdownListenerIID);
nsresult HandleCaseConversionShutdown3::OnShutdown(const nsCID& cid, nsISupports* service) {
if (cid.Equals(kUnicharUtilCID)) {
NS_ASSERTION(service == gCaseConv, "wrong service!");
if(gCaseConv){
gCaseConv->Release();
gCaseConv = 0;
}
}
return NS_OK;
}
class CCaseConversionServiceInitializer {
public:
CCaseConversionServiceInitializer(){
mListener = new HandleCaseConversionShutdown3();
if(mListener){
mListener->AddRef();
nsresult result=nsServiceManager::GetService(kUnicharUtilCID, kICaseConversionIID,(nsISupports**) &gCaseConv, mListener);
}
}
protected:
HandleCaseConversionShutdown3* mListener;
};
#endif
//----------------------------------------------------------------------------------------
/**
* This method performs a case conversion the data in the given buffer
*
* @update gess 01/04/99
* @param aString is the buffer to be case shifted
* @param aCount is the number of chars to compare
* @param aToUpper tells us whether to convert to upper or lower
* @return 0
*/
PRInt32 ConvertCase2(char* aString,PRUint32 aCount,PRBool aToUpper){
PRUnichar* cp = (PRUnichar*)aString;
PRUnichar* end = cp + aCount-1;
PRInt32 result=0;
#ifndef RICKG_TESTBED
static CCaseConversionServiceInitializer gCaseConversionServiceInitializer;
// I18N code begin
if(gCaseConv) {
nsresult err=(aToUpper) ? gCaseConv->ToUpper(cp, cp, aCount) : gCaseConv->ToLower(cp, cp, aCount);
if(NS_SUCCEEDED(err))
return 0;
}
// I18N code end
#endif
while (cp <= end) {
PRUnichar ch = *cp;
if(aToUpper) {
if ((ch >= 'a') && (ch <= 'z')) {
*cp = 'A' + (ch - 'a');
}
}
else {
if ((ch >= 'A') && (ch <= 'Z')) {
*cp = 'a' + (ch - 'A');
}
}
cp++;
}
return result;
}
typedef PRInt32 (*CaseConverters)(char*,PRUint32,PRBool);
CaseConverters gCaseConverters[]={&ConvertCase1,&ConvertCase2};
//----------------------------------------------------------------------------------------
//
// This set of methods is used strip chars from a given buffer...
//
/**
* This method removes chars (given in aSet) from the given buffer
*
* @update gess 01/04/99
* @param aString is the buffer to be manipulated
* @param anOffset is starting pos in buffer for manipulation
* @param aCount is the number of chars to compare
* @param aSet tells us which chars to remove from given buffer
* @return the new length of the given buffer
*/
PRInt32 StripChars1(char* aString,PRUint32 anOffset,PRUint32 aCount,const char* aSet){
PRInt32 result=0;
typedef char chartype;
chartype* from = (chartype*)&aString[anOffset];
chartype* end = (chartype*)from + aCount-1;
chartype* to = from;
if(aSet){
PRUint32 aSetLen=strlen(aSet);
while (from <= end) {
chartype ch = *from;
if(kNotFound==FindChar1(aSet,aSetLen,0,ch,PR_FALSE)){
*to++=*from;
}
from++;
}
*to = 0;
}
return to - (chartype*)aString;
}
/**
* This method removes chars (given in aSet) from the given buffer
*
* @update gess 01/04/99
* @param aString is the buffer to be manipulated
* @param anOffset is starting pos in buffer for manipulation
* @param aCount is the number of chars to compare
* @param aSet tells us which chars to remove from given buffer
* @return the new length of the given buffer
*/
PRInt32 StripChars2(char* aString,PRUint32 anOffset,PRUint32 aCount,const char* aSet){
PRInt32 result=0;
typedef PRUnichar chartype;
chartype* from = (chartype*)&aString[anOffset];
chartype* end = (chartype*)from + aCount-1;
chartype* to = from;
if(aSet){
PRUint32 aSetLen=strlen(aSet);
while (from <= end) {
chartype ch = *from;
if(kNotFound==FindChar1(aSet,aSetLen,0,ch,PR_FALSE)){
*to++=*from;
}
from++;
}
*to = 0;
}
return to - (chartype*)aString;
}
typedef PRInt32 (*StripChars)(char* aString,PRUint32 aDestOffset,PRUint32 aCount,const char* aSet);
StripChars gStripChars[]={&StripChars1,&StripChars2};
//----------------------------------------------------------------------------------------
//
// This set of methods is used trim chars from the edges of a buffer...
//
/**
* This method trims chars (given in aSet) from the edges of given buffer
*
* @update gess 01/04/99
* @param aString is the buffer to be manipulated
* @param aLength is the length of the buffer
* @param aSet tells us which chars to remove from given buffer
* @param aEliminateLeading tells us whether to strip chars from the start of the buffer
* @param aEliminateTrailing tells us whether to strip chars from the start of the buffer
* @return the new length of the given buffer
*/
PRInt32 TrimChars1(char* aString,PRUint32 aLength,const char* aSet,PRBool aEliminateLeading,PRBool aEliminateTrailing){
PRInt32 result=0;
typedef char chartype;
chartype* from = (chartype*)aString;
chartype* end = from + aLength -1;
chartype* to = from;
if(aSet) {
PRUint32 aSetLen=strlen(aSet);
//begin by find the first char not in aTrimSet
if(aEliminateLeading) {
while (from <= end) {
chartype ch = *from;
if(kNotFound==FindChar1(aSet,aSetLen,0,ch,PR_FALSE)){
break;
}
from++;
}
}
//Now, find last char not in aTrimSet
if(aEliminateTrailing) {
while(from<=end) {
chartype ch = *end;
if(kNotFound==FindChar1(aSet,aSetLen,0,ch,PR_FALSE)){
break;
}
end--;
}
}
//now rewrite your string without unwanted
//leading or trailing characters.
if (from != to) {
while (from <= end) {
*to++ = *from++;
}
}
else {
to = ++end;
}
*to = 0;
}
return to - (chartype*)aString;
}
/**
* This method trims chars (given in aSet) from the edges of given buffer
*
* @update gess 01/04/99
* @param aString is the buffer to be manipulated
* @param aLength is the length of the buffer
* @param aSet tells us which chars to remove from given buffer
* @param aEliminateLeading tells us whether to strip chars from the start of the buffer
* @param aEliminateTrailing tells us whether to strip chars from the start of the buffer
* @return the new length of the given buffer
*/
PRInt32 TrimChars2(char* aString,PRUint32 aLength,const char* aSet,PRBool aEliminateLeading,PRBool aEliminateTrailing){
PRInt32 result=0;
typedef PRUnichar chartype;
chartype* from = (chartype*)aString;
chartype* end = from + aLength -1;
chartype* to = from;
if(aSet) {
PRUint32 aSetLen=strlen(aSet);
//begin by find the first char not in aTrimSet
if(aEliminateLeading) {
while (from <= end) {
chartype ch = *from;
if(kNotFound==FindChar1(aSet,aSetLen,0,ch,PR_FALSE)){
break;
}
from++;
}
}
//Now, find last char not in aTrimSet
if(aEliminateTrailing) {
while(from<=end) {
chartype ch = *end;
if(kNotFound==FindChar1(aSet,aSetLen,0,ch,PR_FALSE)){
break;
}
end--;
}
}
//now rewrite your string without unwanted
//leading or trailing characters.
if (from != to) {
while (from <= end) {
*to++ = *from++;
}
}
else {
to = ++end;
}
*to = 0;
}
return to - (chartype*)aString;
}
typedef PRInt32 (*TrimChars)(char* aString,PRUint32 aCount,const char* aSet,PRBool aEliminateLeading,PRBool aEliminateTrailing);
TrimChars gTrimChars[]={&TrimChars1,&TrimChars2};
//----------------------------------------------------------------------------------------
//
// This set of methods is used compress char sequences in a buffer...
//
/**
* This method compresses duplicate runs of a given char from the given buffer
*
* @update gess 01/04/99
* @param aString is the buffer to be manipulated
* @param aLength is the length of the buffer
* @param aSet tells us which chars to compress from given buffer
* @param aEliminateLeading tells us whether to strip chars from the start of the buffer
* @param aEliminateTrailing tells us whether to strip chars from the start of the buffer
* @return the new length of the given buffer
*/
PRInt32 CompressChars1(char* aString,PRUint32 aLength,const char* aSet,PRUint32 aChar,PRBool aEliminateLeading,PRBool aEliminateTrailing){
PRInt32 result=0;
TrimChars1(aString,aLength,aSet,aEliminateLeading,aEliminateTrailing);
typedef char chartype;
chartype* from = aString;
chartype* end = aString + aLength-1;
chartype* to = from;
//this code converts /n, /t, /r into normal space ' ';
//it also compresses runs of whitespace down to a single char...
if(aSet){
PRUint32 aSetLen=strlen(aSet);
while (from <= end) {
chartype ch = *from++;
if(kNotFound!=FindChar1(aSet,aSetLen,0,ch,PR_FALSE)){
*to++ = (char)aChar;
while (from <= end) {
ch = *from++;
if(kNotFound==FindChar1(aSet,aSetLen,0,ch,PR_FALSE)){
*to++ = ch;
break;
}
}
} else {
*to++ = ch;
}
}
*to = 0;
}
return to - (chartype*)aString;
}
/**
* This method compresses duplicate runs of a given char from the given buffer
*
* @update gess 01/04/99
* @param aString is the buffer to be manipulated
* @param aLength is the length of the buffer
* @param aSet tells us which chars to compress from given buffer
* @param aEliminateLeading tells us whether to strip chars from the start of the buffer
* @param aEliminateTrailing tells us whether to strip chars from the start of the buffer
* @return the new length of the given buffer
*/
PRInt32 CompressChars2(char* aString,PRUint32 aLength,const char* aSet,PRUint32 aChar,PRBool aEliminateLeading,PRBool aEliminateTrailing){
PRInt32 result=0;
TrimChars2(aString,aLength,aSet,aEliminateLeading,aEliminateTrailing);
typedef PRUnichar chartype;
chartype* from = (chartype*)aString;
chartype* end = from + aLength-1;
chartype* to = from;
//this code converts /n, /t, /r into normal space ' ';
//it also compresses runs of whitespace down to a single char...
if(aSet){
PRUint32 aSetLen=strlen(aSet);
while (from <= end) {
chartype ch = *from++;
if(kNotFound!=FindChar1(aSet,aSetLen,0,ch,PR_FALSE)){
*to++ = (PRUnichar)aChar;
while (from <= end) {
ch = *from++;
if(kNotFound==FindChar1(aSet,aSetLen,0,ch,PR_FALSE)){
*to++ = ch;
break;
}
}
} else {
*to++ = ch;
}
}
*to = 0;
}
return to - (chartype*)aString;
}
typedef PRInt32 (*CompressChars)(char* aString,PRUint32 aCount,const char* aSet,PRUint32 aChar,PRBool aEliminateLeading,PRBool aEliminateTrailing);
CompressChars gCompressChars[]={&CompressChars1,&CompressChars2};
#endif

View File

@@ -1,118 +0,0 @@
#!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=..\..
MODULE = xpcom
################################################################################
## exports
EXPORTS = \
nsBTree.h \
nsCRT.h \
nsDeque.h \
nsEnumeratorUtils.h \
nsHashtable.h \
nsIArena.h \
nsIAtom.h \
nsIBuffer.h \
nsIByteBuffer.h \
nsIObserverList.h \
nsIPageManager.h \
nsIProperties.h \
nsISimpleEnumerator.h \
nsISizeOfHandler.h \
nsIUnicharBuffer.h \
nsIVariant.h \
nsInt64.h \
nsQuickSort.h \
nsRBTree.h \
nsStr.h \
nsString.h \
nsString2.h \
nsTime.h \
nsUnitConversion.h \
nsVector.h \
nsVoidArray.h \
nsXPIDLString.h \
plvector.h \
$(NULL)
XPIDL_MODULE = xpcom_ds
XPIDLSRCS = \
.\nsICollection.idl \
.\nsIEnumerator.idl \
.\nsIObserver.idl \
.\nsIObserverService.idl \
.\nsISupportsArray.idl \
$(NULL)
################################################################################
## library
LIBRARY_NAME=xpcomds_s
LINCS = \
-I$(PUBLIC)\xpcom \
-I$(PUBLIC)\uconv \
-I$(PUBLIC)\unicharutil \
$(NULL)
LCFLAGS = -D_IMPL_NS_COM -D_IMPL_NS_BASE -DWIN32_LEAN_AND_MEAN
CPP_OBJS = \
.\$(OBJDIR)\nsArena.obj \
.\$(OBJDIR)\nsAtomTable.obj \
.\$(OBJDIR)\nsBTree.obj \
.\$(OBJDIR)\nsBuffer.obj \
.\$(OBJDIR)\nsByteBuffer.obj \
.\$(OBJDIR)\nsCRT.obj \
.\$(OBJDIR)\nsConjoiningEnumerator.obj \
.\$(OBJDIR)\nsDeque.obj \
.\$(OBJDIR)\nsEmptyEnumerator.obj \
.\$(OBJDIR)\nsEnumeratorUtils.obj \
.\$(OBJDIR)\nsHashtable.obj \
.\$(OBJDIR)\nsObserver.obj \
.\$(OBJDIR)\nsObserverList.obj \
.\$(OBJDIR)\nsObserverService.obj \
.\$(OBJDIR)\nsPageMgr.obj \
.\$(OBJDIR)\nsProperties.obj \
.\$(OBJDIR)\nsQuickSort.obj \
.\$(OBJDIR)\nsRBTree.obj \
.\$(OBJDIR)\nsSizeOfHandler.obj \
.\$(OBJDIR)\nsStr.obj \
.\$(OBJDIR)\nsString.obj \
.\$(OBJDIR)\nsString2.obj \
.\$(OBJDIR)\nsSupportsArray.obj \
.\$(OBJDIR)\nsSupportsArrayEnumerator.obj \
.\$(OBJDIR)\nsUnicharBuffer.obj \
.\$(OBJDIR)\nsVariant.obj \
.\$(OBJDIR)\nsVoidArray.obj \
.\$(OBJDIR)\nsXPIDLString.obj \
.\$(OBJDIR)\plvector.obj \
$(NULL)
include <$(DEPTH)\config\rules.mak>
libs:: $(LIBRARY)
$(MAKE_INSTALL) $(LIBRARY) $(DIST)\lib
clobber::
rm -f $(DIST)\lib\$(LIBRARY_NAME).lib

View File

@@ -1,86 +0,0 @@
/* -*- 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 "nsArena.h"
#include "nsCRT.h"
NS_IMETHODIMP
ArenaImpl::Init(PRUint32 aBlockSize)
{
if (aBlockSize < NS_MIN_ARENA_BLOCK_SIZE) {
aBlockSize = NS_DEFAULT_ARENA_BLOCK_SIZE;
}
PL_INIT_ARENA_POOL(&mPool, "nsIArena", aBlockSize);
mBlockSize = aBlockSize;
return NS_OK;
}
NS_IMPL_ISUPPORTS(ArenaImpl, nsIArena::GetIID())
ArenaImpl::~ArenaImpl()
{
PL_FinishArenaPool(&mPool);
}
NS_IMETHODIMP_(void*)
ArenaImpl::Alloc(PRUint32 size)
{
// Adjust size so that it's a multiple of sizeof(double)
PRUint32 align = size & (sizeof(double) - 1);
if (0 != align) {
size += sizeof(double) - align;
}
void* p;
PL_ARENA_ALLOCATE(p, &mPool, size);
return p;
}
NS_METHOD
ArenaImpl::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult)
{
if (aOuter)
return NS_ERROR_NO_AGGREGATION;
ArenaImpl* it = new ArenaImpl();
if (nsnull == it)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(it);
nsresult rv = it->QueryInterface(aIID, aResult);
NS_RELEASE(it);
return rv;
}
NS_COM nsresult NS_NewHeapArena(nsIArena** aInstancePtrResult,
PRUint32 aArenaBlockSize)
{
nsresult rv;
nsIArena* arena;
rv = ArenaImpl::Create(NULL, nsIArena::GetIID(), (void**)&arena);
if (NS_FAILED(rv)) return rv;
rv = arena->Init(aArenaBlockSize);
if (NS_FAILED(rv)) {
NS_RELEASE(arena);
return rv;
}
*aInstancePtrResult = arena;
return rv;
}

View File

@@ -1,47 +0,0 @@
/* -*- 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 nsArena_h__
#define nsArena_h__
#include "nsIArena.h"
#define PL_ARENA_CONST_ALIGN_MASK 7
#include "plarena.h"
// Simple arena implementation layered on plarena
class ArenaImpl : public nsIArena {
public:
ArenaImpl(void) { NS_INIT_REFCNT(); }
virtual ~ArenaImpl();
NS_DECL_ISUPPORTS
static NS_METHOD
Create(nsISupports *aOuter, REFNSIID aIID, void **aResult);
NS_IMETHOD Init(PRUint32 arenaBlockSize);
NS_IMETHOD_(void*) Alloc(PRUint32 size);
protected:
PLArenaPool mPool;
PRUint32 mBlockSize;
};
#endif // nsArena_h__

View File

@@ -1,135 +0,0 @@
/* -*- 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 "nsAtomTable.h"
#include "nsString.h"
#include "nsCRT.h"
#include "plhash.h"
#include "nsISizeOfHandler.h"
/**
* The shared hash table for atom lookups.
*/
static nsrefcnt gAtoms;
static struct PLHashTable* gAtomHashTable;
AtomImpl::AtomImpl()
{
NS_INIT_REFCNT();
// Every live atom holds a reference on the atom hashtable
gAtoms++;
}
AtomImpl::~AtomImpl()
{
NS_PRECONDITION(nsnull != gAtomHashTable, "null atom hashtable");
if (nsnull != gAtomHashTable) {
PL_HashTableRemove(gAtomHashTable, mString);
nsrefcnt cnt = --gAtoms;
if (0 == cnt) {
// When the last atom is destroyed, the atom arena is destroyed
NS_ASSERTION(0 == gAtomHashTable->nentries, "bad atom table");
PL_HashTableDestroy(gAtomHashTable);
gAtomHashTable = nsnull;
}
}
}
static NS_DEFINE_IID(kIAtomIID, NS_IATOM_IID);
NS_IMPL_ISUPPORTS(AtomImpl, kIAtomIID);
void* AtomImpl::operator new(size_t size, const PRUnichar* us, PRInt32 uslen)
{
size = size + uslen * sizeof(PRUnichar);
AtomImpl* ii = (AtomImpl*) ::operator new(size);
nsCRT::memcpy(ii->mString, us, uslen * sizeof(PRUnichar));
ii->mString[uslen] = 0;
return ii;
}
void AtomImpl::ToString(nsString& aBuf) const
{
aBuf.SetLength(0);
aBuf.Append(mString, nsCRT::strlen(mString));
}
const PRUnichar* AtomImpl::GetUnicode() const
{
return mString;
}
NS_IMETHODIMP
AtomImpl::SizeOf(nsISizeOfHandler* aHandler) const
{
aHandler->Add(sizeof(*this) + nsCRT::strlen(mString) * sizeof(PRUnichar));
return NS_OK;
}
//----------------------------------------------------------------------
static PLHashNumber HashKey(const PRUnichar* k)
{
return (PLHashNumber) nsCRT::HashValue(k);
}
static PRIntn CompareKeys(const PRUnichar* k1, const PRUnichar* k2)
{
return nsCRT::strcmp(k1, k2) == 0;
}
NS_COM nsIAtom* NS_NewAtom(const char* isolatin1)
{
nsAutoString tmp(isolatin1);
return NS_NewAtom(tmp.GetUnicode());
}
NS_COM nsIAtom* NS_NewAtom(const nsString& aString)
{
return NS_NewAtom(aString.GetUnicode());
}
NS_COM nsIAtom* NS_NewAtom(const PRUnichar* us)
{
if (nsnull == gAtomHashTable) {
gAtomHashTable = PL_NewHashTable(8, (PLHashFunction) HashKey,
(PLHashComparator) CompareKeys,
(PLHashComparator) nsnull,
nsnull, nsnull);
}
PRUint32 uslen;
PRUint32 hashCode = nsCRT::HashValue(us, &uslen);
PLHashEntry** hep = PL_HashTableRawLookup(gAtomHashTable, hashCode, us);
PLHashEntry* he = *hep;
if (nsnull != he) {
nsIAtom* id = (nsIAtom*) he->value;
NS_ADDREF(id);
return id;
}
AtomImpl* id = new(us, uslen) AtomImpl();
PL_HashTableRawAdd(gAtomHashTable, hep, hashCode, id->mString, id);
NS_ADDREF(id);
return id;
}
NS_COM nsrefcnt NS_GetNumberOfAtoms(void)
{
if (nsnull != gAtomHashTable) {
NS_PRECONDITION(nsrefcnt(gAtomHashTable->nentries) == gAtoms, "bad atom table");
}
return gAtoms;
}

View File

@@ -1,48 +0,0 @@
/* -*- 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 nsAtomTable_h__
#define nsAtomTable_h__
#include "nsIAtom.h"
class AtomImpl : public nsIAtom {
public:
AtomImpl();
virtual ~AtomImpl();
NS_DECL_ISUPPORTS
void* operator new(size_t size, const PRUnichar* us, PRInt32 uslen);
void operator delete(void* ptr) {
::operator delete(ptr);
}
virtual void ToString(nsString& aBuf) const;
virtual const PRUnichar* GetUnicode() const;
NS_IMETHOD SizeOf(nsISizeOfHandler* aHandler) const;
// Actually more; 0 terminated. This slot is reserved for the
// terminating zero.
PRUnichar mString[1];
};
#endif // nsAtomTable_h__

View File

@@ -1,402 +0,0 @@
/**
* This file defines the binary tree class and it
* nsNode child class.
*
* This simple version stores nodes, and the
* nodes store void* ptrs.
*
* @update gess 4/11/98
* @param
* @return
*/
#include "nsBTree.h"
/**
* default constructor
*
* @update gess 4/11/98
*/
nsNode::nsNode(){
mLeft=0;
mRight=0;
mParent=0;
mColor=eBlack;
}
/**
* Copy constructor
*
* @update gess 4/11/98
* @param
* @return
*/
nsNode::nsNode(const nsNode& aNode){
mLeft=aNode.mLeft;
mRight=aNode.mRight;
mParent=aNode.mParent;
mColor=aNode.mColor;
}
/**
* destructor
*
* @update gess 4/11/98
*/
nsNode::~nsNode(){
}
/**
* Retrive ptr to parent node
*
* @update gess 4/11/98
* @return ptr to parent node
*/
nsNode* nsNode::GetParentNode(void) const{
return mParent;
}
/**
* Retrieve ptr to left (less) node
*
* @update gess 4/11/98
* @return ptr to left (may be NULL)
*/
nsNode* nsNode::GetLeftNode(void) const{
return mLeft;
}
/**
* Retrieve ptr to right (more) node
*
* @update gess 4/11/98
* @return ptr to right node (may be NULL)
*/
nsNode* nsNode::GetRightNode(void) const{
return mRight;
}
/**
*
*
* @update gess 4/11/98
* @param
* @return
*/
nsNode& nsNode::operator=(const nsNode& aNode){
if(this!=&aNode){
mLeft=aNode.mLeft;
mRight=aNode.mRight;
mParent=aNode.mParent;
mColor=aNode.mColor;
}
return *this;
}
/********************************************************
* Here comes the BTREE class...
********************************************************/
/**
* nsBTree constructor
*
* @update gess 4/11/98
*/
nsBTree::nsBTree(){
mRoot=0;
}
/**
* destructor
*
* @update gess 4/11/98
*/
nsBTree::~nsBTree(){
if(mRoot){
//walk the tree and destroy the children.
}
}
/**
* Given a node, we're supposed to add it into
* our tree.
*
* @update gess 4/11/98
* @param aNode to be added to tree
* @return ptr to added node or NULL
*/
nsNode* nsBTree::Add(nsNode& aNode){
nsNode* node1=mRoot; //x
nsNode* node2=0; //y
while(node1) {
node2=node1;
if(aNode<*node1)
node1=node1->mLeft;
else node1=node1->mRight;
}
aNode.mParent=node2;
if(!node2){
mRoot=&aNode;
}
else{
if(aNode<*node2)
node2->mLeft=&aNode;
else node2->mRight=&aNode;
}
return &aNode;
}
/**
* Removes given node from tree if present.
*
* @update gess 4/11/98
* @param aNode to be found and removed
* @return ptr to remove node, or NULL
*/
nsNode* nsBTree::Remove(nsNode& aNode){
nsNode* result=0;
nsNode* node3=Find(aNode);
if(node3) {
nsNode* node1;
nsNode* node2;
if((!node3->mLeft) || (!node3->mRight))
node2=node3;
else node2=After(*node3);
if(node2->mLeft)
node1=node2->mLeft;
else node1=node2->mRight;
if(node1)
node1->mParent=node2->mParent;
if(node2->mParent) {
if(node2==node2->mParent->mLeft)
node2->mParent->mLeft=node1;
else node2->mParent->mRight=node1;
}
else mRoot=node1;
if(node2!=node3)
(*node3)==(*node2);
if(node2->mColor == nsNode::eBlack)
ReBalance(*node1);
delete node2;
result=&aNode;
}
return result;
}
/**
* Clears the tree of any data.
* Be careful here if your objects are heap based!
* This method doesn't free the objects, so if you
* don't have your own pointers, they will become
* orphaned.
*
* @update gess 4/11/98
* @param
* @return this
*/
nsBTree& nsBTree::Empty(nsNode* aNode) {
mRoot=0;
return *this;
}
/**
* This method destroys all the objects in the tree.
* WARNING: Never call this method on stored objects
* that are stack-based!
*
* @update gess 4/11/98
* @param
* @return this
*/
nsBTree& nsBTree::Erase(nsNode* aNode){
// nsNode* node1 =(aNode) ? aNode : mRoot;
if(aNode) {
Erase(aNode->mLeft); //begin by walking left side
Erase(aNode->mRight); //then search right side
delete aNode; //until a leaf, then delete
}
return *this;
}
/**
* Retrieve ptr to first node in tree
*
* @update gess 4/11/98
* @return
*/
nsNode* nsBTree::First(void) const{
if(mRoot)
return First(*mRoot);
return 0;
}
/**
* Retrive ptr to first node rel to given node
*
* @update gess 4/11/98
* @param node to begin scan from
* @return ptr to first node from given node or NULL
*/
nsNode* nsBTree::First(const nsNode& aNode) const{
nsNode* result=0;
if(mRoot) {
result=mRoot;
while(result->GetLeftNode()) {
result=result->GetLeftNode();
}
}
return result;
}
/**
* Retrive ptr to last node
*
* @update gess 4/11/98
* @return ptr to last node rel to root or NULL
*/
nsNode* nsBTree::Last(void) const{
if(mRoot)
return Last(*mRoot);
return 0;
}
/**
* Retrive ptr to last node rel to given node
*
* @update gess 4/11/98
* @param node to begin scan from
* @return ptr to first node from given node or NULL
*/
nsNode* nsBTree::Last(const nsNode& aNode) const{
nsNode* result=0;
if(mRoot) {
result=mRoot;
while(result->GetRightNode()) {
result=result->GetRightNode();
}
}
return result;
}
/**
* Retrive ptr to prior node rel to given node
*
* @update gess 4/11/98
* @param node to begin scan from
* @return ptr to prior node from given node or NULL
*/
nsNode* nsBTree::Before(const nsNode& aNode) const{
if(aNode.GetLeftNode())
return Last(*aNode.GetLeftNode());
//otherwise...
nsNode* node1=(nsNode*)&aNode;
nsNode* node2=aNode.GetParentNode();
while((node2) && (node1==node2->GetLeftNode())) {
node1=node2;
node2=node2->GetParentNode();
}
return node2;
}
/**
* Retrive ptr to next node rel to given node
*
* @update gess 4/11/98
* @param node to begin scan from
* @return ptr to next node from given node or NULL
*/
nsNode* nsBTree::After(const nsNode& aNode) const{
if(aNode.GetRightNode())
return First(*aNode.GetRightNode());
//otherwise...
nsNode* node1=(nsNode*)&aNode;
nsNode* node2=aNode.GetParentNode();
while((node2) && (node1==node2->GetRightNode())) {
node1=node2;
node2=node2->GetParentNode();
}
return node2;
}
/**
* Scan for given node
*
* @update gess 4/11/98
* @param node to find
* @return ptr to given node, or NULL
*/
nsNode* nsBTree::Find(const nsNode& aNode) const{
nsNode* result=mRoot;
while((result) && (!(aNode==(*result)))) {
if(aNode<*result)
result=result->mLeft;
else result=result->mRight;
}
return (nsNode*)result;
}
/**
* Rebalances tree around the given node. This only
* needs to be called after a node is deleted.
* This method does nothing for btrees, but is
* needed for RBTrees.
*
* @update gess 4/11/98
* @param aNode -- node to balance around
* @return this
*/
nsBTree& nsBTree::ReBalance(nsNode& aNode){
return *this;
}
/**
*
*
* @update gess 4/11/98
* @param
* @return
*/
const nsBTree& nsBTree::ForEach(nsNodeFunctor& aFunctor,nsNode* aNode) const{
nsNode* node1 =(aNode) ? aNode : mRoot;
if(node1) {
if(node1->mLeft)
ForEach(aFunctor,node1->mLeft); //begin by walking left side
aFunctor(*node1);
if(node1->mRight)
ForEach(aFunctor,node1->mRight); //then search right side
}
return *this;
}

View File

@@ -1,283 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/**
* This file defines the binary tree class and it
* nsNode child class. Note that like all nsBTree
* containers, this one does not automatically balance.
* (Find for random data, bad for pre-ordered data).
*
* This simple version stores nodes, and the
* nodes store void* ptrs.
*
* @update gess 4/11/98
*/
/**
* nsNode
*
* @update gess 4/11/98
* @param
* @return
*/
#ifndef _BTREE_H
#define _BTREE_H
#include "nscore.h"
struct NS_COM nsNode {
/**
*
* @update gess4/20/98
* @param
* @return
*/
nsNode();
/**
* Copy constructor
* @update gess 4/11/98
*/
nsNode(const nsNode& aNode);
/**
* destructor
* @update gess 4/11/98
*/
virtual ~nsNode();
/**
* Retrieve parent node
*
* @update gess 4/11/98
* @return
*/
nsNode* GetParentNode(void) const;
/**
*
* @update gess 4/11/98
* @param
* @return
*/
nsNode* GetLeftNode() const;
/**
*
* @update gess 4/11/98
* @param
* @return
*/
nsNode* GetRightNode() const;
/**
*
* @update gess 4/11/98
* @param
* @return
*/
virtual nsNode& operator=(const nsNode& aNode);
/**
* This method gets called to determine which of
* two nodes is less. When you create your own
* subclass of nsNode, this is the most important
* method for you to overload.
*
* @update gess 4/11/98
* @param
* @return
*/
virtual PRBool operator<(const nsNode& aNode) const=0;
/**
* This method gets called to determine which of
* two nodes is less. When you create your own
* subclass of nsNode, this is the most important
* method for you to overload.
*
* @update gess 4/11/98
* @param
* @return
*/
virtual PRBool operator==(const nsNode& aNode) const=0;
enum eRBColor {eRed,eBlack};
nsNode* mParent;
nsNode* mLeft;
nsNode* mRight;
eRBColor mColor;
};
/**
* The Nodefunctor class is used when you want to create
* callbacks between the nsRBTree and your generic code.
*
* @update gess4/20/98
*/
class NS_COM nsNodeFunctor {
public:
virtual nsNodeFunctor& operator()(nsNode& aNode)=0;
};
/****************************************************
* Here comes the nsBTree class...
****************************************************/
class NS_COM nsBTree {
public:
friend class nsBTreeIterator;
nsBTree();
virtual ~nsBTree();
/**
* Add given node reference into our tree.
*
* @update gess 4/11/98
* @param aNode is a ref to a node to be added
* @return newly added node
*/
nsNode* Add(nsNode& aNode);
/**
* Remove given node reference into our tree.
*
* @update gess 4/11/98
* @param aNode is a ref to a node to be removed
* @return Ptr to node if found (and removed) or NULL
*/
nsNode* Remove(nsNode& aNode);
/**
* Clears the tree of any data.
* Be careful here if your objects are heap based!
* This method doesn't free the objects, so if you
* don't have your own pointers, they will become
* orphaned.
*
* @update gess 4/11/98
* @param
* @return this
*/
nsBTree& Empty(nsNode* aNode=0);
/**
* This method destroys all the objects in the tree.
* WARNING: Never call this method on stored objects
* that are stack-based!
*
* @update gess 4/11/98
* @param
* @return this
*/
nsBTree& Erase(nsNode* aNode=0);
/**
* Retrieve ptr to 1st node in tree (starting at root)
*
* @update gess 4/11/98
* @return ptr to 1st node, possible to be NULL
*/
nsNode* First(void) const;
/**
* Find first node in tree starting at given node
*
* @update gess 4/11/98
* @param aNode node to begin 1st search from
* @return ptr to 1st node below given node
*/
nsNode* First(const nsNode& aNode) const;
/**
* Retrieve ptr to last node in tree relative to root.
*
* @update gess 4/11/98
* @return ptr to last node or NULL
*/
nsNode* Last(void) const;
/**
* Retrieve ptr to last node in tree relative to given node.
*
* @update gess 4/11/98
* @param node to find last node from
* @return ptr to last node or NULL
*/
nsNode* Last(const nsNode& aNode) const;
/**
* Retrieve a ptr to the node that preceeds given node
*
* @update gess 4/11/98
* @param aNode used as reference to find prev.
* @return ptr to prev node or NULL
*/
nsNode* Before(const nsNode& aNode) const;
/**
* Retrieve a ptr to the node after given node
*
* @update gess 4/11/98
* @param aNode used as reference to find next.
* @return ptr to next node or NULL
*/
nsNode* After(const nsNode& aNode) const;
/**
* Find given node in tree.
* (Why would you want to find a node you already have?)
*
* @update gess 4/11/98
* @param aNode is the node you're searching for
* @return ptr to node if found, or NULL
*/
nsNode* Find(const nsNode& aNode) const;
/**
* Walks the tree, starting with root.
*
* @update gess 4/11/98
*/
virtual const nsBTree& ForEach(nsNodeFunctor& aFunctor,nsNode* aNode=0) const;
protected:
/**
* Rebalances tree around the given node. This only
* needs to be called after a node is deleted.
*
* @update gess 4/11/98
* @param aNode -- node to balance around
* @return this
*/
virtual nsBTree& ReBalance(nsNode& aNode);
nsNode* mRoot;
};
#endif

View File

@@ -1,705 +0,0 @@
/* -*- 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 "nsBuffer.h"
#include "nsAutoLock.h"
#include "nsCRT.h"
#include "nsIInputStream.h"
#include "nsIServiceManager.h"
#include "nsIPageManager.h"
////////////////////////////////////////////////////////////////////////////////
nsBuffer::nsBuffer()
: mGrowBySize(0),
mMaxSize(0),
mAllocator(nsnull),
mBufferSize(0),
mReadSegment(nsnull),
mReadCursor(0),
mWriteSegment(nsnull),
mWriteCursor(0),
mReaderClosed(PR_FALSE),
mCondition(NS_OK)
{
NS_INIT_REFCNT();
PR_INIT_CLIST(&mSegments);
}
NS_IMETHODIMP
nsBuffer::Init(PRUint32 growBySize, PRUint32 maxSize,
nsIBufferObserver* observer, nsIAllocator* allocator)
{
NS_ASSERTION(sizeof(PRCList) <= SEGMENT_OVERHEAD,
"need to change SEGMENT_OVERHEAD size");
NS_ASSERTION(growBySize > SEGMENT_OVERHEAD, "bad growBySize");
mGrowBySize = growBySize;
mMaxSize = maxSize;
mObserver = observer;
NS_IF_ADDREF(mObserver);
mAllocator = allocator;
NS_ADDREF(mAllocator);
return NS_OK;
}
nsBuffer::~nsBuffer()
{
NS_IF_RELEASE(mObserver);
NS_IF_RELEASE(mAllocator);
}
NS_IMPL_ISUPPORTS(nsBuffer, nsIBuffer::GetIID());
NS_METHOD
nsBuffer::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult)
{
if (aOuter)
return NS_ERROR_NO_AGGREGATION;
nsBuffer* buf = new nsBuffer();
if (buf == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(buf);
nsresult rv = buf->QueryInterface(aIID, aResult);
NS_RELEASE(buf);
return rv;
}
////////////////////////////////////////////////////////////////////////////////
nsresult
nsBuffer::PushWriteSegment()
{
nsAutoCMonitor mon(this); // protect mSegments
if (mBufferSize >= mMaxSize) {
if (mObserver) {
nsresult rv = mObserver->OnFull(this);
if (NS_FAILED(rv)) return rv;
}
return NS_ERROR_FAILURE;
}
// allocate a new segment to write into
PRCList* header;
header = (PRCList*)mAllocator->Alloc(mGrowBySize);
if (header == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
mBufferSize += mGrowBySize;
PR_INSERT_BEFORE(header, &mSegments); // insert at end
// initialize the write segment
mWriteSegment = header;
mWriteSegmentEnd = (char*)mWriteSegment + mGrowBySize;
mWriteCursor = (char*)mWriteSegment + sizeof(PRCList);
return NS_OK;
}
nsresult
nsBuffer::PopReadSegment()
{
nsresult rv;
nsAutoCMonitor mon(this); // protect mSegments
PRCList* header = (PRCList*)mSegments.next;
char* segment = (char*)header;
NS_ASSERTION(mReadSegment == header, "wrong segment");
// make sure that the writer isn't still in this segment (that the
// reader is removing)
NS_ASSERTION(!(segment <= mWriteCursor && mWriteCursor < segment + mGrowBySize),
"removing writer's segment");
PR_REMOVE_LINK(header); // unlink from mSegments
mBufferSize -= mGrowBySize;
rv = mAllocator->Free(segment);
if (NS_FAILED(rv)) return rv;
// initialize the read segment
if (PR_CLIST_IS_EMPTY(&mSegments)) {
mReadSegment = nsnull;
mReadSegmentEnd = nsnull;
mReadCursor = nsnull;
if (mObserver) {
rv = mObserver->OnEmpty(this);
if (NS_FAILED(rv)) return rv;
}
}
else {
mReadSegment = mSegments.next;
mReadSegmentEnd = (char*)mReadSegment + mGrowBySize;
mReadCursor = (char*)mReadSegment + sizeof(PRCList);
}
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
// nsIBuffer methods:
NS_IMETHODIMP
nsBuffer::ReadSegments(nsWriteSegmentFun writer, void* closure, PRUint32 count,
PRUint32 *readCount)
{
NS_ASSERTION(!mReaderClosed, "state change error");
nsAutoCMonitor mon(this);
nsresult rv = NS_OK;
PRUint32 readBufferLen;
const char* readBuffer;
*readCount = 0;
while (count > 0) {
rv = GetReadSegment(0, &readBuffer, &readBufferLen);
if (rv == NS_BASE_STREAM_EOF) { // all we're going to get
return *readCount == 0 ? rv : NS_OK;
}
NS_ASSERTION(NS_SUCCEEDED(rv), "GetReadSegment failed -- shouldn't happen");
if (readBufferLen == 0) {
return *readCount == 0 ? NS_BASE_STREAM_WOULD_BLOCK : NS_OK;
}
readBufferLen = PR_MIN(readBufferLen, count);
while (readBufferLen > 0) {
PRUint32 writeCount;
rv = writer(closure, readBuffer, *readCount, readBufferLen, &writeCount);
NS_ASSERTION(rv != NS_BASE_STREAM_EOF, "Write should not return EOF");
if (rv == NS_BASE_STREAM_WOULD_BLOCK || NS_FAILED(rv)) {
// if we failed to write just report what we were
// able to read so far
return *readCount == 0 ? rv : NS_OK;
}
NS_ASSERTION(writeCount <= readBufferLen, "writer returned bad writeCount");
readBuffer += writeCount;
readBufferLen -= writeCount;
*readCount += writeCount;
count -= writeCount;
if (mReadCursor + writeCount == mReadSegmentEnd) {
rv = PopReadSegment();
if (NS_FAILED(rv)) {
return *readCount == 0 ? rv : NS_OK;
}
}
else {
mReadCursor += writeCount;
}
}
}
return NS_OK;
}
static NS_METHOD
nsWriteToRawBuffer(void* closure,
const char* fromRawSegment,
PRUint32 offset,
PRUint32 count,
PRUint32 *writeCount)
{
char* toBuf = (char*)closure;
nsCRT::memcpy(&toBuf[offset], fromRawSegment, count);
*writeCount = count;
return NS_OK;
}
NS_IMETHODIMP
nsBuffer::Read(char* toBuf, PRUint32 bufLen, PRUint32 *readCount)
{
return ReadSegments(nsWriteToRawBuffer, toBuf, bufLen, readCount);
}
NS_IMETHODIMP
nsBuffer::GetReadSegment(PRUint32 segmentLogicalOffset,
const char* *resultSegment,
PRUint32 *resultSegmentLen)
{
nsAutoCMonitor mon(this);
// set the read segment and cursor if not already set
if (mReadSegment == nsnull) {
if (PR_CLIST_IS_EMPTY(&mSegments)) {
*resultSegmentLen = 0;
*resultSegment = nsnull;
return mCondition ? mCondition : NS_OK;
}
else {
mReadSegment = mSegments.next;
mReadSegmentEnd = (char*)mReadSegment + mGrowBySize;
mReadCursor = (char*)mReadSegment + sizeof(PRCList);
}
}
// now search for the segment starting from segmentLogicalOffset and return it
PRCList* curSeg = mReadSegment;
char* curSegStart = mReadCursor;
char* curSegEnd = mReadSegmentEnd;
PRInt32 amt;
PRInt32 offset = (PRInt32)segmentLogicalOffset;
while (offset >= 0) {
// snapshot the write cursor into a local variable -- this allows
// a writer to freely change it while we're reading while avoiding
// using a lock
char* snapshotWriteCursor = mWriteCursor; // atomic
// next check if the write cursor is in our segment
if (curSegStart <= snapshotWriteCursor &&
snapshotWriteCursor < curSegEnd) {
// same segment -- read up to the snapshotWriteCursor
curSegEnd = snapshotWriteCursor;
amt = curSegEnd - curSegStart;
if (offset < amt) {
// segmentLogicalOffset is in this segment, so read up to its end
*resultSegmentLen = amt - offset;
*resultSegment = curSegStart + offset;
return NS_OK;
}
else {
// don't continue past the write segment
*resultSegmentLen = 0;
*resultSegment = nsnull;
return mCondition ? mCondition : NS_OK;
}
}
else {
amt = curSegEnd - curSegStart;
if (offset < amt) {
// segmentLogicalOffset is in this segment, so read up to its end
*resultSegmentLen = amt - offset;
*resultSegment = curSegStart + offset;
return NS_OK;
}
else {
curSeg = PR_NEXT_LINK(curSeg);
if (curSeg == mReadSegment) {
// been all the way around
*resultSegmentLen = 0;
*resultSegment = nsnull;
return mCondition ? mCondition : NS_OK;
}
curSegEnd = (char*)curSeg + mGrowBySize;
curSegStart = (char*)curSeg + sizeof(PRCList);
offset -= amt;
}
}
}
NS_NOTREACHED("nsBuffer::GetReadSegment failed");
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsBuffer::GetReadableAmount(PRUint32 *result)
{
NS_ASSERTION(!mReaderClosed, "state change error");
nsAutoCMonitor mon(this);
*result = 0;
// first set the read segment and cursor if not already set
if (mReadSegment == nsnull) {
if (PR_CLIST_IS_EMPTY(&mSegments)) {
return NS_OK;
}
else {
mReadSegment = mSegments.next;
mReadSegmentEnd = (char*)mReadSegment + mGrowBySize;
mReadCursor = (char*)mReadSegment + sizeof(PRCList);
}
}
// now search for the segment starting from segmentLogicalOffset and return it
PRCList* curSeg = mReadSegment;
char* curSegStart = mReadCursor;
char* curSegEnd = mReadSegmentEnd;
PRInt32 amt;
while (PR_TRUE) {
// snapshot the write cursor into a local variable -- this allows
// a writer to freely change it while we're reading while avoiding
// using a lock
char* snapshotWriteCursor = mWriteCursor; // atomic
// next check if the write cursor is in our segment
if (curSegStart <= snapshotWriteCursor &&
snapshotWriteCursor < curSegEnd) {
// same segment -- read up to the snapshotWriteCursor
curSegEnd = snapshotWriteCursor;
amt = curSegEnd - curSegStart;
*result += amt;
return NS_OK;
}
else {
amt = curSegEnd - curSegStart;
*result += amt;
curSeg = PR_NEXT_LINK(curSeg);
if (curSeg == mReadSegment) {
// been all the way around
return NS_OK;
}
curSegEnd = (char*)curSeg + mGrowBySize;
curSegStart = (char*)curSeg + sizeof(PRCList);
}
}
return NS_ERROR_FAILURE;
}
typedef PRInt32 (*compare_t)(const char*, const char*, PRUint32);
NS_IMETHODIMP
nsBuffer::Search(const char* string, PRBool ignoreCase,
PRBool *found, PRUint32 *offsetSearchedTo)
{
NS_ASSERTION(!mReaderClosed, "state change error");
nsresult rv;
const char* bufSeg1;
PRUint32 bufSegLen1;
PRUint32 segmentPos = 0;
PRUint32 strLen = nsCRT::strlen(string);
compare_t compare =
ignoreCase ? (compare_t)nsCRT::strncasecmp : (compare_t)nsCRT::strncmp;
rv = GetReadSegment(segmentPos, &bufSeg1, &bufSegLen1);
if (NS_FAILED(rv) || bufSegLen1 == 0) {
*found = PR_FALSE;
*offsetSearchedTo = segmentPos;
return NS_OK;
}
while (PR_TRUE) {
PRUint32 i;
// check if the string is in the buffer segment
for (i = 0; i < bufSegLen1 - strLen + 1; i++) {
if (compare(&bufSeg1[i], string, strLen) == 0) {
*found = PR_TRUE;
*offsetSearchedTo = segmentPos + i;
return NS_OK;
}
}
// get the next segment
const char* bufSeg2;
PRUint32 bufSegLen2;
segmentPos += bufSegLen1;
rv = GetReadSegment(segmentPos, &bufSeg2, &bufSegLen2);
if (NS_FAILED(rv) || bufSegLen2 == 0) {
*found = PR_FALSE;
if (mCondition != NS_OK) // XXX NS_FAILED?
*offsetSearchedTo = segmentPos - bufSegLen1;
else
*offsetSearchedTo = segmentPos - bufSegLen1 - strLen + 1;
return NS_OK;
}
// check if the string is straddling the next buffer segment
PRUint32 limit = PR_MIN(strLen, bufSegLen2 + 1);
for (i = 0; i < limit; i++) {
PRUint32 strPart1Len = strLen - i - 1;
PRUint32 strPart2Len = strLen - strPart1Len;
const char* strPart2 = &string[strLen - strPart2Len];
PRUint32 bufSeg1Offset = bufSegLen1 - strPart1Len;
if (compare(&bufSeg1[bufSeg1Offset], string, strPart1Len) == 0 &&
compare(bufSeg2, strPart2, strPart2Len) == 0) {
*found = PR_TRUE;
*offsetSearchedTo = segmentPos - strPart1Len;
return NS_OK;
}
}
// finally continue with the next buffer
bufSeg1 = bufSeg2;
bufSegLen1 = bufSegLen2;
}
NS_NOTREACHED("can't get here");
return NS_ERROR_FAILURE; // keep compiler happy
}
NS_IMETHODIMP
nsBuffer::ReaderClosed()
{
nsresult rv = NS_OK;
nsAutoCMonitor mon(this); // protect mSegments
// first prevent any more writing
mReaderClosed = PR_TRUE;
// then free any unread segments...
// first set the read segment and cursor if not already set
if (mReadSegment == nsnull) {
if (!PR_CLIST_IS_EMPTY(&mSegments)) {
mReadSegment = mSegments.next;
mReadSegmentEnd = (char*)mReadSegment + mGrowBySize;
mReadCursor = (char*)mReadSegment + sizeof(PRCList);
}
}
while (mReadSegment) {
// snapshot the write cursor into a local variable -- this allows
// a writer to freely change it while we're reading while avoiding
// using a lock
char* snapshotWriteCursor = mWriteCursor; // atomic
// next check if the write cursor is in our segment
if (mReadCursor <= snapshotWriteCursor &&
snapshotWriteCursor < mReadSegmentEnd) {
// same segment -- we've discarded all the unread segments we
// can, so just updatethe read cursor
mReadCursor = mWriteCursor;
break;
}
// else advance to the next segment, freeing this one
rv = PopReadSegment();
if (NS_FAILED(rv)) break;
}
#ifdef DEBUG
PRUint32 amt;
const char* buf;
rv = GetReadSegment(0, &buf, &amt);
NS_ASSERTION(rv == NS_BASE_STREAM_EOF ||
(NS_SUCCEEDED(rv) && amt == 0), "ReaderClosed failed");
#endif
return rv;
}
NS_IMETHODIMP
nsBuffer::GetCondition(nsresult *result)
{
*result = mCondition;
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
NS_IMETHODIMP
nsBuffer::WriteSegments(nsReadSegmentFun reader, void* closure, PRUint32 count,
PRUint32 *writeCount)
{
nsAutoCMonitor mon(this);
nsresult rv;
if (mReaderClosed)
return NS_BASE_STREAM_CLOSED;
if (NS_FAILED(mCondition))
return mCondition;
*writeCount = 0;
while (count > 0) {
PRUint32 writeBufLen;
char* writeBuf;
rv = GetWriteSegment(&writeBuf, &writeBufLen);
if (NS_FAILED(rv) || writeBufLen == 0) {
// if we failed to allocate a new segment, we're probably out
// of memory, but we don't care -- just report what we were
// able to write so far
return (*writeCount == 0) ? rv : NS_OK;
}
writeBufLen = PR_MIN(writeBufLen, count);
while (writeBufLen > 0) {
PRUint32 readCount;
rv = reader(closure, writeBuf, *writeCount, writeBufLen, &readCount);
if (rv == NS_BASE_STREAM_WOULD_BLOCK) {
// if the place we're putting the data would block (probably ran
// out of room) just return what we were able to write so far
return (*writeCount == 0) ? rv : NS_OK;
}
if (NS_FAILED(rv)) {
// save the failure condition so that we can get it again later
nsresult rv2 = SetCondition(rv);
NS_ASSERTION(NS_SUCCEEDED(rv2), "SetCondition failed");
// if we failed to read just report what we were
// able to write so far
return (*writeCount == 0) ? rv : NS_OK;
}
NS_ASSERTION(readCount <= writeBufLen, "reader returned bad readCount");
writeBuf += readCount;
writeBufLen -= readCount;
*writeCount += readCount;
count -= readCount;
// set the write cursor after the data is valid
if (mWriteCursor + readCount == mWriteSegmentEnd) {
mWriteSegment = nsnull; // allocate a new segment next time around
mWriteSegmentEnd = nsnull;
mWriteCursor = nsnull;
}
else
mWriteCursor += readCount;
}
}
return NS_OK;
}
static NS_METHOD
nsReadFromRawBuffer(void* closure,
char* toRawSegment,
PRUint32 offset,
PRUint32 count,
PRUint32 *readCount)
{
const char* fromBuf = (const char*)closure;
nsCRT::memcpy(toRawSegment, &fromBuf[offset], count);
*readCount = count;
return NS_OK;
}
NS_IMETHODIMP
nsBuffer::Write(const char* fromBuf, PRUint32 bufLen, PRUint32 *writeCount)
{
return WriteSegments(nsReadFromRawBuffer, (void*)fromBuf, bufLen, writeCount);
}
static NS_METHOD
nsReadFromInputStream(void* closure,
char* toRawSegment,
PRUint32 offset,
PRUint32 count,
PRUint32 *readCount)
{
nsIInputStream* fromStream = (nsIInputStream*)closure;
return fromStream->Read(toRawSegment, count, readCount);
}
NS_IMETHODIMP
nsBuffer::WriteFrom(nsIInputStream* fromStream, PRUint32 count, PRUint32 *writeCount)
{
return WriteSegments(nsReadFromInputStream, fromStream, count, writeCount);
}
NS_IMETHODIMP
nsBuffer::GetWriteSegment(char* *resultSegment,
PRUint32 *resultSegmentLen)
{
nsAutoCMonitor mon(this);
if (mReaderClosed)
return NS_BASE_STREAM_CLOSED;
nsresult rv;
*resultSegmentLen = 0;
*resultSegment = nsnull;
if (mWriteSegment == nsnull) {
rv = PushWriteSegment();
if (NS_FAILED(rv)) return rv;
NS_ASSERTION(mWriteSegment != nsnull, "failed to allocate segment");
}
*resultSegmentLen = mWriteSegmentEnd - mWriteCursor;
*resultSegment = mWriteCursor;
NS_ASSERTION(*resultSegmentLen > 0, "Failed to get write segment.");
return NS_OK;
}
NS_IMETHODIMP
nsBuffer::GetWritableAmount(PRUint32 *amount)
{
if (mReaderClosed)
return NS_BASE_STREAM_CLOSED;
nsresult rv;
PRUint32 readableAmount;
rv = GetReadableAmount(&readableAmount);
if (NS_FAILED(rv)) return rv;
*amount = mMaxSize - readableAmount;
return NS_OK;
}
NS_IMETHODIMP
nsBuffer::GetReaderClosed(PRBool *result)
{
*result = mReaderClosed;
return NS_OK;
}
NS_IMETHODIMP
nsBuffer::SetCondition(nsresult condition)
{
nsAutoCMonitor mon(this);
if (mReaderClosed)
return NS_BASE_STREAM_CLOSED;
mCondition = condition;
mWriteSegment = nsnull; // allows reader to free last segment w/o asserting
mWriteSegmentEnd = nsnull;
// don't reset mWriteCursor here -- we need it for the EOF point in the buffer
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
static NS_DEFINE_CID(kAllocatorCID, NS_ALLOCATOR_CID);
NS_COM nsresult
NS_NewBuffer(nsIBuffer* *result,
PRUint32 growBySize, PRUint32 maxSize,
nsIBufferObserver* observer)
{
nsresult rv;
NS_WITH_SERVICE(nsIAllocator, alloc, kAllocatorCID, &rv);
if (NS_FAILED(rv)) return rv;
nsBuffer* buf;
rv = nsBuffer::Create(NULL, nsIBuffer::GetIID(), (void**)&buf);
if (NS_FAILED(rv)) return rv;
rv = buf->Init(growBySize, maxSize, observer, alloc);
if (NS_FAILED(rv)) {
NS_RELEASE(buf);
return rv;
}
*result = buf;
return NS_OK;
}
static NS_DEFINE_CID(kPageManagerCID, NS_PAGEMANAGER_CID);
NS_COM nsresult
NS_NewPageBuffer(nsIBuffer* *result,
PRUint32 growBySize, PRUint32 maxSize,
nsIBufferObserver* observer)
{
nsresult rv;
NS_WITH_SERVICE(nsIAllocator, alloc, kPageManagerCID, &rv);
if (NS_FAILED(rv)) return rv;
nsBuffer* buf;
rv = nsBuffer::Create(NULL, nsIBuffer::GetIID(), (void**)&buf);
if (NS_FAILED(rv)) return rv;
rv = buf->Init(growBySize, maxSize, observer, alloc);
if (NS_FAILED(rv)) {
NS_RELEASE(buf);
return rv;
}
*result = buf;
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////

View File

@@ -1,87 +0,0 @@
/* -*- 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 nsBuffer_h___
#define nsBuffer_h___
#include "nsIBuffer.h"
#include "nscore.h"
#include "prclist.h"
#include "nsIAllocator.h"
class nsBuffer : public nsIBuffer {
public:
NS_DECL_ISUPPORTS
static NS_METHOD
Create(nsISupports *aOuter, REFNSIID aIID, void **aResult);
// nsIBuffer methods:
NS_IMETHOD Init(PRUint32 growBySize, PRUint32 maxSize,
nsIBufferObserver* observer, nsIAllocator* allocator);
NS_IMETHOD Read(char* toBuf, PRUint32 bufLen, PRUint32 *readCount);
NS_IMETHOD ReadSegments(nsWriteSegmentFun writer, void* closure, PRUint32 count,
PRUint32 *readCount);
NS_IMETHOD GetReadSegment(PRUint32 segmentLogicalOffset,
const char* *resultSegment,
PRUint32 *resultSegmentLen);
NS_IMETHOD GetReadableAmount(PRUint32 *amount);
NS_IMETHOD Search(const char* forString, PRBool ignoreCase,
PRBool *found, PRUint32 *offsetSearchedTo);
NS_IMETHOD ReaderClosed(void);
NS_IMETHOD GetCondition(nsresult *result);
NS_IMETHOD Write(const char* fromBuf, PRUint32 bufLen, PRUint32 *writeCount);
NS_IMETHOD WriteFrom(nsIInputStream* fromStream, PRUint32 count, PRUint32 *writeCount);
NS_IMETHOD WriteSegments(nsReadSegmentFun reader, void* closure, PRUint32 count,
PRUint32 *writeCount);
NS_IMETHOD GetWriteSegment(char* *resultSegment,
PRUint32 *resultSegmentLen);
NS_IMETHOD GetWritableAmount(PRUint32 *amount);
NS_IMETHOD GetReaderClosed(PRBool *result);
NS_IMETHOD SetCondition(nsresult condition);
// nsBuffer methods:
nsBuffer();
virtual ~nsBuffer();
nsresult PushWriteSegment();
nsresult PopReadSegment();
protected:
PRUint32 mGrowBySize;
PRUint32 mMaxSize;
nsIAllocator* mAllocator;
nsIBufferObserver* mObserver;
PRCList mSegments;
PRUint32 mBufferSize;
PRCList* mReadSegment;
char* mReadSegmentEnd;
char* mReadCursor;
PRCList* mWriteSegment;
char* mWriteSegmentEnd;
char* mWriteCursor;
PRBool mReaderClosed;
nsresult mCondition;
};
#endif // nsBuffer_h___

View File

@@ -1,40 +0,0 @@
/* -*- 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 nsBufferPoolService_h___
#define nsBufferPoolService_h___
#include "nsIBufferPoolService.h"
class nsBufferPoolService : public nsIBufferPoolService {
public:
NS_DECL_ISUPPORTS
// nsIBufferPoolService methods:
NS_IMETHOD NewBuffer(PRUint32 minSize, PRUint32 maxSize,
nsIByteBuffer* *result);
// nsBufferPoolService methods:
nsBufferPoolService();
virtual ~nsBufferPoolService();
protected:
};
#endif // nsBufferPoolService_h___

View File

@@ -1,152 +0,0 @@
/* -*- 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 "nsByteBuffer.h"
#include "nsIInputStream.h"
#include "nsCRT.h"
#define MIN_BUFFER_SIZE 32
ByteBufferImpl::ByteBufferImpl(void)
: mBuffer(NULL), mSpace(0), mLength(0)
{
NS_INIT_REFCNT();
}
NS_IMETHODIMP
ByteBufferImpl::Init(PRUint32 aBufferSize)
{
if (aBufferSize < MIN_BUFFER_SIZE) {
aBufferSize = MIN_BUFFER_SIZE;
}
mSpace = aBufferSize;
mLength = 0;
mBuffer = new char[aBufferSize];
return mBuffer ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
}
NS_DEFINE_IID(kByteBufferIID,NS_IBYTE_BUFFER_IID);
NS_IMPL_ISUPPORTS(ByteBufferImpl,kByteBufferIID)
ByteBufferImpl::~ByteBufferImpl()
{
if (nsnull != mBuffer) {
delete[] mBuffer;
mBuffer = nsnull;
}
mLength = 0;
}
NS_METHOD
ByteBufferImpl::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult)
{
if (aOuter)
return NS_ERROR_NO_AGGREGATION;
ByteBufferImpl* it = new ByteBufferImpl();
if (nsnull == it)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(it);
nsresult rv = it->QueryInterface(aIID, (void**)aResult);
NS_RELEASE(it);
return rv;
}
NS_IMETHODIMP_(PRUint32)
ByteBufferImpl::GetLength(void) const
{
return mLength;
}
NS_IMETHODIMP_(PRUint32)
ByteBufferImpl::GetBufferSize(void) const
{
return mSpace;
}
NS_IMETHODIMP_(char*)
ByteBufferImpl::GetBuffer(void) const
{
return mBuffer;
}
NS_IMETHODIMP_(PRBool)
ByteBufferImpl::Grow(PRUint32 aNewSize)
{
if (aNewSize < MIN_BUFFER_SIZE) {
aNewSize = MIN_BUFFER_SIZE;
}
char* newbuf = new char[aNewSize];
if (nsnull != newbuf) {
if (0 != mLength) {
nsCRT::memcpy(newbuf, mBuffer, mLength);
}
delete[] mBuffer;
mBuffer = newbuf;
return PR_TRUE;
}
return PR_FALSE;
}
NS_IMETHODIMP_(PRInt32)
ByteBufferImpl::Fill(nsresult* aErrorCode, nsIInputStream* aStream,
PRUint32 aKeep)
{
NS_PRECONDITION(nsnull != aStream, "null stream");
NS_PRECONDITION(aKeep <= mLength, "illegal keep count");
if ((nsnull == aStream) || (PRUint32(aKeep) > PRUint32(mLength))) {
// whoops
*aErrorCode = NS_BASE_STREAM_ILLEGAL_ARGS;
return -1;
}
if (0 != aKeep) {
// Slide over kept data
nsCRT::memmove(mBuffer, mBuffer + (mLength - aKeep), aKeep);
}
// Read in some new data
mLength = aKeep;
PRUint32 nb;
*aErrorCode = aStream->Read(mBuffer + aKeep, mSpace - aKeep, &nb);
if (NS_SUCCEEDED(*aErrorCode)) {
mLength += nb;
}
else
nb = 0;
return nb;
}
NS_COM nsresult NS_NewByteBuffer(nsIByteBuffer** aInstancePtrResult,
nsISupports* aOuter,
PRUint32 aBufferSize)
{
nsresult rv;
nsIByteBuffer* buf;
rv = ByteBufferImpl::Create(aOuter, nsIByteBuffer::GetIID(), (void**)&buf);
if (NS_FAILED(rv)) return rv;
rv = buf->Init(aBufferSize);
if (NS_FAILED(rv)) {
NS_RELEASE(buf);
return rv;
}
*aInstancePtrResult = buf;
return rv;
}

View File

@@ -1,47 +0,0 @@
/* -*- 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 nsByteBuffer_h__
#define nsByteBuffer_h__
#include "nsIByteBuffer.h"
class ByteBufferImpl : public nsIByteBuffer {
public:
ByteBufferImpl(void);
virtual ~ByteBufferImpl();
NS_DECL_ISUPPORTS
static NS_METHOD
Create(nsISupports *aOuter, REFNSIID aIID, void **aResult);
NS_IMETHOD Init(PRUint32 aBufferSize);
NS_IMETHOD_(PRUint32) GetLength(void) const;
NS_IMETHOD_(PRUint32) GetBufferSize(void) const;
NS_IMETHOD_(char*) GetBuffer() const;
NS_IMETHOD_(PRBool) Grow(PRUint32 aNewSize);
NS_IMETHOD_(PRInt32) Fill(nsresult* aErrorCode, nsIInputStream* aStream,
PRUint32 aKeep);
char* mBuffer;
PRUint32 mSpace;
PRUint32 mLength;
};
#endif // nsByteBuffer_h__

View File

@@ -1,552 +0,0 @@
/* -*- 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.
*/
/**
* MODULE NOTES:
* @update gess7/30/98
*
* Much as I hate to do it, we were using string compares wrong.
* Often, programmers call functions like strcmp(s1,s2), and pass
* one or more null strings. Rather than blow up on these, I've
* added quick checks to ensure that cases like this don't cause
* us to fail.
*
* In general, if you pass a null into any of these string compare
* routines, we simply return 0.
*/
#include "nsCRT.h"
#include "nsUnicharUtilCIID.h"
#include "nsIServiceManager.h"
#include "nsICaseConversion.h"
// XXX Bug: These tables don't lowercase the upper 128 characters properly
// This table maps uppercase characters to lower case characters;
// characters that are neither upper nor lower case are unaffected.
static const unsigned char kUpper2Lower[256] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
64,
// upper band mapped to lower [A-Z] => [a-z]
97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111,
112,113,114,115,116,117,118,119,120,121,122,
91, 92, 93, 94, 95,
96, 97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111,
112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,
128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,
176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,
192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,
208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,
224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,
240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255
};
static const unsigned char kLower2Upper[256] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
96,
// lower band mapped to upper [a-z] => [A-Z]
65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,
123,124,125,126,127,
128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,
176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,
192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,
208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,
224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,
240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255
};
// XXX bug: this doesn't map 0x80 to 0x9f properly
const PRUnichar kIsoLatin1ToUCS2[256] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
96, 97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111,
112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,
128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,
176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,
192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,
208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,
224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,
240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255
};
//----------------------------------------------------------------------
#define TOLOWER(_ucs2) \
(((_ucs2) < 128) ? PRUnichar(kUpper2Lower[_ucs2]) : _ToLower(_ucs2))
#define TOUPPER(_ucs2) \
(((_ucs2) < 128) ? PRUnichar(kLower2Upper[_ucs2]) : _ToUpper(_ucs2))
class HandleCaseConversionShutdown : public nsIShutdownListener {
public :
NS_IMETHOD OnShutdown(const nsCID& cid, nsISupports* service);
HandleCaseConversionShutdown(void) { NS_INIT_REFCNT(); }
virtual ~HandleCaseConversionShutdown(void) {}
NS_DECL_ISUPPORTS
};
static NS_DEFINE_CID(kUnicharUtilCID, NS_UNICHARUTIL_CID);
static NS_DEFINE_IID(kICaseConversionIID, NS_ICASECONVERSION_IID);
static nsICaseConversion * gCaseConv = NULL;
static NS_DEFINE_IID(kIShutdownListenerIID, NS_ISHUTDOWNLISTENER_IID);
NS_IMPL_ISUPPORTS(HandleCaseConversionShutdown, kIShutdownListenerIID);
nsresult
HandleCaseConversionShutdown::OnShutdown(const nsCID& cid,
nsISupports* aService)
{
if (cid.Equals(kUnicharUtilCID)) {
NS_ASSERTION(aService == gCaseConv, "wrong service!");
gCaseConv->Release();
gCaseConv = NULL;
}
return NS_OK;
}
static HandleCaseConversionShutdown* gListener = NULL;
static void StartUpCaseConversion()
{
nsresult err;
if ( NULL == gListener )
{
gListener = new HandleCaseConversionShutdown();
gListener->AddRef();
}
err = nsServiceManager::GetService(kUnicharUtilCID, kICaseConversionIID,
(nsISupports**) &gCaseConv, gListener);
}
static void CheckCaseConversion()
{
if(NULL == gCaseConv )
StartUpCaseConversion();
NS_ASSERTION( gCaseConv != NULL , "cannot obtain UnicharUtil");
}
static PRUnichar _ToLower(PRUnichar aChar)
{
PRUnichar oLower;
CheckCaseConversion();
nsresult err = gCaseConv->ToLower(aChar, &oLower);
NS_ASSERTION( NS_SUCCEEDED(err), "failed to communicate to UnicharUtil");
return ( NS_SUCCEEDED(err) ) ? oLower : aChar ;
}
static PRUnichar _ToUpper(PRUnichar aChar)
{
nsresult err;
PRUnichar oUpper;
CheckCaseConversion();
err = gCaseConv->ToUpper(aChar, &oUpper);
NS_ASSERTION( NS_SUCCEEDED(err), "failed to communicate to UnicharUtil");
return ( NS_SUCCEEDED(err) ) ? oUpper : aChar ;
}
//----------------------------------------------------------------------
PRUnichar nsCRT::ToUpper(PRUnichar aChar)
{
return TOUPPER(aChar);
}
PRUnichar nsCRT::ToLower(PRUnichar aChar)
{
return TOLOWER(aChar);
}
PRBool nsCRT::IsUpper(PRUnichar aChar)
{
return aChar != nsCRT::ToLower(aChar);
}
PRBool nsCRT::IsLower(PRUnichar aChar)
{
return aChar != nsCRT::ToUpper(aChar);
}
////////////////////////////////////////////////////////////////////////////////
// My lovely strtok routine
#define IS_DELIM(m, c) ((m)[(c) >> 3] & (1 << ((c) & 7)))
#define SET_DELIM(m, c) ((m)[(c) >> 3] |= (1 << ((c) & 7)))
#define DELIM_TABLE_SIZE 32
char* nsCRT::strtok(char* string, const char* delims, char* *newStr)
{
NS_ASSERTION(string, "Unlike regular strtok, the first argument cannot be null.");
char delimTable[DELIM_TABLE_SIZE];
PRUint32 i;
char* result;
char* str = string;
for (i = 0; i < DELIM_TABLE_SIZE; i++)
delimTable[i] = '\0';
for (i = 0; i < DELIM_TABLE_SIZE && delims[i]; i++) {
SET_DELIM(delimTable, delims[i]);
}
NS_ASSERTION(delims[i] == '\0', "too many delimiters");
// skip to beginning
while (*str && IS_DELIM(delimTable, *str)) {
str++;
}
result = str;
// fix up the end of the token
while (*str) {
if (IS_DELIM(delimTable, *str)) {
*str++ = '\0';
break;
}
str++;
}
*newStr = str;
return str == result ? NULL : result;
}
////////////////////////////////////////////////////////////////////////////////
PRUint32 nsCRT::strlen(const PRUnichar* s)
{
PRUint32 len = 0;
if(s) {
while (*s++ != 0) {
len++;
}
}
return len;
}
/**
* Compare unichar string ptrs, stopping at the 1st null
* NOTE: If both are null, we return 0.
* @update gess7/30/98
* @param s1 and s2 both point to unichar strings
* @return 0 if they match, -1 if s1<s2; 1 if s1>s2
*/
PRInt32 nsCRT::strcmp(const PRUnichar* s1, const PRUnichar* s2)
{
if(s1 && s2) {
for (;;) {
PRUnichar c1 = *s1++;
PRUnichar c2 = *s2++;
if (c1 != c2) {
if (c1 < c2) return -1;
return 1;
}
if ((0==c1) || (0==c2)) break;
}
}
return 0;
}
/**
* Compare unichar string ptrs, stopping at the 1st null or nth char.
* NOTE: If either is null, we return 0.
* @update gess7/30/98
* @param s1 and s2 both point to unichar strings
* @return 0 if they match, -1 if s1<s2; 1 if s1>s2
*/
PRInt32 nsCRT::strncmp(const PRUnichar* s1, const PRUnichar* s2, PRUint32 n)
{
if(s1 && s2) {
if(n != 0) {
do {
PRUnichar c1 = *s1++;
PRUnichar c2 = *s2++;
if (c1 != c2) {
if (c1 < c2) return -1;
return 1;
}
if ((0==c1) || (0==c2)) break;
} while (--n != 0);
}
}
return 0;
}
/**
* Compare unichar string ptrs without regard to case
* NOTE: If both are null, we return 0.
* @update gess7/30/98
* @param s1 and s2 both point to unichar strings
* @return 0 if they match, -1 if s1<s2; 1 if s1>s2
*/
PRInt32 nsCRT::strcasecmp(const PRUnichar* s1, const PRUnichar* s2)
{
if(s1 && s2) {
for (;;) {
PRUnichar c1 = *s1++;
PRUnichar c2 = *s2++;
if (c1 != c2) {
c1 = TOLOWER(c1);
c2 = TOLOWER(c2);
if (c1 != c2) {
if (c1 < c2) return -1;
return 1;
}
}
if ((0==c1) || (0==c2)) break;
}
}
return 0;
}
/**
* Compare unichar string ptrs, stopping at the 1st null or nth char;
* also ignoring the case of characters.
* NOTE: If both are null, we return 0.
* @update gess7/30/98
* @param s1 and s2 both point to unichar strings
* @return 0 if they match, -1 if s1<s2; 1 if s1>s2
*/
PRInt32 nsCRT::strncasecmp(const PRUnichar* s1, const PRUnichar* s2, PRUint32 n)
{
if(s1 && s2) {
if(n != 0){
do {
PRUnichar c1 = *s1++;
PRUnichar c2 = *s2++;
if (c1 != c2) {
c1 = TOLOWER(c1);
c2 = TOLOWER(c2);
if (c1 != c2) {
if (c1 < c2) return -1;
return 1;
}
}
if ((0==c1) || (0==c2)) break;
} while (--n != 0);
}
}
return 0;
}
/**
* Compare a unichar string ptr to cstring.
* NOTE: If both are null, we return 0.
* @update gess7/30/98
* @param s1 points to unichar string
* @param s2 points to cstring
* @return 0 if they match, -1 if s1<s2; 1 if s1>s2
*/
PRInt32 nsCRT::strcmp(const PRUnichar* s1, const char* s2)
{
if(s1 && s2) {
for (;;) {
PRUnichar c1 = *s1++;
PRUnichar c2 = kIsoLatin1ToUCS2[*(const unsigned char*)s2++];
if (c1 != c2) {
if (c1 < c2) return -1;
return 1;
}
if ((0==c1) || (0==c2)) break;
}
}
return 0;
}
/**
* Compare a unichar string ptr to cstring, up to N chars.
* NOTE: If both are null, we return 0.
* @update gess7/30/98
* @param s1 points to unichar string
* @param s2 points to cstring
* @return 0 if they match, -1 if s1<s2; 1 if s1>s2
*/
PRInt32 nsCRT::strncmp(const PRUnichar* s1, const char* s2, PRUint32 n)
{
if(s1 && s2) {
if(n != 0){
do {
PRUnichar c1 = *s1++;
PRUnichar c2 = kIsoLatin1ToUCS2[*(const unsigned char*)s2++];
if (c1 != c2) {
if (c1 < c2) return -1;
return 1;
}
if ((0==c1) || (0==c2)) break;
} while (--n != 0);
}
}
return 0;
}
/**
* Compare a unichar string ptr to cstring without regard to case
* NOTE: If both are null, we return 0.
* @update gess7/30/98
* @param s1 points to unichar string
* @param s2 points to cstring
* @return 0 if they match, -1 if s1<s2; 1 if s1>s2
*/
PRInt32 nsCRT::strcasecmp(const PRUnichar* s1, const char* s2)
{
if(s1 && s2) {
for (;;) {
PRUnichar c1 = *s1++;
PRUnichar c2 = kIsoLatin1ToUCS2[*(const unsigned char*)s2++];
if (c1 != c2) {
c1 = TOLOWER(c1);
c2 = TOLOWER(c2);
if (c1 != c2) {
if (c1 < c2) return -1;
return 1;
}
}
if ((0==c1) || (0==c2)) break;
}
}
return 0;
}
/**
* Caseless compare up to N chars between unichar string ptr to cstring.
* NOTE: If both are null, we return 0.
* @update gess7/30/98
* @param s1 points to unichar string
* @param s2 points to cstring
* @return 0 if they match, -1 if s1<s2; 1 if s1>s2
*/
PRInt32 nsCRT::strncasecmp(const PRUnichar* s1, const char* s2, PRUint32 n)
{
if(s1 && s2){
if(n != 0){
do {
PRUnichar c1 = *s1++;
PRUnichar c2 = kIsoLatin1ToUCS2[*(const unsigned char*)s2++];
if (c1 != c2) {
c1 = TOLOWER(c1);
c2 = TOLOWER(c2);
if (c1 != c2) {
if (c1 < c2) return -1;
return 1;
}
}
if (c1 == 0) break;
} while (--n != 0);
}
}
return 0;
}
PRUnichar* nsCRT::strdup(const PRUnichar* str)
{
PRUint32 len = nsCRT::strlen(str) + 1; // add one for null
PRUnichar* rslt = new PRUnichar[len];
if (rslt == NULL) return NULL;
nsCRT::memcpy(rslt, str, len * sizeof(PRUnichar));
return rslt;
}
PRUint32 nsCRT::HashValue(const char* us)
{
PRUint32 rv = 0;
if(us) {
char ch;
while ((ch = *us++) != 0) {
// FYI: rv = rv*37 + ch
rv = ((rv << 5) + (rv << 2) + rv) + ch;
}
}
return rv;
}
PRUint32 nsCRT::HashValue(const char* us, PRUint32* uslenp)
{
PRUint32 rv = 0;
PRUint32 len = 0;
char ch;
while ((ch = *us++) != 0) {
// FYI: rv = rv*37 + ch
rv = ((rv << 5) + (rv << 2) + rv) + ch;
len++;
}
*uslenp = len;
return rv;
}
PRUint32 nsCRT::HashValue(const PRUnichar* us)
{
PRUint32 rv = 0;
if(us) {
PRUnichar ch;
while ((ch = *us++) != 0) {
// FYI: rv = rv*37 + ch
rv = ((rv << 5) + (rv << 2) + rv) + ch;
}
}
return rv;
}
PRUint32 nsCRT::HashValue(const PRUnichar* us, PRUint32* uslenp)
{
PRUint32 rv = 0;
PRUint32 len = 0;
PRUnichar ch;
while ((ch = *us++) != 0) {
// FYI: rv = rv*37 + ch
rv = ((rv << 5) + (rv << 2) + rv) + ch;
len++;
}
*uslenp = len;
return rv;
}
PRInt32 nsCRT::atoi( const PRUnichar *string )
{
return atoi(string);
}

View File

@@ -1,231 +0,0 @@
/* -*- 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 nsCRT_h___
#define nsCRT_h___
#include <stdlib.h>
#include <string.h>
#include "plstr.h"
#include "nscore.h"
#include "prtypes.h"
#define CR '\015'
#define LF '\012'
#define VTAB '\013'
#define FF '\014'
#define TAB '\011'
#define CRLF "\015\012" /* A CR LF equivalent string */
#ifdef XP_MAC
# define NS_LINEBREAK "\015"
# define NS_LINEBREAK_LEN 1
#else
# ifdef XP_PC
# define NS_LINEBREAK "\015\012"
# define NS_LINEBREAK_LEN 2
# else
# if defined(XP_UNIX) || defined(XP_BEOS)
# define NS_LINEBREAK "\012"
# define NS_LINEBREAK_LEN 1
# endif /* XP_UNIX */
# endif /* XP_PC */
#endif /* XP_MAC */
extern const PRUnichar kIsoLatin1ToUCS2[256];
// This macro can be used in a class declaration for classes that want
// to ensure that their instance memory is zeroed.
#define NS_DECL_AND_IMPL_ZEROING_OPERATOR_NEW \
void* operator new(size_t sz) { \
void* rv = ::operator new(sz); \
if (rv) { \
nsCRT::zero(rv, sz); \
} \
return rv; \
} \
void operator delete(void* ptr) { \
::operator delete(ptr); \
}
// This macro works with the next macro to declare a non-inlined
// version of the above.
#define NS_DECL_ZEROING_OPERATOR_NEW \
void* operator new(size_t sz); \
void operator delete(void* ptr);
#define NS_IMPL_ZEROING_OPERATOR_NEW(_class) \
void* _class::operator new(size_t sz) { \
void* rv = ::operator new(sz); \
if (rv) { \
nsCRT::zero(rv, sz); \
} \
return rv; \
} \
void _class::operator delete(void* ptr) { \
::operator delete(ptr); \
}
/// This is a wrapper class around all the C runtime functions.
class NS_COM nsCRT {
public:
/** Copy bytes from aSrc to aDest.
@param aDest the destination address
@param aSrc the source address
@param aCount the number of bytes to copy
*/
static void memcpy(void* aDest, const void* aSrc, PRUint32 aCount) {
::memcpy(aDest, aSrc, (size_t)aCount);
}
static void memmove(void* aDest, const void* aSrc, PRUint32 aCount) {
::memmove(aDest, aSrc, (size_t)aCount);
}
static void memset(void* aDest, PRUint8 aByte, PRUint32 aCount) {
::memset(aDest, aByte, aCount);
}
static void zero(void* aDest, PRUint32 aCount) {
::memset(aDest, 0, (size_t)aCount);
}
/** Compute the string length of s
@param s the string in question
@return the length of s
*/
static PRUint32 strlen(const char* s) {
return PRUint32(::strlen(s));
}
/// Compare s1 and s2.
static PRInt32 strcmp(const char* s1, const char* s2) {
return PRUint32(PL_strcmp(s1, s2));
}
static PRInt32 strncmp(const char* s1, const char* s2,
PRUint32 aMaxLen) {
return PRInt32(PL_strncmp(s1, s2, aMaxLen));
}
/// Case-insensitive string comparison.
static PRInt32 strcasecmp(const char* s1, const char* s2) {
return PRInt32(PL_strcasecmp(s1, s2));
}
/// Case-insensitive string comparison with length
static PRInt32 strncasecmp(const char* s1, const char* s2, PRUint32 aMaxLen) {
return PRInt32(PL_strncasecmp(s1, s2, aMaxLen));
}
static PRInt32 strncmp(const char* s1, const char* s2, PRInt32 aMaxLen) {
return PRInt32(PL_strncmp(s1,s2,aMaxLen));
}
static char* strdup(const char* str) {
return PL_strdup(str);
}
static void free(char* str) {
PL_strfree(str);
}
/**
How to use this fancy (thread-safe) version of strtok:
void main( void ) {
printf( "%s\n\nTokens:\n", string );
// Establish string and get the first token:
char* newStr;
token = nsCRT::strtok( string, seps, &newStr );
while( token != NULL ) {
// While there are tokens in "string"
printf( " %s\n", token );
// Get next token:
token = nsCRT::strtok( newStr, seps, &newStr );
}
}
* WARNING - STRTOK WHACKS str THE FIRST TIME IT IS CALLED *
* MAKE A COPY OF str IF YOU NEED TO USE IT AFTER strtok() *
*/
static char* strtok(char* str, const char* delims, char* *newStr);
/// Like strlen except for ucs2 strings
static PRUint32 strlen(const PRUnichar* s);
/// Like strcmp except for ucs2 strings
static PRInt32 strcmp(const PRUnichar* s1, const PRUnichar* s2);
/// Like strcmp except for ucs2 strings
static PRInt32 strncmp(const PRUnichar* s1, const PRUnichar* s2,
PRUint32 aMaxLen);
/// Like strcasecmp except for ucs2 strings
static PRInt32 strcasecmp(const PRUnichar* s1, const PRUnichar* s2);
/// Like strncasecmp except for ucs2 strings
static PRInt32 strncasecmp(const PRUnichar* s1, const PRUnichar* s2,
PRUint32 aMaxLen);
/// Like strcmp with a char* and a ucs2 string
static PRInt32 strcmp(const PRUnichar* s1, const char* s2);
/// Like strncmp with a char* and a ucs2 string
static PRInt32 strncmp(const PRUnichar* s1, const char* s2,
PRUint32 aMaxLen);
/// Like strcasecmp with a char* and a ucs2 string
static PRInt32 strcasecmp(const PRUnichar* s1, const char* s2);
/// Like strncasecmp with a char* and a ucs2 string
static PRInt32 strncasecmp(const PRUnichar* s1, const char* s2,
PRUint32 aMaxLen);
// Note: uses new[] to allocate memory, so you must use delete[] to
// free the memory
static PRUnichar* strdup(const PRUnichar* str);
static void free(PRUnichar* str) {
delete[] str;
}
/// Compute a hashcode for a C string
static PRUint32 HashValue(const char* s1);
/// Same as above except that we return the length in s1len
static PRUint32 HashValue(const char* s1, PRUint32* s1len);
/// Compute a hashcode for a ucs2 string
static PRUint32 HashValue(const PRUnichar* s1);
/// Same as above except that we return the length in s1len
static PRUint32 HashValue(const PRUnichar* s1, PRUint32* s1len);
/// String to integer.
static PRInt32 atoi( const PRUnichar *string );
static PRUnichar ToUpper(PRUnichar aChar);
static PRUnichar ToLower(PRUnichar aChar);
static PRBool IsUpper(PRUnichar aChar);
static PRBool IsLower(PRUnichar aChar);
};
#endif /* nsCRT_h___ */

View File

@@ -1,392 +0,0 @@
/* -*- 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(nsCOMTypeInfo<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

@@ -1,569 +0,0 @@
/* -*- 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 "nsDeque.h"
#include "nsCRT.h"
//#define _SELFTEST_DEQUE 1
#undef _SELFTEST_DEQUE
/**
* Standard constructor
* @update gess4/18/98
* @return new deque
*/
nsDeque::nsDeque(nsDequeFunctor* aDeallocator) {
mDeallocator=aDeallocator;
mCapacity=eGrowthDelta;
mOrigin=mSize=0;
mData=new void*[mCapacity];
}
/**
* Destructor
* @update gess4/18/98
*/
nsDeque::~nsDeque() {
Erase();
delete [] mData;
mData=0;
if(mDeallocator) {
delete mDeallocator;
}
mDeallocator=0;
}
/**
* Returns the number of elements currently stored in
* this deque.
*
* @update gess4/18/98
* @param
* @return int contains element count
*/
PRInt32 nsDeque::GetSize(void) const {
return mSize;
}
void nsDeque::SetDeallocator(nsDequeFunctor* aDeallocator){
if(mDeallocator) {
delete mDeallocator;
}
mDeallocator=aDeallocator;
}
/**
* Remove all items from container without destroying them.
*
* @update gess4/18/98
* @param
* @return
*/
nsDeque& nsDeque::Empty() {
if((0<mCapacity) && (mData)) {
nsCRT::zero(mData,mCapacity*sizeof(mData));
}
mSize=0;
mOrigin=0;
return *this;
}
/**
* Remove and delete all items from container
*
* @update gess4/18/98
* @return this
*/
nsDeque& nsDeque::Erase() {
if(mDeallocator) {
ForEach(*mDeallocator);
}
return Empty();
}
/**
* This method adds an item to the end of the deque.
* This operation has the potential to cause the
* underlying buffer to resize.
*
* @update gess4/18/98
* @param anItem: new item to be added to deque
* @return nada
*/
nsDeque& nsDeque::GrowCapacity(void) {
void** temp=new void*[mCapacity+eGrowthDelta];
//Here's the interesting part: You can't just move the elements
//directy (in situ) from the old buffer to the new one.
//Since capacity has changed, the old origin doesn't make
//sense anymore. It's better to resequence the elements now.
int tempi=0;
int i=0;
int j=0;
for(i=mOrigin;i<mCapacity;i++) temp[tempi++]=mData[i]; //copy the leading elements...
for(j=0;j<mOrigin;j++) temp[tempi++]=mData[j]; //copy the trailing elements...
mCapacity+=eGrowthDelta;
mOrigin=0; //now realign the origin...
delete[]mData;
mData=temp;
return *this;
}
/**
* This method adds an item to the end of the deque.
* This operation has the potential to cause the
* underlying buffer to resize.
*
* @update gess4/18/98
* @param anItem: new item to be added to deque
* @return nada
*/
nsDeque& nsDeque::Push(void* anItem) {
if(mSize==mCapacity) {
GrowCapacity();
}
int offset=mOrigin+mSize;
if(offset<mCapacity)
mData[offset]=anItem;
else mData[offset-mCapacity]=anItem;
mSize++;
return *this;
}
/**
* This method adds an item to the front of the deque.
* This operation has the potential to cause the
* underlying buffer to resize.
*
* @update gess4/18/98
* @param anItem: new item to be added to deque
* @return nada
*/
nsDeque& nsDeque::PushFront(void* anItem) {
if(mSize==mCapacity) {
GrowCapacity();
}
if(0==mOrigin){ //case1: [xxx..]
//mOrigin=mCapacity-1-mSize++;
mOrigin=mCapacity-1;
mData[mOrigin]=anItem;
}
else {// if(mCapacity==(mOrigin+mSize-1)){ //case2: [..xxx] and case3: [.xxx.]
mData[--mOrigin]=anItem;
}
mSize++;
return *this;
}
/**
* Remove and return the last item in the container.
*
* @update gess4/18/98
* @param none
* @return ptr to last item in container
*/
void* nsDeque::Pop(void) {
void* result=0;
if(mSize>0) {
int offset=mOrigin+mSize-1;
if(offset>=mCapacity)
offset-=mCapacity;
result=mData[offset];
mData[offset]=0;
mSize--;
if(0==mSize)
mOrigin=0;
}
return result;
}
/**
* This method gets called you want to remove and return
* the first member in the container.
*
* @update gess4/18/98
* @param nada
* @return last item in container
*/
void* nsDeque::PopFront() {
void* result=0;
if(mSize>0) {
result=mData[mOrigin];
mData[mOrigin++]=0; //zero it out for debugging purposes.
mSize--;
if(mCapacity==mOrigin) //you popped off the end, so cycle back around...
mOrigin=0;
if(0==mSize)
mOrigin=0;
}
NS_ASSERTION(mOrigin<mCapacity,"Error: Bad origin");
return result;
}
/**
* This method gets called you want to peek at the topmost
* member without removing it.
*
* @update gess4/18/98
* @param nada
* @return last item in container
*/
void* nsDeque::Peek() {
void* result=0;
if(mSize>0) {
result=mData[mOrigin];
}
return result;
}
/**
* Call this to retrieve the ith element from this container.
* Keep in mind that accessing the underlying elements is
* done in a relative fashion. Object 0 is not necessarily
* the first element (the first element is at mOrigin).
*
* @update gess4/18/98
* @param anIndex : 0 relative offset of item you want
* @return void* or null
*/
void* nsDeque::ObjectAt(PRInt32 anIndex) const {
void* result=0;
if((anIndex>=0) && (anIndex<mSize))
{
if(anIndex<(mCapacity-mOrigin)) {
result=mData[mOrigin+anIndex];
}
else {
result=mData[anIndex-(mCapacity-mOrigin)];
}
}
return result;
}
/**
* Create and return an iterator pointing to
* the beginning of the queue. Note that this
* takes the circular buffer semantics into account.
*
* @update gess4/18/98
* @return new deque iterator, init'ed to 1st item
*/
nsDequeIterator nsDeque::Begin(void) const{
return nsDequeIterator(*this,0);
}
/**
* Create and return an iterator pointing to
* the last of the queue. Note that this
* takes the circular buffer semantics into account.
*
* @update gess4/18/98
* @return new deque iterator, init'ed to last item
*/
nsDequeIterator nsDeque::End(void) const{
return nsDequeIterator(*this,mSize);
}
/**
* Call this method when you wanto to iterate all the
* members of the container, passing a functor along
* to call your code.
*
* @update gess4/20/98
* @param aFunctor object to call for each member
* @return *this
*/
void nsDeque::ForEach(nsDequeFunctor& aFunctor) const{
int i=0;
for(i=0;i<mSize;i++){
void* obj=ObjectAt(i);
obj=aFunctor(obj);
}
}
/**
* Call this method when you wanto to iterate all the
* members of the container, passing a functor along
* to call your code. Iteration continues until your
* functor returns a non-null.
*
* @update gess4/20/98
* @param aFunctor object to call for each member
* @return *this
*/
const void* nsDeque::FirstThat(nsDequeFunctor& aFunctor) const{
int i=0;
for(i=0;i<mSize;i++){
void* obj=ObjectAt(i);
obj=aFunctor(obj);
if(obj)
return obj;
}
return 0;
}
/******************************************************
* Here comes the nsDequeIterator class...
******************************************************/
/**
* DequeIterator is an object that knows how to iterate (forward and backward)
* a Deque. Normally, you don't need to do this, but there are some special
* cases where it is pretty handy, so here you go.
*
* This is a standard dequeiterator constructor
*
* @update gess4/18/98
* @param aQueue is the deque object to be iterated
* @param anIndex is the starting position for your iteration
*/
nsDequeIterator::nsDequeIterator(const nsDeque& aQueue,int anIndex): mIndex(anIndex), mDeque(aQueue) {
}
/**
* Copy construct a new iterator beginning with given
*
* @update gess4/20/98
* @param aCopy is another iterator to copy from
* @return
*/
nsDequeIterator::nsDequeIterator(const nsDequeIterator& aCopy) : mIndex(aCopy.mIndex), mDeque(aCopy.mDeque) {
}
/**
* Moves iterator to first element in deque
* @update gess4/18/98
* @return this
*/
nsDequeIterator& nsDequeIterator::First(void){
mIndex=0;
return *this;
}
/**
* Standard assignment operator for dequeiterator
*
* @update gess4/18/98
* @param aCopy is an iterator to be copied from
* @return *this
*/
nsDequeIterator& nsDequeIterator::operator=(const nsDequeIterator& aCopy) {
//queue's are already equal.
mIndex=aCopy.mIndex;
return *this;
}
/**
* preform ! operation against to iterators to test for equivalence
* (or lack thereof)!
*
* @update gess4/18/98
* @param anIter is the object to be compared to
* @return TRUE if NOT equal.
*/
PRBool nsDequeIterator::operator!=(nsDequeIterator& anIter) {
return PRBool(!this->operator==(anIter));
}
/**
* Compare 2 iterators for equivalence.
*
* @update gess4/18/98
* @param anIter is the other iterator to be compared to
* @return TRUE if EQUAL
*/
PRBool nsDequeIterator::operator<(nsDequeIterator& anIter) {
return PRBool(((mIndex<anIter.mIndex) && (&mDeque==&anIter.mDeque)));
}
/**
* Compare 2 iterators for equivalence.
*
* @update gess4/18/98
* @param anIter is the other iterator to be compared to
* @return TRUE if EQUAL
*/
PRBool nsDequeIterator::operator==(nsDequeIterator& anIter) {
return PRBool(((mIndex==anIter.mIndex) && (&mDeque==&anIter.mDeque)));
}
/**
* Compare 2 iterators for equivalence.
*
* @update gess4/18/98
* @param anIter is the other iterator to be compared to
* @return TRUE if EQUAL
*/
PRBool nsDequeIterator::operator>=(nsDequeIterator& anIter) {
return PRBool(((mIndex>=anIter.mIndex) && (&mDeque==&anIter.mDeque)));
}
/**
* Pre-increment operator
*
* @update gess4/18/98
* @return object at preincremented index
*/
void* nsDequeIterator::operator++() {
return mDeque.ObjectAt(++mIndex);
}
/**
* Post-increment operator
*
* @update gess4/18/98
* @param param is ignored
* @return object at post-incremented index
*/
void* nsDequeIterator::operator++(int) {
return mDeque.ObjectAt(mIndex++);
}
/**
* Pre-decrement operator
*
* @update gess4/18/98
* @return object at pre-decremented index
*/
void* nsDequeIterator::operator--() {
return mDeque.ObjectAt(--mIndex);
}
/**
* Post-decrement operator
*
* @update gess4/18/98
* @param param is ignored
* @return object at post-decremented index
*/
void* nsDequeIterator::operator--(int) {
return mDeque.ObjectAt(mIndex--);
}
/**
* Dereference operator
*
* @update gess4/18/98
* @return object at ith index
*/
void* nsDequeIterator::GetCurrent(void) {
return mDeque.ObjectAt(mIndex);
}
/**
* Call this method when you wanto to iterate all the
* members of the container, passing a functor along
* to call your code.
*
* @update gess4/20/98
* @param aFunctor object to call for each member
* @return *this
*/
void nsDequeIterator::ForEach(nsDequeFunctor& aFunctor) const{
mDeque.ForEach(aFunctor);
}
/**
* Call this method when you wanto to iterate all the
* members of the container, passing a functor along
* to call your code.
*
* @update gess4/20/98
* @param aFunctor object to call for each member
* @return *this
*/
const void* nsDequeIterator::FirstThat(nsDequeFunctor& aFunctor) const{
return mDeque.FirstThat(aFunctor);
}
#ifdef _SELFTEST_DEQUE
/**************************************************************
Now define the token deallocator class...
**************************************************************/
class _SelfTestDeallocator: public nsDequeFunctor{
public:
_SelfTestDeallocator::_SelfTestDeallocator() {
nsDeque::SelfTest();
}
virtual void* operator()(void* anObject) {
return 0;
}
};
static _SelfTestDeallocator gDeallocator;
#endif
/**
* conduct automated self test for this class
*
* @update gess4/18/98
* @param
* @return
*/
void nsDeque::SelfTest(void) {
#ifdef _SELFTEST_DEQUE
{
nsDeque theDeque(gDeallocator); //construct a simple one...
int ints[200];
int count=sizeof(ints)/sizeof(int);
int i=0;
for(i=0;i<count;i++){ //initialize'em
ints[i]=10*(1+i);
}
for(i=0;i<70;i++){
theDeque.Push(&ints[i]);
}
for(i=0;i<56;i++){
int* temp=(int*)theDeque.Pop();
}
for(i=0;i<55;i++){
theDeque.Push(&ints[i]);
}
for(i=0;i<35;i++){
int* temp=(int*)theDeque.Pop();
}
for(i=0;i<35;i++){
theDeque.Push(&ints[i]);
}
for(i=0;i<38;i++){
int* temp=(int*)theDeque.Pop();
}
}
int x;
x=10;
#endif
}

View File

@@ -1,411 +0,0 @@
/* -*- 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.
*/
/**
* MODULE NOTES:
* @update gess 4/15/98 (tax day)
*
* The Deque is a very small, very efficient container object
* than can hold elements of type void*, offering the following features:
* It's interface supports pushing and poping of children.
* It can iterate (via an interator class) it's children.
* When full, it can efficently resize dynamically.
*
*
* NOTE: The only bit of trickery here is that this deque is
* built upon a ring-buffer. Like all ring buffers, the first
* element may not be at index[0]. The mOrigin member determines
* where the first child is. This point is quietly hidden from
* customers of this class.
*
*/
#ifndef _NSDEQUE
#define _NSDEQUE
#include "nscore.h"
/**
* The nsDequefunctor class is used when you want to create
* callbacks between the deque and your generic code.
* Use these objects in a call to ForEach();
*
* @update gess4/20/98
*/
class NS_COM nsDequeFunctor{
public:
virtual void* operator()(void* anObject)=0;
};
/******************************************************
* Here comes the nsDeque class itself...
******************************************************/
/**
* The deque (double-ended queue) class is a common container type,
* whose behavior mimics a line in your favorite checkout stand.
* Classic CS describes the common behavior of a queue as FIFO.
* A Deque allows items to be added and removed from either end of
* the queue.
*
* @update gess4/20/98
*/
class NS_COM nsDeque {
friend class nsDequeIterator;
public:
nsDeque(nsDequeFunctor* aDeallocator);
~nsDeque();
/**
* Returns the number of elements currently stored in
* this deque.
*
* @update gess4/18/98
* @param
* @return int contains element count
*/
PRInt32 GetSize() const;
/**
* Pushes new member onto the end of the deque
*
* @update gess4/18/98
* @param ptr to object to store
* @return *this
*/
nsDeque& Push(void* anItem);
/**
* Pushes new member onto the front of the deque
*
* @update gess4/18/98
* @param ptr to object to store
* @return *this
*/
nsDeque& PushFront(void* anItem);
/**
* Remove and return the first item in the container.
*
* @update gess4/18/98
* @param none
* @return ptr to first item in container
*/
void* Pop(void);
/**
* Remove and return the first item in the container.
*
* @update gess4/18/98
* @param none
* @return ptr to first item in container
*/
void* PopFront(void);
/**
* Return topmost item without removing it.
*
* @update gess4/18/98
* @param none
* @return ptr to first item in container
*/
void* Peek(void);
/**
* method used to retrieve ptr to
* ith member in container. DOesn't remove
* that item.
*
* @update gess4/18/98
* @param index of desired item
* @return ptr to ith element in list
*/
void* ObjectAt(int anIndex) const;
/**
* Remove all items from container without destroying them
*
* @update gess4/18/98
* @param
* @return
*/
nsDeque& Empty();
/**
* Remove and delete all items from container
*
* @update gess4/18/98
* @param
* @return
*/
nsDeque& Erase();
/**
* Creates a new iterator, init'ed to start of container
*
* @update gess4/18/98
* @return new dequeIterator
*/
nsDequeIterator Begin() const;
/**
* Creates a new iterator, init'ed to end of container
*
* @update gess4/18/98
* @return new dequeIterator
*/
nsDequeIterator End() const;
/**
* Call this method when you wanto to iterate all the
* members of the container, passing a functor along
* to call your code.
*
* @update gess4/20/98
* @param aFunctor object to call for each member
* @return *this
*/
void ForEach(nsDequeFunctor& aFunctor) const;
/**
* Call this method when you wanto to iterate all the
* members of the container, passing a functor along
* to call your code. This process will interupt if
* your function returns a null to this iterator.
*
* @update gess4/20/98
* @param aFunctor object to call for each member
* @return *this
*/
const void* FirstThat(nsDequeFunctor& aFunctor) const;
void SetDeallocator(nsDequeFunctor* aDeallocator);
/**
* Perform automated selftest on the deque
*
* @update gess4/18/98
* @param
* @return
*/
static void SelfTest();
protected:
PRInt32 mSize;
PRInt32 mCapacity;
PRInt32 mOrigin;
nsDequeFunctor* mDeallocator;
void** mData;
private:
enum {eGrowthDelta=64};
/**
* Simple default constructor (PRIVATE)
*
* @update gess4/18/98
* @param
* @return
*/
nsDeque();
/**
* Copy constructor (PRIVATE)
*
* @update gess4/18/98
* @param
* @return
*/
nsDeque(const nsDeque& other);
/**
* Deque assignment operator (PRIVATE)
*
* @update gess4/18/98
* @param another deque
* @return *this
*/
nsDeque& operator=(const nsDeque& anOther);
nsDeque& GrowCapacity(void);
};
/******************************************************
* Here comes the nsDequeIterator class...
******************************************************/
class NS_COM nsDequeIterator {
public:
/**
* DequeIterator is an object that knows how to iterate (forward and backward)
* a Deque. Normally, you don't need to do this, but there are some special
* cases where it is pretty handy, so here you go.
*
* @update gess4/18/98
* @param aQueue is the deque object to be iterated
* @param anIndex is the starting position for your iteration
*/
nsDequeIterator(const nsDeque& aQueue,int anIndex=0);
/**
* DequeIterator is an object that knows how to iterate (forward and backward)
* a Deque. Normally, you don't need to do this, but there are some special
* cases where it is pretty handy, so here you go.
*
* @update gess4/18/98
* @param aQueue is the deque object to be iterated
* @param anIndex is the starting position for your iteration
*/
nsDequeIterator(const nsDequeIterator& aCopy);
/**
* Moves iterator to first element in deque
* @update gess4/18/98
* @return this
*/
nsDequeIterator& First(void);
/**
* Standard assignment operator for deque
* @update gess4/18/98
* @param
* @return
*/
nsDequeIterator& operator=(const nsDequeIterator& aCopy);
/**
* preform ! operation against to iterators to test for equivalence
* (or lack thereof)!
*
* @update gess4/18/98
* @param anIter is the object to be compared to
* @return TRUE if NOT equal.
*/
PRBool operator!=(nsDequeIterator& anIter);
/**
* Compare 2 iterators for equivalence.
*
* @update gess4/18/98
* @param anIter is the other iterator to be compared to
* @return TRUE if EQUAL
*/
PRBool operator<(nsDequeIterator& anIter);
/**
* Compare 2 iterators for equivalence.
*
* @update gess4/18/98
* @param anIter is the other iterator to be compared to
* @return TRUE if EQUAL
*/
PRBool operator==(nsDequeIterator& anIter);
/**
* Compare 2 iterators for equivalence.
*
* @update gess4/18/98
* @param anIter is the other iterator to be compared to
* @return TRUE if EQUAL
*/
PRBool operator>=(nsDequeIterator& anIter);
/**
* Pre-increment operator
*
* @update gess4/18/98
* @return object at preincremented index
*/
void* operator++();
/**
* Post-increment operator
*
* @update gess4/18/98
* @param param is ignored
* @return object at post-incremented index
*/
void* operator++(int);
/**
* Pre-decrement operator
*
* @update gess4/18/98
* @return object at pre-decremented index
*/
void* operator--();
/**
* Post-decrement operator
*
* @update gess4/18/98
* @param param is ignored
* @return object at post-decremented index
*/
void* operator--(int);
/**
* Retrieve the ptr to the iterators notion of current node
*
* @update gess4/18/98
* @return object at ith index
*/
void* GetCurrent(void);
/**
* Call this method when you wanto to iterate all the
* members of the container, passing a functor along
* to call your code.
*
* @update gess4/20/98
* @param aFunctor object to call for each member
* @return *this
*/
void ForEach(nsDequeFunctor& aFunctor) const;
/**
* Call this method when you wanto to iterate all the
* members of the container, passing a functor along
* to call your code.
*
* @update gess4/20/98
* @param aFunctor object to call for each member
* @return *this
*/
const void* FirstThat(nsDequeFunctor& aFunctor) const;
protected:
PRInt32 mIndex;
const nsDeque& mDeque;
};
#endif

View File

@@ -1,77 +0,0 @@
/* -*- 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

@@ -1,228 +0,0 @@
/* -*- 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;
PRUint32 cnt;
nsresult rv = mValueArray->Count(&cnt);
if (NS_FAILED(rv)) return rv;
*aResult = (mIndex < (PRInt32) cnt);
return NS_OK;
}
NS_IMETHODIMP
nsArrayEnumerator::GetNext(nsISupports** aResult)
{
NS_PRECONDITION(aResult != 0, "null ptr");
if (! aResult)
return NS_ERROR_NULL_POINTER;
PRUint32 cnt;
nsresult rv = mValueArray->Count(&cnt);
if (NS_FAILED(rv)) return rv;
if (mIndex >= (PRInt32) cnt)
return NS_ERROR_UNEXPECTED;
*aResult = mValueArray->ElementAt(mIndex++);
return NS_OK;
}
extern "C" NS_COM nsresult
NS_NewArrayEnumerator(nsISimpleEnumerator* *result,
nsISupportsArray* array)
{
nsArrayEnumerator* enumer = new nsArrayEnumerator(array);
if (enumer == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(enumer);
*result = enumer;
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;
}
extern "C" NS_COM nsresult
NS_NewSingletonEnumerator(nsISimpleEnumerator* *result,
nsISupports* singleton)
{
nsSingletonEnumerator* enumer = new nsSingletonEnumerator(singleton);
if (enumer == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(enumer);
*result = enumer;
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;
}
extern "C" NS_COM nsresult
NS_NewAdapterEnumerator(nsISimpleEnumerator* *result,
nsIEnumerator* enumerator)
{
nsAdapterEnumerator* enumer = new nsAdapterEnumerator(enumerator);
if (enumer == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(enumer);
*result = enumer;
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////

View File

@@ -1,97 +0,0 @@
/* -*- 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 nsEnumeratorUtils_h__
#define nsEnumeratorUtils_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;
};
extern "C" NS_COM nsresult
NS_NewArrayEnumerator(nsISimpleEnumerator* *result,
nsISupportsArray* array);
////////////////////////////////////////////////////////////////////////////////
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;
};
extern "C" NS_COM nsresult
NS_NewSingletonEnumerator(nsISimpleEnumerator* *result,
nsISupports* singleton);
////////////////////////////////////////////////////////////////////////////////
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;
};
extern "C" NS_COM nsresult
NS_NewAdapterEnumerator(nsISimpleEnumerator* *result,
nsIEnumerator* enumerator);
////////////////////////////////////////////////////////////////////////
#endif /* nsEnumeratorUtils_h__ */

View File

@@ -1,259 +0,0 @@
/* -*- 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

@@ -1,168 +0,0 @@
/* -*- 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

@@ -1,67 +0,0 @@
/* -*- 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 nsIArena_h___
#define nsIArena_h___
#include "nscore.h"
#include "nsISupports.h"
#define NS_MIN_ARENA_BLOCK_SIZE 64
#define NS_DEFAULT_ARENA_BLOCK_SIZE 4096
/// Interface IID for nsIArena
#define NS_IARENA_IID \
{ 0xa24fdad0, 0x93b4, 0x11d1, \
{0x89, 0x5b, 0x00, 0x60, 0x08, 0x91, 0x1b, 0x81} }
#define NS_ARENA_PROGID "component://netscape/arena"
#define NS_ARENA_CLASSNAME "Arena"
/** Interface to a memory arena abstraction. Arena's use large blocks
* of memory to allocate smaller objects. Arena's provide no free
* operator; instead, all of the objects in the arena are deallocated
* by deallocating the arena (e.g. when it's reference count goes to
* zero)
*/
class nsIArena : public nsISupports {
public:
static const nsIID& GetIID() { static nsIID iid = NS_IARENA_IID; return iid; }
NS_IMETHOD Init(PRUint32 arenaBlockSize) = 0;
NS_IMETHOD_(void*) Alloc(PRUint32 size) = 0;
};
/**
* Create a new arena using the desired block size for allocating the
* underlying memory blocks. The underlying memory blocks are allocated
* using the PR heap.
*/
extern NS_COM nsresult NS_NewHeapArena(nsIArena** aInstancePtrResult,
PRUint32 aArenaBlockSize = 0);
#define NS_ARENA_CID \
{ /* 9832ec80-0d6b-11d3-9331-00104ba0fd40 */ \
0x9832ec80, \
0x0d6b, \
0x11d3, \
{0x93, 0x31, 0x00, 0x10, 0x4b, 0xa0, 0xfd, 0x40} \
}
#endif /* nsIArena_h___ */

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