LCOV - code coverage report
Current view: directory - netwerk/streamconv/converters - nsBinHexDecoder.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 209 0 0.0 %
Date: 2012-06-02 Functions: 15 0 0.0 %

       1                 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2                 : /* ***** BEGIN LICENSE BLOCK *****
       3                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
       4                 :  *
       5                 :  * The contents of this file are subject to the Mozilla Public License Version
       6                 :  * 1.1 (the "License"); you may not use this file except in compliance with
       7                 :  * the License. You may obtain a copy of the License at
       8                 :  * http://www.mozilla.org/MPL/
       9                 :  *
      10                 :  * Software distributed under the License is distributed on an "AS IS" basis,
      11                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      12                 :  * for the specific language governing rights and limitations under the
      13                 :  * License.
      14                 :  *
      15                 :  * The Original Code is mozilla.org code.
      16                 :  *
      17                 :  * The Initial Developer of the Original Code is
      18                 :  * Netscape Communications Corporation.
      19                 :  * Portions created by the Initial Developer are Copyright (C) 1999
      20                 :  * the Initial Developer. All Rights Reserved.
      21                 :  *
      22                 :  * Contributor(s):
      23                 :  *   Scott MacGregor <mscott@netscape.com>
      24                 :  *
      25                 :  * Alternatively, the contents of this file may be used under the terms of
      26                 :  * either the GNU General Public License Version 2 or later (the "GPL"), or
      27                 :  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      28                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      29                 :  * of those above. If you wish to allow use of your version of this file only
      30                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      31                 :  * use your version of this file under the terms of the MPL, indicate your
      32                 :  * decision by deleting the provisions above and replace them with the notice
      33                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      34                 :  * the provisions above, a recipient may use your version of this file under
      35                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      36                 :  *
      37                 :  * ***** END LICENSE BLOCK ***** */
      38                 : 
      39                 : #include "nsIOService.h"
      40                 : #include "nsBinHexDecoder.h"
      41                 : #include "nsIServiceManager.h"
      42                 : #include "nsIStreamConverterService.h"
      43                 : #include "nsCRT.h"
      44                 : #include "nsIPipe.h"
      45                 : #include "nsMimeTypes.h"
      46                 : #include "netCore.h"
      47                 : #include "nsXPIDLString.h"
      48                 : #include "prnetdb.h"
      49                 : #include "nsIURI.h"
      50                 : #include "nsIURL.h"
      51                 : 
      52                 : #include "nsIMIMEService.h"
      53                 : #include "nsMimeTypes.h"
      54                 : 
      55                 : 
      56                 : // sadly I couldn't find char defintions for CR LF elsehwere in the code (they are defined as strings in nsCRT.h)
      57                 : #define CR  '\015'
      58                 : #define LF '\012'
      59                 : 
      60               0 : nsBinHexDecoder::nsBinHexDecoder() :
      61                 :   mState(0), mCRC(0), mFileCRC(0), mOctetin(26),
      62                 :   mDonePos(3), mInCRC(0), mCount(0), mMarker(0), mPosInbuff(0),
      63               0 :   mPosOutputBuff(0)
      64                 : {
      65               0 :   mDataBuffer = nsnull;
      66               0 :   mOutgoingBuffer = nsnull;
      67                 : 
      68               0 :   mOctetBuf.val = 0;
      69               0 :   mHeader.type = 0;
      70               0 :   mHeader.creator = 0;
      71               0 :   mHeader.flags = 0;
      72               0 :   mHeader.dlen = 0;
      73               0 :   mHeader.rlen = 0;
      74               0 : }
      75                 : 
      76               0 : nsBinHexDecoder::~nsBinHexDecoder()
      77                 : {
      78               0 :   if (mDataBuffer)
      79               0 :     nsMemory::Free(mDataBuffer);
      80               0 :   if (mOutgoingBuffer)
      81               0 :     nsMemory::Free(mOutgoingBuffer);
      82               0 : }
      83                 : 
      84               0 : NS_IMPL_ADDREF(nsBinHexDecoder)
      85               0 : NS_IMPL_RELEASE(nsBinHexDecoder)
      86                 : 
      87               0 : NS_INTERFACE_MAP_BEGIN(nsBinHexDecoder)
      88               0 :   NS_INTERFACE_MAP_ENTRY(nsIStreamConverter)
      89               0 :   NS_INTERFACE_MAP_ENTRY(nsIStreamListener)
      90               0 :   NS_INTERFACE_MAP_ENTRY(nsIRequestObserver)
      91               0 :   NS_INTERFACE_MAP_ENTRY(nsISupports)
      92               0 : NS_INTERFACE_MAP_END
      93                 : 
      94                 : 
      95                 : // The binhex 4.0 decoder table....
      96                 : 
      97                 : static signed char binhex_decode[256] =
      98                 : {
      99                 :   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
     100                 :   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
     101                 :   -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, -1, -1,
     102                 :   13, 14, 15, 16, 17, 18, 19, -1, 20, 21, -1, -1, -1, -1, -1, -1,
     103                 :   22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, -1,
     104                 :   37, 38, 39, 40, 41, 42, 43, -1, 44, 45, 46, 47, -1, -1, -1, -1,
     105                 :   48, 49, 50, 51, 52, 53, 54, -1, 55, 56, 57, 58, 59, 60, -1, -1,
     106                 :   61, 62, 63, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
     107                 :   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
     108                 :   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
     109                 :   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
     110                 :   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
     111                 :   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
     112                 :   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
     113                 :   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
     114                 :   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
     115                 : };
     116                 : 
     117                 : #define BHEXVAL(c) (binhex_decode[(unsigned char) c])
     118                 : 
     119                 : //////////////////////////////////////////////////////
     120                 : // nsIStreamConverter methods...
     121                 : //////////////////////////////////////////////////////
     122                 : 
     123                 : NS_IMETHODIMP
     124               0 : nsBinHexDecoder::Convert(nsIInputStream *aFromStream,
     125                 :                          const char *aFromType,
     126                 :                          const char *aToType,
     127                 :                          nsISupports *aCtxt,
     128                 :                          nsIInputStream **aResultStream)
     129                 : {
     130               0 :   return NS_ERROR_NOT_IMPLEMENTED;
     131                 : }
     132                 : 
     133                 : NS_IMETHODIMP
     134               0 : nsBinHexDecoder::AsyncConvertData(const char *aFromType,
     135                 :                                   const char *aToType,
     136                 :                                   nsIStreamListener *aListener,
     137                 :                                   nsISupports *aCtxt)
     138                 : {
     139               0 :   NS_ASSERTION(aListener && aFromType && aToType,
     140                 :                "null pointer passed into bin hex converter");
     141                 : 
     142                 :   // hook up our final listener. this guy gets the various On*() calls we want to throw
     143                 :   // at him.
     144                 :   //
     145               0 :   mNextListener = aListener;
     146               0 :   return (aListener) ? NS_OK : NS_ERROR_FAILURE;
     147                 : }
     148                 : 
     149                 : //////////////////////////////////////////////////////
     150                 : // nsIStreamListener methods...
     151                 : //////////////////////////////////////////////////////
     152                 : NS_IMETHODIMP
     153               0 : nsBinHexDecoder::OnDataAvailable(nsIRequest* request,
     154                 :                                  nsISupports *aCtxt,
     155                 :                                  nsIInputStream *aStream,
     156                 :                                  PRUint32 aSourceOffset,
     157                 :                                  PRUint32 aCount)
     158                 : {
     159               0 :   nsresult rv = NS_OK;
     160                 : 
     161               0 :   if (mOutputStream && mDataBuffer && aCount > 0)
     162                 :   {
     163               0 :     PRUint32 numBytesRead = 0;
     164               0 :     while (aCount > 0) // while we still have bytes to copy...
     165                 :     {
     166               0 :       aStream->Read(mDataBuffer, NS_MIN(aCount, nsIOService::gDefaultSegmentSize - 1), &numBytesRead);
     167               0 :       if (aCount >= numBytesRead)
     168               0 :         aCount -= numBytesRead; // subtract off the number of bytes we just read
     169                 :       else
     170               0 :         aCount = 0;
     171                 : 
     172                 :       // Process this new chunk of bin hex data...
     173               0 :       ProcessNextChunk(request, aCtxt, numBytesRead);
     174                 :     }
     175                 :   }
     176                 : 
     177               0 :   return rv;
     178                 : }
     179                 : 
     180               0 : nsresult nsBinHexDecoder::ProcessNextState(nsIRequest * aRequest, nsISupports * aContext)
     181                 : {
     182               0 :   nsresult status = NS_OK;
     183                 :   PRUint16 tmpcrc, cval;
     184               0 :   unsigned char ctmp, c = mRlebuf;
     185                 : 
     186                 :   /* do CRC */
     187               0 :   ctmp = mInCRC ? c : 0;
     188               0 :   cval = mCRC & 0xf000;
     189               0 :   tmpcrc = ((PRUint16) (mCRC << 4) | (ctmp >> 4)) ^ (cval | (cval >> 7) | (cval >> 12));
     190               0 :   cval = tmpcrc & 0xf000;
     191               0 :   mCRC = ((PRUint16) (tmpcrc << 4) | (ctmp & 0x0f)) ^ (cval | (cval >> 7) | (cval >> 12));
     192                 : 
     193                 :   /* handle state */
     194               0 :   switch (mState)
     195                 :   {
     196                 :     case BINHEX_STATE_START:
     197               0 :       mState = BINHEX_STATE_FNAME;
     198               0 :       mCount = 0;
     199                 : 
     200                 :       // c & 63 returns the length of mName. So if we need the length, that's how
     201                 :       // you can figure it out....
     202               0 :       mName.SetLength(c & 63);
     203               0 :       if (mName.Length() != (c & 63)) {
     204                 :         /* XXX ProcessNextState/ProcessNextChunk aren't rv checked */
     205               0 :         mState = BINHEX_STATE_DONE;
     206                 :       }
     207               0 :       break;
     208                 : 
     209                 :     case BINHEX_STATE_FNAME:
     210               0 :       mName.BeginWriting()[mCount] = c;
     211                 : 
     212               0 :       if (++mCount > mName.Length())
     213                 :       {
     214                 :         // okay we've figured out the file name....set the content type on the channel
     215                 :         // based on the file name AND issue our delayed on start request....
     216                 : 
     217               0 :         DetectContentType(aRequest, mName);
     218                 :         // now propagate the on start request
     219               0 :         mNextListener->OnStartRequest(aRequest, aContext);
     220                 : 
     221               0 :         mState = BINHEX_STATE_HEADER;
     222               0 :         mCount = 0;
     223                 :       }
     224               0 :       break;
     225                 : 
     226                 :     case BINHEX_STATE_HEADER:
     227               0 :       ((char *) &mHeader)[mCount] = c;
     228               0 :       if (++mCount == 18)
     229                 :       {
     230                 :         if (sizeof(binhex_header) != 18)  /* fix an alignment problem in some OSes */
     231                 :         {
     232               0 :           char *p = (char *)&mHeader;
     233               0 :           p += 19;
     234               0 :           for (c = 0; c < 8; c++)
     235                 :           {
     236               0 :             *p = *(p-2);
     237               0 :             --p;
     238                 :           }
     239                 :         }
     240                 : 
     241               0 :         mState = BINHEX_STATE_HCRC;
     242               0 :         mInCRC = 1;
     243               0 :         mCount = 0;
     244                 :       }
     245               0 :       break;
     246                 : 
     247                 :     case BINHEX_STATE_DFORK:
     248                 :     case BINHEX_STATE_RFORK:
     249               0 :       mOutgoingBuffer[mPosOutputBuff++] = c;
     250               0 :       if (--mCount == 0)
     251                 :       {
     252                 :         /* only output data fork in the non-mac system.      */
     253               0 :         if (mState == BINHEX_STATE_DFORK)
     254                 :         {
     255               0 :           PRUint32 numBytesWritten = 0;
     256               0 :           mOutputStream->Write(mOutgoingBuffer, mPosOutputBuff, &numBytesWritten);
     257               0 :           if (PRInt32(numBytesWritten) != mPosOutputBuff)
     258               0 :             status = NS_ERROR_FAILURE;
     259                 : 
     260                 :           // now propagate the data we just wrote
     261               0 :           mNextListener->OnDataAvailable(aRequest, aContext, mInputStream, 0, numBytesWritten);
     262                 :         }
     263                 :         else
     264               0 :           status = NS_OK;        /* do nothing for resource fork.  */
     265                 : 
     266               0 :         mPosOutputBuff = 0;
     267                 : 
     268               0 :         if (status != NS_OK)
     269               0 :           mState = BINHEX_STATE_DONE;
     270                 :         else
     271               0 :           ++mState;
     272                 : 
     273               0 :         mInCRC = 1;
     274                 :       }
     275               0 :       else if (mPosOutputBuff >= (PRInt32) nsIOService::gDefaultSegmentSize)
     276                 :       {
     277               0 :         if (mState == BINHEX_STATE_DFORK)
     278                 :         {
     279               0 :           PRUint32 numBytesWritten = 0;
     280               0 :           mOutputStream->Write(mOutgoingBuffer, mPosOutputBuff, &numBytesWritten);
     281               0 :           if (PRInt32(numBytesWritten) != mPosOutputBuff)
     282               0 :             status = NS_ERROR_FAILURE;
     283                 : 
     284               0 :           mNextListener->OnDataAvailable(aRequest, aContext, mInputStream, 0, numBytesWritten);
     285               0 :           mPosOutputBuff = 0;
     286                 :         }
     287                 :       }
     288               0 :       break;
     289                 : 
     290                 :     case BINHEX_STATE_HCRC:
     291                 :     case BINHEX_STATE_DCRC:
     292                 :     case BINHEX_STATE_RCRC:
     293               0 :       if (!mCount++)
     294               0 :         mFileCRC = (unsigned short) c << 8;
     295                 :       else
     296                 :       {
     297               0 :         if ((mFileCRC | c) != mCRC)
     298                 :         {
     299               0 :           mState = BINHEX_STATE_DONE;
     300               0 :           break;
     301                 :         }
     302                 : 
     303                 :         /* passed the CRC check!!!*/
     304               0 :         mCRC = 0;
     305               0 :         if (++mState == BINHEX_STATE_FINISH)
     306                 :         {
     307                 :           // when we reach the finished state...fire an on stop request on the event listener...
     308               0 :           mNextListener->OnStopRequest(aRequest, aContext, NS_OK);
     309               0 :           mNextListener = 0;
     310                 : 
     311                 :           /*   now We are done with everything.  */
     312               0 :           ++mState;
     313               0 :           break;
     314                 :         }
     315                 : 
     316               0 :         if (mState == BINHEX_STATE_DFORK)
     317               0 :           mCount = PR_ntohl(mHeader.dlen);
     318                 :         else
     319                 :         {
     320                 :           // we aren't processing the resurce Fork. uncomment this line if we make this converter
     321                 :           // smart enough to do this in the future.
     322                 :           // mCount = PR_ntohl(mHeader.rlen);  /* it should in host byte order */
     323               0 :           mCount = 0;
     324                 :         }
     325                 : 
     326               0 :         if (mCount) {
     327               0 :           mInCRC = 0;
     328                 :         } else {
     329                 :           /* nothing inside, so skip to the next state. */
     330               0 :           ++mState;
     331                 :         }
     332                 :       }
     333               0 :       break;
     334                 :   }
     335                 : 
     336               0 :   return NS_OK;
     337                 : }
     338                 : 
     339               0 : nsresult nsBinHexDecoder::ProcessNextChunk(nsIRequest * aRequest, nsISupports * aContext, PRUint32 numBytesInBuffer)
     340                 : {
     341                 :   bool foundStart;
     342               0 :   PRInt16 octetpos, c = 0;
     343                 :   PRUint32 val;
     344               0 :   mPosInDataBuffer = 0; // use member variable.
     345                 : 
     346               0 :   NS_ENSURE_TRUE(numBytesInBuffer > 0, NS_ERROR_FAILURE);
     347                 : 
     348                 :   //  if it is the first time, seek to the right start place.
     349               0 :   if (mState == BINHEX_STATE_START)
     350                 :   {
     351               0 :     foundStart = false;
     352                 :     // go through the line, until we get a ':'
     353               0 :     while (mPosInDataBuffer < numBytesInBuffer)
     354                 :     {
     355               0 :       c = mDataBuffer[mPosInDataBuffer++];
     356               0 :       while (c == CR || c == LF)
     357                 :       {
     358               0 :         if (mPosInDataBuffer >= numBytesInBuffer)
     359               0 :           break;
     360                 : 
     361               0 :         c = mDataBuffer[mPosInDataBuffer++];
     362               0 :         if (c == ':')
     363                 :         {
     364               0 :           foundStart = true;
     365               0 :           break;
     366                 :         }
     367                 :       }
     368               0 :       if (foundStart)  break;    /* we got the start point. */
     369                 :     }
     370                 : 
     371               0 :     if (mPosInDataBuffer >= numBytesInBuffer)
     372               0 :       return NS_OK;      /* we meet buff end before we get the start point, wait till next fills. */
     373                 : 
     374               0 :     if (c != ':')
     375               0 :       return NS_ERROR_FAILURE;    /* can't find the start character.  */
     376                 :   }
     377                 : 
     378               0 :   while (mState != BINHEX_STATE_DONE)
     379                 :   {
     380                 :     /* fill in octetbuf */
     381               0 :     do
     382                 :     {
     383               0 :       if (mPosInDataBuffer >= numBytesInBuffer)
     384               0 :         return NS_OK;      /* end of buff, go on for the nxet calls. */
     385                 : 
     386               0 :       c = GetNextChar(numBytesInBuffer);
     387               0 :       if (c == 0)  return NS_OK;
     388                 : 
     389               0 :       if ((val = BHEXVAL(c)) == PRUint32(-1))
     390                 :       {
     391                 :         /* we incount an invalid character.  */
     392               0 :         if (c)
     393                 :         {
     394                 :           /* rolling back. */
     395               0 :           --mDonePos;
     396               0 :           if (mOctetin >= 14)
     397               0 :             --mDonePos;
     398               0 :           if (mOctetin >= 20)
     399               0 :             --mDonePos;
     400                 :         }
     401               0 :         break;
     402                 :       }
     403               0 :       mOctetBuf.val |= val << mOctetin;
     404                 :     }
     405                 :     while ((mOctetin -= 6) > 2);
     406                 : 
     407                 :     /* handle decoded characters -- run length encoding (rle) detection */
     408                 : 
     409                 :     // We put decoded chars into mOctetBuf.val in order from high to low (via
     410                 :     // bitshifting, above).  But we want to byte-address them, so we want the
     411                 :     // first byte to correspond to the high byte.  In other words, we want
     412                 :     // these bytes to be in network order.
     413               0 :     mOctetBuf.val = PR_htonl(mOctetBuf.val);
     414                 : 
     415               0 :     for (octetpos = 0; octetpos < mDonePos; ++octetpos)
     416                 :     {
     417               0 :       c = mOctetBuf.c[octetpos];
     418                 : 
     419               0 :       if (c == 0x90 && !mMarker++)
     420               0 :         continue;
     421                 : 
     422               0 :       if (mMarker)
     423                 :       {
     424               0 :         if (c == 0)
     425                 :         {
     426               0 :           mRlebuf = 0x90;
     427               0 :           ProcessNextState(aRequest, aContext);
     428                 :         }
     429                 :         else
     430                 :         {
     431                 :           /* we are in the run length mode */
     432               0 :           while (--c > 0)
     433               0 :             ProcessNextState(aRequest, aContext);
     434                 :         }
     435               0 :         mMarker = 0;
     436                 :       }
     437                 :       else
     438                 :       {
     439               0 :         mRlebuf = (unsigned char) c;
     440               0 :         ProcessNextState(aRequest, aContext);
     441                 :       }
     442                 : 
     443               0 :       if (mState >= BINHEX_STATE_DONE)
     444               0 :         break;
     445                 :     }
     446                 : 
     447                 :     /* prepare for next 3 characters.  */
     448               0 :     if (mDonePos < 3 && mState < BINHEX_STATE_DONE)
     449               0 :       mState = BINHEX_STATE_DONE;
     450                 : 
     451               0 :     mOctetin = 26;
     452               0 :     mOctetBuf.val = 0;
     453                 :   }
     454                 : 
     455               0 :   return   NS_OK;
     456                 : }
     457                 : 
     458               0 : PRInt16 nsBinHexDecoder::GetNextChar(PRUint32 numBytesInBuffer)
     459                 : {
     460               0 :   char c = 0;
     461                 : 
     462               0 :   while (mPosInDataBuffer < numBytesInBuffer)
     463                 :   {
     464               0 :     c = mDataBuffer[mPosInDataBuffer++];
     465               0 :     if (c != LF && c != CR)
     466               0 :       break;
     467                 :   }
     468               0 :   return (c == LF || c == CR) ? 0 : (int) c;
     469                 : }
     470                 : 
     471                 : //////////////////////////////////////////////////////
     472                 : // nsIRequestObserver methods...
     473                 : //////////////////////////////////////////////////////
     474                 : 
     475                 : NS_IMETHODIMP
     476               0 : nsBinHexDecoder::OnStartRequest(nsIRequest* request, nsISupports *aCtxt)
     477                 : {
     478               0 :   nsresult rv = NS_OK;
     479                 : 
     480               0 :   NS_ENSURE_TRUE(mNextListener, NS_ERROR_FAILURE);
     481                 : 
     482               0 :   mDataBuffer = (char *) nsMemory::Alloc((sizeof(char) * nsIOService::gDefaultSegmentSize));
     483               0 :   mOutgoingBuffer = (char *) nsMemory::Alloc((sizeof(char) * nsIOService::gDefaultSegmentSize));
     484               0 :   if (!mDataBuffer || !mOutgoingBuffer) return NS_ERROR_FAILURE; // out of memory;
     485                 : 
     486                 :   // now we want to create a pipe which we'll use to write our converted data...
     487               0 :   rv = NS_NewPipe(getter_AddRefs(mInputStream), getter_AddRefs(mOutputStream),
     488                 :                   nsIOService::gDefaultSegmentSize,
     489                 :                   nsIOService::gDefaultSegmentSize,
     490               0 :                   true, true);
     491                 : 
     492                 :   // don't propagate the on start request to mNextListener until we have determined the content type.
     493               0 :   return rv;
     494                 : }
     495                 : 
     496                 : // Given the fileName we discovered inside the bin hex decoding, figure out the
     497                 : // content type and set it on the channel associated with the request.  If the
     498                 : // filename tells us nothing useful, just report an unknown type and let the
     499                 : // unknown decoder handle things.
     500               0 : nsresult nsBinHexDecoder::DetectContentType(nsIRequest* aRequest,
     501                 :                                             const nsAFlatCString &aFilename)
     502                 : {
     503               0 :   if (aFilename.IsEmpty()) {
     504                 :     // Nothing to do here.
     505               0 :     return NS_OK;
     506                 :   }
     507                 : 
     508                 :   nsresult rv;
     509               0 :   nsCOMPtr<nsIChannel> channel(do_QueryInterface(aRequest, &rv));
     510               0 :   NS_ENSURE_SUCCESS(rv, rv);
     511                 : 
     512               0 :   nsCOMPtr<nsIMIMEService> mimeService(do_GetService("@mozilla.org/mime;1", &rv));
     513               0 :   NS_ENSURE_SUCCESS(rv, rv);
     514                 : 
     515               0 :   nsCAutoString contentType;
     516                 : 
     517                 :   // extract the extension from aFilename and look it up.
     518               0 :   const char * fileExt = strrchr(aFilename.get(), '.');
     519               0 :   if (!fileExt) {
     520               0 :     return NS_OK;
     521                 :   }
     522                 : 
     523               0 :   mimeService->GetTypeFromExtension(nsDependentCString(fileExt), contentType);
     524                 : 
     525                 :   // Only set the type if it's not empty and, to prevent recursive loops, not the binhex type
     526               0 :   if (!contentType.IsEmpty() && !contentType.Equals(APPLICATION_BINHEX)) {
     527               0 :     channel->SetContentType(contentType);
     528                 :   } else {
     529               0 :     channel->SetContentType(NS_LITERAL_CSTRING(UNKNOWN_CONTENT_TYPE));
     530                 :   }
     531                 : 
     532               0 :   return NS_OK;
     533                 : }
     534                 : 
     535                 : 
     536                 : NS_IMETHODIMP
     537               0 : nsBinHexDecoder::OnStopRequest(nsIRequest* request, nsISupports *aCtxt,
     538                 :                                 nsresult aStatus)
     539                 : {
     540               0 :   nsresult rv = NS_OK;
     541                 : 
     542               0 :   if (!mNextListener) return NS_ERROR_FAILURE;
     543                 :   // don't do anything here...we'll fire our own on stop request when we are done
     544                 :   // processing the data....
     545                 : 
     546               0 :   return rv;
     547                 : }

Generated by: LCOV version 1.7