Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/netwerk/base/nsDownloader.cpp
Line
Count
Source (jump to first uncovered line)
1
/* This Source Code Form is subject to the terms of the Mozilla Public
2
 * License, v. 2.0. If a copy of the MPL was not distributed with this
3
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5
#include "nsDownloader.h"
6
#include "nsIInputStream.h"
7
#include "nsIOutputStream.h"
8
#include "nsDirectoryServiceUtils.h"
9
#include "nsDirectoryServiceDefs.h"
10
#include "nsNetUtil.h"
11
#include "nsCRTGlue.h"
12
13
nsDownloader::~nsDownloader()
14
0
{
15
0
    if (mLocation && mLocationIsTemp) {
16
0
        // release the sink first since it may still hold an open file
17
0
        // descriptor to mLocation.  this needs to happen before the
18
0
        // file can be removed otherwise the Remove call will fail.
19
0
        if (mSink) {
20
0
            mSink->Close();
21
0
            mSink = nullptr;
22
0
        }
23
0
24
0
        nsresult rv = mLocation->Remove(false);
25
0
        if (NS_FAILED(rv))
26
0
            NS_ERROR("unable to remove temp file");
27
0
    }
28
0
}
29
30
NS_IMPL_ISUPPORTS(nsDownloader,
31
                  nsIDownloader,
32
                  nsIStreamListener,
33
                  nsIRequestObserver)
34
35
NS_IMETHODIMP
36
nsDownloader::Init(nsIDownloadObserver *observer, nsIFile *location)
37
0
{
38
0
    mObserver = observer;
39
0
    mLocation = location;
40
0
    return NS_OK;
41
0
}
42
43
NS_IMETHODIMP
44
nsDownloader::OnStartRequest(nsIRequest *request, nsISupports *ctxt)
45
0
{
46
0
    nsresult rv;
47
0
    if (!mLocation) {
48
0
        nsCOMPtr<nsIFile> location;
49
0
        rv = NS_GetSpecialDirectory(NS_OS_TEMP_DIR, getter_AddRefs(location));
50
0
        if (NS_FAILED(rv)) return rv;
51
0
52
0
        char buf[13];
53
0
        NS_MakeRandomString(buf, 8);
54
0
        memcpy(buf+8, ".tmp", 5);
55
0
        rv = location->AppendNative(nsDependentCString(buf, 12));
56
0
        if (NS_FAILED(rv)) return rv;
57
0
58
0
        rv = location->CreateUnique(nsIFile::NORMAL_FILE_TYPE, 0600);
59
0
        if (NS_FAILED(rv)) return rv;
60
0
61
0
        location.swap(mLocation);
62
0
        mLocationIsTemp = true;
63
0
    }
64
0
65
0
    rv = NS_NewLocalFileOutputStream(getter_AddRefs(mSink), mLocation);
66
0
    if (NS_FAILED(rv)) return rv;
67
0
68
0
    // we could wrap this output stream with a buffered output stream,
69
0
    // but it shouldn't be necessary since we will be writing large
70
0
    // chunks given to us via OnDataAvailable.
71
0
72
0
    return NS_OK;
73
0
}
74
75
NS_IMETHODIMP
76
nsDownloader::OnStopRequest(nsIRequest  *request,
77
                            nsISupports *ctxt,
78
                            nsresult     status)
79
0
{
80
0
    if (mSink) {
81
0
        mSink->Close();
82
0
        mSink = nullptr;
83
0
    }
84
0
85
0
    mObserver->OnDownloadComplete(this, request, ctxt, status, mLocation);
86
0
    mObserver = nullptr;
87
0
88
0
    return NS_OK;
89
0
}
90
91
nsresult
92
nsDownloader::ConsumeData(nsIInputStream* in,
93
                          void* closure,
94
                          const char* fromRawSegment,
95
                          uint32_t toOffset,
96
                          uint32_t count,
97
                          uint32_t *writeCount)
98
0
{
99
0
    nsDownloader *self = (nsDownloader *) closure;
100
0
    if (self->mSink)
101
0
        return self->mSink->Write(fromRawSegment, count, writeCount);
102
0
103
0
    *writeCount = count;
104
0
    return NS_OK;
105
0
}
106
107
NS_IMETHODIMP
108
nsDownloader::OnDataAvailable(nsIRequest *request, nsISupports *ctxt,
109
                              nsIInputStream *inStr,
110
                              uint64_t sourceOffset, uint32_t count)
111
0
{
112
0
    uint32_t n;
113
0
    return inStr->ReadSegments(ConsumeData, this, count, &n);
114
0
}