netwerk/base/src/nsDownloader.cpp

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/netwerk/base/src/nsDownloader.cpp	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,113 @@
     1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.7 +
     1.8 +#include "nsDownloader.h"
     1.9 +#include "nsIInputStream.h"
    1.10 +#include "nsDirectoryServiceUtils.h"
    1.11 +#include "nsDirectoryServiceDefs.h"
    1.12 +#include "nsNetUtil.h"
    1.13 +#include "nsCRTGlue.h"
    1.14 +
    1.15 +nsDownloader::~nsDownloader()
    1.16 +{
    1.17 +    if (mLocation && mLocationIsTemp) {
    1.18 +        // release the sink first since it may still hold an open file
    1.19 +        // descriptor to mLocation.  this needs to happen before the
    1.20 +        // file can be removed otherwise the Remove call will fail.
    1.21 +        if (mSink) {
    1.22 +            mSink->Close();
    1.23 +            mSink = nullptr;
    1.24 +        }
    1.25 +
    1.26 +        nsresult rv = mLocation->Remove(false);
    1.27 +        if (NS_FAILED(rv))
    1.28 +            NS_ERROR("unable to remove temp file");
    1.29 +    }
    1.30 +}
    1.31 +
    1.32 +NS_IMPL_ISUPPORTS(nsDownloader,
    1.33 +                  nsIDownloader,
    1.34 +                  nsIStreamListener,
    1.35 +                  nsIRequestObserver)
    1.36 +
    1.37 +NS_IMETHODIMP
    1.38 +nsDownloader::Init(nsIDownloadObserver *observer, nsIFile *location)
    1.39 +{
    1.40 +    mObserver = observer;
    1.41 +    mLocation = location;
    1.42 +    return NS_OK;
    1.43 +}
    1.44 +
    1.45 +NS_IMETHODIMP 
    1.46 +nsDownloader::OnStartRequest(nsIRequest *request, nsISupports *ctxt)
    1.47 +{
    1.48 +    nsresult rv;
    1.49 +    if (!mLocation) {
    1.50 +        nsCOMPtr<nsIFile> location;
    1.51 +        rv = NS_GetSpecialDirectory(NS_OS_TEMP_DIR, getter_AddRefs(location));
    1.52 +        if (NS_FAILED(rv)) return rv;
    1.53 +
    1.54 +        char buf[13];
    1.55 +        NS_MakeRandomString(buf, 8);
    1.56 +        memcpy(buf+8, ".tmp", 5);
    1.57 +        rv = location->AppendNative(nsDependentCString(buf, 12));
    1.58 +        if (NS_FAILED(rv)) return rv;
    1.59 +
    1.60 +        rv = location->CreateUnique(nsIFile::NORMAL_FILE_TYPE, 0600);
    1.61 +        if (NS_FAILED(rv)) return rv;
    1.62 +
    1.63 +        location.swap(mLocation);
    1.64 +        mLocationIsTemp = true;
    1.65 +    }
    1.66 +
    1.67 +    rv = NS_NewLocalFileOutputStream(getter_AddRefs(mSink), mLocation);
    1.68 +    if (NS_FAILED(rv)) return rv;
    1.69 +
    1.70 +    // we could wrap this output stream with a buffered output stream,
    1.71 +    // but it shouldn't be necessary since we will be writing large
    1.72 +    // chunks given to us via OnDataAvailable.
    1.73 +
    1.74 +    return NS_OK;
    1.75 +}
    1.76 +
    1.77 +NS_IMETHODIMP 
    1.78 +nsDownloader::OnStopRequest(nsIRequest  *request,
    1.79 +                            nsISupports *ctxt,
    1.80 +                            nsresult     status)
    1.81 +{
    1.82 +    if (mSink) {
    1.83 +        mSink->Close();
    1.84 +        mSink = nullptr;
    1.85 +    }
    1.86 +
    1.87 +    mObserver->OnDownloadComplete(this, request, ctxt, status, mLocation);
    1.88 +    mObserver = nullptr;
    1.89 +
    1.90 +    return NS_OK;
    1.91 +}
    1.92 +
    1.93 +NS_METHOD
    1.94 +nsDownloader::ConsumeData(nsIInputStream* in,
    1.95 +                          void* closure,
    1.96 +                          const char* fromRawSegment,
    1.97 +                          uint32_t toOffset,
    1.98 +                          uint32_t count,
    1.99 +                          uint32_t *writeCount)
   1.100 +{
   1.101 +    nsDownloader *self = (nsDownloader *) closure;
   1.102 +    if (self->mSink)
   1.103 +        return self->mSink->Write(fromRawSegment, count, writeCount);
   1.104 +
   1.105 +    *writeCount = count;
   1.106 +    return NS_OK;
   1.107 +}
   1.108 +
   1.109 +NS_IMETHODIMP 
   1.110 +nsDownloader::OnDataAvailable(nsIRequest *request, nsISupports *ctxt, 
   1.111 +                              nsIInputStream *inStr, 
   1.112 +                              uint64_t sourceOffset, uint32_t count)
   1.113 +{
   1.114 +    uint32_t n;  
   1.115 +    return inStr->ReadSegments(ConsumeData, this, count, &n);
   1.116 +}

mercurial