/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim:set ts=2 sw=2 sts=2 et cindent: */ /* 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/. */
class CompressionStreamAlgorithms : public TransformerAlgorithmsWrapper { public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(CompressionStreamAlgorithms,
TransformerAlgorithmsBase)
// Step 3 of // https://wicg.github.io/compression/#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 TransformCallbackImpl(JS::Handle<JS::Value> aChunk,
TransformStreamDefaultController& aController,
ErrorResult& aRv) override {
AutoJSAPI jsapi; if (!jsapi.Init(aController.GetParentObject())) {
aRv.ThrowUnknownError("Internal error"); return;
}
JSContext* cx = jsapi.cx();
// Step 1: If chunk is not a BufferSource type, then throw a TypeError.
RootedUnion<OwningArrayBufferViewOrArrayBuffer> bufferSource(cx); if (!bufferSource.Init(cx, aChunk)) {
aRv.MightThrowJSException();
aRv.StealExceptionFromJSContext(cx); return;
}
// Step 2: Let buffer be the result of compressing chunk with cs's format // and context. // Step 3 - 5: (Done in CompressAndEnqueue)
ProcessTypedArraysFixed(
bufferSource,
[&](const Span<uint8_t>& aData) MOZ_CAN_RUN_SCRIPT_BOUNDARY {
CompressAndEnqueue(cx, aData, ZLibFlush::No, aController, aRv);
});
}
// Step 4 of // https://wicg.github.io/compression/#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 FlushCallbackImpl(
TransformStreamDefaultController& aController,
ErrorResult& aRv) override {
AutoJSAPI jsapi; if (!jsapi.Init(aController.GetParentObject())) {
aRv.ThrowUnknownError("Internal error"); return;
}
JSContext* cx = jsapi.cx();
// Step 1: Let buffer be the result of compressing an empty input with cs's // format and context, with the finish flag. // Step 2 - 4: (Done in CompressAndEnqueue)
CompressAndEnqueue(cx, Span<const uint8_t>(), ZLibFlush::Yes, aController,
aRv);
}
// From the manual: deflate() returns ... switch (err) { case Z_OK: case Z_STREAM_END: case Z_BUF_ERROR: // * Z_OK if some progress has been made // * Z_STREAM_END if all input has been consumed and all output has // been produced (only when flush is set to Z_FINISH) // * Z_BUF_ERROR if no progress is possible (for example avail_in or // avail_out was zero). Note that Z_BUF_ERROR is not fatal, and // deflate() can be called again with more input and more output space // to continue compressing. // // (But of course no input should be given after Z_FINISH) break; case Z_STREAM_ERROR: default: // * Z_STREAM_ERROR if the stream state was inconsistent // (which is fatal)
MOZ_ASSERT_UNREACHABLE("Unexpected compression error code");
aRv.ThrowTypeError("Unexpected compression error"); return;
}
// Stream should end only when flushed, see above // The reverse is not true as zlib may have big data to be flushed that is // larger than the buffer size
MOZ_ASSERT_IF(err == Z_STREAM_END, aFlush == ZLibFlush::Yes);
// At this point we either exhausted the input or the output buffer
MOZ_ASSERT(!mZStream.avail_in || !mZStream.avail_out);
size_t written = kBufferSize - mZStream.avail_out; if (!written) { break;
}
// Step 3: If buffer is empty, return. // (We'll implicitly return when the array is empty.)
// Step 4: Split buffer into one or more non-empty pieces and convert them // into Uint8Arrays. // (The buffer is 'split' by having a fixed sized buffer above.)
JS::Rooted<JSObject*> view(aCx, nsJSUtils::MoveBufferAsUint8Array(
aCx, written, std::move(buffer))); if (!view || !array.append(view)) {
JS_ClearPendingException(aCx);
aRv.ThrowTypeError("Out of memory"); return;
}
} while (mZStream.avail_out == 0); // From the manual: // If deflate returns with avail_out == 0, this function must be called // again with the same value of the flush parameter and more output space // (updated avail_out)
// Step 5: For each Uint8Array array, enqueue array in cs's transform. for (constauto& view : array) {
JS::Rooted<JS::Value> value(aCx, JS::ObjectValue(*view));
aController.Enqueue(aCx, value, aRv); if (aRv.Failed()) { return;
}
}
}
// https://wicg.github.io/compression/#dom-compressionstream-compressionstream
already_AddRefed<CompressionStream> CompressionStream::Constructor( const GlobalObject& aGlobal, CompressionFormat aFormat, ErrorResult& aRv) { // Step 1: If format is unsupported in CompressionStream, then throw a // TypeError. // XXX: Skipped as we are using enum for this
// Step 2 - 4: (Done in CompressionStreamAlgorithms)
// Step 5: Set this's transform to a new TransformStream.
// Step 6: Set up this's transform with transformAlgorithm set to // transformAlgorithm and flushAlgorithm set to flushAlgorithm. auto algorithms = MakeRefPtr<CompressionStreamAlgorithms>(aFormat);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.