Back to index

lightning-sunbird  0.9+nobinonly
nsImportService.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is mozilla.org code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1998
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *   Pierre Phaneuf <pp@ludusdesign.com>
00024  *
00025  * Alternatively, the contents of this file may be used under the terms of
00026  * either of the GNU General Public License Version 2 or later (the "GPL"),
00027  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00028  * in which case the provisions of the GPL or the LGPL are applicable instead
00029  * of those above. If you wish to allow use of your version of this file only
00030  * under the terms of either the GPL or the LGPL, and not to allow others to
00031  * use your version of this file under the terms of the MPL, indicate your
00032  * decision by deleting the provisions above and replace them with the notice
00033  * and other provisions required by the GPL or the LGPL. If you do not delete
00034  * the provisions above, a recipient may use your version of this file under
00035  * the terms of any one of the MPL, the GPL or the LGPL.
00036  *
00037  * ***** END LICENSE BLOCK ***** */
00038 
00039 #ifdef MOZ_LOGGING
00040 // sorry, this has to be before the pre-compiled header
00041 #define FORCE_PR_LOG /* Allow logging in the release build */
00042 #endif
00043 
00044 #include "nsICharsetConverterManager.h"
00045 #include "nsICharsetAlias.h"
00046 #include "nsIPlatformCharset.h"
00047 #include "nsICharsetConverterManager.h"
00048 
00049 #include "nsCRT.h"
00050 #include "nsString.h"
00051 #include "nsIComponentManager.h"
00052 #include "nsIServiceManager.h"
00053 #include "nsMemory.h"
00054 #include "nsIEnumerator.h"
00055 #include "nsIImportModule.h"
00056 #include "nsIImportService.h"
00057 #include "nsImportMailboxDescriptor.h"
00058 #include "nsImportABDescriptor.h"
00059 #include "nsIImportGeneric.h"
00060 #include "nsImportFieldMap.h"
00061 #include "nsICategoryManager.h"
00062 #include "nsXPIDLString.h"
00063 #include "nsXPCOM.h"
00064 #include "nsISupportsPrimitives.h"
00065 #include "nsImportStringBundle.h"
00066 #include "plstr.h"
00067 #include "prmem.h"
00068 #include "ImportDebug.h"
00069 #include "nsImportService.h"
00070 
00071 PRLogModuleInfo *IMPORTLOGMODULE = nsnull;
00072 
00073 static nsIImportService *   gImportService = nsnull;
00074 static const char *  kWhitespace = "\b\t\r\n ";
00075 
00076 
00078 
00079 
00080 nsImportService::nsImportService() : m_pModules( nsnull)
00081 {
00082        // Init logging module.
00083   if (!IMPORTLOGMODULE)
00084     IMPORTLOGMODULE = PR_NewLogModule("IMPORT");
00085   IMPORT_LOG0( "* nsImport Service Created\n");
00086 
00087        m_didDiscovery = PR_FALSE;
00088        m_pDecoder = nsnull;
00089        m_pEncoder = nsnull;
00090 
00091        // Go ahead an initialize the charset converter to avoid any 
00092        // thread issues later.
00093        nsString      str;
00094        SystemStringToUnicode( "Dummy", str);
00095     
00096     nsImportStringBundle::GetStringBundle(); 
00097 }
00098 
00099 
00100 nsImportService::~nsImportService()
00101 {
00102        NS_IF_RELEASE(m_pDecoder);
00103        NS_IF_RELEASE(m_pEncoder);
00104 
00105        gImportService = nsnull;
00106 
00107     if (m_pModules != nsnull)
00108         delete m_pModules;
00109 
00110        IMPORT_LOG0( "* nsImport Service Deleted\n");
00111 }
00112 
00113 
00114 
00115 NS_IMPL_THREADSAFE_ISUPPORTS1(nsImportService, nsIImportService)
00116 
00117 
00118 NS_IMETHODIMP nsImportService::DiscoverModules( void)
00119 {
00120        m_didDiscovery = PR_FALSE;
00121        return( DoDiscover());
00122 }
00123 
00124 NS_IMETHODIMP nsImportService::CreateNewFieldMap( nsIImportFieldMap **_retval)
00125 {
00126   nsresult rv;
00127   rv = nsImportFieldMap::Create( nsnull, NS_GET_IID(nsIImportFieldMap), (void**)_retval);
00128   return rv;
00129 }
00130 
00131 NS_IMETHODIMP nsImportService::CreateNewMailboxDescriptor( nsIImportMailboxDescriptor **_retval)
00132 {
00133   nsresult rv;
00134   rv = nsImportMailboxDescriptor::Create( nsnull, NS_GET_IID(nsIImportMailboxDescriptor), (void**)_retval);
00135   return rv;
00136 }
00137 
00138 NS_IMETHODIMP nsImportService::CreateNewABDescriptor(nsIImportABDescriptor **_retval)
00139 {
00140   nsresult rv;
00141   rv = nsImportABDescriptor::Create( nsnull, NS_GET_IID(nsIImportABDescriptor), (void**)_retval);
00142   return rv;
00143 }
00144 
00145 NS_IMETHODIMP nsImportService::SystemStringToUnicode(const char *sysStr, nsString & uniStr)
00146 {
00147   
00148        nsresult      rv;
00149        if (m_sysCharset.IsEmpty()) {
00150               nsCOMPtr <nsIPlatformCharset> platformCharset = do_GetService(NS_PLATFORMCHARSET_CONTRACTID, &rv);
00151               if (NS_SUCCEEDED(rv)) 
00152                      rv = platformCharset->GetCharset(kPlatformCharsetSel_FileName, m_sysCharset);
00153 
00154               if (NS_FAILED(rv)) 
00155                      m_sysCharset.AssignLiteral("ISO-8859-1");
00156        }
00157 
00158        if (!sysStr) {
00159               uniStr.Truncate();
00160               return( NS_OK);
00161        }
00162   
00163        if (*sysStr == '\0') {
00164               uniStr.Truncate();
00165               return( NS_OK);
00166        }
00167        
00168 
00169        if (m_sysCharset.IsEmpty() ||
00170               m_sysCharset.LowerCaseEqualsLiteral("us-ascii") ||
00171               m_sysCharset.LowerCaseEqualsLiteral("iso-8859-1")) {
00172               uniStr.AssignWithConversion( sysStr);
00173               return( NS_OK);
00174        }
00175        
00176 
00177 
00178        
00179        if (!m_pDecoder) {
00180               nsCOMPtr<nsICharsetConverterManager> ccm = do_GetService(NS_CHARSETCONVERTERMANAGER_CONTRACTID, &rv);
00181 
00182               if (NS_SUCCEEDED( rv) && (nsnull != ccm)) {
00183                      // get an unicode converter
00184                      rv = ccm->GetUnicodeDecoder(m_sysCharset.get(), &m_pDecoder);
00185               }          
00186        }
00187 
00188        if (m_pDecoder) {
00189               PRInt32              srcLen = PL_strlen( sysStr);
00190               PRUnichar *   unichars;
00191               PRInt32 unicharLength = 0;
00192               rv = m_pDecoder->GetMaxLength( sysStr, srcLen, &unicharLength);
00193               // allocale an output buffer
00194               unichars = (PRUnichar *) PR_Malloc(unicharLength * sizeof(PRUnichar));
00195               if (unichars != nsnull) {
00196                      // convert to unicode
00197                      rv = m_pDecoder->Convert( sysStr, &srcLen, unichars, &unicharLength);
00198                      uniStr.Assign(unichars, unicharLength);
00199                      PR_Free(unichars);
00200               }
00201               else
00202                      rv = NS_ERROR_OUT_OF_MEMORY;
00203        }
00204        
00205        if (NS_FAILED( rv))
00206               uniStr.AssignWithConversion( sysStr);
00207 
00208        return( rv);
00209 }
00210 
00211 NS_IMETHODIMP nsImportService::SystemStringFromUnicode(const PRUnichar *uniStr, nsCString & sysStr)
00212 {
00213        nsresult      rv;
00214        if (m_sysCharset.IsEmpty()) {
00215               nsCOMPtr <nsIPlatformCharset> platformCharset = do_GetService(NS_PLATFORMCHARSET_CONTRACTID, &rv);
00216               if (NS_SUCCEEDED(rv)) 
00217                      rv = platformCharset->GetCharset(kPlatformCharsetSel_FileName, m_sysCharset);
00218 
00219               if (NS_FAILED(rv)) 
00220                      m_sysCharset.AssignLiteral("ISO-8859-1");
00221        }
00222 
00223        if (!uniStr) {
00224               sysStr.Truncate();
00225               return NS_OK;
00226        }
00227 
00228        if (*uniStr == '\0') {
00229               sysStr.Truncate();
00230               return NS_OK;
00231        }
00232 
00233        if (m_sysCharset.IsEmpty() ||
00234               m_sysCharset.LowerCaseEqualsLiteral("us-ascii") ||
00235               m_sysCharset.LowerCaseEqualsLiteral("iso-8859-1")) {
00236               sysStr.AssignWithConversion(uniStr);
00237               return NS_OK;
00238        }
00239 
00240        if (!m_pEncoder) {
00241               nsCOMPtr<nsICharsetConverterManager> ccm = do_GetService(NS_CHARSETCONVERTERMANAGER_CONTRACTID, &rv);
00242 
00243               if (NS_SUCCEEDED(rv) && (nsnull != ccm)) {
00244                      // get an unicode converter
00245                      rv = ccm->GetUnicodeEncoder(m_sysCharset.get(), &m_pEncoder);
00246       if (NS_SUCCEEDED(rv))
00247         rv = m_pEncoder->SetOutputErrorBehavior(nsIUnicodeEncoder::kOnError_Replace, nsnull, '?');
00248               }
00249        }
00250 
00251        if (m_pEncoder) {
00252               PRInt32 srcLen = nsCRT::strlen(uniStr);
00253               char *  chars;
00254               PRInt32 charLength = 0;
00255 
00256               rv = m_pEncoder->GetMaxLength( uniStr, srcLen, &charLength);
00257               // allocale an output buffer
00258               chars = NS_STATIC_CAST(char*, nsMemory::Alloc((charLength + 1) * sizeof(char)));
00259               if (chars != nsnull) {
00260                      // convert to unicode
00261                      rv = m_pEncoder->Convert( uniStr, &srcLen, chars, &charLength);
00262                      sysStr.Assign(chars, charLength);
00263                      nsMemory::Free(chars);
00264               }
00265               else
00266                      rv = NS_ERROR_OUT_OF_MEMORY;
00267        }
00268        
00269        if (NS_FAILED( rv))
00270               sysStr.AssignWithConversion(uniStr);
00271 
00272        return rv;
00273 }
00274 
00275 extern nsresult NS_NewGenericMail(nsIImportGeneric** aImportGeneric);
00276 
00277 NS_IMETHODIMP nsImportService::CreateNewGenericMail(nsIImportGeneric **_retval)
00278 {
00279     NS_PRECONDITION(_retval != nsnull, "null ptr");
00280     if (! _retval)
00281         return NS_ERROR_NULL_POINTER;
00282 
00283        return( NS_NewGenericMail( _retval));
00284 }
00285 
00286 extern nsresult NS_NewGenericAddressBooks(nsIImportGeneric** aImportGeneric);
00287 
00288 NS_IMETHODIMP nsImportService::CreateNewGenericAddressBooks(nsIImportGeneric **_retval)
00289 {
00290     NS_PRECONDITION(_retval != nsnull, "null ptr");
00291     if (! _retval)
00292         return NS_ERROR_NULL_POINTER;
00293 
00294        return( NS_NewGenericAddressBooks( _retval));
00295 }
00296 
00297 
00298 NS_IMETHODIMP nsImportService::GetModuleCount( const char *filter, PRInt32 *_retval)
00299 {
00300     NS_PRECONDITION(_retval != nsnull, "null ptr");
00301     if (! _retval)
00302         return NS_ERROR_NULL_POINTER;
00303 
00304        DoDiscover();
00305        
00306        if (m_pModules != nsnull) {
00307               ImportModuleDesc *   pDesc;
00308               PRInt32       count = 0;
00309               for (PRInt32 i = 0; i < m_pModules->GetCount(); i++) {
00310                      pDesc = m_pModules->GetModuleDesc( i);
00311                      if (pDesc->SupportsThings( filter))
00312                             count++;
00313               }
00314               *_retval = count;
00315        }
00316        else
00317               *_retval = 0;
00318               
00319        return( NS_OK);
00320 }
00321        
00322 NS_IMETHODIMP nsImportService::GetModuleWithCID( const nsCID& cid, nsIImportModule **ppModule)
00323 {
00324     NS_PRECONDITION(ppModule != nsnull, "null ptr");
00325     if (! ppModule)
00326         return NS_ERROR_NULL_POINTER;
00327        
00328        *ppModule = nsnull;
00329        nsresult rv = DoDiscover();
00330        if (NS_FAILED( rv)) return( rv);
00331        if (m_pModules == nsnull) return( NS_ERROR_FAILURE);
00332        PRInt32       cnt = m_pModules->GetCount();
00333        ImportModuleDesc *pDesc;
00334        for (PRInt32 i = 0; i < cnt; i++) {
00335               pDesc = m_pModules->GetModuleDesc( i);
00336               if (!pDesc) return( NS_ERROR_FAILURE);
00337               if (pDesc->GetCID().Equals( cid)) {
00338                      *ppModule = pDesc->GetModule();
00339                      
00340                      IMPORT_LOG0( "* nsImportService::GetSpecificModule - attempted to load module\n");
00341                      
00342                      if (*ppModule == nsnull)
00343                             return( NS_ERROR_FAILURE);
00344                      else
00345                             return( NS_OK);
00346               }
00347        }
00348        
00349        IMPORT_LOG0( "* nsImportService::GetSpecificModule - module not found\n");
00350        
00351        return( NS_ERROR_NOT_AVAILABLE);
00352 }
00353 
00354 NS_IMETHODIMP nsImportService::GetModuleInfo( const char *filter, PRInt32 index, PRUnichar **name, PRUnichar **moduleDescription)
00355 {
00356     NS_PRECONDITION(name != nsnull, "null ptr");
00357     NS_PRECONDITION(moduleDescription != nsnull, "null ptr");
00358     if (!name || !moduleDescription)
00359         return NS_ERROR_NULL_POINTER;
00360     
00361        *name = nsnull;
00362        *moduleDescription = nsnull;
00363 
00364     DoDiscover();
00365     if (!m_pModules)
00366               return( NS_ERROR_FAILURE);
00367        
00368        if ((index < 0) || (index >= m_pModules->GetCount()))
00369               return( NS_ERROR_FAILURE);
00370        
00371        ImportModuleDesc *   pDesc;
00372        PRInt32       count = 0;
00373        for (PRInt32 i = 0; i < m_pModules->GetCount(); i++) {
00374               pDesc = m_pModules->GetModuleDesc( i);
00375               if (pDesc->SupportsThings( filter)) {
00376                      if (count == index) {
00377                             *name = nsCRT::strdup( pDesc->GetName());
00378                             *moduleDescription = nsCRT::strdup( pDesc->GetDescription());
00379                             return( NS_OK);
00380                      }
00381                      else
00382                             count++;
00383               }
00384        }
00385 
00386        return( NS_ERROR_FAILURE);
00387 }
00388 
00389 NS_IMETHODIMP nsImportService::GetModuleName(const char *filter, PRInt32 index, PRUnichar **_retval)
00390 {
00391     NS_PRECONDITION(_retval != nsnull, "null ptr");
00392     if (!_retval)
00393         return NS_ERROR_NULL_POINTER;
00394        
00395        *_retval = nsnull;
00396            
00397     DoDiscover();
00398     if (!m_pModules)
00399               return( NS_ERROR_FAILURE);
00400        
00401        if ((index < 0) || (index >= m_pModules->GetCount()))
00402               return( NS_ERROR_FAILURE);
00403        
00404        ImportModuleDesc *   pDesc;
00405        PRInt32       count = 0;
00406        for (PRInt32 i = 0; i < m_pModules->GetCount(); i++) {
00407               pDesc = m_pModules->GetModuleDesc( i);
00408               if (pDesc->SupportsThings( filter)) {
00409                      if (count == index) {
00410                             *_retval = nsCRT::strdup( pDesc->GetName());
00411                             return( NS_OK);
00412                      }
00413                      else
00414                             count++;
00415               }
00416        }
00417        
00418        return( NS_ERROR_FAILURE);
00419 }
00420 
00421 
00422 NS_IMETHODIMP nsImportService::GetModuleDescription(const char *filter, PRInt32 index, PRUnichar **_retval)
00423 {
00424     NS_PRECONDITION(_retval != nsnull, "null ptr");
00425     if (!_retval)
00426         return NS_ERROR_NULL_POINTER;
00427     
00428        *_retval = nsnull;
00429 
00430     DoDiscover();
00431     if (!m_pModules)
00432               return( NS_ERROR_FAILURE);
00433        
00434        if ((index < 0) || (index >= m_pModules->GetCount()))
00435               return( NS_ERROR_FAILURE);
00436        
00437        ImportModuleDesc *   pDesc;
00438        PRInt32       count = 0;
00439        for (PRInt32 i = 0; i < m_pModules->GetCount(); i++) {
00440               pDesc = m_pModules->GetModuleDesc( i);
00441               if (pDesc->SupportsThings( filter)) {
00442                      if (count == index) {
00443                             *_retval = nsCRT::strdup( pDesc->GetDescription());
00444                             return( NS_OK);
00445                      }
00446                      else
00447                             count++;
00448               }
00449        }
00450        
00451        return( NS_ERROR_FAILURE);
00452 }
00453 
00454 
00455 
00456 NS_IMETHODIMP nsImportService::GetModule( const char *filter, PRInt32 index, nsIImportModule **_retval)
00457 {
00458     NS_PRECONDITION(_retval != nsnull, "null ptr");
00459     if (!_retval)
00460         return NS_ERROR_NULL_POINTER;
00461        *_retval = nsnull;
00462 
00463     DoDiscover();
00464     if (!m_pModules)
00465               return( NS_ERROR_FAILURE);
00466               
00467        if ((index < 0) || (index >= m_pModules->GetCount()))
00468               return( NS_ERROR_FAILURE);
00469        
00470        ImportModuleDesc *   pDesc;
00471        PRInt32       count = 0;
00472        for (PRInt32 i = 0; i < m_pModules->GetCount(); i++) {
00473               pDesc = m_pModules->GetModuleDesc( i);
00474               if (pDesc->SupportsThings( filter)) {
00475                      if (count == index) {
00476                             *_retval = pDesc->GetModule();
00477                             break;
00478                      }
00479                      else
00480                             count++;
00481               }
00482        }
00483        if (! (*_retval))
00484               return( NS_ERROR_FAILURE);
00485 
00486        return( NS_OK);
00487 }
00488 
00489 
00490 nsresult nsImportService::DoDiscover( void)
00491 {      
00492        if (m_didDiscovery)
00493               return( NS_OK);
00494        
00495        if (m_pModules != nsnull)
00496               m_pModules->ClearList();
00497                   
00498     nsresult rv;
00499        
00500        nsCOMPtr<nsICategoryManager> catMan = do_GetService( NS_CATEGORYMANAGER_CONTRACTID, &rv);
00501        if (NS_FAILED( rv)) return( rv);
00502     
00503        nsCOMPtr<nsISimpleEnumerator> e;
00504        rv = catMan->EnumerateCategory( "mailnewsimport", getter_AddRefs( e));
00505        if (NS_FAILED( rv)) return( rv);
00506        nsCOMPtr<nsISupportsCString> contractid;
00507        rv = e->GetNext( getter_AddRefs( contractid));
00508        while (NS_SUCCEEDED( rv) && contractid) {
00509               nsXPIDLCString       contractIdStr;
00510               contractid->ToString( getter_Copies( contractIdStr));
00511               nsXPIDLCString       supportsStr;
00512               rv = catMan->GetCategoryEntry( "mailnewsimport", contractIdStr, getter_Copies( supportsStr));
00513               if (NS_SUCCEEDED( rv)) {
00514                      LoadModuleInfo( contractIdStr, supportsStr);
00515               }
00516               rv = e->GetNext( getter_AddRefs( contractid));
00517        }
00518 
00519        m_didDiscovery = PR_TRUE;
00520        
00521     return NS_OK;
00522 }
00523 
00524 nsresult nsImportService::LoadModuleInfo( const char *pClsId, const char *pSupports)
00525 {
00526        if (!pClsId || !pSupports)
00527               return( NS_OK);
00528 
00529        if (m_pModules == nsnull)
00530               m_pModules = new nsImportModuleList();
00531               
00532        // load the component and get all of the info we need from it....
00533        // then call AddModule
00534        nsresult      rv;
00535 
00536        nsCID                       clsId;
00537        clsId.Parse( pClsId);
00538        nsIImportModule *    module;
00539        rv = CallCreateInstance( clsId, &module);
00540        if (NS_FAILED(rv)) return rv;
00541        
00542        nsString      theTitle;     
00543        nsString      theDescription;
00544        PRUnichar *   pName;
00545        rv = module->GetName( &pName);
00546        if (NS_SUCCEEDED( rv)) {
00547               theTitle = pName;
00548                 nsMemory::Free(pName);
00549        }
00550        else
00551               theTitle.AssignLiteral("Unknown");
00552               
00553        rv = module->GetDescription( &pName);
00554        if (NS_SUCCEEDED( rv)) {
00555               theDescription = pName;
00556                 nsMemory::Free(pName);
00557        }
00558        else
00559               theDescription.AssignLiteral("Unknown description");
00560        
00561        // call the module to get the info we need
00562        m_pModules->AddModule( clsId, pSupports, theTitle.get(), theDescription.get());
00563        
00564        module->Release();
00565        
00566        return NS_OK;
00567 }
00568 
00569 
00570 nsIImportModule *ImportModuleDesc::GetModule( PRBool keepLoaded)
00571 {
00572        if (m_pModule) {
00573               m_pModule->AddRef();
00574               return( m_pModule);
00575        }
00576        
00577        nsresult      rv;
00578        rv = CallCreateInstance( m_cid, &m_pModule);
00579        if (NS_FAILED(rv)) {
00580               m_pModule = nsnull;
00581               return nsnull;
00582        }
00583        
00584        if (keepLoaded) {
00585               m_pModule->AddRef();
00586               return( m_pModule);
00587        }
00588        else {
00589               nsIImportModule *pModule = m_pModule;
00590               m_pModule = nsnull;
00591               return( pModule);
00592        }
00593 }
00594 
00595 void ImportModuleDesc::ReleaseModule( void)
00596 {
00597        if (m_pModule) {
00598               m_pModule->Release();
00599               m_pModule = nsnull;
00600        }
00601 }
00602 
00603 PRBool ImportModuleDesc::SupportsThings( const char *pThings)
00604 {
00605        if (!pThings)
00606               return( PR_TRUE);
00607        if (!(*pThings))
00608               return( PR_TRUE);
00609 
00610        nsCString     thing(pThings);
00611        nsCString     item;
00612        PRInt32              idx;
00613        
00614        while ((idx = thing.FindChar( ',')) != -1) {
00615               thing.Left( item, idx);
00616               item.Trim( kWhitespace);
00617               ToLowerCase(item);
00618               if (item.Length() && (m_supports.Find( item) == -1))
00619                      return( PR_FALSE);
00620               thing.Right( item, thing.Length() - idx - 1);
00621               thing = item;
00622        }
00623        thing.Trim( kWhitespace);
00624        ToLowerCase(thing);
00625        if (thing.Length() && (m_supports.Find( thing) == -1))
00626               return( PR_FALSE);
00627        
00628        return( PR_TRUE);
00629 }
00630 
00631 void nsImportModuleList::ClearList( void)
00632 {
00633        if (m_pList != nsnull) {
00634               for (int i = 0; i < m_count; i++) {
00635                      if (m_pList[i] != nsnull)
00636                             delete m_pList[i];   
00637                      m_pList[i] = nsnull;
00638               }
00639               m_count = 0;
00640               delete [] m_pList;
00641               m_pList = nsnull;
00642               m_alloc = 0;
00643        }
00644        
00645 }
00646 
00647 void nsImportModuleList::AddModule( const nsCID& cid, const char *pSupports, const PRUnichar *pName, const PRUnichar *pDesc)
00648 {
00649        if (m_pList == nsnull) {
00650               m_alloc = 10;
00651               m_pList = new ImportModuleDesc *[m_alloc];
00652               m_count = 0;
00653               memset( m_pList, 0, sizeof( ImportModuleDesc *) * m_alloc);
00654        }
00655        
00656        if (m_count == m_alloc) {
00657               ImportModuleDesc **pList = new ImportModuleDesc *[m_alloc + 10];
00658               memset( &(pList[m_alloc]), 0, sizeof( ImportModuleDesc *) * 10);
00659               memcpy( pList, m_pList, sizeof( ImportModuleDesc *) * m_alloc);
00660     for(int i = 0; i < m_count; i++)
00661       delete m_pList[i];
00662     delete [] m_pList;
00663               m_pList = pList;
00664               m_alloc += 10;
00665        }
00666        
00667        m_pList[m_count] = new ImportModuleDesc();
00668        m_pList[m_count]->SetCID( cid);
00669        m_pList[m_count]->SetSupports( pSupports);
00670        m_pList[m_count]->SetName( pName);
00671        m_pList[m_count]->SetDescription( pDesc);
00672        
00673        m_count++;
00674 #ifdef IMPORT_DEBUG
00675        nsCString     name; name.AssignWithConversion( pName);
00676        nsCString     desc; desc.AssignWithConversion( pDesc);
00677        IMPORT_LOG3( "* nsImportService registered import module: %s, %s, %s\n", name.get(), desc.get(), pSupports);
00678 #endif
00679 }