CompressionStream.cpp (3825B)
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim:set ts=2 sw=2 sts=2 et cindent: */ 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 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #include "mozilla/dom/CompressionStream.h" 8 9 #include "FormatBrotli.h" 10 #include "FormatZlib.h" 11 #include "js/TypeDecls.h" 12 #include "mozilla/dom/CompressionStreamBinding.h" 13 #include "mozilla/dom/ReadableStream.h" 14 #include "mozilla/dom/TextDecoderStream.h" 15 #include "mozilla/dom/TransformStream.h" 16 #include "mozilla/dom/WritableStream.h" 17 18 // See the zlib manual in https://www.zlib.net/manual.html or in 19 // https://searchfox.org/mozilla-central/source/modules/zlib/src/zlib.h 20 21 namespace mozilla::dom { 22 using namespace compression; 23 24 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(CompressionStream, mGlobal, mStream) 25 NS_IMPL_CYCLE_COLLECTING_ADDREF(CompressionStream) 26 NS_IMPL_CYCLE_COLLECTING_RELEASE(CompressionStream) 27 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(CompressionStream) 28 NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY 29 NS_INTERFACE_MAP_ENTRY(nsISupports) 30 NS_INTERFACE_MAP_END 31 32 /* 33 * Constructs either a ZLibDecompressionStreamAlgorithms or a 34 * BrotliDecompressionStreamAlgorithms, based on the CompressionFormat. 35 */ 36 static Result<already_AddRefed<CompressionStreamAlgorithms>, nsresult> 37 CreateCompressionStreamAlgorithms(CompressionFormat aFormat) { 38 if (aFormat == CompressionFormat::Brotli) { 39 RefPtr<CompressionStreamAlgorithms> brotliAlgos = 40 MOZ_TRY(BrotliCompressionStreamAlgorithms::Create()); 41 return brotliAlgos.forget(); 42 } 43 44 RefPtr<CompressionStreamAlgorithms> zlibAlgos = 45 MOZ_TRY(ZLibCompressionStreamAlgorithms::Create(aFormat)); 46 return zlibAlgos.forget(); 47 } 48 49 CompressionStream::CompressionStream(nsISupports* aGlobal, 50 TransformStream& aStream) 51 : mGlobal(aGlobal), mStream(&aStream) {} 52 53 CompressionStream::~CompressionStream() = default; 54 55 JSObject* CompressionStream::WrapObject(JSContext* aCx, 56 JS::Handle<JSObject*> aGivenProto) { 57 return CompressionStream_Binding::Wrap(aCx, this, aGivenProto); 58 } 59 60 // https://wicg.github.io/compression/#dom-compressionstream-compressionstream 61 already_AddRefed<CompressionStream> CompressionStream::Constructor( 62 const GlobalObject& aGlobal, CompressionFormat aFormat, ErrorResult& aRv) { 63 if (aFormat == CompressionFormat::Zstd) { 64 aRv.ThrowTypeError( 65 "'zstd' (value of argument 1) is not a valid value for enumeration " 66 "CompressionFormat."); 67 return nullptr; 68 } 69 70 // Step 1: If format is unsupported in CompressionStream, then throw a 71 // TypeError. 72 // XXX: Skipped as we are using enum for this 73 74 // Step 2 - 4: (Done in CompressionStreamAlgorithms) 75 76 // Step 5: Set this's transform to a new TransformStream. 77 78 // Step 6: Set up this's transform with transformAlgorithm set to 79 // transformAlgorithm and flushAlgorithm set to flushAlgorithm. 80 Result<already_AddRefed<CompressionStreamAlgorithms>, nsresult> algorithms = 81 CreateCompressionStreamAlgorithms(aFormat); 82 if (algorithms.isErr()) { 83 aRv.ThrowUnknownError("Not enough memory"); 84 return nullptr; 85 } 86 87 RefPtr<CompressionStreamAlgorithms> alg = algorithms.unwrap(); 88 RefPtr<TransformStream> stream = 89 TransformStream::CreateGeneric(aGlobal, *alg, aRv); 90 if (aRv.Failed()) { 91 return nullptr; 92 } 93 return do_AddRef(new CompressionStream(aGlobal.GetAsSupports(), *stream)); 94 } 95 96 already_AddRefed<ReadableStream> CompressionStream::Readable() const { 97 return do_AddRef(mStream->Readable()); 98 } 99 100 already_AddRefed<WritableStream> CompressionStream::Writable() const { 101 return do_AddRef(mStream->Writable()); 102 } 103 104 } // namespace mozilla::dom