diff -r 000000000000 -r 6474c204b198 dom/network/src/UDPSocketChild.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dom/network/src/UDPSocketChild.cpp Wed Dec 31 06:09:35 2014 +0100 @@ -0,0 +1,211 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "UDPSocketChild.h" +#include "mozilla/net/NeckoChild.h" + +using mozilla::net::gNeckoChild; + +namespace mozilla { +namespace dom { + +NS_IMPL_ISUPPORTS(UDPSocketChildBase, nsIUDPSocketChild) + +UDPSocketChildBase::UDPSocketChildBase() +: mIPCOpen(false) +{ +} + +UDPSocketChildBase::~UDPSocketChildBase() +{ +} + +void +UDPSocketChildBase::ReleaseIPDLReference() +{ + MOZ_ASSERT(mIPCOpen); + mIPCOpen = false; + this->Release(); +} + +void +UDPSocketChildBase::AddIPDLReference() +{ + MOZ_ASSERT(!mIPCOpen); + mIPCOpen = true; + this->AddRef(); +} + +NS_IMETHODIMP_(MozExternalRefCountType) UDPSocketChild::Release(void) +{ + nsrefcnt refcnt = UDPSocketChildBase::Release(); + if (refcnt == 1 && mIPCOpen) { + PUDPSocketChild::SendRequestDelete(); + return 1; + } + return refcnt; +} + +UDPSocketChild::UDPSocketChild() +:mLocalPort(0) +{ +} + +UDPSocketChild::~UDPSocketChild() +{ +} + +// nsIUDPSocketChild Methods + +NS_IMETHODIMP +UDPSocketChild::Bind(nsIUDPSocketInternal *aSocket, + const nsACString& aHost, + uint16_t aPort) +{ + NS_ENSURE_ARG(aSocket); + + mSocket = aSocket; + AddIPDLReference(); + + gNeckoChild->SendPUDPSocketConstructor(this, nsCString(aHost), aPort, mFilterName); + + return NS_OK; +} + +NS_IMETHODIMP +UDPSocketChild::Close() +{ + SendClose(); + return NS_OK; +} + +NS_IMETHODIMP +UDPSocketChild::Send(const nsACString& aHost, + uint16_t aPort, + const uint8_t *aData, + uint32_t aByteLength) +{ + NS_ENSURE_ARG(aData); + + FallibleTArray fallibleArray; + if (!fallibleArray.InsertElementsAt(0, aData, aByteLength)) { + return NS_ERROR_OUT_OF_MEMORY; + } + + InfallibleTArray array; + array.SwapElements(fallibleArray); + SendData(array, nsCString(aHost), aPort); + + return NS_OK; +} + +NS_IMETHODIMP +UDPSocketChild::SendWithAddr(nsINetAddr *aAddr, + const uint8_t *aData, + uint32_t aByteLength) +{ + NS_ENSURE_ARG(aAddr); + NS_ENSURE_ARG(aData); + + NetAddr addr; + aAddr->GetNetAddr(&addr); + + return SendWithAddress(&addr, aData, aByteLength); +} + +NS_IMETHODIMP +UDPSocketChild::SendWithAddress(const NetAddr *aAddr, + const uint8_t *aData, + uint32_t aByteLength) +{ + NS_ENSURE_ARG(aAddr); + NS_ENSURE_ARG(aData); + + FallibleTArray fallibleArray; + if (!fallibleArray.InsertElementsAt(0, aData, aByteLength)) { + return NS_ERROR_OUT_OF_MEMORY; + } + + InfallibleTArray array; + array.SwapElements(fallibleArray); + SendDataWithAddress(array, *aAddr); + + return NS_OK; +} + +NS_IMETHODIMP +UDPSocketChild::GetLocalPort(uint16_t *aLocalPort) +{ + NS_ENSURE_ARG_POINTER(aLocalPort); + + *aLocalPort = mLocalPort; + return NS_OK; +} + +NS_IMETHODIMP +UDPSocketChild::GetLocalAddress(nsACString &aLocalAddress) +{ + aLocalAddress = mLocalAddress; + return NS_OK; +} + +NS_IMETHODIMP +UDPSocketChild::SetFilterName(const nsACString &aFilterName) +{ + if (!mFilterName.IsEmpty()) { + // filter name can only be set once. + return NS_ERROR_FAILURE; + } + mFilterName = aFilterName; + return NS_OK; +} + +NS_IMETHODIMP +UDPSocketChild::GetFilterName(nsACString &aFilterName) +{ + aFilterName = mFilterName; + return NS_OK; +} + +// PUDPSocketChild Methods +bool +UDPSocketChild::RecvCallback(const nsCString &aType, + const UDPCallbackData &aData, + const nsCString &aState) +{ + if (NS_FAILED(mSocket->UpdateReadyState(aState))) + NS_ERROR("Shouldn't fail!"); + + nsresult rv = NS_ERROR_FAILURE; + if (aData.type() == UDPCallbackData::Tvoid_t) { + rv = mSocket->CallListenerVoid(aType); + } else if (aData.type() == UDPCallbackData::TUDPError) { + const UDPError& err(aData.get_UDPError()); + rv = mSocket->CallListenerError(aType, err.message(), err.filename(), + err.lineNumber(), err.columnNumber()); + } else if (aData.type() == UDPCallbackData::TUDPMessage) { + const UDPMessage& message(aData.get_UDPMessage()); + InfallibleTArray data(message.data()); + rv = mSocket->CallListenerReceivedData(aType, message.fromAddr(), message.port(), + data.Elements(), data.Length()); + } else if (aData.type() == UDPCallbackData::TUDPAddressInfo) { + //update local address and port. + const UDPAddressInfo& addressInfo(aData.get_UDPAddressInfo()); + mLocalAddress = addressInfo.local(); + mLocalPort = addressInfo.port(); + rv = mSocket->CallListenerVoid(aType); + } else if (aData.type() == UDPCallbackData::TUDPSendResult) { + const UDPSendResult& returnValue(aData.get_UDPSendResult()); + rv = mSocket->CallListenerSent(aType, returnValue.value()); + } else { + MOZ_ASSERT(false, "Invalid callback type!"); + } + + NS_ENSURE_SUCCESS(rv, true); + + return true; +} + +} // namespace dom +} // namespace mozilla