Skip to content

Commit

Permalink
LibCompress: Add ZlibDecompressor.decompress_all
Browse files Browse the repository at this point in the history
  • Loading branch information
jdahlin committed Sep 12, 2024
1 parent d6025d0 commit 0459795
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 26 deletions.
2 changes: 1 addition & 1 deletion Tests/LibWeb/Text/expected/all-window-properties.txt
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,6 @@ Crypto
CryptoKey
CustomElementRegistry
CustomEvent
DecompressionStream
DOMException
DOMImplementation
DOMMatrix
Expand All @@ -83,6 +82,7 @@ DataTransferItem
DataTransferItemList
DataView
Date
DecompressionStream
DisposableStack
Document
DocumentFragment
Expand Down
16 changes: 16 additions & 0 deletions Userland/Libraries/LibCompress/Zlib.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -171,4 +171,20 @@ ErrorOr<ByteBuffer> ZlibCompressor::compress_all(ReadonlyBytes bytes, ZlibCompre
return buffer;
}

ErrorOr<ByteBuffer> ZlibDecompressor::decompress_all(ReadonlyBytes bytes)
{
// Even though the content encoding is "deflate", it's actually deflate with the zlib wrapper.
// https://tools.ietf.org/html/rfc7230#section-4.2.2
auto memory_stream = TRY(try_make<FixedMemoryStream>(bytes));
auto zlib_decompressor = ZlibDecompressor::create(move(memory_stream));
if (zlib_decompressor.is_error()) {
// From the RFC:
// "Note: Some non-conformant implementations send the "deflate"
// compressed data without the zlib wrapper."
return DeflateDecompressor::decompress_all(bytes);
} else {
return zlib_decompressor.value()->read_until_eof();
}
}

}
3 changes: 2 additions & 1 deletion Userland/Libraries/LibCompress/Zlib.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ class ZlibDecompressor : public Stream {
virtual bool is_open() const override;
virtual void close() override;

static ErrorOr<ByteBuffer> decompress_all(ReadonlyBytes);

private:
ZlibDecompressor(ZlibHeader, NonnullOwnPtr<Stream>);

Expand All @@ -72,7 +74,6 @@ class ZlibCompressor : public Stream {
virtual bool is_open() const override;
virtual void close() override;
ErrorOr<void> finish();

static ErrorOr<ByteBuffer> compress_all(ReadonlyBytes bytes, ZlibCompressionLevel = ZlibCompressionLevel::Default);

private:
Expand Down
35 changes: 23 additions & 12 deletions Userland/Libraries/LibWeb/Compression/CompressionStream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,28 @@ JS_DEFINE_ALLOCATOR(CompressionStream);

WebIDL::ExceptionOr<JS::NonnullGCPtr<CompressionStream>> CompressionStream::construct_impl(JS::Realm& realm, Bindings::CompressionFormat format)
{
return realm.heap().allocate<CompressionStream>(realm, realm, format);
auto stream = realm.heap().allocate<CompressionStream>(realm, realm, format);

auto& vm = realm.vm();
auto* env = vm.variable_environment();
if (env) {
// FIXME: Make this private to the web execution context
auto& global_object = realm.global_object();
auto constructor_value_or_error = global_object.get("CompressionStream_constructor");
auto constructor_value = TRY(constructor_value_or_error);
if (constructor_value.is_empty() || constructor_value.is_undefined()) {
return WebIDL::SimpleException {
WebIDL::SimpleExceptionType::TypeError,
"CompressionStream constructor not found"sv
};
}

auto& func = static_cast<JS::ECMAScriptFunctionObject&>(constructor_value.as_function());
JS::MarkedVector<JS::Value> arguments_list { vm.heap() };
arguments_list.append(JS::PrimitiveString::create(vm, Bindings::idl_enum_to_string(format)));
TRY(func.internal_call(stream->m_this_value, move(arguments_list)));
}
return stream;
}

WebIDL::ExceptionOr<JS::NonnullGCPtr<JS::Uint8Array>> CompressionStream::compress(JS::VM& vm, Bindings::CompressionFormat format, JS::Handle<WebIDL::BufferSource> buffer_source)
Expand Down Expand Up @@ -63,7 +84,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<JS::Uint8Array>> CompressionStream::compres
static JS::GCPtr<JS::Script> import_js_script(JS::Realm& realm)
{
auto& vm = realm.vm();
auto file = MUST(Core::File::open("Userland/Libraries/LibWeb/Compression/CompressionStream.js"sv, Core::File::OpenMode::Read));
auto file = MUST(Core::File::open("/Users/johandahlin/dev/ladybird/Userland/Libraries/LibWeb/Compression/CompressionStream.js"sv, Core::File::OpenMode::Read));
auto file_contents = MUST(file->read_until_eof());
auto source = StringView { file_contents };

Expand All @@ -78,16 +99,6 @@ CompressionStream::CompressionStream(JS::Realm& realm, Bindings::CompressionForm
, m_js_script(import_js_script(realm))
, m_this_value(JS::Object::create(realm, realm.intrinsics().object_prototype()))
{
auto& vm = realm.vm();
auto* env = vm.variable_environment();
if (env) {
// FIXME: Make this private to the web execution context
auto constructor_value = MUST(env->get_binding_value(vm, "CompressionStream_constructor", true));
auto& func = static_cast<JS::ECMAScriptFunctionObject&>(constructor_value.as_function());
JS::MarkedVector<JS::Value> arguments_list { vm.heap() };
arguments_list.append(JS::PrimitiveString::create(vm, Bindings::idl_enum_to_string(format)));
MUST(func.internal_call(m_this_value, move(arguments_list)));
}
}

CompressionStream::~CompressionStream() = default;
Expand Down
35 changes: 23 additions & 12 deletions Userland/Libraries/LibWeb/Compression/DecompressionStream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,28 @@ JS_DEFINE_ALLOCATOR(DecompressionStream);

WebIDL::ExceptionOr<JS::NonnullGCPtr<DecompressionStream>> DecompressionStream::construct_impl(JS::Realm& realm, Bindings::CompressionFormat format)
{
return realm.heap().allocate<DecompressionStream>(realm, realm, format);
auto stream = realm.heap().allocate<DecompressionStream>(realm, realm, format);

auto& vm = realm.vm();
auto* env = vm.variable_environment();
if (env) {
// FIXME: Make this private to the web execution context
auto& global_object = realm.global_object();
auto constructor_value_or_error = global_object.get("DecompressionStream_constructor");
auto constructor_value = TRY(constructor_value_or_error);
if (constructor_value.is_empty() || constructor_value.is_undefined()) {
return WebIDL::SimpleException {
WebIDL::SimpleExceptionType::TypeError,
"DecompressionStream constructor not found"sv
};
}

auto& func = static_cast<JS::ECMAScriptFunctionObject&>(constructor_value.as_function());
JS::MarkedVector<JS::Value> arguments_list { vm.heap() };
arguments_list.append(JS::PrimitiveString::create(vm, Bindings::idl_enum_to_string(format)));
TRY(func.internal_call(stream->m_this_value, move(arguments_list)));
}
return stream;
}

WebIDL::ExceptionOr<JS::NonnullGCPtr<JS::Uint8Array>> DecompressionStream::decompress(JS::VM& vm, Bindings::CompressionFormat format, JS::Handle<WebIDL::BufferSource> buffer_source)
Expand Down Expand Up @@ -65,7 +86,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<JS::Uint8Array>> DecompressionStream::decom
static JS::GCPtr<JS::Script> import_js_script(JS::Realm& realm)
{
auto& vm = realm.vm();
auto file = MUST(Core::File::open("Userland/Libraries/LibWeb/Compression/DecompressionStream.js"sv, Core::File::OpenMode::Read));
auto file = MUST(Core::File::open("/Users/johandahlin/dev/ladybird/Userland/Libraries/LibWeb/Compression/DecompressionStream.js"sv, Core::File::OpenMode::Read));
auto file_contents = MUST(file->read_until_eof());
auto source = StringView { file_contents };

Expand All @@ -80,16 +101,6 @@ DecompressionStream::DecompressionStream(JS::Realm& realm, Bindings::Compression
, m_js_script(import_js_script(realm))
, m_this_value(JS::Object::create(realm, realm.intrinsics().object_prototype()))
{
auto& vm = realm.vm();
auto* env = vm.variable_environment();
if (env) {
// FIXME: Make this private to the web execution context
auto constructor_value = MUST(env->get_binding_value(vm, "DecompressionStream_constructor", true));
auto& func = static_cast<JS::ECMAScriptFunctionObject&>(constructor_value.as_function());
JS::MarkedVector<JS::Value> arguments_list { vm.heap() };
arguments_list.append(JS::PrimitiveString::create(vm, Bindings::idl_enum_to_string(format)));
MUST(func.internal_call(m_this_value, move(arguments_list)));
}
}

DecompressionStream::~DecompressionStream() = default;
Expand Down

0 comments on commit 0459795

Please sign in to comment.