replaced by .editorconfig # ignore-this-changeset Differential Revision: https://phabricator.services.mozilla.com/D287843
200 lines
7.3 KiB
C++
200 lines
7.3 KiB
C++
/* 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 "BaseAlgorithms.h"
|
||
|
||
#include "mozilla/dom/BufferSourceBinding.h"
|
||
#include "mozilla/dom/BufferSourceBindingFwd.h"
|
||
#include "mozilla/dom/TransformStreamDefaultController.h"
|
||
#include "mozilla/dom/UnionTypes.h"
|
||
|
||
namespace mozilla::dom::compression {
|
||
|
||
// Step 3 of
|
||
// https://compression.spec.whatwg.org/#dom-compressionstream-compressionstream
|
||
// Let transformAlgorithm be an algorithm which takes a chunk argument and
|
||
// runs the compress and enqueue a chunk algorithm with this and chunk.
|
||
MOZ_CAN_RUN_SCRIPT
|
||
void CompressionStreamAlgorithms::TransformCallbackImpl(
|
||
JS::Handle<JS::Value> aChunk, TransformStreamDefaultController& aController,
|
||
ErrorResult& aRv) {
|
||
AutoJSAPI jsapi;
|
||
if (!jsapi.Init(aController.GetParentObject())) {
|
||
aRv.ThrowUnknownError("Internal error");
|
||
return;
|
||
}
|
||
JSContext* cx = jsapi.cx();
|
||
|
||
// https://compression.spec.whatwg.org/#compress-and-enqueue-a-chunk
|
||
|
||
// Step 1: If chunk is not a BufferSource type, then throw a TypeError.
|
||
RootedUnion<OwningBufferSource> bufferSource(cx);
|
||
if (!bufferSource.Init(cx, aChunk)) {
|
||
aRv.MightThrowJSException();
|
||
aRv.StealExceptionFromJSContext(cx);
|
||
return;
|
||
}
|
||
|
||
// Step 2 - 5: (Done in CompressAndEnqueue)
|
||
ProcessTypedArraysFixed(
|
||
bufferSource,
|
||
[&](const Span<uint8_t>& aData) MOZ_CAN_RUN_SCRIPT_BOUNDARY {
|
||
CompressAndEnqueue(cx, aData, Flush::No, aController, aRv);
|
||
});
|
||
}
|
||
|
||
// Step 4 of
|
||
// https://compression.spec.whatwg.org/#dom-compressionstream-compressionstream
|
||
// Let flushAlgorithm be an algorithm which takes no argument and runs the
|
||
// compress flush and enqueue algorithm with this.
|
||
MOZ_CAN_RUN_SCRIPT void CompressionStreamAlgorithms::FlushCallbackImpl(
|
||
TransformStreamDefaultController& aController, ErrorResult& aRv) {
|
||
AutoJSAPI jsapi;
|
||
if (!jsapi.Init(aController.GetParentObject())) {
|
||
aRv.ThrowUnknownError("Internal error");
|
||
return;
|
||
}
|
||
JSContext* cx = jsapi.cx();
|
||
|
||
// https://compression.spec.whatwg.org/#compress-flush-and-enqueue
|
||
|
||
// Step 1 - 4: (Done in CompressAndEnqueue)
|
||
CompressAndEnqueue(cx, Span<const uint8_t>(), Flush::Yes, aController, aRv);
|
||
}
|
||
|
||
// Shared by:
|
||
// https://compression.spec.whatwg.org/#compress-and-enqueue-a-chunk
|
||
// https://compression.spec.whatwg.org/#compress-flush-and-enqueue
|
||
MOZ_CAN_RUN_SCRIPT void CompressionStreamAlgorithms::CompressAndEnqueue(
|
||
JSContext* aCx, Span<const uint8_t> aInput, Flush aFlush,
|
||
TransformStreamDefaultController& aController, ErrorResult& aRv) {
|
||
MOZ_ASSERT_IF(aFlush == Flush::Yes, !aInput.Length());
|
||
|
||
JS::RootedVector<JSObject*> array(aCx);
|
||
|
||
// Step 2: Let buffer be the result of compressing chunk with cs’s
|
||
// format and context.
|
||
// Step 3: If buffer is empty, return. (implicit as array will be empty then)
|
||
// Step 4: Let arrays be the result of buffer into one or more non-empty
|
||
// pieces and converting them into Uint8Arrays.
|
||
Compress(aCx, aInput, &array, aFlush, aRv);
|
||
if (aRv.Failed()) {
|
||
return;
|
||
}
|
||
|
||
// Step 5: For each Uint8Array array, enqueue array in cs's transform.
|
||
for (const auto& view : array) {
|
||
JS::Rooted<JS::Value> value(aCx, JS::ObjectValue(*view));
|
||
aController.Enqueue(aCx, value, aRv);
|
||
if (aRv.Failed()) {
|
||
return;
|
||
}
|
||
}
|
||
}
|
||
|
||
// Step 3 of
|
||
// https://compression.spec.whatwg.org/#dom-decompressionstream-decompressionstream
|
||
// Let transformAlgorithm be an algorithm which takes a chunk argument and
|
||
// runs the compress and enqueue a chunk algorithm with this and chunk.
|
||
MOZ_CAN_RUN_SCRIPT
|
||
void DecompressionStreamAlgorithms::TransformCallbackImpl(
|
||
JS::Handle<JS::Value> aChunk, TransformStreamDefaultController& aController,
|
||
ErrorResult& aRv) {
|
||
AutoJSAPI jsapi;
|
||
if (!jsapi.Init(aController.GetParentObject())) {
|
||
aRv.ThrowUnknownError("Internal error");
|
||
return;
|
||
}
|
||
JSContext* cx = jsapi.cx();
|
||
|
||
// https://compression.spec.whatwg.org/#decompress-and-enqueue-a-chunk
|
||
|
||
// Step 1: If chunk is not a BufferSource type, then throw a TypeError.
|
||
RootedUnion<OwningBufferSource> bufferSource(cx);
|
||
if (!bufferSource.Init(cx, aChunk)) {
|
||
aRv.MightThrowJSException();
|
||
aRv.StealExceptionFromJSContext(cx);
|
||
return;
|
||
}
|
||
|
||
// Step 2: Let buffer be the result of decompressing chunk with ds's format
|
||
// and context. If this results in an error, then throw a TypeError.
|
||
// Step 3 - 5: (Done in DecompressAndEnqueue)
|
||
ProcessTypedArraysFixed(
|
||
bufferSource,
|
||
[&](const Span<uint8_t>& aData) MOZ_CAN_RUN_SCRIPT_BOUNDARY {
|
||
DecompressAndEnqueue(cx, aData, Flush::No, aController, aRv);
|
||
});
|
||
}
|
||
|
||
// Step 4 of
|
||
// https://compression.spec.whatwg.org/#dom-decompressionstream-decompressionstream
|
||
// Let flushAlgorithm be an algorithm which takes no argument and runs the
|
||
// compress flush and enqueue algorithm with this.
|
||
MOZ_CAN_RUN_SCRIPT void DecompressionStreamAlgorithms::FlushCallbackImpl(
|
||
TransformStreamDefaultController& aController, ErrorResult& aRv) {
|
||
AutoJSAPI jsapi;
|
||
if (!jsapi.Init(aController.GetParentObject())) {
|
||
aRv.ThrowUnknownError("Internal error");
|
||
return;
|
||
}
|
||
JSContext* cx = jsapi.cx();
|
||
|
||
// https://compression.spec.whatwg.org/#decompress-flush-and-enqueue
|
||
|
||
// Step 1: Let buffer be the result of decompressing an empty input with
|
||
// ds's format and context, with the finish flag.
|
||
// Step 2 - 6: (Done in DecompressAndEnqueue)
|
||
DecompressAndEnqueue(cx, Span<const uint8_t>(), Flush::Yes, aController, aRv);
|
||
}
|
||
|
||
// Shared by:
|
||
// https://compression.spec.whatwg.org/#decompress-and-enqueue-a-chunk
|
||
// https://compression.spec.whatwg.org/#decompress-flush-and-enqueue
|
||
MOZ_CAN_RUN_SCRIPT void DecompressionStreamAlgorithms::DecompressAndEnqueue(
|
||
JSContext* aCx, Span<const uint8_t> aInput, Flush aFlush,
|
||
TransformStreamDefaultController& aController, ErrorResult& aRv) {
|
||
MOZ_ASSERT_IF(aFlush == Flush::Yes, !aInput.Length());
|
||
|
||
JS::RootedVector<JSObject*> array(aCx);
|
||
|
||
// Step 2: Let buffer be the result of decompressing chunk with ds’s format
|
||
// and context. If this results in an error, then throw a TypeError.
|
||
// Step 3: If buffer is empty, return.
|
||
// (Skipping, see https://github.com/whatwg/compression/issues/78)
|
||
// Step 4: Let arrays be the result of splitting buffer into one or more
|
||
// non-empty pieces and converting them into Uint8Arrays.
|
||
bool fullyConsumed = Decompress(aCx, aInput, &array, aFlush, aRv);
|
||
if (aRv.Failed()) {
|
||
return;
|
||
}
|
||
|
||
// Step 5: For each Uint8Array array, enqueue array in ds's transform.
|
||
for (const auto& view : array) {
|
||
JS::Rooted<JS::Value> value(aCx, JS::ObjectValue(*view));
|
||
aController.Enqueue(aCx, value, aRv);
|
||
if (aRv.Failed()) {
|
||
return;
|
||
}
|
||
}
|
||
|
||
// Step 6: If the end of the compressed input has been reached, and ds's
|
||
// context has not fully consumed chunk, then throw a TypeError.
|
||
if (mObservedStreamEnd && !fullyConsumed) {
|
||
aRv.ThrowTypeError("Unexpected input after the end of stream");
|
||
return;
|
||
}
|
||
|
||
// Step 3 of
|
||
// https://compression.spec.whatwg.org/#decompress-flush-and-enqueue
|
||
// If the end of the compressed input has not been reached, then throw a
|
||
// TypeError.
|
||
if (aFlush == Flush::Yes && !mObservedStreamEnd) {
|
||
aRv.ThrowTypeError("The input is ended without reaching the stream end");
|
||
return;
|
||
}
|
||
}
|
||
|
||
} // namespace mozilla::dom::compression
|