Bug 1690111 - Use new TypedArray APIs for appending data to a container. r=farre,extension-reviewers,media-playback-reviewers,kmag,alwu,padenot
Depends on D152494 Differential Revision: https://phabricator.services.mozilla.com/D152495
This commit is contained in:
@@ -172,17 +172,26 @@ void nsDOMDataChannel::Close() {
|
||||
|
||||
// All of the following is copy/pasted from WebSocket.cpp.
|
||||
void nsDOMDataChannel::Send(const nsAString& aData, ErrorResult& aRv) {
|
||||
if (!CheckReadyState(aRv)) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsAutoCString msgString;
|
||||
if (!AppendUTF16toUTF8(aData, msgString, mozilla::fallible_t())) {
|
||||
aRv.Throw(NS_ERROR_FILE_TOO_BIG);
|
||||
return;
|
||||
}
|
||||
Send(nullptr, &msgString, false, aRv);
|
||||
|
||||
mDataChannel->SendMsg(msgString, aRv);
|
||||
}
|
||||
|
||||
void nsDOMDataChannel::Send(Blob& aData, ErrorResult& aRv) {
|
||||
MOZ_ASSERT(NS_IsMainThread(), "Not running on main thread");
|
||||
|
||||
if (!CheckReadyState(aRv)) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIInputStream> msgStream;
|
||||
aData.CreateInputStream(getter_AddRefs(msgStream), aRv);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
@@ -199,50 +208,42 @@ void nsDOMDataChannel::Send(Blob& aData, ErrorResult& aRv) {
|
||||
return;
|
||||
}
|
||||
|
||||
Send(&aData, nullptr, true, aRv);
|
||||
mDataChannel->SendBinaryBlob(aData, aRv);
|
||||
}
|
||||
|
||||
void nsDOMDataChannel::Send(const ArrayBuffer& aData, ErrorResult& aRv) {
|
||||
MOZ_ASSERT(NS_IsMainThread(), "Not running on main thread");
|
||||
|
||||
aData.ComputeState();
|
||||
if (!CheckReadyState(aRv)) {
|
||||
return;
|
||||
}
|
||||
|
||||
static_assert(sizeof(*aData.Data()) == 1, "byte-sized data required");
|
||||
|
||||
uint32_t len = aData.Length();
|
||||
char* data = reinterpret_cast<char*>(aData.Data());
|
||||
|
||||
nsDependentCSubstring msgString;
|
||||
if (!msgString.Assign(data, len, mozilla::fallible_t())) {
|
||||
nsCString msgString;
|
||||
if (!aData.AppendDataTo(msgString)) {
|
||||
aRv.Throw(NS_ERROR_FILE_TOO_BIG);
|
||||
return;
|
||||
}
|
||||
|
||||
Send(nullptr, &msgString, true, aRv);
|
||||
mDataChannel->SendBinaryMsg(msgString, aRv);
|
||||
}
|
||||
|
||||
void nsDOMDataChannel::Send(const ArrayBufferView& aData, ErrorResult& aRv) {
|
||||
MOZ_ASSERT(NS_IsMainThread(), "Not running on main thread");
|
||||
|
||||
aData.ComputeState();
|
||||
if (!CheckReadyState(aRv)) {
|
||||
return;
|
||||
}
|
||||
|
||||
static_assert(sizeof(*aData.Data()) == 1, "byte-sized data required");
|
||||
|
||||
uint32_t len = aData.Length();
|
||||
char* data = reinterpret_cast<char*>(aData.Data());
|
||||
|
||||
nsDependentCSubstring msgString;
|
||||
if (!msgString.Assign(data, len, mozilla::fallible_t())) {
|
||||
nsCString msgString;
|
||||
if (!aData.AppendDataTo(msgString)) {
|
||||
aRv.Throw(NS_ERROR_FILE_TOO_BIG);
|
||||
return;
|
||||
}
|
||||
|
||||
Send(nullptr, &msgString, true, aRv);
|
||||
mDataChannel->SendBinaryMsg(msgString, aRv);
|
||||
}
|
||||
|
||||
void nsDOMDataChannel::Send(mozilla::dom::Blob* aMsgBlob,
|
||||
const nsACString* aMsgString, bool aIsBinary,
|
||||
mozilla::ErrorResult& aRv) {
|
||||
bool nsDOMDataChannel::CheckReadyState(ErrorResult& aRv) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
uint16_t state = mozilla::DataChannel::CLOSED;
|
||||
if (!mSentClose) {
|
||||
@@ -253,26 +254,18 @@ void nsDOMDataChannel::Send(mozilla::dom::Blob* aMsgBlob,
|
||||
// look like WebSockets
|
||||
if (state == mozilla::DataChannel::CONNECTING) {
|
||||
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (state == mozilla::DataChannel::CLOSING ||
|
||||
state == mozilla::DataChannel::CLOSED) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(state == mozilla::DataChannel::OPEN,
|
||||
"Unknown state in nsDOMDataChannel::Send");
|
||||
|
||||
if (aMsgBlob) {
|
||||
mDataChannel->SendBinaryBlob(*aMsgBlob, aRv);
|
||||
} else {
|
||||
if (aIsBinary) {
|
||||
mDataChannel->SendBinaryMsg(*aMsgString, aRv);
|
||||
} else {
|
||||
mDataChannel->SendMsg(*aMsgString, aRv);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
nsresult nsDOMDataChannel::DoOnMessageAvailable(const nsACString& aData,
|
||||
|
||||
@@ -108,8 +108,7 @@ class nsDOMDataChannel final : public mozilla::DOMEventTargetHelper,
|
||||
~nsDOMDataChannel();
|
||||
|
||||
private:
|
||||
void Send(mozilla::dom::Blob* aMsgBlob, const nsACString* aMsgString,
|
||||
bool aIsBinary, mozilla::ErrorResult& aRv);
|
||||
bool CheckReadyState(mozilla::ErrorResult& aRv);
|
||||
|
||||
void ReleaseSelf();
|
||||
|
||||
|
||||
@@ -38,46 +38,30 @@ uint8_t* CryptoBuffer::Assign(const nsTArray<uint8_t>& aData) {
|
||||
}
|
||||
|
||||
uint8_t* CryptoBuffer::Assign(const ArrayBuffer& aData) {
|
||||
aData.ComputeState();
|
||||
return Assign(aData.Data(), aData.Length());
|
||||
Clear();
|
||||
return aData.AppendDataTo(*this) ? Elements() : nullptr;
|
||||
}
|
||||
|
||||
uint8_t* CryptoBuffer::Assign(const ArrayBufferView& aData) {
|
||||
aData.ComputeState();
|
||||
return Assign(aData.Data(), aData.Length());
|
||||
Clear();
|
||||
return aData.AppendDataTo(*this) ? Elements() : nullptr;
|
||||
}
|
||||
|
||||
uint8_t* CryptoBuffer::Assign(const ArrayBufferViewOrArrayBuffer& aData) {
|
||||
if (aData.IsArrayBufferView()) {
|
||||
return Assign(aData.GetAsArrayBufferView());
|
||||
}
|
||||
if (aData.IsArrayBuffer()) {
|
||||
return Assign(aData.GetAsArrayBuffer());
|
||||
}
|
||||
|
||||
// If your union is uninitialized, something's wrong
|
||||
MOZ_ASSERT(false);
|
||||
Clear();
|
||||
return nullptr;
|
||||
|
||||
return AppendTypedArrayDataTo(aData, *this) ? Elements() : nullptr;
|
||||
}
|
||||
|
||||
uint8_t* CryptoBuffer::Assign(const OwningArrayBufferViewOrArrayBuffer& aData) {
|
||||
if (aData.IsArrayBufferView()) {
|
||||
return Assign(aData.GetAsArrayBufferView());
|
||||
}
|
||||
if (aData.IsArrayBuffer()) {
|
||||
return Assign(aData.GetAsArrayBuffer());
|
||||
}
|
||||
|
||||
// If your union is uninitialized, something's wrong
|
||||
MOZ_ASSERT(false);
|
||||
Clear();
|
||||
return nullptr;
|
||||
|
||||
return AppendTypedArrayDataTo(aData, *this) ? Elements() : nullptr;
|
||||
}
|
||||
|
||||
uint8_t* CryptoBuffer::Assign(const Uint8Array& aArray) {
|
||||
aArray.ComputeState();
|
||||
return Assign(aArray.Data(), aArray.Length());
|
||||
Clear();
|
||||
return aArray.AppendDataTo(*this) ? Elements() : nullptr;
|
||||
}
|
||||
|
||||
uint8_t* CryptoBuffer::AppendSECItem(const SECItem* aItem) {
|
||||
|
||||
@@ -325,7 +325,6 @@ void FetchStreamReader::ChunkSteps(JSContext* aCx, JS::Handle<JS::Value> aChunk,
|
||||
CloseAndRelease(aCx, NS_ERROR_DOM_WRONG_TYPE_ERR);
|
||||
return;
|
||||
}
|
||||
chunk.ComputeState();
|
||||
|
||||
MOZ_DIAGNOSTIC_ASSERT(mBuffer.IsEmpty());
|
||||
|
||||
@@ -333,13 +332,13 @@ void FetchStreamReader::ChunkSteps(JSContext* aCx, JS::Handle<JS::Value> aChunk,
|
||||
// FIXME: We could sometimes avoid this copy by trying to write `chunk`
|
||||
// directly into `mPipeOut` eagerly, and only filling `mBuffer` if there isn't
|
||||
// enough space in the pipe's buffer.
|
||||
if (!mBuffer.AppendElements(chunk.Data(), chunk.Length(), fallible)) {
|
||||
if (!chunk.AppendDataTo(mBuffer)) {
|
||||
CloseAndRelease(aCx, NS_ERROR_OUT_OF_MEMORY);
|
||||
return;
|
||||
}
|
||||
|
||||
mBufferOffset = 0;
|
||||
mBufferRemaining = chunk.Length();
|
||||
mBufferRemaining = mBuffer.Length();
|
||||
|
||||
nsresult rv = WriteBuffer();
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
|
||||
@@ -44,13 +44,8 @@ ArrayData GetArrayBufferViewOrArrayBufferData(
|
||||
void CopyArrayBufferViewOrArrayBufferData(
|
||||
const dom::ArrayBufferViewOrArrayBuffer& aBufferOrView,
|
||||
nsTArray<uint8_t>& aOutData) {
|
||||
JS::AutoCheckCannotGC nogc;
|
||||
ArrayData data = GetArrayBufferViewOrArrayBufferData(aBufferOrView);
|
||||
aOutData.Clear();
|
||||
if (!data.IsValid()) {
|
||||
return;
|
||||
}
|
||||
aOutData.AppendElements(data.mData, data.mLength);
|
||||
Unused << dom::AppendTypedArrayDataTo(aBufferOrView, aOutData);
|
||||
}
|
||||
|
||||
bool IsClearkeyKeySystem(const nsAString& aKeySystem) {
|
||||
|
||||
@@ -330,17 +330,12 @@ void WaveShaperNode::SetCurve(const Nullable<Float32Array>& aCurve,
|
||||
return;
|
||||
}
|
||||
|
||||
const Float32Array& floats = aCurve.Value();
|
||||
floats.ComputeState();
|
||||
|
||||
nsTArray<float> curve;
|
||||
uint32_t argLength = floats.Length();
|
||||
if (!curve.SetLength(argLength, fallible)) {
|
||||
if (!aCurve.Value().AppendDataTo(curve)) {
|
||||
aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
|
||||
return;
|
||||
}
|
||||
|
||||
PodCopy(curve.Elements(), floats.Data(), argLength);
|
||||
SetCurveInternal(curve, aRv);
|
||||
}
|
||||
|
||||
|
||||
@@ -233,15 +233,9 @@ static nsTArray<UniquePtr<TrackInfo>> GetTracksInfo(MIMECreateParam aParam) {
|
||||
|
||||
static Result<RefPtr<MediaByteBuffer>, nsresult> GetExtraData(
|
||||
const OwningMaybeSharedArrayBufferViewOrMaybeSharedArrayBuffer& aBuffer) {
|
||||
RefPtr<MediaByteBuffer> data = nullptr;
|
||||
Span<uint8_t> buf;
|
||||
MOZ_TRY_VAR(buf, GetSharedArrayBufferData(aBuffer));
|
||||
if (buf.empty()) {
|
||||
return data;
|
||||
}
|
||||
data = MakeRefPtr<MediaByteBuffer>();
|
||||
data->AppendElements(buf);
|
||||
return data;
|
||||
RefPtr<MediaByteBuffer> data = MakeRefPtr<MediaByteBuffer>();
|
||||
Unused << AppendTypedArrayDataTo(aBuffer, *data);
|
||||
return data->Length() > 0 ? data : nullptr;
|
||||
}
|
||||
|
||||
static Result<UniquePtr<TrackInfo>, nsresult> CreateVideoInfo(
|
||||
|
||||
@@ -73,9 +73,6 @@ Nullable<T> MaybeToNullable(const Maybe<T>& aOptional) {
|
||||
* Below are helpers to operate ArrayBuffer or ArrayBufferView.
|
||||
*/
|
||||
|
||||
template <class T>
|
||||
Result<Span<uint8_t>, nsresult> GetArrayBufferData(const T& aBuffer);
|
||||
|
||||
Result<Span<uint8_t>, nsresult> GetSharedArrayBufferData(
|
||||
const MaybeSharedArrayBufferViewOrMaybeSharedArrayBuffer& aBuffer);
|
||||
|
||||
|
||||
@@ -811,27 +811,36 @@ bool TCPSocket::Send(const ArrayBuffer& aData, uint32_t aByteOffset,
|
||||
|
||||
nsCOMPtr<nsIArrayBufferInputStream> stream;
|
||||
|
||||
aData.ComputeState();
|
||||
uint32_t byteLength =
|
||||
aByteLength.WasPassed() ? aByteLength.Value() : aData.Length();
|
||||
uint32_t nbytes;
|
||||
auto calculateOffsetAndCount = [&](uint32_t aLength) {
|
||||
uint32_t offset = std::min(aLength, aByteOffset);
|
||||
nbytes = std::min(aLength - aByteOffset,
|
||||
aByteLength.WasPassed() ? aByteLength.Value() : aLength);
|
||||
return std::pair(offset, nbytes);
|
||||
};
|
||||
|
||||
if (mSocketBridgeChild) {
|
||||
nsresult rv = mSocketBridgeChild->SendSend(aData, aByteOffset, byteLength);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
aRv.Throw(rv);
|
||||
nsTArray<uint8_t> arrayBuffer;
|
||||
if (!aData.AppendDataTo(arrayBuffer, calculateOffsetAndCount)) {
|
||||
aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
|
||||
return false;
|
||||
}
|
||||
|
||||
mSocketBridgeChild->SendSend(std::move(arrayBuffer));
|
||||
} else {
|
||||
aData.ComputeState();
|
||||
calculateOffsetAndCount(aData.Length());
|
||||
|
||||
JS::Rooted<JS::Value> value(RootingCx(), JS::ObjectValue(*aData.Obj()));
|
||||
|
||||
stream = do_CreateInstance("@mozilla.org/io/arraybuffer-input-stream;1");
|
||||
nsresult rv = stream->SetData(value, aByteOffset, byteLength);
|
||||
nsresult rv = stream->SetData(value, aByteOffset, nbytes);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
aRv.Throw(rv);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return Send(stream, byteLength);
|
||||
return Send(stream, nbytes);
|
||||
}
|
||||
|
||||
bool TCPSocket::Send(nsIInputStream* aStream, uint32_t aByteLength) {
|
||||
|
||||
@@ -145,19 +145,8 @@ void TCPSocketChild::SendSend(const nsACString& aData) {
|
||||
SendData(nsCString(aData));
|
||||
}
|
||||
|
||||
nsresult TCPSocketChild::SendSend(const ArrayBuffer& aData,
|
||||
uint32_t aByteOffset, uint32_t aByteLength) {
|
||||
uint32_t buflen = aData.Length();
|
||||
uint32_t offset = std::min(buflen, aByteOffset);
|
||||
uint32_t nbytes = std::min(buflen - aByteOffset, aByteLength);
|
||||
FallibleTArray<uint8_t> fallibleArr;
|
||||
if (!fallibleArr.InsertElementsAt(0, aData.Data() + offset, nbytes,
|
||||
fallible)) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
SendData(SendableData{std::move(fallibleArr)});
|
||||
return NS_OK;
|
||||
void TCPSocketChild::SendSend(nsTArray<uint8_t>&& aData) {
|
||||
SendData(SendableData{std::move(aData)});
|
||||
}
|
||||
|
||||
void TCPSocketChild::SetSocket(TCPSocket* aSocket) { mSocket = aSocket; }
|
||||
|
||||
@@ -52,8 +52,7 @@ class TCPSocketChild : public mozilla::net::PTCPSocketChild,
|
||||
void SendOpen(nsITCPSocketCallback* aSocket, bool aUseSSL,
|
||||
bool aUseArrayBuffers);
|
||||
void SendSend(const nsACString& aData);
|
||||
nsresult SendSend(const ArrayBuffer& aData, uint32_t aByteOffset,
|
||||
uint32_t aByteLength);
|
||||
void SendSend(nsTArray<uint8_t>&& aData);
|
||||
void SetSocket(TCPSocket* aSocket);
|
||||
|
||||
void GetHost(nsAString& aHost);
|
||||
|
||||
@@ -341,16 +341,14 @@ bool UDPSocket::Send(const StringOrBlobOrArrayBufferOrArrayBufferView& aData,
|
||||
if (aData.IsString()) {
|
||||
NS_ConvertUTF16toUTF8 data(aData.GetAsString());
|
||||
aRv = strStream->SetData(data.BeginReading(), data.Length());
|
||||
} else if (aData.IsArrayBuffer()) {
|
||||
const ArrayBuffer& data = aData.GetAsArrayBuffer();
|
||||
data.ComputeState();
|
||||
aRv = strStream->SetData(reinterpret_cast<const char*>(data.Data()),
|
||||
data.Length());
|
||||
} else {
|
||||
const ArrayBufferView& data = aData.GetAsArrayBufferView();
|
||||
data.ComputeState();
|
||||
aRv = strStream->SetData(reinterpret_cast<const char*>(data.Data()),
|
||||
data.Length());
|
||||
Vector<char> data;
|
||||
if (!AppendTypedArrayDataTo(aData, data)) {
|
||||
aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
|
||||
return false;
|
||||
}
|
||||
size_t length = data.length();
|
||||
aRv = strStream->AdoptData(data.extractOrCopyRawBuffer(), length);
|
||||
}
|
||||
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
|
||||
@@ -522,18 +522,10 @@ nsresult PushManager::NormalizeAppServerKey(
|
||||
return NS_ERROR_DOM_INVALID_CHARACTER_ERR;
|
||||
}
|
||||
aAppServerKey = decodedKey;
|
||||
} else if (aSource.IsArrayBuffer()) {
|
||||
if (!PushUtil::CopyArrayBufferToArray(aSource.GetAsArrayBuffer(),
|
||||
aAppServerKey)) {
|
||||
return NS_ERROR_DOM_PUSH_INVALID_KEY_ERR;
|
||||
}
|
||||
} else if (aSource.IsArrayBufferView()) {
|
||||
if (!PushUtil::CopyArrayBufferViewToArray(aSource.GetAsArrayBufferView(),
|
||||
aAppServerKey)) {
|
||||
return NS_ERROR_DOM_PUSH_INVALID_KEY_ERR;
|
||||
}
|
||||
} else {
|
||||
MOZ_CRASH("Uninitialized union: expected string, buffer, or view");
|
||||
if (!AppendTypedArrayDataTo(aSource, aAppServerKey)) {
|
||||
return NS_ERROR_DOM_PUSH_INVALID_KEY_ERR;
|
||||
}
|
||||
}
|
||||
if (aAppServerKey.IsEmpty()) {
|
||||
return NS_ERROR_DOM_PUSH_INVALID_KEY_ERR;
|
||||
|
||||
@@ -228,8 +228,7 @@ already_AddRefed<PushSubscription> PushSubscription::Constructor(
|
||||
nsTArray<uint8_t> rawKey;
|
||||
if (aInitDict.mP256dhKey.WasPassed() &&
|
||||
!aInitDict.mP256dhKey.Value().IsNull() &&
|
||||
!PushUtil::CopyArrayBufferToArray(aInitDict.mP256dhKey.Value().Value(),
|
||||
rawKey)) {
|
||||
!aInitDict.mP256dhKey.Value().Value().AppendDataTo(rawKey)) {
|
||||
aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
|
||||
return nullptr;
|
||||
}
|
||||
@@ -237,8 +236,7 @@ already_AddRefed<PushSubscription> PushSubscription::Constructor(
|
||||
nsTArray<uint8_t> authSecret;
|
||||
if (aInitDict.mAuthSecret.WasPassed() &&
|
||||
!aInitDict.mAuthSecret.Value().IsNull() &&
|
||||
!PushUtil::CopyArrayBufferToArray(aInitDict.mAuthSecret.Value().Value(),
|
||||
authSecret)) {
|
||||
!aInitDict.mAuthSecret.Value().Value().AppendDataTo(authSecret)) {
|
||||
aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -9,35 +9,12 @@
|
||||
|
||||
namespace mozilla::dom {
|
||||
|
||||
/* static */
|
||||
bool PushUtil::CopyArrayBufferToArray(const ArrayBuffer& aBuffer,
|
||||
nsTArray<uint8_t>& aArray) {
|
||||
MOZ_ASSERT(aArray.IsEmpty());
|
||||
aBuffer.ComputeState();
|
||||
return aArray.SetCapacity(aBuffer.Length(), fallible) &&
|
||||
aArray.InsertElementsAt(0, aBuffer.Data(), aBuffer.Length(), fallible);
|
||||
}
|
||||
|
||||
/* static */
|
||||
bool PushUtil::CopyArrayBufferViewToArray(const ArrayBufferView& aView,
|
||||
nsTArray<uint8_t>& aArray) {
|
||||
MOZ_ASSERT(aArray.IsEmpty());
|
||||
aView.ComputeState();
|
||||
return aArray.SetCapacity(aView.Length(), fallible) &&
|
||||
aArray.InsertElementsAt(0, aView.Data(), aView.Length(), fallible);
|
||||
}
|
||||
|
||||
/* static */
|
||||
bool PushUtil::CopyBufferSourceToArray(
|
||||
const OwningArrayBufferViewOrArrayBuffer& aSource,
|
||||
nsTArray<uint8_t>& aArray) {
|
||||
if (aSource.IsArrayBuffer()) {
|
||||
return CopyArrayBufferToArray(aSource.GetAsArrayBuffer(), aArray);
|
||||
}
|
||||
if (aSource.IsArrayBufferView()) {
|
||||
return CopyArrayBufferViewToArray(aSource.GetAsArrayBufferView(), aArray);
|
||||
}
|
||||
MOZ_CRASH("Uninitialized union: expected buffer or view");
|
||||
MOZ_ASSERT(aArray.IsEmpty());
|
||||
return AppendTypedArrayDataTo(aSource, aArray);
|
||||
}
|
||||
|
||||
/* static */
|
||||
|
||||
@@ -23,12 +23,6 @@ class PushUtil final {
|
||||
PushUtil() = delete;
|
||||
|
||||
public:
|
||||
static bool CopyArrayBufferToArray(const ArrayBuffer& aBuffer,
|
||||
nsTArray<uint8_t>& aArray);
|
||||
|
||||
static bool CopyArrayBufferViewToArray(const ArrayBufferView& aView,
|
||||
nsTArray<uint8_t>& aArray);
|
||||
|
||||
static bool CopyBufferSourceToArray(
|
||||
const OwningArrayBufferViewOrArrayBuffer& aSource,
|
||||
nsTArray<uint8_t>& aArray);
|
||||
|
||||
@@ -1030,19 +1030,10 @@ nsresult ExtractBytesFromUSVString(const nsAString& aStr,
|
||||
nsresult ExtractBytesFromData(
|
||||
const OwningArrayBufferViewOrArrayBufferOrUSVString& aDataInit,
|
||||
nsTArray<uint8_t>& aBytes) {
|
||||
if (aDataInit.IsArrayBufferView()) {
|
||||
const ArrayBufferView& view = aDataInit.GetAsArrayBufferView();
|
||||
if (NS_WARN_IF(!PushUtil::CopyArrayBufferViewToArray(view, aBytes))) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
if (aDataInit.IsArrayBuffer()) {
|
||||
const ArrayBuffer& buffer = aDataInit.GetAsArrayBuffer();
|
||||
if (NS_WARN_IF(!PushUtil::CopyArrayBufferToArray(buffer, aBytes))) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
return NS_OK;
|
||||
MOZ_ASSERT(aBytes.IsEmpty());
|
||||
Maybe<bool> result = AppendTypedArrayDataTo(aDataInit, aBytes);
|
||||
if (result.isSome()) {
|
||||
return NS_WARN_IF(!result.value()) ? NS_ERROR_OUT_OF_MEMORY : NS_OK;
|
||||
}
|
||||
if (aDataInit.IsUSVString()) {
|
||||
return ExtractBytesFromUSVString(aDataInit.GetAsUSVString(), aBytes);
|
||||
|
||||
@@ -1033,10 +1033,9 @@ already_AddRefed<Promise> IOUtils::SetMacXAttr(GlobalObject& aGlobal,
|
||||
nsCOMPtr<nsIFile> file = new nsLocalFile();
|
||||
REJECT_IF_INIT_PATH_FAILED(file, aPath, promise);
|
||||
|
||||
aValue.ComputeState();
|
||||
nsTArray<uint8_t> value;
|
||||
|
||||
if (!value.AppendElements(aValue.Data(), aValue.Length(), fallible)) {
|
||||
if (!aValue.AppendDataTo(value)) {
|
||||
RejectJSPromise(
|
||||
promise,
|
||||
IOError(NS_ERROR_OUT_OF_MEMORY)
|
||||
@@ -2834,10 +2833,9 @@ static nsCString FromUnixString(const IOUtils::UnixString& aString) {
|
||||
return aString.GetAsUTF8String();
|
||||
}
|
||||
if (aString.IsUint8Array()) {
|
||||
const auto& u8a = aString.GetAsUint8Array();
|
||||
u8a.ComputeState();
|
||||
// Cast to deal with char signedness
|
||||
return nsCString(reinterpret_cast<const char*>(u8a.Data()), u8a.Length());
|
||||
nsCString data;
|
||||
Unused << aString.GetAsUint8Array().AppendDataTo(data);
|
||||
return data;
|
||||
}
|
||||
MOZ_CRASH("unreachable");
|
||||
}
|
||||
|
||||
@@ -2388,37 +2388,31 @@ void WebSocket::Send(Blob& aData, ErrorResult& aRv) {
|
||||
void WebSocket::Send(const ArrayBuffer& aData, ErrorResult& aRv) {
|
||||
AssertIsOnTargetThread();
|
||||
|
||||
aData.ComputeState();
|
||||
static_assert(
|
||||
sizeof(std::remove_reference<decltype(aData)>::type::element_type) == 1,
|
||||
"byte-sized data required");
|
||||
|
||||
static_assert(sizeof(*aData.Data()) == 1, "byte-sized data required");
|
||||
|
||||
uint32_t len = aData.Length();
|
||||
char* data = reinterpret_cast<char*>(aData.Data());
|
||||
|
||||
nsDependentCSubstring msgString;
|
||||
if (!msgString.Assign(data, len, mozilla::fallible_t())) {
|
||||
nsCString msgString;
|
||||
if (!aData.AppendDataTo(msgString)) {
|
||||
aRv.Throw(NS_ERROR_FILE_TOO_BIG);
|
||||
return;
|
||||
}
|
||||
Send(nullptr, msgString, len, true, aRv);
|
||||
Send(nullptr, msgString, msgString.Length(), true, aRv);
|
||||
}
|
||||
|
||||
void WebSocket::Send(const ArrayBufferView& aData, ErrorResult& aRv) {
|
||||
AssertIsOnTargetThread();
|
||||
|
||||
aData.ComputeState();
|
||||
static_assert(
|
||||
sizeof(std::remove_reference<decltype(aData)>::type::element_type) == 1,
|
||||
"byte-sized data required");
|
||||
|
||||
static_assert(sizeof(*aData.Data()) == 1, "byte-sized data required");
|
||||
|
||||
uint32_t len = aData.Length();
|
||||
char* data = reinterpret_cast<char*>(aData.Data());
|
||||
|
||||
nsDependentCSubstring msgString;
|
||||
if (!msgString.Assign(data, len, mozilla::fallible_t())) {
|
||||
nsCString msgString;
|
||||
if (!aData.AppendDataTo(msgString)) {
|
||||
aRv.Throw(NS_ERROR_FILE_TOO_BIG);
|
||||
return;
|
||||
}
|
||||
Send(nullptr, msgString, len, true, aRv);
|
||||
Send(nullptr, msgString, msgString.Length(), true, aRv);
|
||||
}
|
||||
|
||||
void WebSocket::Send(nsIInputStream* aMsgStream, const nsACString& aMsgString,
|
||||
|
||||
@@ -123,18 +123,6 @@ bool StreamFilter::CheckAlive() {
|
||||
* Binding methods
|
||||
*****************************************************************************/
|
||||
|
||||
template <typename T>
|
||||
static inline bool ReadTypedArrayData(nsTArray<uint8_t>& aData, const T& aArray,
|
||||
ErrorResult& aRv) {
|
||||
aArray.ComputeState();
|
||||
if (!aData.SetLength(aArray.Length(), fallible)) {
|
||||
aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
|
||||
return false;
|
||||
}
|
||||
memcpy(aData.Elements(), aArray.Data(), aArray.Length());
|
||||
return true;
|
||||
}
|
||||
|
||||
void StreamFilter::Write(const ArrayBufferOrUint8Array& aData,
|
||||
ErrorResult& aRv) {
|
||||
if (!mActor) {
|
||||
@@ -143,20 +131,12 @@ void StreamFilter::Write(const ArrayBufferOrUint8Array& aData,
|
||||
}
|
||||
|
||||
nsTArray<uint8_t> data;
|
||||
|
||||
bool ok;
|
||||
if (aData.IsArrayBuffer()) {
|
||||
ok = ReadTypedArrayData(data, aData.GetAsArrayBuffer(), aRv);
|
||||
} else if (aData.IsUint8Array()) {
|
||||
ok = ReadTypedArrayData(data, aData.GetAsUint8Array(), aRv);
|
||||
} else {
|
||||
MOZ_ASSERT_UNREACHABLE("Argument should be ArrayBuffer or Uint8Array");
|
||||
if (!AppendTypedArrayDataTo(aData, data)) {
|
||||
aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ok) {
|
||||
mActor->Write(std::move(data), aRv);
|
||||
}
|
||||
mActor->Write(std::move(data), aRv);
|
||||
}
|
||||
|
||||
StreamFilterStatus StreamFilter::Status() const {
|
||||
|
||||
Reference in New Issue
Block a user