DecompressionStream.cpp (4256B)
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/DecompressionStream.h" 8 9 #include "BaseAlgorithms.h" 10 #include "FormatBrotli.h" 11 #include "FormatZlib.h" 12 #include "FormatZstd.h" 13 #include "js/TypeDecls.h" 14 #include "mozilla/StaticPrefs_dom.h" 15 #include "mozilla/dom/CompressionStreamBinding.h" 16 #include "mozilla/dom/DecompressionStreamBinding.h" 17 #include "mozilla/dom/ReadableStream.h" 18 #include "mozilla/dom/TextDecoderStream.h" 19 #include "mozilla/dom/TransformStream.h" 20 #include "mozilla/dom/UnionTypes.h" 21 #include "mozilla/dom/WritableStream.h" 22 23 namespace mozilla::dom { 24 using namespace compression; 25 26 /* 27 * Constructs either a ZLibDecompressionStreamAlgorithms or a 28 * Brotli/ZstdDecompressionStreamAlgorithms, based on the CompressionFormat. 29 */ 30 static Result<already_AddRefed<DecompressionStreamAlgorithms>, nsresult> 31 CreateDecompressionStreamAlgorithms(CompressionFormat aFormat) { 32 if (aFormat == CompressionFormat::Brotli) { 33 RefPtr<DecompressionStreamAlgorithms> brotliAlgos = 34 MOZ_TRY(BrotliDecompressionStreamAlgorithms::Create()); 35 return brotliAlgos.forget(); 36 } 37 if (aFormat == CompressionFormat::Zstd) { 38 RefPtr<DecompressionStreamAlgorithms> zstdAlgos = 39 MOZ_TRY(ZstdDecompressionStreamAlgorithms::Create()); 40 return zstdAlgos.forget(); 41 } 42 43 RefPtr<DecompressionStreamAlgorithms> zlibAlgos = 44 MOZ_TRY(ZLibDecompressionStreamAlgorithms::Create(aFormat)); 45 return zlibAlgos.forget(); 46 } 47 48 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(DecompressionStream, mGlobal, mStream) 49 NS_IMPL_CYCLE_COLLECTING_ADDREF(DecompressionStream) 50 NS_IMPL_CYCLE_COLLECTING_RELEASE(DecompressionStream) 51 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(DecompressionStream) 52 NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY 53 NS_INTERFACE_MAP_ENTRY(nsISupports) 54 NS_INTERFACE_MAP_END 55 56 DecompressionStream::DecompressionStream(nsISupports* aGlobal, 57 TransformStream& aStream) 58 : mGlobal(aGlobal), mStream(&aStream) {} 59 60 DecompressionStream::~DecompressionStream() = default; 61 62 JSObject* DecompressionStream::WrapObject(JSContext* aCx, 63 JS::Handle<JSObject*> aGivenProto) { 64 return DecompressionStream_Binding::Wrap(aCx, this, aGivenProto); 65 } 66 67 // https://wicg.github.io/compression/#dom-decompressionstream-decompressionstream 68 already_AddRefed<DecompressionStream> DecompressionStream::Constructor( 69 const GlobalObject& aGlobal, CompressionFormat aFormat, ErrorResult& aRv) { 70 if (aFormat == CompressionFormat::Zstd && 71 aGlobal.CallerType() != CallerType::System && 72 !StaticPrefs::dom_compression_streams_zstd_enabled()) { 73 aRv.ThrowTypeError( 74 "'zstd' (value of argument 1) is not a valid value for enumeration " 75 "CompressionFormat."); 76 return nullptr; 77 } 78 79 // Step 1: If format is unsupported in DecompressionStream, then throw a 80 // TypeError. 81 // XXX: Skipped as we are using enum for this 82 83 // Step 2 - 4: (Done in {ZLib|Zstd}DecompressionStreamAlgorithms) 84 85 // Step 5: Set this's transform to a new TransformStream. 86 87 // Step 6: Set up this's transform with transformAlgorithm set to 88 // transformAlgorithm and flushAlgorithm set to flushAlgorithm. 89 90 Result<already_AddRefed<DecompressionStreamAlgorithms>, nsresult> algorithms = 91 CreateDecompressionStreamAlgorithms(aFormat); 92 if (algorithms.isErr()) { 93 aRv.ThrowUnknownError("Not enough memory"); 94 return nullptr; 95 } 96 97 RefPtr<DecompressionStreamAlgorithms> alg = algorithms.unwrap(); 98 RefPtr<TransformStream> stream = 99 TransformStream::CreateGeneric(aGlobal, *alg, aRv); 100 if (aRv.Failed()) { 101 return nullptr; 102 } 103 return do_AddRef(new DecompressionStream(aGlobal.GetAsSupports(), *stream)); 104 } 105 106 already_AddRefed<ReadableStream> DecompressionStream::Readable() const { 107 return do_AddRef(mStream->Readable()); 108 }; 109 110 already_AddRefed<WritableStream> DecompressionStream::Writable() const { 111 return do_AddRef(mStream->Writable()); 112 }; 113 114 } // namespace mozilla::dom