Back to index

lightning-sunbird  0.9+nobinonly
nsMimeTypeArray.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
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 #include "nsMimeTypeArray.h"
00040 #include "nsContentUtils.h"
00041 #include "nsIScriptGlobalObject.h"
00042 #include "nsIDOMNavigator.h"
00043 #include "nsIDOMPluginArray.h"
00044 #include "nsIDOMPlugin.h"
00045 #include "nsDOMClassInfo.h"
00046 #include "nsIMIMEService.h"
00047 #include "nsIMIMEInfo.h"
00048 #include "nsIFile.h"
00049 
00050 
00051 nsMimeTypeArray::nsMimeTypeArray(nsIDOMNavigator* navigator)
00052 {
00053   mNavigator = navigator;
00054   mMimeTypeCount = 0;
00055   mMimeTypeArray = nsnull;
00056 }
00057 
00058 nsMimeTypeArray::~nsMimeTypeArray()
00059 {
00060   Clear();
00061 }
00062 
00063 
00064 // QueryInterface implementation for nsMimeTypeArray
00065 NS_INTERFACE_MAP_BEGIN(nsMimeTypeArray)
00066   NS_INTERFACE_MAP_ENTRY(nsISupports)
00067   NS_INTERFACE_MAP_ENTRY(nsIDOMMimeTypeArray)
00068   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(MimeTypeArray)
00069 NS_INTERFACE_MAP_END
00070 
00071 
00072 NS_IMPL_ADDREF(nsMimeTypeArray)
00073 NS_IMPL_RELEASE(nsMimeTypeArray)
00074 
00075 
00076 NS_IMETHODIMP
00077 nsMimeTypeArray::GetLength(PRUint32* aLength)
00078 {
00079   if (mMimeTypeArray == nsnull) {
00080     nsresult rv = GetMimeTypes();
00081     if (rv != NS_OK)
00082       return rv;
00083   }
00084   *aLength = mMimeTypeCount;
00085   return NS_OK;
00086 }
00087 
00088 NS_IMETHODIMP
00089 nsMimeTypeArray::Item(PRUint32 aIndex, nsIDOMMimeType** aReturn)
00090 {
00091   if (mMimeTypeArray == nsnull) {
00092     nsresult rv = GetMimeTypes();
00093     if (rv != NS_OK)
00094       return rv;
00095   }
00096   if (aIndex < mMimeTypeCount) {
00097     *aReturn = mMimeTypeArray[aIndex];
00098     NS_IF_ADDREF(*aReturn);
00099     return NS_OK;
00100   }
00101   return NS_ERROR_FAILURE;
00102 }
00103 
00104 NS_IMETHODIMP
00105 nsMimeTypeArray::NamedItem(const nsAString& aName, nsIDOMMimeType** aReturn)
00106 {
00107   NS_ENSURE_ARG_POINTER(aReturn);
00108   *aReturn = nsnull;
00109 
00110   if (mMimeTypeArray == nsnull) {
00111     nsresult rv = GetMimeTypes();
00112     if (rv != NS_OK)
00113       return rv;
00114   }
00115 
00116   nsAutoString type;
00117 
00118   for (PRUint32 i = 0; i < mMimeTypeCount; i++) {
00119     nsIDOMMimeType *mtype = mMimeTypeArray[i];
00120 
00121     mtype->GetType(type);
00122 
00123     if (type.Equals(aName)) {
00124       *aReturn = mtype;
00125 
00126       NS_ADDREF(*aReturn);
00127 
00128       return NS_OK;
00129     }
00130   }
00131 
00132   // Now let's check with the MIME service.
00133   nsCOMPtr<nsIMIMEService> mimeSrv = do_GetService("@mozilla.org/mime;1");
00134   if (mimeSrv) {
00135     nsCOMPtr<nsIMIMEInfo> mimeInfo;
00136     mimeSrv->GetFromTypeAndExtension(NS_ConvertUCS2toUTF8(aName), EmptyCString(),
00137                                      getter_AddRefs(mimeInfo));
00138     if (mimeInfo) {
00139       // Now we check whether we can really claim to support this type
00140       nsMIMEInfoHandleAction action = nsIMIMEInfo::saveToDisk;
00141       mimeInfo->GetPreferredAction(&action);
00142       if (action != nsIMIMEInfo::handleInternally) {
00143         PRBool hasHelper = PR_FALSE;
00144         mimeInfo->GetHasDefaultHandler(&hasHelper);
00145         if (!hasHelper) {
00146           nsCOMPtr<nsIFile> helper;
00147           mimeInfo->GetPreferredApplicationHandler(getter_AddRefs(helper));
00148           if (!helper) {
00149             // mime info from the OS may not have a PreferredApplicationHandler
00150             // so just check for an empty default description
00151             nsAutoString defaultDescription;
00152             mimeInfo->GetDefaultDescription(defaultDescription);
00153             if (defaultDescription.IsEmpty()) {
00154               // no support; just leave
00155               return NS_OK;
00156             }
00157           }
00158         }
00159       }
00160 
00161       // If we got here, we support this type!  Say so.
00162       nsCOMPtr<nsIDOMMimeType> helper = new nsHelperMimeType(aName);
00163       if (!helper) {
00164         return NS_ERROR_OUT_OF_MEMORY;
00165       }
00166       nsCOMPtr<nsIDOMMimeType> entry = new nsMimeType(nsnull, helper);
00167       if (!entry) {
00168         return NS_ERROR_OUT_OF_MEMORY;
00169       }
00170 
00171       entry.swap(*aReturn);
00172     }
00173   }
00174 
00175   return NS_OK;
00176 }
00177 
00178 void  nsMimeTypeArray::Clear()
00179 {
00180   if (mMimeTypeArray != nsnull) {
00181     for (PRUint32 i = 0; i < mMimeTypeCount; i++) {
00182       NS_IF_RELEASE(mMimeTypeArray[i]);
00183     }
00184     delete[] mMimeTypeArray;
00185     mMimeTypeArray = nsnull;
00186   }
00187   mMimeTypeCount = 0;
00188 }
00189 
00190 nsresult nsMimeTypeArray::Refresh()
00191 {
00192   Clear();
00193   return GetMimeTypes();
00194 }
00195 
00196 nsresult nsMimeTypeArray::GetMimeTypes()
00197 {
00198   NS_PRECONDITION(!mMimeTypeArray && mMimeTypeCount==0,
00199                       "already initialized");
00200 
00201   nsIDOMPluginArray* pluginArray = nsnull;
00202   nsresult rv = mNavigator->GetPlugins(&pluginArray);
00203   if (rv == NS_OK) {
00204     // count up all possible MimeTypes, and collect them here. Later,
00205     // we'll remove duplicates.
00206     mMimeTypeCount = 0;
00207     PRUint32 pluginCount = 0;
00208     rv = pluginArray->GetLength(&pluginCount);
00209     if (rv == NS_OK) {
00210       PRUint32 i;
00211       for (i = 0; i < pluginCount; i++) {
00212         nsIDOMPlugin* plugin = nsnull;
00213         if (NS_SUCCEEDED(pluginArray->Item(i, &plugin)) &&
00214             plugin) {
00215           PRUint32 mimeTypeCount = 0;
00216           if (plugin->GetLength(&mimeTypeCount) == NS_OK)
00217             mMimeTypeCount += mimeTypeCount;
00218           NS_RELEASE(plugin);
00219         }
00220       }
00221       // now we know how many there are, start gathering them.
00222       mMimeTypeArray = new nsIDOMMimeType*[mMimeTypeCount];
00223       if (mMimeTypeArray == nsnull)
00224         return NS_ERROR_OUT_OF_MEMORY;
00225       PRUint32 mimeTypeIndex = 0;
00226       PRUint32 k;
00227       for (k = 0; k < pluginCount; k++) {
00228         nsIDOMPlugin* plugin = nsnull;
00229         if (pluginArray->Item(k, &plugin) == NS_OK) {
00230           PRUint32 mimeTypeCount = 0;
00231           if (plugin->GetLength(&mimeTypeCount) == NS_OK) {
00232             for (PRUint32 j = 0; j < mimeTypeCount; j++)
00233               plugin->Item(j, &mMimeTypeArray[mimeTypeIndex++]);
00234           }
00235           NS_RELEASE(plugin);
00236         }
00237       }
00238     }
00239     NS_RELEASE(pluginArray);
00240   }
00241   return rv;
00242 }
00243 
00244 nsMimeType::nsMimeType(nsIDOMPlugin* aPlugin, nsIDOMMimeType* aMimeType)
00245 {
00246   mPlugin = aPlugin;
00247   mMimeType = aMimeType;
00248 }
00249 
00250 nsMimeType::~nsMimeType()
00251 {
00252 }
00253 
00254 
00255 // QueryInterface implementation for nsMimeType
00256 NS_INTERFACE_MAP_BEGIN(nsMimeType)
00257   NS_INTERFACE_MAP_ENTRY(nsISupports)
00258   NS_INTERFACE_MAP_ENTRY(nsIDOMMimeType)
00259   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(MimeType)
00260 NS_INTERFACE_MAP_END
00261 
00262 
00263 NS_IMPL_ADDREF(nsMimeType)
00264 NS_IMPL_RELEASE(nsMimeType)
00265 
00266 
00267 NS_IMETHODIMP
00268 nsMimeType::GetDescription(nsAString& aDescription)
00269 {
00270   return mMimeType->GetDescription(aDescription);
00271 }
00272 
00273 NS_IMETHODIMP
00274 nsMimeType::GetEnabledPlugin(nsIDOMPlugin** aEnabledPlugin)
00275 {
00276   nsAutoString type;
00277   GetType(type);
00278 
00279   PRBool disabled = PR_FALSE;
00280 
00281   if (type.Length() == 1 && type.First() == '*') {
00282     // Check if the default plugin is disabled.
00283     disabled = nsContentUtils::GetBoolPref("plugin.default_plugin_disabled");
00284   }
00285 
00286   *aEnabledPlugin = disabled ? nsnull : mPlugin;
00287 
00288   NS_IF_ADDREF(*aEnabledPlugin);
00289 
00290   return NS_OK;
00291 }
00292 
00293 NS_IMETHODIMP
00294 nsMimeType::GetSuffixes(nsAString& aSuffixes)
00295 {
00296   return mMimeType->GetSuffixes(aSuffixes);
00297 }
00298 
00299 NS_IMETHODIMP
00300 nsMimeType::GetType(nsAString& aType)
00301 {
00302   return mMimeType->GetType(aType);
00303 }
00304 
00305 // QueryInterface implementation for nsHelperMimeType
00306 NS_IMPL_ISUPPORTS1(nsHelperMimeType, nsIDOMMimeType)
00307 
00308 NS_IMETHODIMP
00309 nsHelperMimeType::GetDescription(nsAString& aDescription)
00310 {
00311   aDescription.Truncate();
00312   return NS_OK;
00313 }
00314 
00315 NS_IMETHODIMP
00316 nsHelperMimeType::GetEnabledPlugin(nsIDOMPlugin** aEnabledPlugin)
00317 {
00318   *aEnabledPlugin = nsnull;
00319   return NS_OK;
00320 }
00321 
00322 NS_IMETHODIMP
00323 nsHelperMimeType::GetSuffixes(nsAString& aSuffixes)
00324 {
00325   aSuffixes.Truncate();
00326   return NS_OK;
00327 }
00328 
00329 NS_IMETHODIMP
00330 nsHelperMimeType::GetType(nsAString& aType)
00331 {
00332   aType = mType;
00333   return NS_OK;
00334 }
00335