diff options
Diffstat (limited to '')
-rw-r--r-- | src/libs/xpcom18a4/xpcom/reflect/xptinfo/src/xptiWorkingSet.cpp | 432 |
1 files changed, 432 insertions, 0 deletions
diff --git a/src/libs/xpcom18a4/xpcom/reflect/xptinfo/src/xptiWorkingSet.cpp b/src/libs/xpcom18a4/xpcom/reflect/xptinfo/src/xptiWorkingSet.cpp new file mode 100644 index 00000000..b9602726 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/reflect/xptinfo/src/xptiWorkingSet.cpp @@ -0,0 +1,432 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (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/MPL/ + * + * 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.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1999 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Mike McCabe <mccabe@netscape.com> + * John Bandhauer <jband@netscape.com> + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* Implementation of xptiWorkingSet. */ + +#include "xptiprivate.h" +#include "nsString.h" + +#define XPTI_STRING_ARENA_BLOCK_SIZE (1024 * 1) +#define XPTI_STRUCT_ARENA_BLOCK_SIZE (1024 * 1) +#define XPTI_HASHTABLE_SIZE 128 + +/***************************************************************************/ + +PR_STATIC_CALLBACK(const void*) +IIDGetKey(PLDHashTable *table, PLDHashEntryHdr *entry) +{ + return ((xptiHashEntry*)entry)->value->GetTheIID(); +} + +PR_STATIC_CALLBACK(PLDHashNumber) +IIDHash(PLDHashTable *table, const void *key) +{ + return (PLDHashNumber) ((const nsIID*)key)->m0; +} + +PR_STATIC_CALLBACK(PRBool) +IIDMatch(PLDHashTable *table, + const PLDHashEntryHdr *entry, + const void *key) +{ + const nsIID* iid1 = ((xptiHashEntry*)entry)->value->GetTheIID(); + const nsIID* iid2 = (const nsIID*)key; + + return iid1 == iid2 || iid1->Equals(*iid2); +} + +const static struct PLDHashTableOps IIDTableOps = +{ + PL_DHashAllocTable, + PL_DHashFreeTable, + IIDGetKey, + IIDHash, + IIDMatch, + PL_DHashMoveEntryStub, + PL_DHashClearEntryStub, + PL_DHashFinalizeStub +}; + +/***************************************************************************/ + +PR_STATIC_CALLBACK(const void*) +NameGetKey(PLDHashTable *table, PLDHashEntryHdr *entry) +{ + return ((xptiHashEntry*)entry)->value->GetTheName(); +} + +PR_STATIC_CALLBACK(PRBool) +NameMatch(PLDHashTable *table, + const PLDHashEntryHdr *entry, + const void *key) +{ + const char* str1 = ((xptiHashEntry*)entry)->value->GetTheName(); + const char* str2 = (const char*) key; + return str1 == str2 || 0 == PL_strcmp(str1, str2); +} + +static const struct PLDHashTableOps NameTableOps = +{ + PL_DHashAllocTable, + PL_DHashFreeTable, + NameGetKey, + PL_DHashStringKey, + NameMatch, + PL_DHashMoveEntryStub, + PL_DHashClearEntryStub, + PL_DHashFinalizeStub +}; + +/***************************************************************************/ + +MOZ_DECL_CTOR_COUNTER(xptiWorkingSet) + +xptiWorkingSet::xptiWorkingSet(nsISupportsArray* aDirectories) + : mFileCount(0), + mMaxFileCount(0), + mFileArray(nsnull), + mZipItemCount(0), + mMaxZipItemCount(0), + mZipItemArray(nsnull), + mStringArena(XPT_NewArena(XPTI_STRING_ARENA_BLOCK_SIZE, sizeof(char), + "xptiWorkingSet strings")), + mStructArena(XPT_NewArena(XPTI_STRUCT_ARENA_BLOCK_SIZE, sizeof(double), + "xptiWorkingSet structs")), + mDirectories(aDirectories), + mNameTable(PL_NewDHashTable(&NameTableOps, nsnull, sizeof(xptiHashEntry), + XPTI_HASHTABLE_SIZE)), + mIIDTable(PL_NewDHashTable(&IIDTableOps, nsnull, sizeof(xptiHashEntry), + XPTI_HASHTABLE_SIZE)), + mFileMergeOffsetMap(nsnull), + mZipItemMergeOffsetMap(nsnull) +{ + MOZ_COUNT_CTOR(xptiWorkingSet); + // do nothing else... +} + +PRBool +xptiWorkingSet::IsValid() const +{ + return (mFileCount == 0 || mFileArray) && + (mZipItemCount == 0 || mZipItemArray) && + mStringArena && + mStructArena && + mNameTable && + mIIDTable; +} + +PR_STATIC_CALLBACK(PLDHashOperator) +xpti_Remover(PLDHashTable *table, PLDHashEntryHdr *hdr, + PRUint32 number, void *arg) +{ + return PL_DHASH_REMOVE; +} + +PR_STATIC_CALLBACK(PLDHashOperator) +xpti_Invalidator(PLDHashTable *table, PLDHashEntryHdr *hdr, + PRUint32 number, void *arg) +{ + xptiInterfaceEntry* entry = ((xptiHashEntry*)hdr)->value; + entry->LockedInvalidateInterfaceInfo(); + return PL_DHASH_NEXT; +} + +void +xptiWorkingSet::InvalidateInterfaceInfos() +{ + if(mNameTable) + { + nsAutoMonitor lock(xptiInterfaceInfoManager::GetInfoMonitor()); + PL_DHashTableEnumerate(mNameTable, xpti_Invalidator, nsnull); + } +} + +void +xptiWorkingSet::ClearHashTables() +{ + if(mNameTable) + PL_DHashTableEnumerate(mNameTable, xpti_Remover, nsnull); + + if(mIIDTable) + PL_DHashTableEnumerate(mIIDTable, xpti_Remover, nsnull); +} + +void +xptiWorkingSet::ClearFiles() +{ + if(mFileArray) + delete [] mFileArray; + mFileArray = nsnull; + mMaxFileCount = 0; + mFileCount = 0; +} + +void +xptiWorkingSet::ClearZipItems() +{ + if(mZipItemArray) + delete [] mZipItemArray; + mZipItemArray = nsnull; + mMaxZipItemCount = 0; + mZipItemCount = 0; +} + +xptiWorkingSet::~xptiWorkingSet() +{ + MOZ_COUNT_DTOR(xptiWorkingSet); + + ClearFiles(); + ClearZipItems(); + ClearHashTables(); + + if(mNameTable) + PL_DHashTableDestroy(mNameTable); + + if(mIIDTable) + PL_DHashTableDestroy(mIIDTable); + + if(mFileArray) + delete [] mFileArray; + + if(mZipItemArray) + delete [] mZipItemArray; + + // Destroy arenas last in case they are referenced in other members' dtors. + + if(mStringArena) + { +#ifdef DEBUG + XPT_DumpStats(mStringArena); +#endif + XPT_DestroyArena(mStringArena); + } + + if(mStructArena) + { +#ifdef DEBUG + XPT_DumpStats(mStructArena); +#endif + XPT_DestroyArena(mStructArena); + } +} + +PRUint32 +xptiWorkingSet::FindFile(PRUint32 dir, const char* name) +{ + if(mFileArray) + { + for(PRUint32 i = 0; i < mFileCount;++i) + { + xptiFile& file = mFileArray[i]; + if(file.GetDirectory() == dir && + 0 == PL_strcmp(name, file.GetName())) + { + return i; + } + } + } + return NOT_FOUND; +} + +PRBool +xptiWorkingSet::NewFileArray(PRUint32 count) +{ + if(mFileArray) + delete [] mFileArray; + mFileCount = 0; + mFileArray = new xptiFile[count]; + if(!mFileArray) + { + mMaxFileCount = 0; + return PR_FALSE; + } + mMaxFileCount = count; + return PR_TRUE; +} + +PRBool +xptiWorkingSet::ExtendFileArray(PRUint32 count) +{ + if(mFileArray && count < mMaxFileCount) + return PR_TRUE; + + xptiFile* newArray = new xptiFile[count]; + if(!newArray) + return PR_FALSE; + + if(mFileArray) + { + for(PRUint32 i = 0; i < mFileCount; ++i) + newArray[i] = mFileArray[i]; + delete [] mFileArray; + } + mFileArray = newArray; + mMaxFileCount = count; + return PR_TRUE; +} + +/***************************************************************************/ + +PRUint32 +xptiWorkingSet::FindZipItemWithName(const char* name) +{ + if(mZipItemArray) + { + for(PRUint32 i = 0; i < mZipItemCount;++i) + if(0 == PL_strcmp(name, mZipItemArray[i].GetName())) + return i; + } + return NOT_FOUND; +} + +PRBool +xptiWorkingSet::NewZipItemArray(PRUint32 count) +{ + if(mZipItemArray) + delete [] mZipItemArray; + mZipItemCount = 0; + mZipItemArray = new xptiZipItem[count]; + if(!mZipItemArray) + { + mMaxZipItemCount = 0; + return PR_FALSE; + } + mMaxZipItemCount = count; + return PR_TRUE; +} + +PRBool +xptiWorkingSet::ExtendZipItemArray(PRUint32 count) +{ + if(mZipItemArray && count < mMaxZipItemCount) + return PR_TRUE; + + xptiZipItem* newArray = new xptiZipItem[count]; + if(!newArray) + return PR_FALSE; + + if(mZipItemArray) + { + for(PRUint32 i = 0; i < mZipItemCount; ++i) + newArray[i] = mZipItemArray[i]; + delete [] mZipItemArray; + } + mZipItemArray = newArray; + mMaxZipItemCount = count; + return PR_TRUE; +} + +/***************************************************************************/ +// Directory stuff... + +PRUint32 xptiWorkingSet::GetDirectoryCount() +{ + PRUint32 count = 0; + mDirectories->Count(&count); + return count; +} + +nsresult xptiWorkingSet::GetCloneOfDirectoryAt(PRUint32 i, nsILocalFile** dir) +{ + return xptiCloneElementAsLocalFile(mDirectories, i, dir); +} + +nsresult xptiWorkingSet::GetDirectoryAt(PRUint32 i, nsILocalFile** dir) +{ + return mDirectories->QueryElementAt(i, NS_GET_IID(nsILocalFile), (void**)dir); +} + +PRBool xptiWorkingSet::FindDirectory(nsILocalFile* dir, PRUint32* index) +{ + PRUint32 count; + nsresult rv = mDirectories->Count(&count); + if(NS_FAILED(rv)) + return PR_FALSE; + + for(PRUint32 i = 0; i < count; i++) + { + PRBool same; + nsCOMPtr<nsILocalFile> current; + mDirectories->QueryElementAt(i, NS_GET_IID(nsILocalFile), + getter_AddRefs(current)); + if(!current || NS_FAILED(current->Equals(dir, &same))) + break; + if(same) + { + *index = i; + return PR_TRUE; + } + } + return PR_FALSE; +} + +PRBool xptiWorkingSet::FindDirectoryOfFile(nsILocalFile* file, PRUint32* index) +{ + nsCOMPtr<nsIFile> dirAbstract; + file->GetParent(getter_AddRefs(dirAbstract)); + if(!dirAbstract) + return PR_FALSE; + nsCOMPtr<nsILocalFile> dir = do_QueryInterface(dirAbstract); + if(!dir) + return PR_FALSE; + return FindDirectory(dir, index); +} + +PRBool xptiWorkingSet::DirectoryAtMatchesPersistentDescriptor(PRUint32 i, + const char* inDesc) +{ + nsCOMPtr<nsILocalFile> dir; + GetDirectoryAt(i, getter_AddRefs(dir)); + if(!dir) + return PR_FALSE; + + nsCOMPtr<nsILocalFile> descDir; + nsresult rv = NS_NewNativeLocalFile(EmptyCString(), PR_FALSE, getter_AddRefs(descDir)); + if(NS_FAILED(rv)) + return PR_FALSE; + + rv = descDir->SetPersistentDescriptor(nsDependentCString(inDesc)); + if(NS_FAILED(rv)) + return PR_FALSE; + + PRBool matches; + rv = dir->Equals(descDir, &matches); + return NS_SUCCEEDED(rv) && matches; +} + |