archive_r_ruby 0.1.7 → 0.1.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +21 -0
  3. data/NOTICE +71 -0
  4. data/VERSION +1 -0
  5. data/ext/archive_r/archive_r_ext.cc +9 -8
  6. data/ext/archive_r/vendor/archive_r/LICENSE +21 -0
  7. data/ext/archive_r/vendor/archive_r/NOTICE +71 -0
  8. data/ext/archive_r/vendor/archive_r/include/archive_r/data_stream.h +2 -2
  9. data/ext/archive_r/vendor/archive_r/include/archive_r/entry.h +8 -8
  10. data/ext/archive_r/vendor/archive_r/include/archive_r/multi_volume_stream_base.h +2 -2
  11. data/ext/archive_r/vendor/archive_r/include/archive_r/path_hierarchy_utils.h +0 -1
  12. data/ext/archive_r/vendor/archive_r/include/archive_r/platform_compat.h +8 -8
  13. data/ext/archive_r/vendor/archive_r/include/archive_r/traverser.h +2 -2
  14. data/ext/archive_r/vendor/archive_r/src/archive_stack_cursor.cc +10 -34
  15. data/ext/archive_r/vendor/archive_r/src/archive_stack_cursor.h +1 -3
  16. data/ext/archive_r/vendor/archive_r/src/archive_stack_orchestrator.cc +5 -6
  17. data/ext/archive_r/vendor/archive_r/src/archive_stack_orchestrator.h +2 -3
  18. data/ext/archive_r/vendor/archive_r/src/archive_type.cc +6 -13
  19. data/ext/archive_r/vendor/archive_r/src/archive_type.h +3 -3
  20. data/ext/archive_r/vendor/archive_r/src/entry.cc +2 -17
  21. data/ext/archive_r/vendor/archive_r/src/entry_fault_error.cc +23 -23
  22. data/ext/archive_r/vendor/archive_r/src/entry_impl.h +1 -2
  23. data/ext/archive_r/vendor/archive_r/src/multi_volume_manager.cc +3 -8
  24. data/ext/archive_r/vendor/archive_r/src/multi_volume_manager.h +2 -4
  25. data/ext/archive_r/vendor/archive_r/src/multi_volume_stream_base.cc +23 -14
  26. data/ext/archive_r/vendor/archive_r/src/path_hierarchy.cc +1 -4
  27. data/ext/archive_r/vendor/archive_r/src/path_hierarchy_utils.cc +14 -36
  28. data/ext/archive_r/vendor/archive_r/src/simple_profiler.h +64 -75
  29. data/ext/archive_r/vendor/archive_r/src/system_file_stream.cc +21 -26
  30. data/ext/archive_r/vendor/archive_r/src/system_file_stream.h +2 -2
  31. data/ext/archive_r/vendor/archive_r/src/traverser.cc +18 -42
  32. data/lib/archive_r.rb +5 -1
  33. metadata +11 -5
  34. data/LICENSE.txt +0 -97
  35. data/ext/archive_r/vendor/archive_r/LICENSE.txt +0 -97
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 648064959d139565d2e122215cb49ae178b9d5e735a99176b8d785238b753800
4
- data.tar.gz: d9f05748fbcca7aa76bb615b53480c9133423905c1137005d1c6df895a8b09c3
3
+ metadata.gz: a67077047d1881a2760f1e04788746c09f7476ac86543d0edf506446f3c95d27
4
+ data.tar.gz: 7c9c88796f1382285ff08cbcc2e61e59cbe517ef81d72eb7d41ef2c20ddb438a
5
5
  SHA512:
6
- metadata.gz: dd1b45fd72e08536d0b95b261b8ca071d68fa0a1840c984c9d5aae4d9449b394a11ad6e7f8a4ca8df53b68ee7aef68791468e98404fd6a4ec098a34d831affd6
7
- data.tar.gz: ebf2a08b3ff59ba317b48cd175d87bf0624e2d4c67d2c95c90b1c8fb32cd9c1afa6ff48f0d24cb467401d3b9b2364cf368946cf4af01e8bdb744431ee9cd961f
6
+ metadata.gz: a5129e0027a2f4bd1d9bf99f98589f9713408deb0a3ebf207101af4ea25b371ee81396579396590e6b659187967a84fb967d9cbc5dae6cf167eeb3f4345b43ed
7
+ data.tar.gz: 118cb09083a9ca57fa4a90ad719a16178bcdd4d5f7926892f31c5849a9af0e40487dfe1d4f6bdaee61c684d942db3b3c43195fcee7d510ddcf0ed5b8f34a1f00
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 archive_r Team
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/NOTICE ADDED
@@ -0,0 +1,71 @@
1
+ archive_r Notices
2
+
3
+ This file contains third-party notices and licensing information for bundled or
4
+ linked components. It does not replace the project license.
5
+
6
+ ----------------------------------------
7
+ Third-Party Notices
8
+ ----------------------------------------
9
+
10
+ This distribution bundles or links against the following third-party
11
+ components. Their respective license terms apply in addition to the MIT
12
+ License.
13
+
14
+ 1. libarchive
15
+ - Purpose: core archive reading and writing functionality for the C++
16
+ library and language bindings.
17
+ - License: New BSD License (https://www.libarchive.org/)
18
+
19
+ 2. pybind11
20
+ - Purpose: header-only binding generator for the Python extension module.
21
+ - License: BSD-style License (https://github.com/pybind/pybind11)
22
+
23
+ The following components are redistributed only because libarchive (bundled with archive_r) depends on them at runtime:
24
+
25
+ 3. zlib
26
+ - Purpose: libarchive dependency providing DEFLATE compression; bundled inside archive_r binaries and wheels because libarchive requires it.
27
+ - License: zlib License (https://zlib.net/zlib_license.html)
28
+
29
+ 4. bzip2
30
+ - Purpose: libarchive dependency providing bzip2 compression support; distributed with archive_r artifacts.
31
+ - License: BSD-style license (https://sourceware.org/bzip2/)
32
+
33
+ 5. liblzma (XZ Utils)
34
+ - Purpose: libarchive dependency providing LZMA/XZ compression; included with archive_r packages.
35
+ - License: Public Domain + GNU LGPLv2.1+ (https://tukaani.org/xz/)
36
+
37
+ 6. libxml2
38
+ - Purpose: libarchive dependency used for archive formats such as xar; distributed alongside archive_r.
39
+ - License: MIT-style License (http://xmlsoft.org/)
40
+
41
+ 7. zstd
42
+ - Purpose: libarchive dependency providing Zstandard compression; shipped within archive_r binaries.
43
+ - License: BSD License (https://github.com/facebook/zstd)
44
+
45
+ 8. Nettle
46
+ - Purpose: libarchive dependency providing cryptographic support (macOS/Linux); bundled with archive_r binaries.
47
+ - License: GNU LGPLv3+ or GNU GPLv2+ (https://www.lysator.liu.se/~nisse/nettle/)
48
+
49
+ 9. mini-gmp
50
+ - Purpose: Nettle dependency for arithmetic operations (macOS/Linux); bundled with archive_r binaries.
51
+ - License: GNU LGPLv3+ or GNU GPLv2+ (https://gmplib.org/)
52
+
53
+ 10. OpenSSL 3
54
+ - Purpose: libarchive dependency providing cryptographic support (Windows); bundled with archive_r Windows wheels.
55
+ - License: Apache License 2.0 with OpenSSL exception (https://www.openssl.org/source/license.html)
56
+
57
+ 11. lz4
58
+ - Purpose: libarchive dependency providing LZ4 compression; shipped with archive_r artifacts when required.
59
+ - License: BSD 2-Clause (https://github.com/lz4/lz4)
60
+
61
+ 12. libb2 (BLAKE2)
62
+ - Purpose: libarchive dependency providing BLAKE2 hashing; bundled when archive formats require it.
63
+ - License: CC0 1.0 Universal (https://github.com/BLAKE2/libb2)
64
+
65
+ 13. libattr
66
+ - Purpose: libarchive dependency providing extended attribute support on POSIX platforms; included in POSIX builds only.
67
+ - License: LGPL-2.1-or-later for the library (https://savannah.nongnu.org/projects/attr)
68
+
69
+ 14. libacl
70
+ - Purpose: libarchive dependency providing POSIX ACL support; included in POSIX builds only.
71
+ - License: LGPL-2.1-or-later for the library (https://savannah.nongnu.org/projects/acl)
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.9
@@ -12,13 +12,16 @@
12
12
  #include <cstring>
13
13
  #include <memory>
14
14
  #include <ruby.h>
15
+ #ifdef memcpy
16
+ #undef memcpy
17
+ #endif
18
+ #include <limits>
19
+ #include <optional>
15
20
  #include <stdexcept>
16
21
  #include <string>
17
22
  #include <utility>
18
23
  #include <variant>
19
24
  #include <vector>
20
- #include <limits>
21
- #include <optional>
22
25
 
23
26
  using namespace archive_r;
24
27
 
@@ -292,16 +295,14 @@ static void stream_wrapper_free(void *ptr) {
292
295
  delete wrapper;
293
296
  }
294
297
 
295
- static size_t stream_wrapper_memsize(const void *ptr) {
296
- return sizeof(RubyStreamWrapper);
297
- }
298
+ static size_t stream_wrapper_memsize(const void *ptr) { return sizeof(RubyStreamWrapper); }
298
299
 
299
300
  static const rb_data_type_t stream_wrapper_type = {
300
301
  "ArchiveR::Stream",
301
302
  {
302
- nullptr,
303
- stream_wrapper_free,
304
- stream_wrapper_memsize,
303
+ nullptr,
304
+ stream_wrapper_free,
305
+ stream_wrapper_memsize,
305
306
  },
306
307
  nullptr,
307
308
  nullptr,
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 archive_r Team
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,71 @@
1
+ archive_r Notices
2
+
3
+ This file contains third-party notices and licensing information for bundled or
4
+ linked components. It does not replace the project license.
5
+
6
+ ----------------------------------------
7
+ Third-Party Notices
8
+ ----------------------------------------
9
+
10
+ This distribution bundles or links against the following third-party
11
+ components. Their respective license terms apply in addition to the MIT
12
+ License.
13
+
14
+ 1. libarchive
15
+ - Purpose: core archive reading and writing functionality for the C++
16
+ library and language bindings.
17
+ - License: New BSD License (https://www.libarchive.org/)
18
+
19
+ 2. pybind11
20
+ - Purpose: header-only binding generator for the Python extension module.
21
+ - License: BSD-style License (https://github.com/pybind/pybind11)
22
+
23
+ The following components are redistributed only because libarchive (bundled with archive_r) depends on them at runtime:
24
+
25
+ 3. zlib
26
+ - Purpose: libarchive dependency providing DEFLATE compression; bundled inside archive_r binaries and wheels because libarchive requires it.
27
+ - License: zlib License (https://zlib.net/zlib_license.html)
28
+
29
+ 4. bzip2
30
+ - Purpose: libarchive dependency providing bzip2 compression support; distributed with archive_r artifacts.
31
+ - License: BSD-style license (https://sourceware.org/bzip2/)
32
+
33
+ 5. liblzma (XZ Utils)
34
+ - Purpose: libarchive dependency providing LZMA/XZ compression; included with archive_r packages.
35
+ - License: Public Domain + GNU LGPLv2.1+ (https://tukaani.org/xz/)
36
+
37
+ 6. libxml2
38
+ - Purpose: libarchive dependency used for archive formats such as xar; distributed alongside archive_r.
39
+ - License: MIT-style License (http://xmlsoft.org/)
40
+
41
+ 7. zstd
42
+ - Purpose: libarchive dependency providing Zstandard compression; shipped within archive_r binaries.
43
+ - License: BSD License (https://github.com/facebook/zstd)
44
+
45
+ 8. Nettle
46
+ - Purpose: libarchive dependency providing cryptographic support (macOS/Linux); bundled with archive_r binaries.
47
+ - License: GNU LGPLv3+ or GNU GPLv2+ (https://www.lysator.liu.se/~nisse/nettle/)
48
+
49
+ 9. mini-gmp
50
+ - Purpose: Nettle dependency for arithmetic operations (macOS/Linux); bundled with archive_r binaries.
51
+ - License: GNU LGPLv3+ or GNU GPLv2+ (https://gmplib.org/)
52
+
53
+ 10. OpenSSL 3
54
+ - Purpose: libarchive dependency providing cryptographic support (Windows); bundled with archive_r Windows wheels.
55
+ - License: Apache License 2.0 with OpenSSL exception (https://www.openssl.org/source/license.html)
56
+
57
+ 11. lz4
58
+ - Purpose: libarchive dependency providing LZ4 compression; shipped with archive_r artifacts when required.
59
+ - License: BSD 2-Clause (https://github.com/lz4/lz4)
60
+
61
+ 12. libb2 (BLAKE2)
62
+ - Purpose: libarchive dependency providing BLAKE2 hashing; bundled when archive formats require it.
63
+ - License: CC0 1.0 Universal (https://github.com/BLAKE2/libb2)
64
+
65
+ 13. libattr
66
+ - Purpose: libarchive dependency providing extended attribute support on POSIX platforms; included in POSIX builds only.
67
+ - License: LGPL-2.1-or-later for the library (https://savannah.nongnu.org/projects/attr)
68
+
69
+ 14. libacl
70
+ - Purpose: libarchive dependency providing POSIX ACL support; included in POSIX builds only.
71
+ - License: LGPL-2.1-or-later for the library (https://savannah.nongnu.org/projects/acl)
@@ -3,12 +3,12 @@
3
3
 
4
4
  #pragma once
5
5
 
6
- #include "archive_r/platform_compat.h"
7
6
  #include "archive_r/path_hierarchy.h"
7
+ #include "archive_r/platform_compat.h"
8
8
 
9
+ #include <cstdint>
9
10
  #include <functional>
10
11
  #include <memory>
11
- #include <cstdint>
12
12
 
13
13
  namespace archive_r {
14
14
 
@@ -97,8 +97,8 @@ public:
97
97
  /**
98
98
  * @brief Read data from the entry
99
99
  *
100
- * Each call uses an internal ArchiveStackOrchestrator so reads remain valid even
101
- * if the owning iterator advances.
100
+ * Each call uses an internal ArchiveStackOrchestrator so reads remain valid even
101
+ * if the owning iterator advances.
102
102
  *
103
103
  * @param buffer Buffer to read data into
104
104
  * @param length Maximum number of bytes to read
@@ -109,9 +109,9 @@ public:
109
109
  /**
110
110
  * @brief Enable or disable automatic descent into this entry
111
111
  * @param enabled true to descend (default), false to keep traversal at current level
112
- *
113
- * This control is only available for entries that are managed by a Traverser.
114
- * Calling this on an Entry that is not traverser-managed reports a fault.
112
+ *
113
+ * This control is only available for entries that are managed by a Traverser.
114
+ * Calling this on an Entry that is not traverser-managed reports a fault.
115
115
  */
116
116
  void set_descent(bool enabled);
117
117
 
@@ -139,9 +139,9 @@ public:
139
139
  * }
140
140
  * }
141
141
  * @endcode
142
- *
143
- * This control is only available for entries that are managed by a Traverser.
144
- * Calling this on an Entry that is not traverser-managed reports a fault.
142
+ *
143
+ * This control is only available for entries that are managed by a Traverser.
144
+ * Calling this on an Entry that is not traverser-managed reports a fault.
145
145
  */
146
146
  void set_multi_volume_group(const std::string &base_name, const MultiVolumeGroupOptions &options = {});
147
147
 
@@ -30,8 +30,8 @@ protected:
30
30
  virtual void open_single_part(const PathHierarchy &single_part) = 0;
31
31
  virtual void close_single_part() = 0;
32
32
  virtual ssize_t read_from_single_part(void *buffer, size_t size) = 0;
33
- virtual int64_t seek_within_single_part(int64_t offset, int whence) = 0;
34
- virtual int64_t size_of_single_part(const PathHierarchy &single_part) = 0;
33
+ virtual int64_t seek_within_single_part(int64_t offset, int whence);
34
+ virtual int64_t size_of_single_part(const PathHierarchy &single_part);
35
35
 
36
36
  PathHierarchy _logical_path;
37
37
  void deactivate_active_part();
@@ -33,5 +33,4 @@ bool entry_name_from_component(const PathEntry &entry, std::string &output);
33
33
  std::string path_entry_display(const PathEntry &entry);
34
34
  std::string hierarchy_display(const PathHierarchy &hierarchy);
35
35
 
36
-
37
36
  } // namespace archive_r
@@ -6,16 +6,16 @@
6
6
  #include <sys/types.h>
7
7
 
8
8
  #if defined(_WIN32)
9
- # include <sys/stat.h>
10
- # include <BaseTsd.h>
11
- # if !defined(_SSIZE_T_DEFINED)
9
+ #include <BaseTsd.h>
10
+ #include <sys/stat.h>
11
+ #if !defined(_SSIZE_T_DEFINED)
12
12
  using ssize_t = SSIZE_T;
13
- # define _SSIZE_T_DEFINED
14
- # endif
15
- # if !defined(_MODE_T_DEFINED)
13
+ #define _SSIZE_T_DEFINED
14
+ #endif
15
+ #if !defined(_MODE_T_DEFINED)
16
16
  using mode_t = unsigned short; // MSVC does not expose POSIX mode_t by default
17
- # define _MODE_T_DEFINED
18
- # endif
17
+ #define _MODE_T_DEFINED
18
+ #endif
19
19
  #endif
20
20
 
21
21
  namespace archive_r {
@@ -75,8 +75,8 @@ public:
75
75
  * Provide one or more paths to traverse. Single-path traversal can be
76
76
  * achieved by passing a container with one element:
77
77
  * Traverser traverser({make_single_path("archive.tar.gz")});
78
- *
79
- * @throws std::invalid_argument if paths is empty or contains an empty hierarchy
78
+ *
79
+ * @throws std::invalid_argument if paths is empty or contains an empty hierarchy
80
80
  */
81
81
  explicit Traverser(std::vector<PathHierarchy> paths, TraverserOptions options = {});
82
82
 
@@ -125,9 +125,7 @@ EntryPayloadStream::EntryPayloadStream(std::shared_ptr<StreamArchive> parent_arc
125
125
  }
126
126
  }
127
127
 
128
- EntryPayloadStream::~EntryPayloadStream() {
129
- deactivate_active_part();
130
- }
128
+ EntryPayloadStream::~EntryPayloadStream() { deactivate_active_part(); }
131
129
 
132
130
  std::shared_ptr<StreamArchive> EntryPayloadStream::parent_archive() const { return _parent_archive; }
133
131
 
@@ -154,19 +152,7 @@ void EntryPayloadStream::close_single_part() {
154
152
  // so explicit skipping here is unnecessary and avoids potential exceptions in destructor.
155
153
  }
156
154
 
157
- ssize_t EntryPayloadStream::read_from_single_part(void *buffer, size_t size) {
158
- if (size == 0) {
159
- return 0;
160
- }
161
- return _parent_archive->read_current(buffer, size);
162
- }
163
-
164
- int64_t EntryPayloadStream::seek_within_single_part(int64_t offset, int whence) { return -1; }
165
-
166
- int64_t EntryPayloadStream::size_of_single_part(const PathHierarchy &single_part) {
167
- (void)single_part;
168
- return -1;
169
- }
155
+ ssize_t EntryPayloadStream::read_from_single_part(void *buffer, size_t size) { return _parent_archive->read_current(buffer, size); }
170
156
 
171
157
  // ============================================================================
172
158
  // ArchiveStackCursor Implementation
@@ -177,9 +163,7 @@ ArchiveStackCursor::ArchiveStackCursor()
177
163
  , _current_stream(nullptr)
178
164
  , _current_archive(nullptr) {}
179
165
 
180
- void ArchiveStackCursor::configure(const ArchiveOption &options) {
181
- options_snapshot = options;
182
- }
166
+ void ArchiveStackCursor::configure(const ArchiveOption &options) { options_snapshot = options; }
183
167
 
184
168
  void ArchiveStackCursor::reset() {
185
169
  options_snapshot = ArchiveOption{};
@@ -207,17 +191,12 @@ bool ArchiveStackCursor::descend() {
207
191
  }
208
192
 
209
193
  bool ArchiveStackCursor::ascend() {
210
- if (depth() <= 0) {
194
+ if (!_current_archive) {
211
195
  return false;
212
196
  }
213
197
 
214
- if (_current_archive) {
215
- _current_stream = _current_archive->get_stream();
216
- _current_archive = _current_archive->parent_archive();
217
- } else {
218
- _current_stream = nullptr;
219
- }
220
-
198
+ _current_stream = _current_archive->get_stream();
199
+ _current_archive = _current_archive->parent_archive();
221
200
  return true;
222
201
  }
223
202
 
@@ -250,8 +229,7 @@ bool ArchiveStackCursor::synchronize_to_hierarchy(const PathHierarchy &target_hi
250
229
  // 1. Ascend until we find a common ancestor
251
230
  while (depth() > 0) {
252
231
  auto current_h = _current_archive->source_hierarchy();
253
- if (current_h.size() <= target_hierarchy.size() &&
254
- hierarchies_equal(current_h, pathhierarchy_prefix_until(target_hierarchy, current_h.size() - 1))) {
232
+ if (current_h.size() <= target_hierarchy.size() && hierarchies_equal(current_h, pathhierarchy_prefix_until(target_hierarchy, current_h.size() - 1))) {
255
233
  break;
256
234
  }
257
235
  ascend();
@@ -289,12 +267,10 @@ ssize_t ArchiveStackCursor::read(void *buff, size_t len) {
289
267
  return 0;
290
268
  }
291
269
 
292
- StreamArchive *ArchiveStackCursor::current_archive() {
293
- return _current_archive.get();
294
- }
270
+ StreamArchive *ArchiveStackCursor::current_archive() { return _current_archive.get(); }
295
271
 
296
272
  PathHierarchy ArchiveStackCursor::current_entry_hierarchy() {
297
- if (depth() == 0 || (!_current_stream && !_current_archive)) {
273
+ if (!_current_stream && !_current_archive) {
298
274
  return {};
299
275
  }
300
276
 
@@ -306,7 +282,7 @@ PathHierarchy ArchiveStackCursor::current_entry_hierarchy() {
306
282
  return path;
307
283
  }
308
284
 
309
- return _current_stream->source_hierarchy();
285
+ return _current_stream ? _current_stream->source_hierarchy() : PathHierarchy{};
310
286
  }
311
287
 
312
288
  std::shared_ptr<IDataStream> ArchiveStackCursor::create_stream(const PathHierarchy &hierarchy) {
@@ -4,10 +4,10 @@
4
4
  #pragma once
5
5
 
6
6
  #include "archive_r/data_stream.h"
7
+ #include "archive_r/multi_volume_stream_base.h"
7
8
  #include "archive_r/path_hierarchy.h"
8
9
  #include "archive_type.h"
9
10
  #include "entry_fault_error.h"
10
- #include "archive_r/multi_volume_stream_base.h"
11
11
  #include <array>
12
12
  #include <cstddef>
13
13
  #include <exception>
@@ -64,8 +64,6 @@ private:
64
64
  void open_single_part(const PathHierarchy &single_part) override;
65
65
  void close_single_part() override;
66
66
  ssize_t read_from_single_part(void *buffer, size_t size) override;
67
- int64_t seek_within_single_part(int64_t offset, int whence) override;
68
- int64_t size_of_single_part(const PathHierarchy &single_part) override;
69
67
  };
70
68
 
71
69
  // ============================================================================
@@ -2,8 +2,8 @@
2
2
  // Copyright (c) 2025 archive_r Team
3
3
 
4
4
  #include "archive_stack_orchestrator.h"
5
- #include "archive_r/path_hierarchy_utils.h"
6
5
  #include "archive_r/entry_fault.h"
6
+ #include "archive_r/path_hierarchy_utils.h"
7
7
  #include "system_file_stream.h"
8
8
 
9
9
  #include <algorithm>
@@ -19,9 +19,8 @@
19
19
  namespace archive_r {
20
20
 
21
21
  ArchiveStackOrchestrator::ArchiveStackOrchestrator(const ArchiveOption &options)
22
- : _archive_options(options)
23
- , _metadata_keys(options.metadata_keys.begin(), options.metadata_keys.end()) {
24
- _head.configure(_archive_options);
22
+ : _archive_options(options) {
23
+ _head.configure(_archive_options);
25
24
  }
26
25
 
27
26
  ArchiveStackOrchestrator::~ArchiveStackOrchestrator() = default;
@@ -135,12 +134,12 @@ void ArchiveStackOrchestrator::mark_entry_as_multi_volume(const PathHierarchy &e
135
134
  }
136
135
 
137
136
  bool ArchiveStackOrchestrator::descend_pending_multi_volumes() {
138
- const PathHierarchy current_hierarchy = _head.current_entry_hierarchy();
137
+ const PathHierarchy current_hierarchy = (depth() == 0) ? PathHierarchy{} : _head.current_entry_hierarchy();
139
138
  PathHierarchy multi_volume_target;
140
139
  if (!_multi_volume_manager.pop_multi_volume_group(current_hierarchy, multi_volume_target)) {
141
140
  return false;
142
141
  }
143
-
142
+
144
143
  _head.synchronize_to_hierarchy(multi_volume_target);
145
144
  _head.descend();
146
145
  return true;
@@ -5,8 +5,8 @@
5
5
 
6
6
  #include "archive_r/path_hierarchy.h"
7
7
  #include "archive_r/platform_compat.h"
8
- #include "archive_type.h"
9
8
  #include "archive_stack_cursor.h"
9
+ #include "archive_type.h"
10
10
  #include "entry_fault_error.h"
11
11
  #include "multi_volume_manager.h"
12
12
  #include <limits>
@@ -36,7 +36,7 @@ public:
36
36
  StreamArchive *current_archive();
37
37
  ssize_t read_head(void *buff, size_t len);
38
38
 
39
- const std::unordered_set<std::string> &metadata_keys() const { return _metadata_keys; }
39
+ const std::unordered_set<std::string> &metadata_keys() const { return _archive_options.metadata_keys; }
40
40
  const ArchiveOption &options() const { return _archive_options; }
41
41
 
42
42
  void mark_entry_as_multi_volume(const PathHierarchy &entry_path, const std::string &base_name, PathEntry::Parts::Ordering ordering = PathEntry::Parts::Ordering::Natural);
@@ -44,7 +44,6 @@ public:
44
44
 
45
45
  private:
46
46
  ArchiveOption _archive_options;
47
- std::unordered_set<std::string> _metadata_keys;
48
47
  ArchiveStackCursor _head;
49
48
  MultiVolumeManager _multi_volume_manager;
50
49
 
@@ -232,9 +232,7 @@ bool Archive::search_forward_until_eof(const std::string &entryname) {
232
232
  if (current_entryname == entryname) {
233
233
  return true;
234
234
  }
235
- if (!skip_data()) {
236
- return false;
237
- }
235
+ skip_data();
238
236
  }
239
237
  return false;
240
238
  }
@@ -247,9 +245,7 @@ bool Archive::search_until_position(const std::string &entryname, const std::str
247
245
  if (current_entryname == stop_position) {
248
246
  break;
249
247
  }
250
- if (!skip_data()) {
251
- return false;
252
- }
248
+ skip_data();
253
249
  }
254
250
  return false;
255
251
  }
@@ -268,6 +264,7 @@ ssize_t Archive::read_current(void *buff, size_t len) {
268
264
  return bytes_read;
269
265
  }
270
266
 
267
+ // Returns the current entry size in bytes, or 0 when no entry is selected.
271
268
  uint64_t Archive::current_entry_size() const {
272
269
  if (!current_entry) {
273
270
  return 0;
@@ -275,6 +272,7 @@ uint64_t Archive::current_entry_size() const {
275
272
  return archive_entry_size(current_entry);
276
273
  }
277
274
 
275
+ // Returns the current entry filetype bits, or 0 when no entry is selected.
278
276
  mode_t Archive::current_entry_filetype() const {
279
277
  if (!current_entry) {
280
278
  return 0;
@@ -451,14 +449,9 @@ EntryMetadataMap Archive::current_entry_metadata(const std::unordered_set<std::s
451
449
  }
452
450
  }
453
451
 
454
- ssize_t acl_length = 0;
455
- char *acl_text = wants("acl_text") ? archive_entry_acl_to_text(current_entry, &acl_length, ARCHIVE_ENTRY_ACL_STYLE_SEPARATOR_COMMA) : nullptr;
452
+ char *acl_text = wants("acl_text") ? archive_entry_acl_to_text(current_entry, nullptr, ARCHIVE_ENTRY_ACL_STYLE_SEPARATOR_COMMA) : nullptr;
456
453
  if (acl_text) {
457
- if (acl_length >= 0) {
458
- metadata["acl_text"] = std::string(acl_text, static_cast<size_t>(acl_length));
459
- } else {
460
- metadata["acl_text"] = std::string(acl_text);
461
- }
454
+ metadata["acl_text"] = std::string(acl_text);
462
455
  std::free(acl_text);
463
456
  }
464
457
 
@@ -26,9 +26,9 @@ using archive_ptr = std::unique_ptr<struct archive, archive_deleter>;
26
26
  using open_delegate = std::function<int(struct archive *ar)>;
27
27
 
28
28
  struct ArchiveOption {
29
- std::vector<std::string> passphrases; ///< Passphrases for encrypted archives
30
- std::vector<std::string> formats; ///< Specific format names to enable (empty = all)
31
- std::vector<std::string> metadata_keys; ///< Metadata keys to capture (empty = none)
29
+ std::vector<std::string> passphrases; ///< Passphrases for encrypted archives
30
+ std::vector<std::string> formats; ///< Specific format names to enable (empty = all)
31
+ std::unordered_set<std::string> metadata_keys; ///< Metadata keys to capture (empty = none)
32
32
  };
33
33
 
34
34
  archive_ptr new_read_archive_common(const std::vector<std::string> &passphrases, const std::vector<std::string> &format_names, open_delegate archive_open);
@@ -32,24 +32,9 @@ Entry::Impl::Impl(const Impl &other)
32
32
  , _descend_enabled(other._descend_enabled)
33
33
  , _orchestrator(nullptr)
34
34
  , _shares_traverser_orchestrator(false)
35
- , _archive_options(other._archive_options) {
36
- }
35
+ , _archive_options(other._archive_options) {}
37
36
 
38
37
  // Copy assignment operator
39
- Entry::Impl &Entry::Impl::operator=(const Impl &other) {
40
- if (this != &other) {
41
- _path_hierarchy = other._path_hierarchy;
42
- _size = other._size;
43
- _filetype = other._filetype;
44
- _metadata = other._metadata;
45
- _descend_enabled = other._descend_enabled;
46
- _orchestrator.reset();
47
- _shares_traverser_orchestrator = false;
48
- _archive_options = other._archive_options;
49
- }
50
- return *this;
51
- }
52
-
53
38
  Entry::Impl::Impl(const PathHierarchy &hierarchy, std::shared_ptr<ArchiveStackOrchestrator> data_source_orchestrator, bool default_descent)
54
39
  : _path_hierarchy(hierarchy)
55
40
  , _size(0)
@@ -199,7 +184,7 @@ ssize_t Entry::Impl::read(void *buffer, size_t length) {
199
184
  // ============================================================================
200
185
 
201
186
  Entry::Entry(const PathHierarchy &hierarchy, std::shared_ptr<ArchiveStackOrchestrator> data_source_orchestrator, bool default_descent)
202
- : _impl(std::make_unique<Impl>(hierarchy, std::move(data_source_orchestrator), default_descent)) {}
187
+ : _impl(std::make_unique<Impl>(hierarchy, std::move(data_source_orchestrator), default_descent)) {}
203
188
 
204
189
  Entry::Entry(Impl *impl)
205
190
  : _impl(impl) {}