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/. */
5 #include "InputStreamUtils.h"
7 #include "nsIIPCSerializableInputStream.h"
9 #include "mozilla/Assertions.h"
10 #include "mozilla/dom/File.h"
11 #include "mozilla/dom/ipc/BlobChild.h"
12 #include "mozilla/dom/ipc/BlobParent.h"
13 #include "nsComponentManagerUtils.h"
16 #include "nsIXULRuntime.h"
17 #include "nsMIMEInputStream.h"
18 #include "nsMultiplexInputStream.h"
20 #include "nsStringStream.h"
21 #include "nsXULAppAPI.h"
23 using namespace mozilla::dom
;
27 NS_DEFINE_CID(kStringInputStreamCID
, NS_STRINGINPUTSTREAM_CID
);
28 NS_DEFINE_CID(kFileInputStreamCID
, NS_LOCALFILEINPUTSTREAM_CID
);
29 NS_DEFINE_CID(kPartialFileInputStreamCID
, NS_PARTIALLOCALFILEINPUTSTREAM_CID
);
30 NS_DEFINE_CID(kBufferedInputStreamCID
, NS_BUFFEREDINPUTSTREAM_CID
);
31 NS_DEFINE_CID(kMIMEInputStreamCID
, NS_MIMEINPUTSTREAM_CID
);
32 NS_DEFINE_CID(kMultiplexInputStreamCID
, NS_MULTIPLEXINPUTSTREAM_CID
);
34 } // anonymous namespace
40 SerializeInputStream(nsIInputStream
* aInputStream
,
41 InputStreamParams
& aParams
,
42 nsTArray
<FileDescriptor
>& aFileDescriptors
)
44 MOZ_ASSERT(aInputStream
);
46 nsCOMPtr
<nsIIPCSerializableInputStream
> serializable
=
47 do_QueryInterface(aInputStream
);
49 MOZ_CRASH("Input stream is not serializable!");
52 serializable
->Serialize(aParams
, aFileDescriptors
);
54 if (aParams
.type() == InputStreamParams::T__None
) {
55 MOZ_CRASH("Serialize failed!");
60 SerializeInputStream(nsIInputStream
* aInputStream
,
61 OptionalInputStreamParams
& aParams
,
62 nsTArray
<FileDescriptor
>& aFileDescriptors
)
65 InputStreamParams params
;
66 SerializeInputStream(aInputStream
, params
, aFileDescriptors
);
70 aParams
= mozilla::void_t();
74 already_AddRefed
<nsIInputStream
>
75 DeserializeInputStream(const InputStreamParams
& aParams
,
76 const nsTArray
<FileDescriptor
>& aFileDescriptors
)
78 nsCOMPtr
<nsIInputStream
> stream
;
79 nsCOMPtr
<nsIIPCSerializableInputStream
> serializable
;
81 switch (aParams
.type()) {
82 case InputStreamParams::TStringInputStreamParams
:
83 serializable
= do_CreateInstance(kStringInputStreamCID
);
86 case InputStreamParams::TFileInputStreamParams
:
87 serializable
= do_CreateInstance(kFileInputStreamCID
);
90 case InputStreamParams::TPartialFileInputStreamParams
:
91 serializable
= do_CreateInstance(kPartialFileInputStreamCID
);
94 case InputStreamParams::TBufferedInputStreamParams
:
95 serializable
= do_CreateInstance(kBufferedInputStreamCID
);
98 case InputStreamParams::TMIMEInputStreamParams
:
99 serializable
= do_CreateInstance(kMIMEInputStreamCID
);
102 case InputStreamParams::TMultiplexInputStreamParams
:
103 serializable
= do_CreateInstance(kMultiplexInputStreamCID
);
106 // When the input stream already exists in this process, all we need to do
107 // is retrieve the original instead of sending any data over the wire.
108 case InputStreamParams::TRemoteInputStreamParams
: {
109 if (NS_WARN_IF(XRE_GetProcessType() != GeckoProcessType_Default
)) {
113 const nsID
& id
= aParams
.get_RemoteInputStreamParams().id();
115 nsRefPtr
<FileImpl
> blobImpl
= BlobParent::GetBlobImplForID(id
);
117 MOZ_ASSERT(blobImpl
, "Invalid blob contents");
119 // If fetching the internal stream fails, we ignore it and return a
121 nsCOMPtr
<nsIInputStream
> stream
;
122 nsresult rv
= blobImpl
->GetInternalStream(getter_AddRefs(stream
));
123 if (NS_FAILED(rv
) || !stream
) {
124 NS_WARNING("Couldn't obtain a valid stream from the blob");
126 return stream
.forget();
129 case InputStreamParams::TSameProcessInputStreamParams
: {
130 MOZ_ASSERT(aFileDescriptors
.IsEmpty());
132 const SameProcessInputStreamParams
& params
=
133 aParams
.get_SameProcessInputStreamParams();
135 stream
= dont_AddRef(
136 reinterpret_cast<nsIInputStream
*>(params
.addRefedInputStream()));
139 return stream
.forget();
143 MOZ_ASSERT(false, "Unknown params!");
147 MOZ_ASSERT(serializable
);
149 if (!serializable
->Deserialize(aParams
, aFileDescriptors
)) {
150 MOZ_ASSERT(false, "Deserialize failed!");
154 stream
= do_QueryInterface(serializable
);
157 return stream
.forget();
160 already_AddRefed
<nsIInputStream
>
161 DeserializeInputStream(const OptionalInputStreamParams
& aParams
,
162 const nsTArray
<FileDescriptor
>& aFileDescriptors
)
164 nsCOMPtr
<nsIInputStream
> stream
;
166 switch (aParams
.type()) {
167 case OptionalInputStreamParams::Tvoid_t
:
168 // Leave stream null.
171 case OptionalInputStreamParams::TInputStreamParams
:
172 stream
= DeserializeInputStream(aParams
.get_InputStreamParams(),
177 MOZ_ASSERT(false, "Unknown params!");
180 return stream
.forget();
184 } // namespace mozilla