Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/dom/file/StreamBlobImpl.cpp
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
3
/* This Source Code Form is subject to the terms of the Mozilla Public
4
 * License, v. 2.0. If a copy of the MPL was not distributed with this
5
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7
#include "EmptyBlobImpl.h"
8
#include "mozilla/InputStreamLengthWrapper.h"
9
#include "mozilla/SlicedInputStream.h"
10
#include "StreamBlobImpl.h"
11
#include "nsStreamUtils.h"
12
#include "nsStringStream.h"
13
#include "nsICloneableInputStream.h"
14
15
namespace mozilla {
16
namespace dom {
17
18
NS_IMPL_ISUPPORTS_INHERITED(StreamBlobImpl, BlobImpl, nsIMemoryReporter)
19
20
/* static */ already_AddRefed<StreamBlobImpl>
21
StreamBlobImpl::Create(already_AddRefed<nsIInputStream> aInputStream,
22
                       const nsAString& aContentType,
23
                       uint64_t aLength)
24
0
{
25
0
  nsCOMPtr<nsIInputStream> inputStream = std::move(aInputStream);
26
0
27
0
  RefPtr<StreamBlobImpl> blobImplStream =
28
0
    new StreamBlobImpl(inputStream.forget(), aContentType, aLength);
29
0
  blobImplStream->MaybeRegisterMemoryReporter();
30
0
  return blobImplStream.forget();
31
0
}
32
33
/* static */ already_AddRefed<StreamBlobImpl>
34
StreamBlobImpl::Create(already_AddRefed<nsIInputStream> aInputStream,
35
                       const nsAString& aName,
36
                       const nsAString& aContentType,
37
                       int64_t aLastModifiedDate,
38
                       uint64_t aLength)
39
0
{
40
0
  nsCOMPtr<nsIInputStream> inputStream = std::move(aInputStream);
41
0
42
0
  RefPtr<StreamBlobImpl> blobImplStream =
43
0
    new StreamBlobImpl(inputStream.forget(), aName, aContentType,
44
0
                       aLastModifiedDate, aLength);
45
0
  blobImplStream->MaybeRegisterMemoryReporter();
46
0
  return blobImplStream.forget();
47
0
}
48
49
StreamBlobImpl::StreamBlobImpl(already_AddRefed<nsIInputStream> aInputStream,
50
                               const nsAString& aContentType,
51
                               uint64_t aLength)
52
  : BaseBlobImpl(aContentType, aLength)
53
  , mInputStream(std::move(aInputStream))
54
  , mIsDirectory(false)
55
  , mFileId(-1)
56
0
{
57
0
  mImmutable = true;
58
0
}
59
60
StreamBlobImpl::StreamBlobImpl(already_AddRefed<nsIInputStream> aInputStream,
61
                               const nsAString& aName,
62
                               const nsAString& aContentType,
63
                               int64_t aLastModifiedDate,
64
                               uint64_t aLength)
65
  : BaseBlobImpl(aName, aContentType, aLength, aLastModifiedDate)
66
  , mInputStream(std::move(aInputStream))
67
  , mIsDirectory(false)
68
  , mFileId(-1)
69
0
{
70
0
  mImmutable = true;
71
0
}
72
73
StreamBlobImpl::~StreamBlobImpl()
74
0
{
75
0
  UnregisterWeakMemoryReporter(this);
76
0
}
77
78
void
79
StreamBlobImpl::CreateInputStream(nsIInputStream** aStream, ErrorResult& aRv)
80
0
{
81
0
  nsCOMPtr<nsIInputStream> clonedStream;
82
0
  nsCOMPtr<nsIInputStream> replacementStream;
83
0
84
0
  aRv = NS_CloneInputStream(mInputStream, getter_AddRefs(clonedStream),
85
0
                            getter_AddRefs(replacementStream));
86
0
  if (NS_WARN_IF(aRv.Failed())) {
87
0
    return;
88
0
  }
89
0
90
0
  if (replacementStream) {
91
0
    mInputStream = replacementStream.forget();
92
0
  }
93
0
94
0
  nsCOMPtr<nsIInputStream> wrappedStream =
95
0
    InputStreamLengthWrapper::MaybeWrap(clonedStream.forget(), mLength);
96
0
97
0
  wrappedStream.forget(aStream);
98
0
}
99
100
already_AddRefed<BlobImpl>
101
StreamBlobImpl::CreateSlice(uint64_t aStart, uint64_t aLength,
102
                            const nsAString& aContentType, ErrorResult& aRv)
103
0
{
104
0
  if (!aLength) {
105
0
    RefPtr<BlobImpl> impl = new EmptyBlobImpl(aContentType);
106
0
    return impl.forget();
107
0
  }
108
0
109
0
  nsCOMPtr<nsIInputStream> clonedStream;
110
0
111
0
  nsCOMPtr<nsICloneableInputStreamWithRange> stream =
112
0
    do_QueryInterface(mInputStream);
113
0
  if (stream) {
114
0
    aRv = stream->CloneWithRange(aStart, aLength, getter_AddRefs(clonedStream));
115
0
    if (NS_WARN_IF(aRv.Failed())) {
116
0
      return nullptr;
117
0
    }
118
0
  } else {
119
0
    CreateInputStream(getter_AddRefs(clonedStream), aRv);
120
0
    if (NS_WARN_IF(aRv.Failed())) {
121
0
      return nullptr;
122
0
    }
123
0
124
0
    clonedStream =
125
0
      new SlicedInputStream(clonedStream.forget(), aStart, aLength);
126
0
  }
127
0
128
0
  MOZ_ASSERT(clonedStream);
129
0
130
0
  RefPtr<BlobImpl> impl =
131
0
    new StreamBlobImpl(clonedStream.forget(), aContentType, aLength);
132
0
  return impl.forget();
133
0
}
134
135
void
136
StreamBlobImpl::MaybeRegisterMemoryReporter()
137
0
{
138
0
  // We report only stringInputStream.
139
0
  nsCOMPtr<nsIStringInputStream> stringInputStream =
140
0
    do_QueryInterface(mInputStream);
141
0
  if (!stringInputStream) {
142
0
    return;
143
0
  }
144
0
145
0
  RegisterWeakMemoryReporter(this);
146
0
}
147
148
NS_IMETHODIMP
149
StreamBlobImpl::CollectReports(nsIHandleReportCallback* aHandleReport,
150
                               nsISupports* aData, bool aAnonymize)
151
0
{
152
0
  nsCOMPtr<nsIStringInputStream> stringInputStream =
153
0
    do_QueryInterface(mInputStream);
154
0
  if (!stringInputStream) {
155
0
    return NS_OK;
156
0
  }
157
0
158
0
  MOZ_COLLECT_REPORT(
159
0
    "explicit/dom/memory-file-data/stream", KIND_HEAP, UNITS_BYTES,
160
0
    stringInputStream->SizeOfIncludingThis(MallocSizeOf),
161
0
    "Memory used to back a File/Blob based on an input stream.");
162
0
163
0
  return NS_OK;
164
0
}
165
166
size_t
167
StreamBlobImpl::GetAllocationSize() const
168
0
{
169
0
  nsCOMPtr<nsIStringInputStream> stringInputStream =
170
0
    do_QueryInterface(mInputStream);
171
0
  if (!stringInputStream) {
172
0
    return 0;
173
0
  }
174
0
175
0
  return stringInputStream->SizeOfIncludingThis(MallocSizeOf);
176
0
}
177
178
} // namespace dom
179
} // namespace mozilla