File 4421-Add-compressed_one-to-file-Modes.patch of Package erlang
From d2e88f0e4ec68b428babfb3857cb13b6e3044f52 Mon Sep 17 00:00:00 2001
From: Simon Cornish <7t9jna402@sneakemail.com>
Date: Mon, 3 Oct 2022 10:59:16 -0700
Subject: [PATCH 1/2] Add compressed_one to file Modes
compressed_one will read one member of a gzipped compressed file
---
lib/kernel/doc/src/file.xml | 6 ++++++
lib/kernel/src/file.erl | 2 +-
lib/kernel/src/raw_file_io.erl | 1 +
lib/kernel/src/raw_file_io_inflate.erl | 13 ++++++++++---
4 files changed, 18 insertions(+), 4 deletions(-)
diff --git a/lib/kernel/doc/src/file.xml b/lib/kernel/doc/src/file.xml
index aa1201d381..463ba4d037 100644
--- a/lib/kernel/doc/src/file.xml
+++ b/lib/kernel/doc/src/file.xml
@@ -867,6 +867,12 @@ f.txt: {person, "kalle", 25}.
does probably not match the number of bytes that can be
read from a compressed file.</p>
</item>
+ <tag><c>compressed_one</c></tag>
+ <item>
+ <p>Read one member of a gzip compressed file.
+ Option <c>compressed_one</c> can only be combined
+ with <c>read</c>.</p>
+ </item>
<tag><c>{encoding, Encoding}</c></tag>
<item>
<p>Makes the file perform automatic translation of characters to
diff --git a/lib/kernel/src/file.erl b/lib/kernel/src/file.erl
index 57d3add4cb..8dbfb6fa61 100644
--- a/lib/kernel/src/file.erl
+++ b/lib/kernel/src/file.erl
@@ -95,7 +95,7 @@
Size :: non_neg_integer(),
Delay :: non_neg_integer()}
| 'delayed_write' | {'read_ahead', Size :: pos_integer()}
- | 'read_ahead' | 'compressed'
+ | 'read_ahead' | 'compressed' | 'compressed_one'
| {'encoding', unicode:encoding()}
| sync.
-type deep_list() :: [char() | atom() | deep_list()].
diff --git a/lib/kernel/src/raw_file_io.erl b/lib/kernel/src/raw_file_io.erl
index a153adeff0..718381dc17 100644
--- a/lib/kernel/src/raw_file_io.erl
+++ b/lib/kernel/src/raw_file_io.erl
@@ -56,6 +56,7 @@ match_list(list) -> true;
match_list(_Other) -> false.
match_compressed(compressed) -> true;
+match_compressed(compressed_one) -> true;
match_compressed(_Other) -> false.
match_delayed({delayed_write, _Size, _Timeout}) -> true;
diff --git a/lib/kernel/src/raw_file_io_inflate.erl b/lib/kernel/src/raw_file_io_inflate.erl
index a0c32b1b5e..01e0af9a61 100644
--- a/lib/kernel/src/raw_file_io_inflate.erl
+++ b/lib/kernel/src/raw_file_io_inflate.erl
@@ -32,12 +32,19 @@
callback_mode() -> state_functions.
init({Owner, Secret, [compressed]}) ->
- Monitor = monitor(process, Owner),
- %% We're using the undocumented inflateInit/3 to open the stream in
%% 'reset mode', which resets the inflate state at the end of every stream,
%% allowing us to read concatenated gzip files.
+ init(Owner, Secret, reset);
+init({Owner, Secret, [compressed_one]}) ->
+ %% 'cut mode', which stops the inflate after one member
+ %% allowing us to read gzipped tar files
+ init(Owner, Secret, cut).
+
+init(Owner, Secret, Mode) ->
+ Monitor = monitor(process, Owner),
+ %% We're using the undocumented inflateInit/3 to set the mode
Z = zlib:open(),
- ok = zlib:inflateInit(Z, ?GZIP_WBITS, reset),
+ ok = zlib:inflateInit(Z, ?GZIP_WBITS, Mode),
Data =
#{ owner => Owner,
monitor => Monitor,
--
2.35.3