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 "IPCStreamDestination.h"
8 #include "IPCStreamSource.h"
9 
10 #include "mozilla/Unused.h"
11 #include "mozilla/ipc/PChildToParentStreamChild.h"
12 #include "mozilla/ipc/PParentToChildStreamChild.h"
13 
14 namespace mozilla {
15 namespace ipc {
16 
17 // Child to Parent implementation
18 // ----------------------------------------------------------------------------
19 
20 namespace {
21 
22 class IPCStreamSourceChild final : public PChildToParentStreamChild,
23                                    public IPCStreamSource {
24  public:
Create(nsIAsyncInputStream * aInputStream)25   static IPCStreamSourceChild* Create(nsIAsyncInputStream* aInputStream) {
26     MOZ_ASSERT(aInputStream);
27 
28     IPCStreamSourceChild* source = new IPCStreamSourceChild(aInputStream);
29     if (!source->Initialize()) {
30       delete source;
31       return nullptr;
32     }
33 
34     return source;
35   }
36 
37   // PChildToParentStreamChild methods
38 
ActorDestroy(ActorDestroyReason aReason)39   void ActorDestroy(ActorDestroyReason aReason) override { ActorDestroyed(); }
40 
RecvStartReading()41   IPCResult RecvStartReading() override {
42     Start();
43     return IPC_OK();
44   }
45 
RecvRequestClose(const nsresult & aRv)46   IPCResult RecvRequestClose(const nsresult& aRv) override {
47     OnEnd(aRv);
48     return IPC_OK();
49   }
50 
Close(nsresult aRv)51   void Close(nsresult aRv) override {
52     MOZ_ASSERT(IPCStreamSource::mState == IPCStreamSource::eClosed);
53     Unused << SendClose(aRv);
54   }
55 
SendData(const wr::ByteBuffer & aBuffer)56   void SendData(const wr::ByteBuffer& aBuffer) override {
57     Unused << SendBuffer(aBuffer);
58   }
59 
60  private:
IPCStreamSourceChild(nsIAsyncInputStream * aInputStream)61   explicit IPCStreamSourceChild(nsIAsyncInputStream* aInputStream)
62       : IPCStreamSource(aInputStream) {}
63 };
64 
65 }  // anonymous namespace
66 
67 /* static */
Create(nsIAsyncInputStream * aInputStream,ChildToParentStreamActorManager * aManager)68 PChildToParentStreamChild* IPCStreamSource::Create(
69     nsIAsyncInputStream* aInputStream,
70     ChildToParentStreamActorManager* aManager) {
71   MOZ_ASSERT(aInputStream);
72   MOZ_ASSERT(aManager);
73 
74   IPCStreamSourceChild* source = IPCStreamSourceChild::Create(aInputStream);
75   if (!source) {
76     return nullptr;
77   }
78 
79   if (!aManager->SendPChildToParentStreamConstructor(source)) {
80     return nullptr;
81   }
82 
83   source->ActorConstructed();
84   return source;
85 }
86 
87 /* static */
Cast(PChildToParentStreamChild * aActor)88 IPCStreamSource* IPCStreamSource::Cast(PChildToParentStreamChild* aActor) {
89   MOZ_ASSERT(aActor);
90   return static_cast<IPCStreamSourceChild*>(aActor);
91 }
92 
93 // Parent to Child implementation
94 // ----------------------------------------------------------------------------
95 
96 namespace {
97 
98 class IPCStreamDestinationChild final : public PParentToChildStreamChild,
99                                         public IPCStreamDestination {
100  public:
Initialize()101   nsresult Initialize() { return IPCStreamDestination::Initialize(); }
102 
103   ~IPCStreamDestinationChild() = default;
104 
105  private:
106   // PParentToChildStreamChild methods
107 
ActorDestroy(ActorDestroyReason aReason)108   void ActorDestroy(ActorDestroyReason aReason) override { ActorDestroyed(); }
109 
RecvBuffer(const wr::ByteBuffer & aBuffer)110   IPCResult RecvBuffer(const wr::ByteBuffer& aBuffer) override {
111     BufferReceived(aBuffer);
112     return IPC_OK();
113   }
114 
RecvClose(const nsresult & aRv)115   IPCResult RecvClose(const nsresult& aRv) override {
116     CloseReceived(aRv);
117     return IPC_OK();
118   }
119 
120   // IPCStreamDestination methods
121 
StartReading()122   void StartReading() override {
123     MOZ_ASSERT(HasDelayedStart());
124     Unused << SendStartReading();
125   }
126 
RequestClose(nsresult aRv)127   void RequestClose(nsresult aRv) override { Unused << SendRequestClose(aRv); }
128 
TerminateDestination()129   void TerminateDestination() override { Unused << Send__delete__(this); }
130 };
131 
132 }  // anonymous namespace
133 
AllocPParentToChildStreamChild()134 PParentToChildStreamChild* AllocPParentToChildStreamChild() {
135   IPCStreamDestinationChild* actor = new IPCStreamDestinationChild();
136 
137   if (NS_WARN_IF(NS_FAILED(actor->Initialize()))) {
138     delete actor;
139     actor = nullptr;
140   }
141 
142   return actor;
143 }
144 
DeallocPParentToChildStreamChild(PParentToChildStreamChild * aActor)145 void DeallocPParentToChildStreamChild(PParentToChildStreamChild* aActor) {
146   delete aActor;
147 }
148 
149 /* static */
Cast(PParentToChildStreamChild * aActor)150 IPCStreamDestination* IPCStreamDestination::Cast(
151     PParentToChildStreamChild* aActor) {
152   MOZ_ASSERT(aActor);
153   return static_cast<IPCStreamDestinationChild*>(aActor);
154 }
155 
156 }  // namespace ipc
157 }  // namespace mozilla
158