archive_r_ruby 0.1.3 → 0.1.4

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 (43) hide show
  1. checksums.yaml +4 -4
  2. data/{LICENSE → LICENSE.txt} +77 -77
  3. data/README.md +103 -103
  4. data/ext/archive_r/Makefile +48 -45
  5. data/ext/archive_r/archive_r-x64-mingw-ucrt.def +2 -0
  6. data/ext/archive_r/archive_r_ext.cc +1106 -1106
  7. data/ext/archive_r/archive_r_ext.o +0 -0
  8. data/ext/archive_r/extconf.rb +120 -120
  9. data/ext/archive_r/mkmf.log +23 -18
  10. data/ext/archive_r/vendor/archive_r/LICENSE.txt +77 -77
  11. data/ext/archive_r/vendor/archive_r/include/archive_r/data_stream.h +52 -52
  12. data/ext/archive_r/vendor/archive_r/include/archive_r/entry.h +166 -166
  13. data/ext/archive_r/vendor/archive_r/include/archive_r/entry_fault.h +34 -34
  14. data/ext/archive_r/vendor/archive_r/include/archive_r/entry_metadata.h +56 -56
  15. data/ext/archive_r/vendor/archive_r/include/archive_r/multi_volume_stream_base.h +46 -46
  16. data/ext/archive_r/vendor/archive_r/include/archive_r/path_hierarchy.h +109 -109
  17. data/ext/archive_r/vendor/archive_r/include/archive_r/path_hierarchy_utils.h +37 -37
  18. data/ext/archive_r/vendor/archive_r/include/archive_r/platform_compat.h +19 -19
  19. data/ext/archive_r/vendor/archive_r/include/archive_r/traverser.h +122 -122
  20. data/ext/archive_r/vendor/archive_r/src/archive_stack_cursor.cc +330 -330
  21. data/ext/archive_r/vendor/archive_r/src/archive_stack_cursor.h +97 -97
  22. data/ext/archive_r/vendor/archive_r/src/archive_stack_orchestrator.cc +162 -162
  23. data/ext/archive_r/vendor/archive_r/src/archive_stack_orchestrator.h +54 -54
  24. data/ext/archive_r/vendor/archive_r/src/archive_type.cc +552 -552
  25. data/ext/archive_r/vendor/archive_r/src/archive_type.h +77 -77
  26. data/ext/archive_r/vendor/archive_r/src/data_stream.cc +35 -35
  27. data/ext/archive_r/vendor/archive_r/src/entry.cc +253 -253
  28. data/ext/archive_r/vendor/archive_r/src/entry_fault.cc +26 -26
  29. data/ext/archive_r/vendor/archive_r/src/entry_fault_error.cc +54 -54
  30. data/ext/archive_r/vendor/archive_r/src/entry_fault_error.h +32 -32
  31. data/ext/archive_r/vendor/archive_r/src/entry_impl.h +57 -57
  32. data/ext/archive_r/vendor/archive_r/src/multi_volume_manager.cc +81 -81
  33. data/ext/archive_r/vendor/archive_r/src/multi_volume_manager.h +41 -41
  34. data/ext/archive_r/vendor/archive_r/src/multi_volume_stream_base.cc +199 -199
  35. data/ext/archive_r/vendor/archive_r/src/path_hierarchy.cc +151 -151
  36. data/ext/archive_r/vendor/archive_r/src/path_hierarchy_utils.cc +304 -304
  37. data/ext/archive_r/vendor/archive_r/src/simple_profiler.h +120 -120
  38. data/ext/archive_r/vendor/archive_r/src/system_file_stream.cc +295 -295
  39. data/ext/archive_r/vendor/archive_r/src/system_file_stream.h +46 -46
  40. data/ext/archive_r/vendor/archive_r/src/traverser.cc +314 -314
  41. data/lib/archive_r.rb +105 -105
  42. metadata +11 -8
  43. data/ext/archive_r/archive_r.bundle +0 -0
@@ -1,253 +1,253 @@
1
- // SPDX-License-Identifier: MIT
2
- // Copyright (c) 2025 archive_r Team
3
-
4
- #include "archive_r/entry.h"
5
- #include "archive_r/path_hierarchy_utils.h"
6
- #include "archive_stack_orchestrator.h"
7
- #include "entry_fault_error.h"
8
- #include "entry_impl.h"
9
- #include "system_file_stream.h"
10
- #include <archive.h>
11
- #include <archive_entry.h>
12
- #include <filesystem>
13
- #include <sstream>
14
- #include <sys/stat.h>
15
- #include <system_error>
16
- #include <unordered_set>
17
- #include <utility>
18
-
19
- namespace archive_r {
20
-
21
- // ============================================================================
22
- // Entry::Impl Implementation
23
- // ============================================================================
24
-
25
- // Unified constructor - receives metadata directly
26
- // Copy constructor - cached orchestrator is NOT copied (will be recreated on first read)
27
- Entry::Impl::Impl(const Impl &other)
28
- : _path_hierarchy(other._path_hierarchy)
29
- , _size(other._size)
30
- , _filetype(other._filetype)
31
- , _metadata(other._metadata)
32
- , _descend_enabled(other._descend_enabled)
33
- , _orchestrator(nullptr)
34
- , _shares_traverser_orchestrator(false)
35
- , _archive_options(other._archive_options) {
36
- }
37
-
38
- // 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
- Entry::Impl::Impl(const PathHierarchy &hierarchy, std::shared_ptr<ArchiveStackOrchestrator> data_source_orchestrator, bool default_descent)
54
- : _path_hierarchy(hierarchy)
55
- , _size(0)
56
- , _filetype(0)
57
- , _descend_enabled(default_descent)
58
- , _orchestrator(std::move(data_source_orchestrator))
59
- , _shares_traverser_orchestrator(static_cast<bool>(_orchestrator)) {
60
- if (!_orchestrator) {
61
- return;
62
- }
63
-
64
- const auto &keys = _orchestrator->metadata_keys();
65
-
66
- const StreamArchive *archive = _orchestrator->current_archive();
67
- const bool use_archive_metadata = archive && _path_hierarchy.size() > 1;
68
-
69
- if (use_archive_metadata) {
70
- _size = archive->current_entry_size();
71
- _filetype = archive->current_entry_filetype();
72
- if (!keys.empty()) {
73
- _metadata = archive->current_entry_metadata(keys);
74
- }
75
- } else if (!hierarchy.empty()) {
76
- FilesystemMetadataInfo info = collect_root_path_metadata(hierarchy, keys);
77
- _size = info.size;
78
- _filetype = info.filetype;
79
- _metadata = std::move(info.metadata);
80
- }
81
-
82
- if (use_archive_metadata) {
83
- _archive_options = _orchestrator->options();
84
- } else {
85
- _archive_options.reset();
86
- }
87
-
88
- if (_filetype == 0 && archive && _orchestrator->depth() == _path_hierarchy.size()) {
89
- _filetype = AE_IFREG;
90
- }
91
- }
92
-
93
- std::string Entry::Impl::name() const {
94
- if (_path_hierarchy.empty()) {
95
- return "";
96
- }
97
- const PathEntry &tail = _path_hierarchy.back();
98
- std::string display_name;
99
- if (entry_name_from_component(tail, display_name) && !display_name.empty()) {
100
- return display_name;
101
- }
102
- if (tail.is_single()) {
103
- return tail.single_value();
104
- }
105
- return path_entry_display(tail);
106
- }
107
-
108
- const PathHierarchy &Entry::Impl::path_hierarchy() const { return _path_hierarchy; }
109
-
110
- bool Entry::Impl::is_directory() const { return _filetype == AE_IFDIR; }
111
-
112
- bool Entry::Impl::is_file() const { return _filetype == AE_IFREG; }
113
-
114
- uint64_t Entry::Impl::size() const { return _size; }
115
-
116
- size_t Entry::Impl::depth() const {
117
- // Depth is based on path hierarchy length
118
- return _path_hierarchy.size() > 0 ? _path_hierarchy.size() - 1 : 0;
119
- }
120
-
121
- void Entry::Impl::set_descent(bool enabled) {
122
- if (!_shares_traverser_orchestrator) {
123
- emit_fault("set_descent requires traverser-managed orchestrator");
124
- return;
125
- }
126
- _descend_enabled = enabled;
127
- }
128
-
129
- bool Entry::Impl::descent_enabled() const { return _descend_enabled; }
130
-
131
- const EntryMetadataMap &Entry::Impl::metadata() const { return _metadata; }
132
-
133
- const EntryMetadataValue *Entry::Impl::metadata_value(const std::string &key) const {
134
- const auto it = _metadata.find(key);
135
- if (it == _metadata.end()) {
136
- return nullptr;
137
- }
138
- return &it->second;
139
- }
140
-
141
- void Entry::Impl::set_multi_volume_group(const std::string &base_name, const MultiVolumeGroupOptions &options) {
142
- if (!_shares_traverser_orchestrator) {
143
- emit_fault("set_multi_volume_group requires traverser-managed orchestrator");
144
- return;
145
- }
146
-
147
- // Notify traverser via ArchiveStackOrchestrator
148
- _descend_enabled = false;
149
- _orchestrator->mark_entry_as_multi_volume(_path_hierarchy, base_name, options.ordering);
150
- }
151
-
152
- void Entry::Impl::emit_fault(const std::string &message, int errno_value) const {
153
- EntryFault fault;
154
- fault.message = message;
155
- fault.errno_value = errno_value;
156
- fault.hierarchy = _path_hierarchy;
157
- dispatch_registered_fault(fault);
158
- }
159
-
160
- std::shared_ptr<ArchiveStackOrchestrator> Entry::Impl::ensure_orchestrator() {
161
- if (_orchestrator) {
162
- if (_shares_traverser_orchestrator && _orchestrator->depth() == 0) {
163
- // Traverser-managed orchestrator never synchronized to this entry (depth 0 filesystem read).
164
- _orchestrator.reset();
165
- _shares_traverser_orchestrator = false;
166
- } else {
167
- return _orchestrator;
168
- }
169
- }
170
-
171
- ArchiveOption opts = _archive_options.value_or(ArchiveOption{});
172
- _orchestrator = std::make_shared<ArchiveStackOrchestrator>(opts);
173
- if (!_orchestrator->synchronize_to_hierarchy(_path_hierarchy)) {
174
- _orchestrator.reset();
175
- return nullptr;
176
- }
177
- _shares_traverser_orchestrator = false;
178
- return _orchestrator;
179
- }
180
-
181
- ssize_t Entry::Impl::read(void *buffer, size_t length) {
182
- if (!ensure_orchestrator()) {
183
- emit_fault("Failed to initialize ArchiveStackOrchestrator");
184
- return -1;
185
- }
186
- const ssize_t bytes_read = _orchestrator->read_head(buffer, length);
187
- if (bytes_read < 0) {
188
- emit_fault("Failed to read entry content");
189
- return -1;
190
- }
191
-
192
- _descend_enabled = false; // Require explicit re-enable before descending again
193
-
194
- return bytes_read;
195
- }
196
-
197
- // ============================================================================
198
- // Entry Public API Implementation
199
- // ============================================================================
200
-
201
- 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)) {}
203
-
204
- Entry::Entry(Impl *impl)
205
- : _impl(impl) {}
206
-
207
- Entry::~Entry() = default;
208
-
209
- std::unique_ptr<Entry> Entry::create(PathHierarchy hierarchy, std::shared_ptr<ArchiveStackOrchestrator> data_source_orchestrator, bool default_descent) {
210
- return std::unique_ptr<Entry>(new Entry(hierarchy, std::move(data_source_orchestrator), default_descent));
211
- }
212
-
213
- // Copy operations - creates a new Impl copy
214
- Entry::Entry(const Entry &other)
215
- : _impl(other._impl ? std::make_unique<Impl>(*other._impl) : nullptr) {}
216
-
217
- Entry &Entry::operator=(const Entry &other) {
218
- if (this != &other) {
219
- _impl = other._impl ? std::make_unique<Impl>(*other._impl) : nullptr;
220
- }
221
- return *this;
222
- }
223
-
224
- Entry::Entry(Entry &&) noexcept = default;
225
- Entry &Entry::operator=(Entry &&) noexcept = default;
226
-
227
- std::string Entry::name() const { return _impl->name(); }
228
-
229
- std::string Entry::path() const { return hierarchy_display(_impl->path_hierarchy()); }
230
-
231
- const PathHierarchy &Entry::path_hierarchy() const { return _impl->path_hierarchy(); }
232
-
233
- bool Entry::is_directory() const { return _impl->is_directory(); }
234
-
235
- bool Entry::is_file() const { return _impl->is_file(); }
236
-
237
- uint64_t Entry::size() const { return _impl->size(); }
238
-
239
- size_t Entry::depth() const { return _impl->depth(); }
240
-
241
- ssize_t Entry::read(void *buffer, size_t length) { return _impl->read(buffer, length); }
242
-
243
- void Entry::set_descent(bool enabled) { _impl->set_descent(enabled); }
244
-
245
- bool Entry::descent_enabled() const { return _impl->descent_enabled(); }
246
-
247
- void Entry::set_multi_volume_group(const std::string &base_name, const MultiVolumeGroupOptions &options) { _impl->set_multi_volume_group(base_name, options); }
248
-
249
- const EntryMetadataMap &Entry::metadata() const { return _impl->metadata(); }
250
-
251
- const EntryMetadataValue *Entry::find_metadata(const std::string &key) const { return _impl->metadata_value(key); }
252
-
253
- } // namespace archive_r
1
+ // SPDX-License-Identifier: MIT
2
+ // Copyright (c) 2025 archive_r Team
3
+
4
+ #include "archive_r/entry.h"
5
+ #include "archive_r/path_hierarchy_utils.h"
6
+ #include "archive_stack_orchestrator.h"
7
+ #include "entry_fault_error.h"
8
+ #include "entry_impl.h"
9
+ #include "system_file_stream.h"
10
+ #include <archive.h>
11
+ #include <archive_entry.h>
12
+ #include <filesystem>
13
+ #include <sstream>
14
+ #include <sys/stat.h>
15
+ #include <system_error>
16
+ #include <unordered_set>
17
+ #include <utility>
18
+
19
+ namespace archive_r {
20
+
21
+ // ============================================================================
22
+ // Entry::Impl Implementation
23
+ // ============================================================================
24
+
25
+ // Unified constructor - receives metadata directly
26
+ // Copy constructor - cached orchestrator is NOT copied (will be recreated on first read)
27
+ Entry::Impl::Impl(const Impl &other)
28
+ : _path_hierarchy(other._path_hierarchy)
29
+ , _size(other._size)
30
+ , _filetype(other._filetype)
31
+ , _metadata(other._metadata)
32
+ , _descend_enabled(other._descend_enabled)
33
+ , _orchestrator(nullptr)
34
+ , _shares_traverser_orchestrator(false)
35
+ , _archive_options(other._archive_options) {
36
+ }
37
+
38
+ // 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
+ Entry::Impl::Impl(const PathHierarchy &hierarchy, std::shared_ptr<ArchiveStackOrchestrator> data_source_orchestrator, bool default_descent)
54
+ : _path_hierarchy(hierarchy)
55
+ , _size(0)
56
+ , _filetype(0)
57
+ , _descend_enabled(default_descent)
58
+ , _orchestrator(std::move(data_source_orchestrator))
59
+ , _shares_traverser_orchestrator(static_cast<bool>(_orchestrator)) {
60
+ if (!_orchestrator) {
61
+ return;
62
+ }
63
+
64
+ const auto &keys = _orchestrator->metadata_keys();
65
+
66
+ const StreamArchive *archive = _orchestrator->current_archive();
67
+ const bool use_archive_metadata = archive && _path_hierarchy.size() > 1;
68
+
69
+ if (use_archive_metadata) {
70
+ _size = archive->current_entry_size();
71
+ _filetype = archive->current_entry_filetype();
72
+ if (!keys.empty()) {
73
+ _metadata = archive->current_entry_metadata(keys);
74
+ }
75
+ } else if (!hierarchy.empty()) {
76
+ FilesystemMetadataInfo info = collect_root_path_metadata(hierarchy, keys);
77
+ _size = info.size;
78
+ _filetype = info.filetype;
79
+ _metadata = std::move(info.metadata);
80
+ }
81
+
82
+ if (use_archive_metadata) {
83
+ _archive_options = _orchestrator->options();
84
+ } else {
85
+ _archive_options.reset();
86
+ }
87
+
88
+ if (_filetype == 0 && archive && _orchestrator->depth() == _path_hierarchy.size()) {
89
+ _filetype = AE_IFREG;
90
+ }
91
+ }
92
+
93
+ std::string Entry::Impl::name() const {
94
+ if (_path_hierarchy.empty()) {
95
+ return "";
96
+ }
97
+ const PathEntry &tail = _path_hierarchy.back();
98
+ std::string display_name;
99
+ if (entry_name_from_component(tail, display_name) && !display_name.empty()) {
100
+ return display_name;
101
+ }
102
+ if (tail.is_single()) {
103
+ return tail.single_value();
104
+ }
105
+ return path_entry_display(tail);
106
+ }
107
+
108
+ const PathHierarchy &Entry::Impl::path_hierarchy() const { return _path_hierarchy; }
109
+
110
+ bool Entry::Impl::is_directory() const { return _filetype == AE_IFDIR; }
111
+
112
+ bool Entry::Impl::is_file() const { return _filetype == AE_IFREG; }
113
+
114
+ uint64_t Entry::Impl::size() const { return _size; }
115
+
116
+ size_t Entry::Impl::depth() const {
117
+ // Depth is based on path hierarchy length
118
+ return _path_hierarchy.size() > 0 ? _path_hierarchy.size() - 1 : 0;
119
+ }
120
+
121
+ void Entry::Impl::set_descent(bool enabled) {
122
+ if (!_shares_traverser_orchestrator) {
123
+ emit_fault("set_descent requires traverser-managed orchestrator");
124
+ return;
125
+ }
126
+ _descend_enabled = enabled;
127
+ }
128
+
129
+ bool Entry::Impl::descent_enabled() const { return _descend_enabled; }
130
+
131
+ const EntryMetadataMap &Entry::Impl::metadata() const { return _metadata; }
132
+
133
+ const EntryMetadataValue *Entry::Impl::metadata_value(const std::string &key) const {
134
+ const auto it = _metadata.find(key);
135
+ if (it == _metadata.end()) {
136
+ return nullptr;
137
+ }
138
+ return &it->second;
139
+ }
140
+
141
+ void Entry::Impl::set_multi_volume_group(const std::string &base_name, const MultiVolumeGroupOptions &options) {
142
+ if (!_shares_traverser_orchestrator) {
143
+ emit_fault("set_multi_volume_group requires traverser-managed orchestrator");
144
+ return;
145
+ }
146
+
147
+ // Notify traverser via ArchiveStackOrchestrator
148
+ _descend_enabled = false;
149
+ _orchestrator->mark_entry_as_multi_volume(_path_hierarchy, base_name, options.ordering);
150
+ }
151
+
152
+ void Entry::Impl::emit_fault(const std::string &message, int errno_value) const {
153
+ EntryFault fault;
154
+ fault.message = message;
155
+ fault.errno_value = errno_value;
156
+ fault.hierarchy = _path_hierarchy;
157
+ dispatch_registered_fault(fault);
158
+ }
159
+
160
+ std::shared_ptr<ArchiveStackOrchestrator> Entry::Impl::ensure_orchestrator() {
161
+ if (_orchestrator) {
162
+ if (_shares_traverser_orchestrator && _orchestrator->depth() == 0) {
163
+ // Traverser-managed orchestrator never synchronized to this entry (depth 0 filesystem read).
164
+ _orchestrator.reset();
165
+ _shares_traverser_orchestrator = false;
166
+ } else {
167
+ return _orchestrator;
168
+ }
169
+ }
170
+
171
+ ArchiveOption opts = _archive_options.value_or(ArchiveOption{});
172
+ _orchestrator = std::make_shared<ArchiveStackOrchestrator>(opts);
173
+ if (!_orchestrator->synchronize_to_hierarchy(_path_hierarchy)) {
174
+ _orchestrator.reset();
175
+ return nullptr;
176
+ }
177
+ _shares_traverser_orchestrator = false;
178
+ return _orchestrator;
179
+ }
180
+
181
+ ssize_t Entry::Impl::read(void *buffer, size_t length) {
182
+ if (!ensure_orchestrator()) {
183
+ emit_fault("Failed to initialize ArchiveStackOrchestrator");
184
+ return -1;
185
+ }
186
+ const ssize_t bytes_read = _orchestrator->read_head(buffer, length);
187
+ if (bytes_read < 0) {
188
+ emit_fault("Failed to read entry content");
189
+ return -1;
190
+ }
191
+
192
+ _descend_enabled = false; // Require explicit re-enable before descending again
193
+
194
+ return bytes_read;
195
+ }
196
+
197
+ // ============================================================================
198
+ // Entry Public API Implementation
199
+ // ============================================================================
200
+
201
+ 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)) {}
203
+
204
+ Entry::Entry(Impl *impl)
205
+ : _impl(impl) {}
206
+
207
+ Entry::~Entry() = default;
208
+
209
+ std::unique_ptr<Entry> Entry::create(PathHierarchy hierarchy, std::shared_ptr<ArchiveStackOrchestrator> data_source_orchestrator, bool default_descent) {
210
+ return std::unique_ptr<Entry>(new Entry(hierarchy, std::move(data_source_orchestrator), default_descent));
211
+ }
212
+
213
+ // Copy operations - creates a new Impl copy
214
+ Entry::Entry(const Entry &other)
215
+ : _impl(other._impl ? std::make_unique<Impl>(*other._impl) : nullptr) {}
216
+
217
+ Entry &Entry::operator=(const Entry &other) {
218
+ if (this != &other) {
219
+ _impl = other._impl ? std::make_unique<Impl>(*other._impl) : nullptr;
220
+ }
221
+ return *this;
222
+ }
223
+
224
+ Entry::Entry(Entry &&) noexcept = default;
225
+ Entry &Entry::operator=(Entry &&) noexcept = default;
226
+
227
+ std::string Entry::name() const { return _impl->name(); }
228
+
229
+ std::string Entry::path() const { return hierarchy_display(_impl->path_hierarchy()); }
230
+
231
+ const PathHierarchy &Entry::path_hierarchy() const { return _impl->path_hierarchy(); }
232
+
233
+ bool Entry::is_directory() const { return _impl->is_directory(); }
234
+
235
+ bool Entry::is_file() const { return _impl->is_file(); }
236
+
237
+ uint64_t Entry::size() const { return _impl->size(); }
238
+
239
+ size_t Entry::depth() const { return _impl->depth(); }
240
+
241
+ ssize_t Entry::read(void *buffer, size_t length) { return _impl->read(buffer, length); }
242
+
243
+ void Entry::set_descent(bool enabled) { _impl->set_descent(enabled); }
244
+
245
+ bool Entry::descent_enabled() const { return _impl->descent_enabled(); }
246
+
247
+ void Entry::set_multi_volume_group(const std::string &base_name, const MultiVolumeGroupOptions &options) { _impl->set_multi_volume_group(base_name, options); }
248
+
249
+ const EntryMetadataMap &Entry::metadata() const { return _impl->metadata(); }
250
+
251
+ const EntryMetadataValue *Entry::find_metadata(const std::string &key) const { return _impl->metadata_value(key); }
252
+
253
+ } // namespace archive_r
@@ -1,26 +1,26 @@
1
- // SPDX-License-Identifier: MIT
2
- // Copyright (c) 2025 archive_r Team
3
-
4
- #include "archive_r/entry_fault.h"
5
-
6
- #include <atomic>
7
- #include <memory>
8
-
9
- namespace archive_r {
10
- namespace {
11
- std::shared_ptr<const FaultCallback> g_fault_callback = std::make_shared<const FaultCallback>();
12
- }
13
-
14
- void register_fault_callback(FaultCallback callback) {
15
- auto new_callback = std::make_shared<const FaultCallback>(std::move(callback));
16
- std::atomic_store_explicit(&g_fault_callback, std::move(new_callback), std::memory_order_release);
17
- }
18
-
19
- void dispatch_registered_fault(const EntryFault &fault) {
20
- auto callback = std::atomic_load_explicit(&g_fault_callback, std::memory_order_acquire);
21
- if (callback && *callback) {
22
- (*callback)(fault);
23
- }
24
- }
25
-
26
- } // namespace archive_r
1
+ // SPDX-License-Identifier: MIT
2
+ // Copyright (c) 2025 archive_r Team
3
+
4
+ #include "archive_r/entry_fault.h"
5
+
6
+ #include <atomic>
7
+ #include <memory>
8
+
9
+ namespace archive_r {
10
+ namespace {
11
+ std::shared_ptr<const FaultCallback> g_fault_callback = std::make_shared<const FaultCallback>();
12
+ }
13
+
14
+ void register_fault_callback(FaultCallback callback) {
15
+ auto new_callback = std::make_shared<const FaultCallback>(std::move(callback));
16
+ std::atomic_store_explicit(&g_fault_callback, std::move(new_callback), std::memory_order_release);
17
+ }
18
+
19
+ void dispatch_registered_fault(const EntryFault &fault) {
20
+ auto callback = std::atomic_load_explicit(&g_fault_callback, std::memory_order_acquire);
21
+ if (callback && *callback) {
22
+ (*callback)(fault);
23
+ }
24
+ }
25
+
26
+ } // namespace archive_r
@@ -1,54 +1,54 @@
1
- // SPDX-License-Identifier: MIT
2
- // Copyright (c) 2025 archive_r Team
3
-
4
- #include "entry_fault_error.h"
5
-
6
- #include <cstring>
7
- #include <string>
8
- #include <utility>
9
-
10
- namespace archive_r {
11
-
12
- EntryFaultError::EntryFaultError(EntryFault fault)
13
- : std::runtime_error(fault.message)
14
- , _fault(std::move(fault)) {}
15
-
16
- EntryFaultError::EntryFaultError(EntryFault fault, const std::string &internal_message)
17
- : std::runtime_error(internal_message.empty() ? fault.message : internal_message)
18
- , _fault(std::move(fault)) {}
19
-
20
- EntryFaultError make_entry_fault_error(const std::string &message, PathHierarchy hierarchy, int errno_value) {
21
- EntryFault fault;
22
- fault.hierarchy = std::move(hierarchy);
23
- fault.message = message;
24
- fault.errno_value = errno_value;
25
- return EntryFaultError(std::move(fault));
26
- }
27
-
28
- std::string format_errno_error(const std::string &prefix, int err) {
29
- if (err == 0) {
30
- return prefix;
31
- }
32
-
33
- std::string message = prefix;
34
- message.append(": ");
35
- message.append(std::strerror(err));
36
- message.append(" (posix errno=");
37
- message.append(std::to_string(err));
38
- message.push_back(')');
39
- return message;
40
- }
41
-
42
- std::string format_path_errno_error(const std::string &action, const std::string &path, int err) {
43
- std::string prefix = action;
44
- if (!path.empty()) {
45
- prefix.append(" '");
46
- prefix.append(path);
47
- prefix.push_back('\'');
48
- }
49
- return format_errno_error(prefix, err);
50
- }
51
-
52
- std::string prefer_error_detail(const std::string &detail, const std::string &fallback) { return detail.empty() ? fallback : detail; }
53
-
54
- } // namespace archive_r
1
+ // SPDX-License-Identifier: MIT
2
+ // Copyright (c) 2025 archive_r Team
3
+
4
+ #include "entry_fault_error.h"
5
+
6
+ #include <cstring>
7
+ #include <string>
8
+ #include <utility>
9
+
10
+ namespace archive_r {
11
+
12
+ EntryFaultError::EntryFaultError(EntryFault fault)
13
+ : std::runtime_error(fault.message)
14
+ , _fault(std::move(fault)) {}
15
+
16
+ EntryFaultError::EntryFaultError(EntryFault fault, const std::string &internal_message)
17
+ : std::runtime_error(internal_message.empty() ? fault.message : internal_message)
18
+ , _fault(std::move(fault)) {}
19
+
20
+ EntryFaultError make_entry_fault_error(const std::string &message, PathHierarchy hierarchy, int errno_value) {
21
+ EntryFault fault;
22
+ fault.hierarchy = std::move(hierarchy);
23
+ fault.message = message;
24
+ fault.errno_value = errno_value;
25
+ return EntryFaultError(std::move(fault));
26
+ }
27
+
28
+ std::string format_errno_error(const std::string &prefix, int err) {
29
+ if (err == 0) {
30
+ return prefix;
31
+ }
32
+
33
+ std::string message = prefix;
34
+ message.append(": ");
35
+ message.append(std::strerror(err));
36
+ message.append(" (posix errno=");
37
+ message.append(std::to_string(err));
38
+ message.push_back(')');
39
+ return message;
40
+ }
41
+
42
+ std::string format_path_errno_error(const std::string &action, const std::string &path, int err) {
43
+ std::string prefix = action;
44
+ if (!path.empty()) {
45
+ prefix.append(" '");
46
+ prefix.append(path);
47
+ prefix.push_back('\'');
48
+ }
49
+ return format_errno_error(prefix, err);
50
+ }
51
+
52
+ std::string prefer_error_detail(const std::string &detail, const std::string &fallback) { return detail.empty() ? fallback : detail; }
53
+
54
+ } // namespace archive_r