Bug 1732219 - Add API for fetching the preview image. r=geckoview-reviewers,agi,mconley
[gecko.git] / dom / file / StreamBlobImpl.cpp
blob43ff3c526bcc12d0d3c276756cf7b4d98e004e29
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/. */
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"
15 namespace mozilla::dom {
17 NS_IMPL_ISUPPORTS_INHERITED(StreamBlobImpl, BlobImpl, nsIMemoryReporter)
19 /* static */
20 already_AddRefed<StreamBlobImpl> StreamBlobImpl::Create(
21 already_AddRefed<nsIInputStream> aInputStream,
22 const nsAString& aContentType, uint64_t aLength,
23 const nsAString& aBlobImplType) {
24 nsCOMPtr<nsIInputStream> inputStream = std::move(aInputStream);
26 RefPtr<StreamBlobImpl> blobImplStream = new StreamBlobImpl(
27 inputStream.forget(), aContentType, aLength, aBlobImplType);
28 blobImplStream->MaybeRegisterMemoryReporter();
29 return blobImplStream.forget();
32 /* static */
33 already_AddRefed<StreamBlobImpl> StreamBlobImpl::Create(
34 already_AddRefed<nsIInputStream> aInputStream, const nsAString& aName,
35 const nsAString& aContentType, int64_t aLastModifiedDate, uint64_t aLength,
36 const nsAString& aBlobImplType) {
37 nsCOMPtr<nsIInputStream> inputStream = std::move(aInputStream);
39 RefPtr<StreamBlobImpl> blobImplStream =
40 new StreamBlobImpl(inputStream.forget(), aName, aContentType,
41 aLastModifiedDate, aLength, aBlobImplType);
42 blobImplStream->MaybeRegisterMemoryReporter();
43 return blobImplStream.forget();
46 StreamBlobImpl::StreamBlobImpl(already_AddRefed<nsIInputStream> aInputStream,
47 const nsAString& aContentType, uint64_t aLength,
48 const nsAString& aBlobImplType)
49 : BaseBlobImpl(aContentType, aLength),
50 mInputStream(std::move(aInputStream)),
51 mBlobImplType(aBlobImplType),
52 mIsDirectory(false),
53 mFileId(-1) {}
55 StreamBlobImpl::StreamBlobImpl(already_AddRefed<nsIInputStream> aInputStream,
56 const nsAString& aName,
57 const nsAString& aContentType,
58 int64_t aLastModifiedDate, uint64_t aLength,
59 const nsAString& aBlobImplType)
60 : BaseBlobImpl(aName, aContentType, aLength, aLastModifiedDate),
61 mInputStream(std::move(aInputStream)),
62 mBlobImplType(aBlobImplType),
63 mIsDirectory(false),
64 mFileId(-1) {}
66 StreamBlobImpl::~StreamBlobImpl() { UnregisterWeakMemoryReporter(this); }
68 void StreamBlobImpl::CreateInputStream(nsIInputStream** aStream,
69 ErrorResult& aRv) {
70 nsCOMPtr<nsIInputStream> clonedStream;
71 nsCOMPtr<nsIInputStream> replacementStream;
73 aRv = NS_CloneInputStream(mInputStream, getter_AddRefs(clonedStream),
74 getter_AddRefs(replacementStream));
75 if (NS_WARN_IF(aRv.Failed())) {
76 return;
79 if (replacementStream) {
80 mInputStream = std::move(replacementStream);
83 nsCOMPtr<nsIInputStream> wrappedStream =
84 InputStreamLengthWrapper::MaybeWrap(clonedStream.forget(), mLength);
86 wrappedStream.forget(aStream);
89 already_AddRefed<BlobImpl> StreamBlobImpl::CreateSlice(
90 uint64_t aStart, uint64_t aLength, const nsAString& aContentType,
91 ErrorResult& aRv) {
92 if (!aLength) {
93 RefPtr<BlobImpl> impl = new EmptyBlobImpl(aContentType);
94 return impl.forget();
97 nsCOMPtr<nsIInputStream> clonedStream;
99 nsCOMPtr<nsICloneableInputStreamWithRange> stream =
100 do_QueryInterface(mInputStream);
101 if (stream) {
102 aRv = stream->CloneWithRange(aStart, aLength, getter_AddRefs(clonedStream));
103 if (NS_WARN_IF(aRv.Failed())) {
104 return nullptr;
106 } else {
107 CreateInputStream(getter_AddRefs(clonedStream), aRv);
108 if (NS_WARN_IF(aRv.Failed())) {
109 return nullptr;
112 clonedStream =
113 new SlicedInputStream(clonedStream.forget(), aStart, aLength);
116 MOZ_ASSERT(clonedStream);
118 RefPtr<BlobImpl> impl = new StreamBlobImpl(
119 clonedStream.forget(), aContentType, aLength, mBlobImplType);
120 return impl.forget();
123 void StreamBlobImpl::MaybeRegisterMemoryReporter() {
124 // We report only stringInputStream.
125 nsCOMPtr<nsIStringInputStream> stringInputStream =
126 do_QueryInterface(mInputStream);
127 if (!stringInputStream) {
128 return;
131 RegisterWeakMemoryReporter(this);
134 NS_IMETHODIMP
135 StreamBlobImpl::CollectReports(nsIHandleReportCallback* aHandleReport,
136 nsISupports* aData, bool aAnonymize) {
137 nsCOMPtr<nsIStringInputStream> stringInputStream =
138 do_QueryInterface(mInputStream);
139 if (!stringInputStream) {
140 return NS_OK;
143 MOZ_COLLECT_REPORT(
144 "explicit/dom/memory-file-data/stream", KIND_HEAP, UNITS_BYTES,
145 stringInputStream->SizeOfIncludingThisIfUnshared(MallocSizeOf),
146 "Memory used to back a File/Blob based on an input stream.");
148 return NS_OK;
151 size_t StreamBlobImpl::GetAllocationSize() const {
152 nsCOMPtr<nsIStringInputStream> stringInputStream =
153 do_QueryInterface(mInputStream);
154 if (!stringInputStream) {
155 return 0;
158 return stringInputStream->SizeOfIncludingThisEvenIfShared(MallocSizeOf);
161 void StreamBlobImpl::GetBlobImplType(nsAString& aBlobImplType) const {
162 aBlobImplType.AssignLiteral("StreamBlobImpl[");
163 aBlobImplType.Append(mBlobImplType);
164 aBlobImplType.AppendLiteral("]");
167 } // namespace mozilla::dom