Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/netwerk/base/nsPreloadedStream.cpp
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
/* This Source Code Form is subject to the terms of the Mozilla Public
3
 * License, v. 2.0. If a copy of the MPL was not distributed with this
4
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5
6
#include "nsPreloadedStream.h"
7
#include "nsIRunnable.h"
8
9
#include "nsThreadUtils.h"
10
#include <algorithm>
11
12
namespace mozilla {
13
namespace net {
14
15
NS_IMPL_ISUPPORTS(nsPreloadedStream,
16
                  nsIInputStream,
17
                  nsIAsyncInputStream)
18
19
nsPreloadedStream::nsPreloadedStream(nsIAsyncInputStream *aStream,
20
                                     const char *data, uint32_t datalen)
21
    : mStream(aStream),
22
      mOffset(0),
23
      mLen(datalen)
24
0
{
25
0
    mBuf = (char *) moz_xmalloc(datalen);
26
0
    memcpy(mBuf, data, datalen);
27
0
}
28
29
nsPreloadedStream::~nsPreloadedStream()
30
0
{
31
0
    free(mBuf);
32
0
}
33
34
NS_IMETHODIMP
35
nsPreloadedStream::Close()
36
0
{
37
0
    mLen = 0;
38
0
    return mStream->Close();
39
0
}
40
41
42
NS_IMETHODIMP
43
nsPreloadedStream::Available(uint64_t *_retval)
44
0
{
45
0
    uint64_t avail = 0;
46
0
47
0
    nsresult rv = mStream->Available(&avail);
48
0
    if (NS_FAILED(rv))
49
0
        return rv;
50
0
    *_retval = avail + mLen;
51
0
    return NS_OK;
52
0
}
53
54
NS_IMETHODIMP
55
nsPreloadedStream::Read(char *aBuf, uint32_t aCount,
56
                        uint32_t *_retval)
57
0
{
58
0
    if (!mLen)
59
0
        return mStream->Read(aBuf, aCount, _retval);
60
0
61
0
    uint32_t toRead = std::min(mLen, aCount);
62
0
    memcpy(aBuf, mBuf + mOffset, toRead);
63
0
    mOffset += toRead;
64
0
    mLen -= toRead;
65
0
    *_retval = toRead;
66
0
    return NS_OK;
67
0
}
68
69
NS_IMETHODIMP
70
nsPreloadedStream::ReadSegments(nsWriteSegmentFun aWriter,
71
                                void *aClosure, uint32_t aCount,
72
                                uint32_t *result)
73
0
{
74
0
    if (!mLen)
75
0
        return mStream->ReadSegments(aWriter, aClosure, aCount, result);
76
0
77
0
    *result = 0;
78
0
    while (mLen > 0 && aCount > 0) {
79
0
        uint32_t toRead = std::min(mLen, aCount);
80
0
        uint32_t didRead = 0;
81
0
        nsresult rv;
82
0
83
0
        rv = aWriter(this, aClosure, mBuf + mOffset, *result, toRead, &didRead);
84
0
85
0
        if (NS_FAILED(rv))
86
0
            return NS_OK;
87
0
88
0
        *result += didRead;
89
0
        mOffset += didRead;
90
0
        mLen -= didRead;
91
0
        aCount -= didRead;
92
0
    }
93
0
94
0
    return NS_OK;
95
0
}
96
97
NS_IMETHODIMP
98
nsPreloadedStream::IsNonBlocking(bool *_retval)
99
0
{
100
0
    return mStream->IsNonBlocking(_retval);
101
0
}
102
103
NS_IMETHODIMP
104
nsPreloadedStream::CloseWithStatus(nsresult aStatus)
105
0
{
106
0
    mLen = 0;
107
0
    return mStream->CloseWithStatus(aStatus);
108
0
}
109
110
class RunOnThread : public Runnable
111
{
112
public:
113
  RunOnThread(nsIAsyncInputStream* aStream, nsIInputStreamCallback* aCallback)
114
    : Runnable("net::RunOnThread")
115
    , mStream(aStream)
116
    , mCallback(aCallback)
117
0
  {
118
0
  }
119
120
0
  virtual ~RunOnThread() = default;
121
122
  NS_IMETHOD Run() override
123
0
  {
124
0
    mCallback->OnInputStreamReady(mStream);
125
0
    return NS_OK;
126
0
    }
127
128
private:
129
    nsCOMPtr<nsIAsyncInputStream>    mStream;
130
    nsCOMPtr<nsIInputStreamCallback> mCallback;
131
};
132
133
NS_IMETHODIMP
134
nsPreloadedStream::AsyncWait(nsIInputStreamCallback *aCallback,
135
                             uint32_t aFlags,
136
                             uint32_t aRequestedCount,
137
                             nsIEventTarget *aEventTarget)
138
0
{
139
0
    if (!mLen)
140
0
        return mStream->AsyncWait(aCallback, aFlags, aRequestedCount,
141
0
                                  aEventTarget);
142
0
143
0
    if (!aCallback)
144
0
        return NS_OK;
145
0
146
0
    if (!aEventTarget)
147
0
        return aCallback->OnInputStreamReady(this);
148
0
149
0
    nsCOMPtr<nsIRunnable> event =
150
0
        new RunOnThread(this, aCallback);
151
0
    return aEventTarget->Dispatch(event, nsIEventTarget::DISPATCH_NORMAL);
152
0
}
153
154
} // namespace net
155
} // namespace mozilla