Back to index

lightning-sunbird  0.9+nobinonly
nsIconChannel.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
00002  *
00003  * ***** BEGIN LICENSE BLOCK *****
00004  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00005  *
00006  * The contents of this file are subject to the Mozilla Public License Version
00007  * 1.1 (the "License"); you may not use this file except in compliance with
00008  * the License. You may obtain a copy of the License at
00009  * http://www.mozilla.org/MPL/
00010  *
00011  * Software distributed under the License is distributed on an "AS IS" basis,
00012  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00013  * for the specific language governing rights and limitations under the
00014  * License.
00015  *
00016  * The Original Code is mozilla.org code.
00017  *
00018  * The Initial Developer of the Original Code is
00019  * Brian Ryner.
00020  * Portions created by the Initial Developer are Copyright (C) 2000
00021  * the Initial Developer. All Rights Reserved.
00022  *
00023  * Contributor(s):
00024  *   Scott MacGregor          <mscott@mozilla.org>
00025  *   Robert John Churchill    <rjc@netscape.com>
00026  *   Josh Aas                 <josh@mozilla.com>
00027  *
00028  * Alternatively, the contents of this file may be used under the terms of
00029  * either the GNU General Public License Version 2 or later (the "GPL"), or
00030  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00031  * in which case the provisions of the GPL or the LGPL are applicable instead
00032  * of those above. If you wish to allow use of your version of this file only
00033  * under the terms of either the GPL or the LGPL, and not to allow others to
00034  * use your version of this file under the terms of the MPL, indicate your
00035  * decision by deleting the provisions above and replace them with the notice
00036  * and other provisions required by the GPL or the LGPL. If you do not delete
00037  * the provisions above, a recipient may use your version of this file under
00038  * the terms of any one of the MPL, the GPL or the LGPL.
00039  *
00040  * ***** END LICENSE BLOCK ***** */
00041 
00042 
00043 #include "nsIconChannel.h"
00044 #include "nsIIconURI.h"
00045 #include "nsIServiceManager.h"
00046 #include "nsIInterfaceRequestor.h"
00047 #include "nsIInterfaceRequestorUtils.h"
00048 #include "nsXPIDLString.h"
00049 #include "nsMimeTypes.h"
00050 #include "nsMemory.h"
00051 #include "nsIStringStream.h"
00052 #include "nsIURL.h"
00053 #include "nsNetUtil.h"
00054 #include "nsIMIMEService.h"
00055 #include "nsCExternalHandlerService.h"
00056 #include "plstr.h"
00057 #include "nsILocalFileMac.h"
00058 #include "nsIFileURL.h"
00059 #include "nsInt64.h"
00060 
00061 #include <Icons.h>
00062 #include <Files.h>
00063 #include <Folders.h>
00064 #include <Icons.h>
00065 #include <Quickdraw.h>
00066 #include <MacMemory.h>
00067 
00068 // nsIconChannel methods
00069 nsIconChannel::nsIconChannel()
00070 {
00071 }
00072 
00073 nsIconChannel::~nsIconChannel() 
00074 {}
00075 
00076 NS_IMPL_THREADSAFE_ISUPPORTS4(nsIconChannel, 
00077                               nsIChannel, 
00078                               nsIRequest,
00079                             nsIRequestObserver,
00080                             nsIStreamListener)
00081 
00082 nsresult nsIconChannel::Init(nsIURI* uri)
00083 {
00084   NS_ASSERTION(uri, "no uri");
00085   mUrl = uri;
00086   
00087   nsresult rv;
00088   mPump = do_CreateInstance(NS_INPUTSTREAMPUMP_CONTRACTID, &rv);
00089   return rv;
00090 }
00091 
00093 // nsIRequest methods:
00094 
00095 NS_IMETHODIMP nsIconChannel::GetName(nsACString &result)
00096 {
00097   return mUrl->GetSpec(result);
00098 }
00099 
00100 NS_IMETHODIMP nsIconChannel::IsPending(PRBool *result)
00101 {
00102   return mPump->IsPending(result);
00103 }
00104 
00105 NS_IMETHODIMP nsIconChannel::GetStatus(nsresult *status)
00106 {
00107   return mPump->GetStatus(status);
00108 }
00109 
00110 NS_IMETHODIMP nsIconChannel::Cancel(nsresult status)
00111 {
00112   return mPump->Cancel(status);
00113 }
00114 
00115 NS_IMETHODIMP nsIconChannel::Suspend(void)
00116 {
00117   return mPump->Suspend();
00118 }
00119 
00120 NS_IMETHODIMP nsIconChannel::Resume(void)
00121 {
00122   return mPump->Resume();
00123 }
00124 
00125 // nsIRequestObserver methods
00126 NS_IMETHODIMP nsIconChannel::OnStartRequest(nsIRequest* aRequest, nsISupports* aContext)
00127 {
00128   if (mListener)
00129     return mListener->OnStartRequest(this, aContext);
00130   return NS_OK;
00131 }
00132 
00133 NS_IMETHODIMP nsIconChannel::OnStopRequest(nsIRequest* aRequest, nsISupports* aContext, nsresult aStatus)
00134 {
00135   if (mListener) {
00136     mListener->OnStopRequest(this, aContext, aStatus);
00137     mListener = nsnull;
00138   }
00139 
00140   // Remove from load group
00141   if (mLoadGroup)
00142     mLoadGroup->RemoveRequest(this, nsnull, aStatus);
00143 
00144   return NS_OK;
00145 }
00146 
00147 // nsIStreamListener methods
00148 NS_IMETHODIMP nsIconChannel::OnDataAvailable(nsIRequest* aRequest,
00149                                              nsISupports* aContext,
00150                                              nsIInputStream* aStream,
00151                                              PRUint32 aOffset,
00152                                              PRUint32 aCount)
00153 {
00154   if (mListener)
00155     return mListener->OnDataAvailable(this, aContext, aStream, aOffset, aCount);
00156   return NS_OK;
00157 }
00158 
00160 // nsIChannel methods:
00161 
00162 NS_IMETHODIMP nsIconChannel::GetOriginalURI(nsIURI* *aURI)
00163 {
00164   *aURI = mOriginalURI ? mOriginalURI : mUrl;
00165   NS_ADDREF(*aURI);
00166   return NS_OK;
00167 }
00168 
00169 NS_IMETHODIMP nsIconChannel::SetOriginalURI(nsIURI* aURI)
00170 {
00171   mOriginalURI = aURI;
00172   return NS_OK;
00173 }
00174 
00175 NS_IMETHODIMP nsIconChannel::GetURI(nsIURI* *aURI)
00176 {
00177   *aURI = mUrl;
00178   NS_IF_ADDREF(*aURI);
00179   return NS_OK;
00180 }
00181 
00182 NS_IMETHODIMP
00183 nsIconChannel::Open(nsIInputStream **_retval)
00184 {
00185   return MakeInputStream(_retval, PR_FALSE);
00186 }
00187 
00188 nsresult nsIconChannel::ExtractIconInfoFromUrl(nsIFile ** aLocalFile, PRUint32 * aDesiredImageSize, nsACString &aContentType, nsACString &aFileExtension)
00189 {
00190   nsresult rv = NS_OK;
00191   nsCOMPtr<nsIMozIconURI> iconURI (do_QueryInterface(mUrl, &rv));
00192   NS_ENSURE_SUCCESS(rv, rv);
00193 
00194   iconURI->GetImageSize(aDesiredImageSize);
00195   iconURI->GetContentType(aContentType);
00196   iconURI->GetFileExtension(aFileExtension);
00197   
00198   nsCOMPtr<nsIURI> fileURI;
00199   rv = iconURI->GetIconFile(getter_AddRefs(fileURI));
00200   if (NS_FAILED(rv) || !fileURI) return NS_OK;
00201 
00202   nsCOMPtr<nsIFileURL> fileURL = do_QueryInterface(fileURI, &rv);
00203   if (NS_FAILED(rv) || !fileURL) return NS_OK;
00204 
00205   nsCOMPtr<nsIFile> file;
00206   rv = fileURL->GetFile(getter_AddRefs(file));
00207   if (NS_FAILED(rv) || !file) return NS_OK;
00208   
00209   nsCOMPtr<nsILocalFileMac> localFileMac (do_QueryInterface(file, &rv));
00210   if (NS_FAILED(rv) || !localFileMac) return NS_OK;
00211   
00212   *aLocalFile = file;
00213   NS_IF_ADDREF(*aLocalFile);
00214 
00215   return NS_OK;
00216 }
00217 
00218 nsresult
00219 GetLockedIconData(IconFamilyHandle iconFamilyH, PRUint32 iconType,
00220                            Handle iconDataH, PRUint32 *iconDataSize)
00221 {
00222   *iconDataSize = 0;
00223 
00224   if (::GetIconFamilyData(iconFamilyH, iconType, iconDataH) != noErr)
00225     return(NS_ERROR_FAILURE);
00226 
00227   *iconDataSize = (PRUint32)::GetHandleSize(iconDataH);
00228   if (*iconDataSize > 0)
00229   {
00230     ::HLock(iconDataH);
00231   }
00232   return(NS_OK);
00233 }
00234 
00235 
00236 nsresult
00237 GetLockedIcons(IconFamilyHandle icnFamily, PRUint32 desiredImageSize,
00238             Handle iconH, PRUint32 *dataCount, PRBool *isIndexedData,
00239             Handle iconMaskH, PRUint32 *maskCount, PRUint8 *alphaBitCount)
00240 {
00241   // note: this code could be improved by:
00242   //
00243   // o  adding support for icon scaling, i.e. if we want a
00244   //    32x32 icon but can only get a 16x16 icon (or vice versa),
00245   //    scale the pixels appropriately
00246   //
00247   // o  adding support for Mac OS X "huge" 128x128 icons with alpha
00248   //    which is also tricky as the alpha data defines the mask for the icon
00249 
00250   *dataCount = *maskCount = 0L;
00251 
00252   // make sure icon/mask handles are unlocked
00253   // so that they can move in memory
00254   HUnlock(iconH);
00255   HUnlock(iconMaskH);
00256 
00257   // Note: Always try and get 32bit non-indexed icons first
00258   // so that we don't have to worry about color palette issues        
00259   nsresult rv = GetLockedIconData(icnFamily, (desiredImageSize > 16) ?
00260                                   kLarge32BitData : kSmall32BitData,
00261                                   iconH, dataCount);
00262   if (NS_SUCCEEDED(rv) && (*dataCount > 0))
00263   {
00264     *isIndexedData = PR_FALSE;
00265   }
00266   else
00267   {
00268     // if couldn't get a 32bit non-indexed icon,
00269     // then try getting an 8-bit icon
00270     rv = GetLockedIconData(icnFamily, (desiredImageSize > 16) ?
00271                            kLarge8BitData : kSmall8BitData,
00272                            iconH, dataCount);
00273     if (NS_SUCCEEDED(rv) && (*dataCount > 0))
00274     {
00275       *isIndexedData = PR_TRUE;
00276     }
00277   }
00278 
00279   // if we have an icon, try getting a mask too
00280   if (NS_SUCCEEDED(rv) && (*dataCount > 0))
00281   {
00282     // try to get an 8-bit alpha mask first
00283     *alphaBitCount = 8;
00284     rv = GetLockedIconData(icnFamily, (desiredImageSize > 16) ?
00285                            kLarge8BitMask : kSmall8BitMask,
00286                            iconMaskH, maskCount);
00287     if (NS_FAILED(rv) || (*maskCount == 0)) {
00288       // oh well, try to get a 1-bit mask
00289       *alphaBitCount = 1;
00290       rv = GetLockedIconData(icnFamily, (desiredImageSize > 16) ?
00291                              kLarge1BitMask : kSmall1BitMask,
00292                              iconMaskH, maskCount);
00293       if (NS_FAILED(rv) || (*maskCount == 0))
00294       {
00295         // if we can't get a mask, the file's BNDL might be
00296         // messed up, etc.  Let's just fake a 1-bit mask
00297         // which will blit the entire icon... its not perfect,
00298         // but its better than no icon at all
00299         *maskCount = (desiredImageSize > 16) ? 256 : 64;
00300         rv = NS_OK;
00301       }
00302     }
00303   }
00304   return rv;
00305 }
00306 
00307 
00308 NS_IMETHODIMP nsIconChannel::AsyncOpen(nsIStreamListener *aListener, nsISupports *ctxt)
00309 {
00310   nsCOMPtr<nsIInputStream> inStream;
00311   nsresult rv = MakeInputStream(getter_AddRefs(inStream), PR_TRUE);
00312   NS_ENSURE_SUCCESS(rv, rv);
00313 
00314   // Init our stream pump
00315   rv = mPump->Init(inStream, nsInt64(-1), nsInt64(-1), 0, 0, PR_FALSE);
00316   NS_ENSURE_SUCCESS(rv, rv);
00317   
00318   rv = mPump->AsyncRead(this, ctxt);
00319   if (NS_SUCCEEDED(rv)) 
00320   {
00321     // Store our real listener
00322     mListener = aListener;
00323     // Add ourself to the load group, if available
00324     if (mLoadGroup)
00325       mLoadGroup->AddRequest(this, nsnull);
00326   }
00327 
00328   return rv;
00329 }
00330 
00331 nsresult nsIconChannel::MakeInputStream(nsIInputStream** _retval, PRBool nonBlocking)
00332   {
00333   nsXPIDLCString contentType;
00334   nsCAutoString fileExt;
00335   nsCOMPtr<nsIFile> fileloc; // file we want an icon for
00336   PRUint32 desiredImageSize;
00337   nsresult rv = ExtractIconInfoFromUrl(getter_AddRefs(fileloc), &desiredImageSize, contentType, fileExt);
00338   NS_ENSURE_SUCCESS(rv, rv);
00339 
00340   // ensure that we DO NOT resolve aliases, very important for file views
00341   nsCOMPtr<nsILocalFile>  localFile = do_QueryInterface(fileloc);
00342   if (localFile)
00343     localFile->SetFollowLinks(PR_FALSE);
00344 
00345   PRBool fileExists = PR_FALSE;
00346   if (fileloc)
00347     localFile->Exists(&fileExists);
00348 
00349   IconRef icnRef = nsnull;
00350   if (fileExists)
00351   {
00352     // if the file exists, first try getting icons via Icon Services
00353     nsCOMPtr<nsILocalFileMac> localFileMac (do_QueryInterface(fileloc, &rv));
00354     NS_ENSURE_SUCCESS(rv, rv);
00355 
00356     FSSpec spec;
00357     if (NS_FAILED(localFileMac->GetFSSpec(&spec)))
00358       return NS_ERROR_FAILURE;
00359 
00360     SInt16  label;
00361     if (::GetIconRefFromFile (&spec, &icnRef, &label) != noErr)
00362       return NS_ERROR_FAILURE;
00363   }
00364 
00365   // note: once we have an IconRef,
00366   // we MUST release it before exiting this method!
00367 
00368   // start with zero-sized icons which ::GetIconFamilyData will resize
00369   PRUint32 dataCount = 0L;
00370   PRUint32 maskCount = 0L;
00371   PRUint8 alphaBitsCount = 1;
00372   Handle iconH = ::NewHandle(dataCount);
00373   Handle iconMaskH = ::NewHandle(maskCount);
00374 
00375   PRUint8 *iconBitmapData = nsnull, *maskBitmapData = nsnull;
00376 
00377   PRBool  isIndexedData = PR_FALSE;
00378   IconFamilyHandle icnFamily;
00379   if (fileExists && (::IconRefToIconFamily(icnRef,
00380       kSelectorAllAvailableData, &icnFamily) == noErr))
00381   {
00382     GetLockedIcons(icnFamily, desiredImageSize, iconH,  &dataCount,
00383                    &isIndexedData, iconMaskH, &maskCount, &alphaBitsCount);
00384     if (dataCount > 0)
00385     {
00386       iconBitmapData = (PRUint8 *)*iconH;
00387       if (maskCount > 0)  maskBitmapData = (PRUint8 *)*iconMaskH;
00388     }
00389     ::DisposeHandle((Handle)icnFamily);
00390   }
00391   ::ReleaseIconRef(icnRef);
00392   icnRef = nsnull;
00393 
00394   if (!dataCount)
00395   {
00396     // if file didn't exist, or couldn't get an appropriate
00397     // icon resource, then try again by mimetype mapping
00398 
00399     nsCOMPtr<nsIMIMEService> mimeService (do_GetService(NS_MIMESERVICE_CONTRACTID, &rv));
00400     NS_ENSURE_SUCCESS(rv, rv);
00401 
00402     // if we were given an explicit content type, use it....
00403     nsCOMPtr<nsIMIMEInfo> mimeInfo;
00404     if (mimeService && (!contentType.IsEmpty() || !fileExt.IsEmpty()))
00405     {
00406       mimeService->GetFromTypeAndExtension(contentType,
00407                                            fileExt,
00408                                            getter_AddRefs(mimeInfo));
00409     }
00410 
00411     // if we don't have enough info to fetch an application icon, bail
00412     if (!mimeInfo)
00413     {
00414       if (iconH)      ::DisposeHandle(iconH);
00415       if (iconMaskH)  ::DisposeHandle(iconMaskH);
00416       return NS_ERROR_FAILURE;
00417     }
00418 
00419     // get the mac creator and file type for this mime object
00420     PRUint32 macType;
00421     PRUint32 macCreator;
00422     mimeInfo->GetMacType(&macType);
00423     mimeInfo->GetMacCreator(&macCreator);
00424 
00425     if (::GetIconRef(kOnSystemDisk, macCreator, macType, &icnRef) != noErr)
00426     {
00427       if (iconH)      ::DisposeHandle(iconH);
00428       if (iconMaskH)  ::DisposeHandle(iconMaskH);
00429       return(NS_ERROR_FAILURE);
00430     }
00431 
00432     if (::IconRefToIconFamily(icnRef, kSelectorAllAvailableData, &icnFamily) == noErr)
00433     {
00434       GetLockedIcons(icnFamily, desiredImageSize, iconH, &dataCount,
00435                      &isIndexedData, iconMaskH, &maskCount, &alphaBitsCount);
00436       if (dataCount > 0)
00437       {
00438         iconBitmapData = (PRUint8 *)*iconH;
00439         if (maskCount > 0)  maskBitmapData = (PRUint8 *)*iconMaskH;
00440       }
00441       ::DisposeHandle((Handle)icnFamily);
00442     }
00443     ::ReleaseIconRef(icnRef);
00444     icnRef = nsnull;
00445   }
00446 
00447   // note: we must have icon data, but it is OK to not
00448   // have maskBitmapData (we fake a mask in that case)
00449   if (!iconBitmapData)
00450   {
00451     if (iconH)      DisposeHandle(iconH);
00452     if (iconMaskH)  DisposeHandle(iconMaskH);
00453     return(NS_ERROR_FAILURE);
00454   }
00455 
00456   PRUint32 numPixelsInRow = (desiredImageSize > 16) ? 32 : 16;
00457   PRUint8  *bitmapData = (PRUint8 *)iconBitmapData;
00458 
00459   nsCString iconBuffer;
00460   iconBuffer.Assign((char) numPixelsInRow);
00461   iconBuffer.Append((char) numPixelsInRow);
00462   iconBuffer.Append((char) alphaBitsCount); // alpha bits per pixel
00463 
00464   CTabHandle cTabHandle = nsnull;
00465   CTabPtr colTable = nsnull;
00466   if (isIndexedData)
00467   {
00468     // only need the CTable if we have an palette-indexed icon
00469     cTabHandle = ::GetCTable(72);
00470     if (!cTabHandle)
00471     {
00472       if (iconH)      ::DisposeHandle(iconH);
00473       if (iconMaskH)  ::DisposeHandle(iconMaskH);
00474       return NS_ERROR_FAILURE;
00475     }
00476     ::HLock((Handle) cTabHandle);
00477     colTable = *cTabHandle;
00478   }
00479 
00480   RGBColor rgbCol;
00481   PRUint8 redValue, greenValue, blueValue;
00482   PRUint32 index = 0L;
00483   while (index < dataCount)
00484   {
00485     if (!isIndexedData)
00486     {
00487       // 32 bit icon data
00488       iconBuffer.Append((char) bitmapData[index++]);
00489       iconBuffer.Append((char) bitmapData[index++]);
00490       iconBuffer.Append((char) bitmapData[index++]);
00491       iconBuffer.Append((char) bitmapData[index++]);
00492     }
00493     else
00494     {
00495       // each byte in bitmapData needs to be converted from an 8 bit system color into 
00496       // 24 bit RGB data which our special icon image decoder can understand.
00497       ColorSpec colSpec =  colTable->ctTable[ bitmapData[index]];
00498       rgbCol = colSpec.rgb;
00499 
00500       redValue = rgbCol.red & 0xff;
00501       greenValue = rgbCol.green & 0xff;
00502       blueValue = rgbCol.blue & 0xff;
00503 
00504       iconBuffer.Append((char) 0);        // alpha channel byte
00505       iconBuffer.Append((char) redValue);
00506       iconBuffer.Append((char) greenValue);
00507       iconBuffer.Append((char) blueValue);
00508       index++;
00509     }
00510   }
00511   
00512   if (cTabHandle)
00513   {
00514     ::HUnlock((Handle) cTabHandle);
00515     ::DisposeCTable(cTabHandle);
00516   }
00517 
00518   ::DisposeHandle(iconH);
00519   iconH = nsnull;
00520 
00521   bitmapData = (PRUint8 *)maskBitmapData;
00522   if (maskBitmapData && alphaBitsCount == 1)
00523   {
00524     // skip over ICN# data to get to mask
00525     // which is half way into data
00526     index = maskCount / 2;
00527     while (index < maskCount)
00528     {
00529       iconBuffer.Append((char) bitmapData[index]);
00530       iconBuffer.Append((char) bitmapData[index + 1]);
00531 
00532       if (numPixelsInRow == 32)
00533       {
00534         iconBuffer.Append((char) bitmapData[index + 2]);
00535         iconBuffer.Append((char) bitmapData[index + 3]);
00536         index += 4;
00537       }
00538       else
00539       {
00540         iconBuffer.Append((char) 255); // 2 bytes of padding
00541         iconBuffer.Append((char) 255);
00542         index += 2;
00543       }
00544     }
00545   }
00546   else if (maskBitmapData && alphaBitsCount == 8) {
00547     index = 0;
00548     while (index < maskCount) {
00549       iconBuffer.Append((char)bitmapData[index]);
00550       index++;
00551     }
00552   }
00553   else
00554   {
00555     index = 0L;
00556     while (index++ < maskCount)
00557     {
00558       // edgecase: without a mask, just blit entire icon
00559       iconBuffer.Append((char) 255);
00560     }
00561   }
00562 
00563   if (iconMaskH)
00564   {
00565     ::DisposeHandle(iconMaskH);
00566     iconMaskH = nsnull;
00567   }
00568 
00569   // Now, create a pipe and stuff our data into it
00570   nsCOMPtr<nsIInputStream> inStream;
00571   nsCOMPtr<nsIOutputStream> outStream;
00572   PRUint32 iconSize = iconBuffer.Length();
00573   rv = NS_NewPipe(getter_AddRefs(inStream), getter_AddRefs(outStream), iconSize, iconSize, nonBlocking);  
00574 
00575   if (NS_SUCCEEDED(rv))
00576   {
00577     PRUint32 written;
00578     rv = outStream->Write(iconBuffer.get(), iconSize, &written);
00579     if (NS_SUCCEEDED(rv))
00580       NS_IF_ADDREF(*_retval = inStream);
00581   }
00582 
00583   // Drop notification callbacks to prevent cycles.
00584   mCallbacks = nsnull;
00585 
00586   return NS_OK;
00587 }
00588 
00589 NS_IMETHODIMP nsIconChannel::GetLoadFlags(PRUint32 *aLoadAttributes)
00590 {
00591   return mPump->GetLoadFlags(aLoadAttributes);
00592 }
00593 
00594 NS_IMETHODIMP nsIconChannel::SetLoadFlags(PRUint32 aLoadAttributes)
00595 {
00596   return mPump->SetLoadFlags(aLoadAttributes);
00597 }
00598 
00599 NS_IMETHODIMP nsIconChannel::GetContentType(nsACString &aContentType) 
00600 {
00601   aContentType.AssignLiteral("image/icon");
00602   return NS_OK;
00603 }
00604 
00605 NS_IMETHODIMP
00606 nsIconChannel::SetContentType(const nsACString &aContentType)
00607 {
00608   //It doesn't make sense to set the content-type on this type
00609   // of channel...
00610   return NS_ERROR_FAILURE;
00611 }
00612 
00613 NS_IMETHODIMP nsIconChannel::GetContentCharset(nsACString &aContentCharset) 
00614 {
00615   aContentCharset.AssignLiteral("image/icon");
00616   return NS_OK;
00617 }
00618 
00619 NS_IMETHODIMP
00620 nsIconChannel::SetContentCharset(const nsACString &aContentCharset)
00621 {
00622   //It doesn't make sense to set the content-type on this type
00623   // of channel...
00624   return NS_ERROR_FAILURE;
00625 }
00626 
00627 NS_IMETHODIMP nsIconChannel::GetContentLength(PRInt32 *aContentLength)
00628 {
00629   *aContentLength = mContentLength;
00630   return NS_OK;
00631 }
00632 
00633 NS_IMETHODIMP nsIconChannel::SetContentLength(PRInt32 aContentLength)
00634 {
00635   NS_NOTREACHED("nsIconChannel::SetContentLength");
00636   return NS_ERROR_NOT_IMPLEMENTED;
00637 }
00638 
00639 NS_IMETHODIMP nsIconChannel::GetLoadGroup(nsILoadGroup* *aLoadGroup)
00640 {
00641   *aLoadGroup = mLoadGroup;
00642   NS_IF_ADDREF(*aLoadGroup);
00643   return NS_OK;
00644 }
00645 
00646 NS_IMETHODIMP nsIconChannel::SetLoadGroup(nsILoadGroup* aLoadGroup)
00647 {
00648   mLoadGroup = aLoadGroup;
00649   return NS_OK;
00650 }
00651 
00652 NS_IMETHODIMP nsIconChannel::GetOwner(nsISupports* *aOwner)
00653 {
00654   *aOwner = mOwner.get();
00655   NS_IF_ADDREF(*aOwner);
00656   return NS_OK;
00657 }
00658 
00659 NS_IMETHODIMP nsIconChannel::SetOwner(nsISupports* aOwner)
00660 {
00661   mOwner = aOwner;
00662   return NS_OK;
00663 }
00664 
00665 NS_IMETHODIMP nsIconChannel::GetNotificationCallbacks(nsIInterfaceRequestor* *aNotificationCallbacks)
00666 {
00667   *aNotificationCallbacks = mCallbacks.get();
00668   NS_IF_ADDREF(*aNotificationCallbacks);
00669   return NS_OK;
00670 }
00671 
00672 NS_IMETHODIMP nsIconChannel::SetNotificationCallbacks(nsIInterfaceRequestor* aNotificationCallbacks)
00673 {
00674   mCallbacks = aNotificationCallbacks;
00675   return NS_OK;
00676 }
00677 
00678 NS_IMETHODIMP nsIconChannel::GetSecurityInfo(nsISupports * *aSecurityInfo)
00679 {
00680   *aSecurityInfo = nsnull;
00681   return NS_OK;
00682 }
00683