ipc/glue/InputStreamUtils.cpp

changeset 0
6474c204b198
equal deleted inserted replaced
-1:000000000000 0:5a132c366f3f
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 "InputStreamUtils.h"
6
7 #include "nsIIPCSerializableInputStream.h"
8
9 #include "mozilla/Assertions.h"
10 #include "mozilla/dom/ipc/Blob.h"
11 #include "nsComponentManagerUtils.h"
12 #include "nsDebug.h"
13 #include "nsID.h"
14 #include "nsIDOMFile.h"
15 #include "nsIXULRuntime.h"
16 #include "nsMIMEInputStream.h"
17 #include "nsMultiplexInputStream.h"
18 #include "nsNetCID.h"
19 #include "nsStringStream.h"
20 #include "nsThreadUtils.h"
21 #include "nsXULAppAPI.h"
22
23 using mozilla::dom::BlobChild;
24 using mozilla::dom::BlobParent;
25
26 namespace {
27
28 NS_DEFINE_CID(kStringInputStreamCID, NS_STRINGINPUTSTREAM_CID);
29 NS_DEFINE_CID(kFileInputStreamCID, NS_LOCALFILEINPUTSTREAM_CID);
30 NS_DEFINE_CID(kPartialFileInputStreamCID, NS_PARTIALLOCALFILEINPUTSTREAM_CID);
31 NS_DEFINE_CID(kBufferedInputStreamCID, NS_BUFFEREDINPUTSTREAM_CID);
32 NS_DEFINE_CID(kMIMEInputStreamCID, NS_MIMEINPUTSTREAM_CID);
33 NS_DEFINE_CID(kMultiplexInputStreamCID, NS_MULTIPLEXINPUTSTREAM_CID);
34
35 } // anonymous namespace
36
37 namespace mozilla {
38 namespace ipc {
39
40 void
41 SerializeInputStream(nsIInputStream* aInputStream,
42 InputStreamParams& aParams,
43 nsTArray<FileDescriptor>& aFileDescriptors)
44 {
45 MOZ_ASSERT(NS_IsMainThread());
46 MOZ_ASSERT(aInputStream);
47
48 nsCOMPtr<nsIIPCSerializableInputStream> serializable =
49 do_QueryInterface(aInputStream);
50 if (!serializable) {
51 MOZ_CRASH("Input stream is not serializable!");
52 }
53
54 serializable->Serialize(aParams, aFileDescriptors);
55
56 if (aParams.type() == InputStreamParams::T__None) {
57 MOZ_CRASH("Serialize failed!");
58 }
59 }
60
61 void
62 SerializeInputStream(nsIInputStream* aInputStream,
63 OptionalInputStreamParams& aParams,
64 nsTArray<FileDescriptor>& aFileDescriptors)
65 {
66 MOZ_ASSERT(NS_IsMainThread());
67
68 if (aInputStream) {
69 InputStreamParams params;
70 SerializeInputStream(aInputStream, params, aFileDescriptors);
71 aParams = params;
72 }
73 else {
74 aParams = mozilla::void_t();
75 }
76 }
77
78 already_AddRefed<nsIInputStream>
79 DeserializeInputStream(const InputStreamParams& aParams,
80 const nsTArray<FileDescriptor>& aFileDescriptors)
81 {
82 MOZ_ASSERT(NS_IsMainThread());
83
84 nsCOMPtr<nsIIPCSerializableInputStream> serializable;
85
86 switch (aParams.type()) {
87 case InputStreamParams::TStringInputStreamParams:
88 serializable = do_CreateInstance(kStringInputStreamCID);
89 break;
90
91 case InputStreamParams::TFileInputStreamParams:
92 serializable = do_CreateInstance(kFileInputStreamCID);
93 break;
94
95 case InputStreamParams::TPartialFileInputStreamParams:
96 serializable = do_CreateInstance(kPartialFileInputStreamCID);
97 break;
98
99 case InputStreamParams::TBufferedInputStreamParams:
100 serializable = do_CreateInstance(kBufferedInputStreamCID);
101 break;
102
103 case InputStreamParams::TMIMEInputStreamParams:
104 serializable = do_CreateInstance(kMIMEInputStreamCID);
105 break;
106
107 case InputStreamParams::TMultiplexInputStreamParams:
108 serializable = do_CreateInstance(kMultiplexInputStreamCID);
109 break;
110
111 // When the input stream already exists in this process, all we need to do
112 // is retrieve the original instead of sending any data over the wire.
113 case InputStreamParams::TRemoteInputStreamParams: {
114 nsCOMPtr<nsIDOMBlob> domBlob;
115 const RemoteInputStreamParams& params =
116 aParams.get_RemoteInputStreamParams();
117
118 domBlob = params.remoteBlobParent() ?
119 static_cast<BlobParent*>(params.remoteBlobParent())->GetBlob() :
120 static_cast<BlobChild*>(params.remoteBlobChild())->GetBlob();
121
122 MOZ_ASSERT(domBlob, "Invalid blob contents");
123
124 // If fetching the internal stream fails, we ignore it and return a
125 // null stream.
126 nsCOMPtr<nsIInputStream> stream;
127 nsresult rv = domBlob->GetInternalStream(getter_AddRefs(stream));
128 if (NS_FAILED(rv) || !stream) {
129 NS_WARNING("Couldn't obtain a valid stream from the blob");
130 }
131 return stream.forget();
132 }
133
134 default:
135 MOZ_ASSERT(false, "Unknown params!");
136 return nullptr;
137 }
138
139 MOZ_ASSERT(serializable);
140
141 if (!serializable->Deserialize(aParams, aFileDescriptors)) {
142 MOZ_ASSERT(false, "Deserialize failed!");
143 return nullptr;
144 }
145
146 nsCOMPtr<nsIInputStream> stream = do_QueryInterface(serializable);
147 MOZ_ASSERT(stream);
148
149 return stream.forget();
150 }
151
152 already_AddRefed<nsIInputStream>
153 DeserializeInputStream(const OptionalInputStreamParams& aParams,
154 const nsTArray<FileDescriptor>& aFileDescriptors)
155 {
156 MOZ_ASSERT(NS_IsMainThread());
157
158 nsCOMPtr<nsIInputStream> stream;
159
160 switch (aParams.type()) {
161 case OptionalInputStreamParams::Tvoid_t:
162 // Leave stream null.
163 break;
164
165 case OptionalInputStreamParams::TInputStreamParams:
166 stream = DeserializeInputStream(aParams.get_InputStreamParams(),
167 aFileDescriptors);
168 break;
169
170 default:
171 MOZ_ASSERT(false, "Unknown params!");
172 }
173
174 return stream.forget();
175 }
176
177 } // namespace ipc
178 } // namespace mozilla

mercurial