зеркало из https://github.com/mozilla/gecko-dev.git
Leaking nsCStringKey objects
bug 73308 r=valeski sr=shaver a=brendan patch=tmutreja@netscape.com
This commit is contained in:
Родитель
6ae5af8556
Коммит
00fea02e9e
|
@ -121,7 +121,7 @@ nsStreamConverterService::BuildGraph() {
|
|||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// cobble the entry string w/ the converter key to produce a full contractID.
|
||||
nsCString contractID(NS_ISTREAMCONVERTER_KEY);
|
||||
nsCAutoString contractID(NS_ISTREAMCONVERTER_KEY);
|
||||
contractID.Append((const char *)entryString);
|
||||
|
||||
// now we've got the CONTRACTID, let's parse it up.
|
||||
|
@ -144,65 +144,63 @@ nsStreamConverterService::AddAdjacency(const char *aContractID) {
|
|||
nsresult rv;
|
||||
// first parse out the FROM and TO MIME-types.
|
||||
|
||||
nsCString fromStr, toStr;
|
||||
nsCAutoString fromStr, toStr;
|
||||
rv = ParseFromTo(aContractID, fromStr, toStr);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// Each MIME-type is a vertex in the graph, so first lets make sure
|
||||
// each MIME-type is represented as a key in our hashtable.
|
||||
|
||||
nsCStringKey *fromKey = new nsCStringKey(ToNewCString(fromStr), fromStr.Length(), nsCStringKey::OWN);
|
||||
if (!fromKey) return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
SCTableData *fromEdges = (SCTableData*)mAdjacencyList->Get(fromKey);
|
||||
nsCStringKey fromKey(fromStr);
|
||||
SCTableData *fromEdges = (SCTableData*)mAdjacencyList->Get(&fromKey);
|
||||
if (!fromEdges) {
|
||||
// There is no fromStr vertex, create one.
|
||||
SCTableData *data = new SCTableData;
|
||||
|
||||
nsCStringKey *newFromKey = new nsCStringKey(ToNewCString(fromStr), fromStr.Length(), nsCStringKey::OWN);
|
||||
if (!newFromKey) return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
SCTableData *data = new SCTableData(newFromKey);
|
||||
if (!data) {
|
||||
delete fromKey;
|
||||
delete newFromKey;
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
data->key = fromKey;
|
||||
nsCOMPtr<nsISupportsArray> edgeArray;
|
||||
rv = NS_NewISupportsArray(getter_AddRefs(edgeArray));
|
||||
if (NS_FAILED(rv)) {
|
||||
delete fromKey;
|
||||
delete newFromKey;
|
||||
data->key = nsnull;
|
||||
delete data;
|
||||
return rv;
|
||||
}
|
||||
NS_ADDREF(data->data.edges = edgeArray.get());
|
||||
|
||||
mAdjacencyList->Put(fromKey, data);
|
||||
mAdjacencyList->Put(newFromKey, data);
|
||||
fromEdges = data;
|
||||
} else {
|
||||
delete fromKey;
|
||||
fromKey = nsnull;
|
||||
}
|
||||
|
||||
nsCStringKey *toKey = new nsCStringKey(ToNewCString(toStr), toStr.Length(), nsCStringKey::OWN);
|
||||
if (!toKey) return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
if (!mAdjacencyList->Get(toKey)) {
|
||||
nsCStringKey toKey(toStr);
|
||||
if (!mAdjacencyList->Get(&toKey)) {
|
||||
// There is no toStr vertex, create one.
|
||||
SCTableData *data = new SCTableData;
|
||||
nsCStringKey *newToKey = new nsCStringKey(ToNewCString(toStr), toStr.Length(), nsCStringKey::OWN);
|
||||
if (!newToKey) return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
SCTableData *data = new SCTableData(newToKey);
|
||||
if (!data) {
|
||||
delete toKey;
|
||||
delete newToKey;
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
data->key = toKey;
|
||||
nsCOMPtr<nsISupportsArray> edgeArray;
|
||||
rv = NS_NewISupportsArray(getter_AddRefs(edgeArray));
|
||||
if (NS_FAILED(rv)) {
|
||||
delete toKey;
|
||||
delete newToKey;
|
||||
data->key = nsnull;
|
||||
delete data;
|
||||
return rv;
|
||||
}
|
||||
NS_ADDREF(data->data.edges = edgeArray.get());
|
||||
|
||||
mAdjacencyList->Put(toKey, data);
|
||||
} else {
|
||||
delete toKey;
|
||||
toKey = nsnull;
|
||||
mAdjacencyList->Put(newToKey, data);
|
||||
}
|
||||
|
||||
// Now we know the FROM and TO types are represented as keys in the hashtable.
|
||||
|
@ -212,6 +210,9 @@ nsStreamConverterService::AddAdjacency(const char *aContractID) {
|
|||
if (!vertex) return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
NS_ASSERTION(fromEdges, "something wrong in adjacency list construction");
|
||||
if (!fromEdges)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsISupportsArray> adjacencyList = fromEdges->data.edges;
|
||||
return adjacencyList->AppendElement(vertex) ? NS_OK : NS_ERROR_FAILURE; // XXX this method incorrectly returns a bool
|
||||
}
|
||||
|
@ -219,13 +220,16 @@ nsStreamConverterService::AddAdjacency(const char *aContractID) {
|
|||
nsresult
|
||||
nsStreamConverterService::ParseFromTo(const char *aContractID, nsCString &aFromRes, nsCString &aToRes) {
|
||||
|
||||
nsCString ContractIDStr(aContractID);
|
||||
nsCAutoString ContractIDStr(aContractID);
|
||||
|
||||
PRInt32 fromLoc = ContractIDStr.Find("from=") + 5;
|
||||
PRInt32 toLoc = ContractIDStr.Find("to=") + 3;
|
||||
PRInt32 fromLoc = ContractIDStr.Find("from=");
|
||||
PRInt32 toLoc = ContractIDStr.Find("to=");
|
||||
if (-1 == fromLoc || -1 == toLoc ) return NS_ERROR_FAILURE;
|
||||
|
||||
nsCString fromStr, toStr;
|
||||
fromLoc = fromLoc + 5;
|
||||
toLoc = toLoc + 3;
|
||||
|
||||
nsCAutoString fromStr, toStr;
|
||||
|
||||
ContractIDStr.Mid(fromStr, fromLoc, toLoc - 4 - fromLoc);
|
||||
ContractIDStr.Mid(toStr, toLoc, ContractIDStr.Length() - toLoc);
|
||||
|
@ -246,15 +250,17 @@ static PRBool PR_CALLBACK InitBFSTable(nsHashKey *aKey, void *aData, void* closu
|
|||
if (!BFSTable) return PR_FALSE;
|
||||
|
||||
BFSState *state = new BFSState;
|
||||
if (!state) return NS_ERROR_OUT_OF_MEMORY;
|
||||
if (!state) return PR_FALSE;
|
||||
|
||||
state->color = white;
|
||||
state->distance = -1;
|
||||
state->predecessor = nsnull;
|
||||
|
||||
SCTableData *data = new SCTableData;
|
||||
if (!data) return NS_ERROR_OUT_OF_MEMORY;
|
||||
data->key = (nsCStringKey*)aKey->Clone();
|
||||
SCTableData *data = new SCTableData(NS_STATIC_CAST(nsCStringKey*, aKey));
|
||||
if (!data) {
|
||||
delete state;
|
||||
return PR_FALSE;
|
||||
}
|
||||
data->data.state = state;
|
||||
|
||||
BFSTable->Put(aKey, data);
|
||||
|
@ -264,15 +270,22 @@ static PRBool PR_CALLBACK InitBFSTable(nsHashKey *aKey, void *aData, void* closu
|
|||
// cleans up the BFS state table
|
||||
static PRBool PR_CALLBACK DeleteBFSEntry(nsHashKey *aKey, void *aData, void *closure) {
|
||||
SCTableData *data = (SCTableData*)aData;
|
||||
delete data->key;
|
||||
BFSState *state = data->data.state;
|
||||
if (state->predecessor) // there might not be a predecessor depending on the graph
|
||||
delete state->predecessor;
|
||||
delete state;
|
||||
data->key = nsnull;
|
||||
delete data;
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
class CStreamConvDeallocator : public nsDequeFunctor {
|
||||
public:
|
||||
virtual void* operator()(void* anObject) {
|
||||
nsCStringKey *key = (nsCStringKey*)anObject;
|
||||
delete key;
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
// walks the graph using a breadth-first-search algorithm which generates a discovered
|
||||
// verticies tree. This tree is then walked up (from destination vertex, to origin vertex)
|
||||
// and each link in the chain is added to an nsStringArray. A direct lookup for the given
|
||||
|
@ -282,6 +295,7 @@ nsresult
|
|||
nsStreamConverterService::FindConverter(const char *aContractID, nsCStringArray **aEdgeList) {
|
||||
nsresult rv;
|
||||
if (!aEdgeList) return NS_ERROR_NULL_POINTER;
|
||||
*aEdgeList = nsnull;
|
||||
|
||||
// walk the graph in search of the appropriate converter.
|
||||
|
||||
|
@ -295,55 +309,80 @@ nsStreamConverterService::FindConverter(const char *aContractID, nsCStringArray
|
|||
NS_ASSERTION(lBFSTable.Count() == vertexCount, "strmconv BFS table init problem");
|
||||
|
||||
// This is our source vertex; our starting point.
|
||||
nsCString fromC, toC;
|
||||
nsCAutoString fromC, toC;
|
||||
rv = ParseFromTo(aContractID, fromC, toC);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
nsCStringKey *source = new nsCStringKey(fromC.get());
|
||||
if (!source) return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
SCTableData *data = (SCTableData*)lBFSTable.Get(source);
|
||||
if (!data) return NS_ERROR_FAILURE;
|
||||
if (!data) {
|
||||
delete source;
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
BFSState *state = data->data.state;
|
||||
|
||||
state->color = gray;
|
||||
state->distance = 0;
|
||||
nsDeque grayQ(0);
|
||||
CStreamConvDeallocator *dtorFunc = new CStreamConvDeallocator();
|
||||
if (!dtorFunc) {
|
||||
delete source;
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
nsDeque grayQ(dtorFunc);
|
||||
|
||||
// Now generate the shortest path tree.
|
||||
grayQ.Push(source);
|
||||
while (0 < grayQ.GetSize()) {
|
||||
nsHashKey *currentHead = (nsHashKey*)grayQ.PeekFront();
|
||||
nsCStringKey *currentHead = (nsCStringKey*)grayQ.PeekFront();
|
||||
SCTableData *data2 = (SCTableData*)mAdjacencyList->Get(currentHead);
|
||||
if (!data2) return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsISupportsArray> edges = data2->data.edges;
|
||||
NS_ASSERTION(edges, "something went wrong with BFS strmconv algorithm");
|
||||
if (!edges) return NS_ERROR_FAILURE;
|
||||
|
||||
// Get the state of the current head to calculate the distance of each
|
||||
// reachable vertex in the loop.
|
||||
data2 = (SCTableData*)lBFSTable.Get(currentHead);
|
||||
if (!data2) return NS_ERROR_FAILURE;
|
||||
|
||||
BFSState *headVertexState = data2->data.state;
|
||||
NS_ASSERTION(headVertexState, "problem with the BFS strmconv algorithm");
|
||||
if (!headVertexState) return NS_ERROR_FAILURE;
|
||||
|
||||
PRUint32 edgeCount = 0;
|
||||
rv = edges->Count(&edgeCount);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
for (PRUint32 i = 0; i < edgeCount; i++) {
|
||||
|
||||
nsIAtom *curVertexAtom = (nsIAtom*)edges->ElementAt(i);
|
||||
nsAutoString curVertexStr;
|
||||
curVertexAtom->ToString(curVertexStr);
|
||||
nsCStringKey *curVertex = new nsCStringKey(ToNewCString(curVertexStr),
|
||||
curVertexStr.Length(), nsCStringKey::OWN);
|
||||
if (!curVertex) return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
SCTableData *data3 = (SCTableData*)lBFSTable.Get(curVertex);
|
||||
if (!data3) {
|
||||
delete curVertex;
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
BFSState *curVertexState = data3->data.state;
|
||||
NS_ASSERTION(curVertexState, "something went wrong with the BFS strmconv algorithm");
|
||||
if (!curVertexState) return NS_ERROR_FAILURE;
|
||||
|
||||
if (white == curVertexState->color) {
|
||||
curVertexState->color = gray;
|
||||
curVertexState->distance = headVertexState->distance + 1;
|
||||
curVertexState->predecessor = currentHead->Clone();
|
||||
curVertexState->predecessor = (nsCStringKey*)currentHead->Clone();
|
||||
if (!curVertexState->predecessor) {
|
||||
delete curVertex;
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
grayQ.Push(curVertex);
|
||||
} else {
|
||||
delete curVertex; // if this vertex has already been discovered, we don't want
|
||||
|
@ -361,27 +400,28 @@ nsStreamConverterService::FindConverter(const char *aContractID, nsCStringArray
|
|||
|
||||
// first parse out the FROM and TO MIME-types being registered.
|
||||
|
||||
nsCString fromStr, toStr;
|
||||
nsCAutoString fromStr, toStr;
|
||||
rv = ParseFromTo(aContractID, fromStr, toStr);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// get the root CONTRACTID
|
||||
nsCString ContractIDPrefix(NS_ISTREAMCONVERTER_KEY);
|
||||
nsCAutoString ContractIDPrefix(NS_ISTREAMCONVERTER_KEY);
|
||||
nsCStringArray *shortestPath = new nsCStringArray();
|
||||
if (!shortestPath) return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
nsCStringKey toMIMEType(toStr);
|
||||
data = (SCTableData*)lBFSTable.Get(&toMIMEType);
|
||||
|
||||
if (!data) {
|
||||
// If this vertex isn't in the BFSTable, then no-one has registered for it,
|
||||
// therefore we can't do the conversion.
|
||||
*aEdgeList = nsnull;
|
||||
delete shortestPath;
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
while (data) {
|
||||
BFSState *curState = data->data.state;
|
||||
|
||||
nsCStringKey *key = (nsCStringKey*)data->key;
|
||||
nsCStringKey *key = data->key;
|
||||
|
||||
if (fromStr.Equals(key->GetString())) {
|
||||
// found it. We're done here.
|
||||
|
@ -393,13 +433,14 @@ nsStreamConverterService::FindConverter(const char *aContractID, nsCStringArray
|
|||
// Get the predecessor.
|
||||
if (!curState->predecessor) break; // no predecessor
|
||||
SCTableData *predecessorData = (SCTableData*)lBFSTable.Get(curState->predecessor);
|
||||
|
||||
if (!predecessorData) break; // no predecessor, chain doesn't exist.
|
||||
|
||||
// build out the CONTRACTID.
|
||||
nsCString newContractID(ContractIDPrefix);
|
||||
nsCAutoString newContractID(ContractIDPrefix);
|
||||
newContractID.Append("?from=");
|
||||
|
||||
nsCStringKey *predecessorKey = (nsCStringKey*)predecessorData->key;
|
||||
nsCStringKey *predecessorKey = predecessorData->key;
|
||||
newContractID.Append(predecessorKey->GetString());
|
||||
|
||||
newContractID.Append("&to=");
|
||||
|
@ -412,10 +453,8 @@ nsStreamConverterService::FindConverter(const char *aContractID, nsCStringArray
|
|||
// move up the tree.
|
||||
data = predecessorData;
|
||||
}
|
||||
|
||||
*aEdgeList = nsnull;
|
||||
delete shortestPath;
|
||||
return NS_ERROR_FAILURE; // couldn't find a stream converter or chain.
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -432,7 +471,7 @@ nsStreamConverterService::Convert(nsIInputStream *aFromStream,
|
|||
|
||||
// first determine whether we can even handle this covnversion
|
||||
// build a CONTRACTID
|
||||
nsCString contractID(NS_ISTREAMCONVERTER_KEY);
|
||||
nsCAutoString contractID(NS_ISTREAMCONVERTER_KEY);
|
||||
contractID.Append("?from=");
|
||||
contractID.AppendWithConversion(aFromType);
|
||||
contractID.Append("&to=");
|
||||
|
@ -478,7 +517,7 @@ nsStreamConverterService::Convert(nsIInputStream *aFromStream,
|
|||
return rv;
|
||||
}
|
||||
|
||||
nsCString fromStr, toStr;
|
||||
nsCAutoString fromStr, toStr;
|
||||
rv = ParseFromTo(lContractID, fromStr, toStr);
|
||||
if (NS_FAILED(rv)) {
|
||||
delete converterChain;
|
||||
|
@ -531,7 +570,7 @@ nsStreamConverterService::AsyncConvertData(const PRUnichar *aFromType,
|
|||
|
||||
// first determine whether we can even handle this covnversion
|
||||
// build a CONTRACTID
|
||||
nsCString contractID(NS_ISTREAMCONVERTER_KEY);
|
||||
nsCAutoString contractID(NS_ISTREAMCONVERTER_KEY);
|
||||
contractID.Append("?from=");
|
||||
contractID.AppendWithConversion(aFromType);
|
||||
contractID.Append("&to=");
|
||||
|
@ -575,7 +614,7 @@ nsStreamConverterService::AsyncConvertData(const PRUnichar *aFromType,
|
|||
nsCOMPtr<nsIStreamConverter> converter(do_CreateInstance(lContractID, &rv));
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "graph construction problem, built a contractid that wasn't registered");
|
||||
|
||||
nsCString fromStr, toStr;
|
||||
nsCAutoString fromStr, toStr;
|
||||
rv = ParseFromTo(lContractID, fromStr, toStr);
|
||||
if (NS_FAILED(rv)) {
|
||||
delete converterChain;
|
||||
|
|
|
@ -80,19 +80,25 @@ private:
|
|||
// used to establish discovered vertecies.
|
||||
enum BFScolors {white, gray, black};
|
||||
|
||||
typedef struct _BFSState {
|
||||
struct BFSState {
|
||||
BFScolors color;
|
||||
PRInt32 distance;
|
||||
nsHashKey *predecessor;
|
||||
} BFSState;
|
||||
nsCStringKey *predecessor;
|
||||
~BFSState() {
|
||||
delete predecessor;
|
||||
}
|
||||
};
|
||||
|
||||
// adjacency list and BFS hashtable data class.
|
||||
typedef struct _tableData {
|
||||
struct SCTableData {
|
||||
nsCStringKey *key;
|
||||
union _data {
|
||||
BFSState *state;
|
||||
nsISupportsArray *edges;
|
||||
} data;
|
||||
} SCTableData;
|
||||
|
||||
SCTableData(nsCStringKey* aKey) : key(aKey) {
|
||||
data.state = nsnull;
|
||||
}
|
||||
};
|
||||
#endif // __nsstreamconverterservice__h___
|
||||
|
|
|
@ -522,6 +522,33 @@ nsresult nsIDKey::Write(nsIObjectOutputStream* aStream) const
|
|||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Copy Constructor
|
||||
// We need to free mStr if the object is passed with mOwnership as OWN. As the
|
||||
// destructor here is freeing mStr in that case, mStr is NOT getting leaked here.
|
||||
|
||||
nsCStringKey::nsCStringKey(const nsCStringKey& aKey)
|
||||
: mStr(aKey.mStr), mStrLen(aKey.mStrLen), mOwnership(aKey.mOwnership)
|
||||
{
|
||||
if (mOwnership != NEVER_OWN) {
|
||||
PRUint32 len = mStrLen * sizeof(char);
|
||||
char* str = NS_REINTERPRET_CAST(char*, nsMemory::Alloc(len + sizeof(char)));
|
||||
if (!str) {
|
||||
// Pray we don't dangle!
|
||||
mOwnership = NEVER_OWN;
|
||||
} else {
|
||||
// Use memcpy in case there are embedded NULs.
|
||||
memcpy(str, mStr, len);
|
||||
str[mStrLen] = '\0';
|
||||
mStr = str;
|
||||
mOwnership = OWN;
|
||||
}
|
||||
}
|
||||
#ifdef DEBUG
|
||||
mKeyType = CStringKey;
|
||||
#endif
|
||||
MOZ_COUNT_CTOR(nsCStringKey);
|
||||
}
|
||||
|
||||
nsCStringKey::nsCStringKey(const nsAFlatCString& str)
|
||||
: mStr(NS_CONST_CAST(char*, str.get())),
|
||||
mStrLen(str.Length()),
|
||||
|
@ -620,6 +647,33 @@ nsCStringKey::Write(nsIObjectOutputStream* aStream) const
|
|||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Copy Constructor
|
||||
// We need to free mStr if the object is passed with mOwnership as OWN. As the
|
||||
// destructor here is freeing mStr in that case, mStr is NOT getting leaked here.
|
||||
|
||||
nsStringKey::nsStringKey(const nsStringKey& aKey)
|
||||
: mStr(aKey.mStr), mStrLen(aKey.mStrLen), mOwnership(aKey.mOwnership)
|
||||
{
|
||||
if (mOwnership != NEVER_OWN) {
|
||||
PRUint32 len = mStrLen * sizeof(PRUnichar);
|
||||
PRUnichar* str = NS_REINTERPRET_CAST(PRUnichar*, nsMemory::Alloc(len + sizeof(PRUnichar)));
|
||||
if (!str) {
|
||||
// Pray we don't dangle!
|
||||
mOwnership = NEVER_OWN;
|
||||
} else {
|
||||
// Use memcpy in case there are embedded NULs.
|
||||
memcpy(str, mStr, len);
|
||||
str[mStrLen] = 0;
|
||||
mStr = str;
|
||||
mOwnership = OWN;
|
||||
}
|
||||
}
|
||||
#ifdef DEBUG
|
||||
mKeyType = StringKey;
|
||||
#endif
|
||||
MOZ_COUNT_CTOR(nsStringKey);
|
||||
}
|
||||
|
||||
nsStringKey::nsStringKey(const nsAFlatString& str)
|
||||
: mStr(NS_CONST_CAST(PRUnichar*, str.get())),
|
||||
mStrLen(str.Length()),
|
||||
|
@ -713,6 +767,30 @@ nsStringKey::Write(nsIObjectOutputStream* aStream) const
|
|||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Copy Constructor
|
||||
// We need to free mBuf if the object is passed with mOwnership as OWN. As the
|
||||
// destructor here is freeing mBuf in that case, mBuf is NOT getting leaked.
|
||||
|
||||
nsOpaqueKey::nsOpaqueKey(const nsOpaqueKey& aKey)
|
||||
: mBuf(aKey.mBuf), mBufLen(aKey.mBufLen), mOwnership(aKey.mOwnership)
|
||||
{
|
||||
if (mOwnership != NEVER_OWN) {
|
||||
char* newBuf = NS_REINTERPRET_CAST(char*, nsMemory::Alloc(mBufLen));
|
||||
if (!newBuf) {
|
||||
// Pray we don't dangle!
|
||||
mOwnership = NEVER_OWN;
|
||||
} else {
|
||||
memcpy(newBuf, mBuf, mBufLen);
|
||||
mBuf = newBuf;
|
||||
mOwnership = OWN;
|
||||
}
|
||||
}
|
||||
#ifdef DEBUG
|
||||
mKeyType = OpaqueKey;
|
||||
#endif
|
||||
MOZ_COUNT_CTOR(nsOpaqueKey);
|
||||
}
|
||||
|
||||
nsOpaqueKey::nsOpaqueKey(const char* str, PRUint32 strLen, Ownership own)
|
||||
: mBuf((char*)str), mBufLen(strLen), mOwnership(own)
|
||||
{
|
||||
|
|
|
@ -205,6 +205,13 @@ class NS_COM nsISupportsKey : public nsHashKey {
|
|||
nsISupports* mKey;
|
||||
|
||||
public:
|
||||
nsISupportsKey(const nsISupportsKey& aKey) : mKey(aKey.mKey) {
|
||||
#ifdef DEBUG
|
||||
mKeyType = SupportsKey;
|
||||
#endif
|
||||
NS_IF_ADDREF(mKey);
|
||||
}
|
||||
|
||||
nsISupportsKey(nsISupports* key) {
|
||||
#ifdef DEBUG
|
||||
mKeyType = SupportsKey;
|
||||
|
@ -267,6 +274,12 @@ class nsVoidKey : public nsHashKey {
|
|||
void* mKey;
|
||||
|
||||
public:
|
||||
nsVoidKey(const nsVoidKey& aKey) : mKey(aKey.mKey) {
|
||||
#ifdef DEBUG
|
||||
mKeyType = aKey.mKeyType;
|
||||
#endif
|
||||
}
|
||||
|
||||
nsVoidKey(void* key) {
|
||||
#ifdef DEBUG
|
||||
mKeyType = VoidKey;
|
||||
|
@ -300,6 +313,12 @@ class NS_COM nsIDKey : public nsHashKey {
|
|||
nsID mID;
|
||||
|
||||
public:
|
||||
nsIDKey(const nsIDKey& aKey) : mID(aKey.mID) {
|
||||
#ifdef DEBUG
|
||||
mKeyType = IDKey;
|
||||
#endif
|
||||
}
|
||||
|
||||
nsIDKey(const nsID &aID) {
|
||||
#ifdef DEBUG
|
||||
mKeyType = IDKey;
|
||||
|
@ -339,6 +358,7 @@ class NS_COM nsCStringKey : public nsHashKey {
|
|||
OWN // to be free'd in key dtor. Clones make their own copy.
|
||||
};
|
||||
|
||||
nsCStringKey(const nsCStringKey& aStrKey);
|
||||
nsCStringKey(const char* str, PRInt32 strLen = -1, Ownership own = OWN_CLONE);
|
||||
nsCStringKey(const nsAFlatCString& str);
|
||||
nsCStringKey(const nsACString& str);
|
||||
|
@ -372,6 +392,7 @@ class NS_COM nsStringKey : public nsHashKey {
|
|||
OWN // to be free'd in key dtor. Clones make their own copy.
|
||||
};
|
||||
|
||||
nsStringKey(const nsStringKey& aKey);
|
||||
nsStringKey(const PRUnichar* str, PRInt32 strLen = -1, Ownership own = OWN_CLONE);
|
||||
nsStringKey(const nsAFlatString& str);
|
||||
nsStringKey(const nsAString& str);
|
||||
|
@ -405,6 +426,7 @@ class NS_COM nsOpaqueKey : public nsHashKey {
|
|||
OWN // to be free'd in key dtor. Clones make their own copy.
|
||||
};
|
||||
|
||||
nsOpaqueKey(const nsOpaqueKey& aKey);
|
||||
nsOpaqueKey(const char* buf, PRUint32 bufLen, Ownership own = OWN_CLONE);
|
||||
~nsOpaqueKey(void);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче