Bug 1707290 [wpt PR 28671] - Auto-expand details elements for find-in-page, a=testonly
[gecko.git] / dom / network / TCPSocketChild.cpp
blob3397dc853e4a5b85784ecc1e41f2a1f80dbce5ff
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 file,
5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include <algorithm>
8 #include "TCPSocketChild.h"
9 #include "mozilla/HoldDropJSObjects.h"
10 #include "mozilla/Unused.h"
11 #include "mozilla/UniquePtr.h"
12 #include "mozilla/net/NeckoChild.h"
13 #include "mozilla/dom/PBrowserChild.h"
14 #include "mozilla/dom/BrowserChild.h"
15 #include "nsITCPSocketCallback.h"
16 #include "TCPSocket.h"
17 #include "nsContentUtils.h"
18 #include "js/ArrayBuffer.h" // JS::NewArrayBufferWithContents
19 #include "js/RootingAPI.h" // JS::MutableHandle
20 #include "js/Utility.h" // js::ArrayBufferContentsArena, JS::FreePolicy, js_pod_arena_malloc
21 #include "js/Value.h" // JS::Value
23 using mozilla::net::gNeckoChild;
25 namespace IPC {
27 bool DeserializeArrayBuffer(JSContext* cx, const nsTArray<uint8_t>& aBuffer,
28 JS::MutableHandle<JS::Value> aVal) {
29 mozilla::UniquePtr<uint8_t[], JS::FreePolicy> data(
30 js_pod_arena_malloc<uint8_t>(js::ArrayBufferContentsArena,
31 aBuffer.Length()));
32 if (!data) return false;
33 memcpy(data.get(), aBuffer.Elements(), aBuffer.Length());
35 JSObject* obj =
36 JS::NewArrayBufferWithContents(cx, aBuffer.Length(), data.get());
37 if (!obj) return false;
38 // If JS::NewArrayBufferWithContents returns non-null, the ownership of
39 // the data is transfered to obj, so we release the ownership here.
40 mozilla::Unused << data.release();
42 aVal.setObject(*obj);
43 return true;
46 } // namespace IPC
48 namespace mozilla::dom {
50 NS_IMPL_CYCLE_COLLECTION_CLASS(TCPSocketChildBase)
52 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(TCPSocketChildBase)
53 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSocket)
54 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
56 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(TCPSocketChildBase)
57 NS_IMPL_CYCLE_COLLECTION_UNLINK(mSocket)
58 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
60 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(TCPSocketChildBase)
61 NS_IMPL_CYCLE_COLLECTION_TRACE_END
63 NS_IMPL_CYCLE_COLLECTING_ADDREF(TCPSocketChildBase)
64 NS_IMPL_CYCLE_COLLECTING_RELEASE(TCPSocketChildBase)
66 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(TCPSocketChildBase)
67 NS_INTERFACE_MAP_ENTRY(nsISupports)
68 NS_INTERFACE_MAP_END
70 TCPSocketChildBase::TCPSocketChildBase() : mIPCOpen(false) {
71 mozilla::HoldJSObjects(this);
74 TCPSocketChildBase::~TCPSocketChildBase() { mozilla::DropJSObjects(this); }
76 NS_IMETHODIMP_(MozExternalRefCountType) TCPSocketChild::Release(void) {
77 nsrefcnt refcnt = TCPSocketChildBase::Release();
78 if (refcnt == 1 && mIPCOpen) {
79 PTCPSocketChild::SendRequestDelete();
80 return 1;
82 return refcnt;
85 TCPSocketChild::TCPSocketChild(const nsAString& aHost, const uint16_t& aPort,
86 nsISerialEventTarget* aTarget)
87 : mHost(aHost), mPort(aPort), mIPCEventTarget(aTarget) {}
89 void TCPSocketChild::SendOpen(nsITCPSocketCallback* aSocket, bool aUseSSL,
90 bool aUseArrayBuffers) {
91 mSocket = aSocket;
93 if (mIPCEventTarget) {
94 gNeckoChild->SetEventTargetForActor(this, mIPCEventTarget);
97 AddIPDLReference();
98 gNeckoChild->SendPTCPSocketConstructor(this, mHost, mPort);
99 PTCPSocketChild::SendOpen(mHost, mPort, aUseSSL, aUseArrayBuffers);
102 void TCPSocketChildBase::ReleaseIPDLReference() {
103 MOZ_ASSERT(mIPCOpen);
104 mIPCOpen = false;
105 mSocket = nullptr;
106 this->Release();
109 void TCPSocketChildBase::AddIPDLReference() {
110 MOZ_ASSERT(!mIPCOpen);
111 mIPCOpen = true;
112 this->AddRef();
115 TCPSocketChild::~TCPSocketChild() = default;
117 mozilla::ipc::IPCResult TCPSocketChild::RecvUpdateBufferedAmount(
118 const uint32_t& aBuffered, const uint32_t& aTrackingNumber) {
119 mSocket->UpdateBufferedAmount(aBuffered, aTrackingNumber);
120 return IPC_OK();
123 mozilla::ipc::IPCResult TCPSocketChild::RecvCallback(
124 const nsString& aType, const CallbackData& aData,
125 const uint32_t& aReadyState) {
126 mSocket->UpdateReadyState(aReadyState);
128 if (aData.type() == CallbackData::Tvoid_t) {
129 mSocket->FireEvent(aType);
131 } else if (aData.type() == CallbackData::TTCPError) {
132 const TCPError& err(aData.get_TCPError());
133 mSocket->FireErrorEvent(err.name(), err.message(), err.errorCode());
135 } else if (aData.type() == CallbackData::TSendableData) {
136 const SendableData& data = aData.get_SendableData();
138 if (data.type() == SendableData::TArrayOfuint8_t) {
139 mSocket->FireDataArrayEvent(aType, data.get_ArrayOfuint8_t());
140 } else if (data.type() == SendableData::TnsCString) {
141 mSocket->FireDataStringEvent(aType, data.get_nsCString());
142 } else {
143 MOZ_CRASH("Invalid callback data type!");
145 } else {
146 MOZ_CRASH("Invalid callback type!");
148 return IPC_OK();
151 void TCPSocketChild::SendSend(const nsACString& aData) {
152 SendData(nsCString(aData));
155 nsresult TCPSocketChild::SendSend(const ArrayBuffer& aData,
156 uint32_t aByteOffset, uint32_t aByteLength) {
157 uint32_t buflen = aData.Length();
158 uint32_t offset = std::min(buflen, aByteOffset);
159 uint32_t nbytes = std::min(buflen - aByteOffset, aByteLength);
160 FallibleTArray<uint8_t> fallibleArr;
161 if (!fallibleArr.InsertElementsAt(0, aData.Data() + offset, nbytes,
162 fallible)) {
163 return NS_ERROR_OUT_OF_MEMORY;
166 SendData(SendableData{std::move(fallibleArr)});
167 return NS_OK;
170 void TCPSocketChild::SetSocket(TCPSocket* aSocket) { mSocket = aSocket; }
172 void TCPSocketChild::GetHost(nsAString& aHost) { aHost = mHost; }
174 void TCPSocketChild::GetPort(uint16_t* aPort) { *aPort = mPort; }
176 mozilla::ipc::IPCResult TCPSocketChild::RecvRequestDelete() {
177 mozilla::Unused << Send__delete__(this);
178 return IPC_OK();
181 } // namespace mozilla::dom