LCOV - code coverage report
Current view: directory - modules/libjar/zipwriter/src - nsZipDataStream.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 83 74 89.2 %
Date: 2012-06-02 Functions: 10 10 100.0 %

       1                 : /* ***** BEGIN LICENSE BLOCK *****
       2                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
       3                 :  *
       4                 :  * The contents of this file are subject to the Mozilla Public License Version
       5                 :  * 1.1 (the "License"); you may not use this file except in compliance with
       6                 :  * the License. You may obtain a copy of the License at
       7                 :  * http://www.mozilla.org/MPL/
       8                 :  *
       9                 :  * Software distributed under the License is distributed on an "AS IS" basis,
      10                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      11                 :  * for the specific language governing rights and limitations under the
      12                 :  * License.
      13                 :  *
      14                 :  * The Original Code is Zip Writer Component.
      15                 :  *
      16                 :  * The Initial Developer of the Original Code is
      17                 :  * Dave Townsend <dtownsend@oxymoronical.com>.
      18                 :  *
      19                 :  * Portions created by the Initial Developer are Copyright (C) 2007
      20                 :  * the Initial Developer. All Rights Reserved.
      21                 :  *
      22                 :  * Contributor(s):
      23                 :  *      Mook <mook.moz+random.code@gmail.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                 : 
      40                 : #include "StreamFunctions.h"
      41                 : #include "nsZipDataStream.h"
      42                 : #include "nsIStringStream.h"
      43                 : #include "nsISeekableStream.h"
      44                 : #include "nsDeflateConverter.h"
      45                 : #include "nsNetUtil.h"
      46                 : #include "nsComponentManagerUtils.h"
      47                 : #include "nsMemory.h"
      48                 : 
      49                 : #define ZIP_METHOD_STORE 0
      50                 : #define ZIP_METHOD_DEFLATE 8
      51                 : 
      52                 : /**
      53                 :  * nsZipDataStream handles the writing an entry's into the zip file.
      54                 :  * It is set up to wither write the data as is, or in the event that compression
      55                 :  * has been requested to pass it through a stream converter.
      56                 :  * Currently only the deflate compression method is supported.
      57                 :  * The CRC checksum for the entry's data is also generated here.
      58                 :  */
      59           17223 : NS_IMPL_THREADSAFE_ISUPPORTS2(nsZipDataStream, nsIStreamListener,
      60                 :                                                nsIRequestObserver)
      61                 : 
      62            5731 : nsresult nsZipDataStream::Init(nsZipWriter *aWriter,
      63                 :                                nsIOutputStream *aStream,
      64                 :                                nsZipHeader *aHeader,
      65                 :                                PRInt32 aCompression)
      66                 : {
      67            5731 :     mWriter = aWriter;
      68            5731 :     mHeader = aHeader;
      69            5731 :     mStream = aStream;
      70            5731 :     mHeader->mCRC = crc32(0L, Z_NULL, 0);
      71                 : 
      72            5731 :     nsresult rv = NS_NewSimpleStreamListener(getter_AddRefs(mOutput), aStream,
      73            5731 :                                              nsnull);
      74            5731 :     NS_ENSURE_SUCCESS(rv, rv);
      75                 : 
      76            5731 :     if (aCompression > 0) {
      77            5146 :         mHeader->mMethod = ZIP_METHOD_DEFLATE;
      78                 :         nsCOMPtr<nsIStreamConverter> converter =
      79           10292 :                               new nsDeflateConverter(aCompression);
      80            5146 :         NS_ENSURE_TRUE(converter, NS_ERROR_OUT_OF_MEMORY);
      81                 : 
      82            5146 :         rv = converter->AsyncConvertData("uncompressed", "rawdeflate", mOutput,
      83            5146 :                                          nsnull);
      84            5146 :         NS_ENSURE_SUCCESS(rv, rv);
      85                 : 
      86            5146 :         mOutput = do_QueryInterface(converter, &rv);
      87            5146 :         NS_ENSURE_SUCCESS(rv, rv);
      88                 :     }
      89                 :     else {
      90             585 :         mHeader->mMethod = ZIP_METHOD_STORE;
      91                 :     }
      92                 : 
      93            5731 :     return NS_OK;
      94                 : }
      95                 : 
      96                 : /* void onDataAvailable (in nsIRequest aRequest, in nsISupports aContext,
      97                 :  *                       in nsIInputStream aInputStream,
      98                 :  *                       in unsigned long aOffset, in unsigned long aCount); */
      99               6 : NS_IMETHODIMP nsZipDataStream::OnDataAvailable(nsIRequest *aRequest,
     100                 :                                                nsISupports *aContext,
     101                 :                                                nsIInputStream *aInputStream,
     102                 :                                                PRUint32 aOffset,
     103                 :                                                PRUint32 aCount)
     104                 : {
     105               6 :     if (!mOutput)
     106               0 :         return NS_ERROR_NOT_INITIALIZED;
     107                 : 
     108              18 :     nsAutoArrayPtr<char> buffer(new char[aCount]);
     109               6 :     NS_ENSURE_TRUE(buffer, NS_ERROR_OUT_OF_MEMORY);
     110                 : 
     111               6 :     nsresult rv = ZW_ReadData(aInputStream, buffer.get(), aCount);
     112               6 :     NS_ENSURE_SUCCESS(rv, rv);
     113                 : 
     114               6 :     return ProcessData(aRequest, aContext, buffer.get(), aOffset, aCount);
     115                 : }
     116                 : 
     117                 : /* void onStartRequest (in nsIRequest aRequest, in nsISupports aContext); */
     118            5731 : NS_IMETHODIMP nsZipDataStream::OnStartRequest(nsIRequest *aRequest,
     119                 :                                               nsISupports *aContext)
     120                 : {
     121            5731 :     if (!mOutput)
     122               0 :         return NS_ERROR_NOT_INITIALIZED;
     123                 : 
     124            5731 :     return mOutput->OnStartRequest(aRequest, aContext);
     125                 : }
     126                 : 
     127                 : /* void onStopRequest (in nsIRequest aRequest, in nsISupports aContext,
     128                 :  *                     in nsresult aStatusCode); */
     129            5731 : NS_IMETHODIMP nsZipDataStream::OnStopRequest(nsIRequest *aRequest,
     130                 :                                              nsISupports *aContext,
     131                 :                                              nsresult aStatusCode)
     132                 : {
     133            5731 :     if (!mOutput)
     134               0 :         return NS_ERROR_NOT_INITIALIZED;
     135                 : 
     136            5731 :     nsresult rv = mOutput->OnStopRequest(aRequest, aContext, aStatusCode);
     137            5731 :     mOutput = nsnull;
     138            5731 :     if (NS_FAILED(rv)) {
     139               0 :         mWriter->EntryCompleteCallback(mHeader, rv);
     140                 :     }
     141                 :     else {
     142            5731 :         rv = CompleteEntry();
     143            5731 :         rv = mWriter->EntryCompleteCallback(mHeader, rv);
     144                 :     }
     145                 : 
     146            5731 :     mStream = nsnull;
     147            5731 :     mWriter = nsnull;
     148            5731 :     mHeader = nsnull;
     149                 : 
     150            5731 :     return rv;
     151                 : }
     152                 : 
     153            5731 : inline nsresult nsZipDataStream::CompleteEntry()
     154                 : {
     155                 :     nsresult rv;
     156           11462 :     nsCOMPtr<nsISeekableStream> seekable = do_QueryInterface(mStream, &rv);
     157            5731 :     NS_ENSURE_SUCCESS(rv, rv);
     158                 :     PRInt64 pos;
     159            5731 :     rv = seekable->Tell(&pos);
     160            5731 :     NS_ENSURE_SUCCESS(rv, rv);
     161                 : 
     162            5731 :     mHeader->mCSize = pos - mHeader->mOffset - mHeader->GetFileHeaderLength();
     163            5731 :     mHeader->mWriteOnClose = true;
     164            5731 :     return NS_OK;
     165                 : }
     166                 : 
     167          162031 : nsresult nsZipDataStream::ProcessData(nsIRequest *aRequest,
     168                 :                                       nsISupports *aContext, char *aBuffer,
     169                 :                                       PRUint32 aOffset, PRUint32 aCount)
     170                 : {
     171          324062 :     mHeader->mCRC = crc32(mHeader->mCRC,
     172                 :                           reinterpret_cast<const unsigned char*>(aBuffer),
     173          324062 :                           aCount);
     174                 : 
     175                 :     nsresult rv;
     176                 :     nsCOMPtr<nsIStringInputStream> stream =
     177          324062 :              do_CreateInstance("@mozilla.org/io/string-input-stream;1", &rv);
     178          162031 :     NS_ENSURE_SUCCESS(rv, rv);
     179                 : 
     180          162031 :     stream->ShareData(aBuffer, aCount);
     181          162031 :     rv = mOutput->OnDataAvailable(aRequest, aContext, stream, aOffset, aCount);
     182          162031 :     mHeader->mUSize += aCount;
     183                 : 
     184          162031 :     return rv;
     185                 : }
     186                 : 
     187            5725 : nsresult nsZipDataStream::ReadStream(nsIInputStream *aStream)
     188                 : {
     189            5725 :     if (!mOutput)
     190               0 :         return NS_ERROR_NOT_INITIALIZED;
     191                 : 
     192            5725 :     nsresult rv = OnStartRequest(nsnull, nsnull);
     193            5725 :     NS_ENSURE_SUCCESS(rv, rv);
     194                 : 
     195           11450 :     nsAutoArrayPtr<char> buffer(new char[4096]);
     196            5725 :     NS_ENSURE_TRUE(buffer, NS_ERROR_OUT_OF_MEMORY);
     197                 : 
     198            5725 :     PRUint32 read = 0;
     199            5725 :     PRUint32 offset = 0;
     200          167750 :     do
     201                 :     {
     202          167750 :         rv = aStream->Read(buffer.get(), 4096, &read);
     203          167750 :         if (NS_FAILED(rv)) {
     204               0 :             OnStopRequest(nsnull, nsnull, rv);
     205               0 :             return rv;
     206                 :         }
     207                 : 
     208          167750 :         if (read > 0) {
     209          162025 :             rv = ProcessData(nsnull, nsnull, buffer.get(), offset, read);
     210          162025 :             if (NS_FAILED(rv)) {
     211               0 :                 OnStopRequest(nsnull, nsnull, rv);
     212               0 :                 return rv;
     213                 :             }
     214          162025 :             offset += read;
     215                 :         }
     216                 :     } while (read > 0);
     217                 : 
     218            5725 :     return OnStopRequest(nsnull, nsnull, NS_OK);
     219                 : }

Generated by: LCOV version 1.7