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,295 +1,295 @@
1
- // SPDX-License-Identifier: MIT
2
- // Copyright (c) 2025 archive_r Team
3
-
4
- #include "system_file_stream.h"
5
- #include "archive_r/path_hierarchy_utils.h"
6
- #include "archive_r/platform_compat.h"
7
- #include "entry_fault_error.h"
8
-
9
- #include <algorithm>
10
- #include <cerrno>
11
- #include <cstdio>
12
- #include <filesystem>
13
- #include <stdexcept>
14
- #include <sys/stat.h>
15
- #include <system_error>
16
- #include <string_view>
17
- #include <utility>
18
- #include <vector>
19
-
20
- #if !defined(_WIN32)
21
- # include <grp.h>
22
- # include <pwd.h>
23
- # include <unistd.h>
24
- #endif
25
-
26
- namespace archive_r {
27
-
28
- namespace {
29
-
30
- #if !defined(_WIN32)
31
- static long determine_buffer_size(int name) {
32
- long size = ::sysconf(name);
33
- if (size < 0) {
34
- size = 16384; // Fallback for systems without a specific limit
35
- }
36
- return size;
37
- }
38
-
39
- static bool lookup_username(uid_t uid, std::string &name_out) {
40
- const long buf_size = determine_buffer_size(_SC_GETPW_R_SIZE_MAX);
41
- std::vector<char> buffer(static_cast<std::size_t>(buf_size));
42
- struct passwd pwd;
43
- struct passwd *result = nullptr;
44
-
45
- if (::getpwuid_r(uid, &pwd, buffer.data(), buffer.size(), &result) == 0 && result && result->pw_name) {
46
- name_out.assign(result->pw_name);
47
- return true;
48
- }
49
- return false;
50
- }
51
-
52
- static bool lookup_groupname(gid_t gid, std::string &name_out) {
53
- const long buf_size = determine_buffer_size(_SC_GETGR_R_SIZE_MAX);
54
- std::vector<char> buffer(static_cast<std::size_t>(buf_size));
55
- struct group grp;
56
- struct group *result = nullptr;
57
-
58
- if (::getgrgid_r(gid, &grp, buffer.data(), buffer.size(), &result) == 0 && result && result->gr_name) {
59
- name_out.assign(result->gr_name);
60
- return true;
61
- }
62
- return false;
63
- }
64
- #endif
65
-
66
- } // namespace
67
-
68
- SystemFileStream::SystemFileStream(PathHierarchy logical_path)
69
- : MultiVolumeStreamBase(std::move(logical_path), true)
70
- , _handle(nullptr) {
71
- if (_logical_path.empty()) {
72
- throw std::invalid_argument("Root file hierarchy cannot be empty");
73
- }
74
-
75
- const PathEntry &root_entry = _logical_path.front();
76
- if (!root_entry.is_single() && !root_entry.is_multi_volume()) {
77
- throw std::invalid_argument("Root file hierarchy must be a single file or multi-volume source");
78
- }
79
- }
80
-
81
- SystemFileStream::~SystemFileStream() = default;
82
-
83
- void SystemFileStream::open_single_part(const PathHierarchy &single_part) {
84
- const PathEntry &entry = single_part.back();
85
-
86
- const std::string path = entry.single_value();
87
- errno = 0;
88
- FILE *handle = std::fopen(path.c_str(), "rb");
89
- if (!handle) {
90
- const int err = errno;
91
- throw make_entry_fault_error(format_path_errno_error("Failed to open root file", path, err), single_part, err);
92
- }
93
-
94
- _handle = handle;
95
- _active_path = path;
96
-
97
- #if defined(_WIN32)
98
- // Enable larger buffering on Windows to improve performance
99
- // Use 64KB buffer to match StreamArchive's buffer size
100
- if (_handle) {
101
- std::setvbuf(_handle, nullptr, _IOFBF, 65536);
102
- }
103
- #endif
104
- }
105
-
106
- void SystemFileStream::close_single_part() {
107
- std::fclose(_handle);
108
- _handle = nullptr;
109
- _active_path.clear();
110
- }
111
-
112
- ssize_t SystemFileStream::read_from_single_part(void *buffer, size_t size) {
113
- errno = 0;
114
- const std::size_t bytes_read = std::fread(buffer, 1, size, _handle);
115
- if (bytes_read > 0) {
116
- return static_cast<ssize_t>(bytes_read);
117
- }
118
-
119
- if (std::feof(_handle)) {
120
- return 0;
121
- }
122
-
123
- if (std::ferror(_handle)) {
124
- report_read_failure(errno);
125
- }
126
- return -1;
127
- }
128
-
129
- int64_t SystemFileStream::seek_within_single_part(int64_t offset, int whence) {
130
- int64_t position = -1;
131
- #if defined(_WIN32)
132
- if (_fseeki64(_handle, offset, whence) == 0) {
133
- if (whence == SEEK_SET) {
134
- position = offset;
135
- } else {
136
- position = _ftelli64(_handle);
137
- }
138
- }
139
- #else
140
- if (fseeko(_handle, offset, whence) == 0) {
141
- if (whence == SEEK_SET) {
142
- position = offset;
143
- } else {
144
- position = ftello(_handle);
145
- }
146
- }
147
- #endif
148
- return position >= 0 ? position : -1;
149
- }
150
-
151
- int64_t SystemFileStream::size_of_single_part(const PathHierarchy &single_part) {
152
- const PathEntry &entry = single_part.back();
153
-
154
- struct stat st;
155
- if (::stat(entry.single_value().c_str(), &st) != 0) {
156
- return -1;
157
- }
158
- return static_cast<int64_t>(st.st_size);
159
- }
160
-
161
- void SystemFileStream::report_read_failure(int err) {
162
- const std::string detailed = format_path_errno_error("Failed to read root file", _active_path, err);
163
- close_single_part();
164
- throw make_entry_fault_error(detailed, _logical_path, err);
165
- }
166
-
167
- FilesystemMetadataInfo collect_root_path_metadata(const PathHierarchy &hierarchy, const std::unordered_set<std::string> &allowed_keys) {
168
- FilesystemMetadataInfo info;
169
-
170
- if (hierarchy.empty()) {
171
- return info;
172
- }
173
-
174
- std::error_code ec;
175
- const PathEntry &root_entry = hierarchy[0];
176
- if (!root_entry.is_single()) {
177
- return info;
178
- }
179
-
180
- const std::filesystem::path target(root_entry.single_value());
181
- std::filesystem::directory_entry entry(target, ec);
182
- if (ec) {
183
- return info;
184
- }
185
-
186
- mode_t filetype = 0;
187
- uint64_t size = 0;
188
-
189
- ec.clear();
190
- const bool is_regular = entry.is_regular_file(ec);
191
- if (!ec && is_regular) {
192
- ec.clear();
193
- size = entry.file_size(ec);
194
- if (ec) {
195
- size = 0;
196
- }
197
- filetype = S_IFREG;
198
- } else {
199
- ec.clear();
200
- const bool is_directory = entry.is_directory(ec);
201
- if (!ec && is_directory) {
202
- filetype = S_IFDIR;
203
- } else {
204
- ec.clear();
205
- const bool is_symlink = entry.is_symlink(ec);
206
- if (!ec && is_symlink) {
207
- #ifdef S_IFLNK
208
- filetype = S_IFLNK;
209
- #endif
210
- }
211
- }
212
- }
213
-
214
- info.size = size;
215
- info.filetype = filetype;
216
- EntryMetadataMap metadata;
217
- if (!allowed_keys.empty()) {
218
- const auto wants = [&allowed_keys](std::string_view key) {
219
- return allowed_keys.find(std::string(key)) != allowed_keys.end();
220
- };
221
-
222
- // Path hierarchy / directory entry derived metadata
223
- if (wants("pathname")) {
224
- const PathEntry &tail = hierarchy.back();
225
- if (tail.is_single()) {
226
- metadata["pathname"] = tail.single_value();
227
- } else {
228
- metadata["pathname"] = path_entry_display(tail);
229
- }
230
- }
231
-
232
- if (wants("filetype")) {
233
- metadata["filetype"] = static_cast<uint64_t>(filetype);
234
- }
235
-
236
- if (wants("mode")) {
237
- std::error_code status_ec;
238
- const auto status = entry.status(status_ec);
239
- if (!status_ec) {
240
- metadata["mode"] = static_cast<uint64_t>(status.permissions());
241
- }
242
- }
243
-
244
- const bool needs_stat = (wants("size") && size == 0)
245
- #if !defined(_WIN32)
246
- || wants("uid") || wants("gid") || wants("uname") || wants("gname")
247
- #endif
248
- ;
249
-
250
- struct stat stat_buffer;
251
- bool have_stat = false;
252
- if (needs_stat) {
253
- const std::string native_path = entry.path().string();
254
- have_stat = (::stat(native_path.c_str(), &stat_buffer) == 0);
255
- }
256
-
257
- if (wants("size")) {
258
- uint64_t resolved = size;
259
- if (resolved == 0 && have_stat) {
260
- resolved = static_cast<uint64_t>(stat_buffer.st_size);
261
- }
262
- if (resolved > 0 || (size == 0 && have_stat)) {
263
- metadata["size"] = resolved;
264
- }
265
- }
266
-
267
- #if !defined(_WIN32)
268
- if (have_stat) {
269
- if (wants("uid")) {
270
- metadata["uid"] = static_cast<int64_t>(stat_buffer.st_uid);
271
- }
272
- if (wants("gid")) {
273
- metadata["gid"] = static_cast<int64_t>(stat_buffer.st_gid);
274
- }
275
- if (wants("uname")) {
276
- std::string uname;
277
- if (lookup_username(stat_buffer.st_uid, uname)) {
278
- metadata["uname"] = std::move(uname);
279
- }
280
- }
281
- if (wants("gname")) {
282
- std::string gname;
283
- if (lookup_groupname(stat_buffer.st_gid, gname)) {
284
- metadata["gname"] = std::move(gname);
285
- }
286
- }
287
- }
288
- #endif
289
- }
290
-
291
- info.metadata = std::move(metadata);
292
- return info;
293
- }
294
-
295
- } // namespace archive_r
1
+ // SPDX-License-Identifier: MIT
2
+ // Copyright (c) 2025 archive_r Team
3
+
4
+ #include "system_file_stream.h"
5
+ #include "archive_r/path_hierarchy_utils.h"
6
+ #include "archive_r/platform_compat.h"
7
+ #include "entry_fault_error.h"
8
+
9
+ #include <algorithm>
10
+ #include <cerrno>
11
+ #include <cstdio>
12
+ #include <filesystem>
13
+ #include <stdexcept>
14
+ #include <sys/stat.h>
15
+ #include <system_error>
16
+ #include <string_view>
17
+ #include <utility>
18
+ #include <vector>
19
+
20
+ #if !defined(_WIN32)
21
+ # include <grp.h>
22
+ # include <pwd.h>
23
+ # include <unistd.h>
24
+ #endif
25
+
26
+ namespace archive_r {
27
+
28
+ namespace {
29
+
30
+ #if !defined(_WIN32)
31
+ static long determine_buffer_size(int name) {
32
+ long size = ::sysconf(name);
33
+ if (size < 0) {
34
+ size = 16384; // Fallback for systems without a specific limit
35
+ }
36
+ return size;
37
+ }
38
+
39
+ static bool lookup_username(uid_t uid, std::string &name_out) {
40
+ const long buf_size = determine_buffer_size(_SC_GETPW_R_SIZE_MAX);
41
+ std::vector<char> buffer(static_cast<std::size_t>(buf_size));
42
+ struct passwd pwd;
43
+ struct passwd *result = nullptr;
44
+
45
+ if (::getpwuid_r(uid, &pwd, buffer.data(), buffer.size(), &result) == 0 && result && result->pw_name) {
46
+ name_out.assign(result->pw_name);
47
+ return true;
48
+ }
49
+ return false;
50
+ }
51
+
52
+ static bool lookup_groupname(gid_t gid, std::string &name_out) {
53
+ const long buf_size = determine_buffer_size(_SC_GETGR_R_SIZE_MAX);
54
+ std::vector<char> buffer(static_cast<std::size_t>(buf_size));
55
+ struct group grp;
56
+ struct group *result = nullptr;
57
+
58
+ if (::getgrgid_r(gid, &grp, buffer.data(), buffer.size(), &result) == 0 && result && result->gr_name) {
59
+ name_out.assign(result->gr_name);
60
+ return true;
61
+ }
62
+ return false;
63
+ }
64
+ #endif
65
+
66
+ } // namespace
67
+
68
+ SystemFileStream::SystemFileStream(PathHierarchy logical_path)
69
+ : MultiVolumeStreamBase(std::move(logical_path), true)
70
+ , _handle(nullptr) {
71
+ if (_logical_path.empty()) {
72
+ throw std::invalid_argument("Root file hierarchy cannot be empty");
73
+ }
74
+
75
+ const PathEntry &root_entry = _logical_path.front();
76
+ if (!root_entry.is_single() && !root_entry.is_multi_volume()) {
77
+ throw std::invalid_argument("Root file hierarchy must be a single file or multi-volume source");
78
+ }
79
+ }
80
+
81
+ SystemFileStream::~SystemFileStream() = default;
82
+
83
+ void SystemFileStream::open_single_part(const PathHierarchy &single_part) {
84
+ const PathEntry &entry = single_part.back();
85
+
86
+ const std::string path = entry.single_value();
87
+ errno = 0;
88
+ FILE *handle = std::fopen(path.c_str(), "rb");
89
+ if (!handle) {
90
+ const int err = errno;
91
+ throw make_entry_fault_error(format_path_errno_error("Failed to open root file", path, err), single_part, err);
92
+ }
93
+
94
+ _handle = handle;
95
+ _active_path = path;
96
+
97
+ #if defined(_WIN32)
98
+ // Enable larger buffering on Windows to improve performance
99
+ // Use 64KB buffer to match StreamArchive's buffer size
100
+ if (_handle) {
101
+ std::setvbuf(_handle, nullptr, _IOFBF, 65536);
102
+ }
103
+ #endif
104
+ }
105
+
106
+ void SystemFileStream::close_single_part() {
107
+ std::fclose(_handle);
108
+ _handle = nullptr;
109
+ _active_path.clear();
110
+ }
111
+
112
+ ssize_t SystemFileStream::read_from_single_part(void *buffer, size_t size) {
113
+ errno = 0;
114
+ const std::size_t bytes_read = std::fread(buffer, 1, size, _handle);
115
+ if (bytes_read > 0) {
116
+ return static_cast<ssize_t>(bytes_read);
117
+ }
118
+
119
+ if (std::feof(_handle)) {
120
+ return 0;
121
+ }
122
+
123
+ if (std::ferror(_handle)) {
124
+ report_read_failure(errno);
125
+ }
126
+ return -1;
127
+ }
128
+
129
+ int64_t SystemFileStream::seek_within_single_part(int64_t offset, int whence) {
130
+ int64_t position = -1;
131
+ #if defined(_WIN32)
132
+ if (_fseeki64(_handle, offset, whence) == 0) {
133
+ if (whence == SEEK_SET) {
134
+ position = offset;
135
+ } else {
136
+ position = _ftelli64(_handle);
137
+ }
138
+ }
139
+ #else
140
+ if (fseeko(_handle, offset, whence) == 0) {
141
+ if (whence == SEEK_SET) {
142
+ position = offset;
143
+ } else {
144
+ position = ftello(_handle);
145
+ }
146
+ }
147
+ #endif
148
+ return position >= 0 ? position : -1;
149
+ }
150
+
151
+ int64_t SystemFileStream::size_of_single_part(const PathHierarchy &single_part) {
152
+ const PathEntry &entry = single_part.back();
153
+
154
+ struct stat st;
155
+ if (::stat(entry.single_value().c_str(), &st) != 0) {
156
+ return -1;
157
+ }
158
+ return static_cast<int64_t>(st.st_size);
159
+ }
160
+
161
+ void SystemFileStream::report_read_failure(int err) {
162
+ const std::string detailed = format_path_errno_error("Failed to read root file", _active_path, err);
163
+ close_single_part();
164
+ throw make_entry_fault_error(detailed, _logical_path, err);
165
+ }
166
+
167
+ FilesystemMetadataInfo collect_root_path_metadata(const PathHierarchy &hierarchy, const std::unordered_set<std::string> &allowed_keys) {
168
+ FilesystemMetadataInfo info;
169
+
170
+ if (hierarchy.empty()) {
171
+ return info;
172
+ }
173
+
174
+ std::error_code ec;
175
+ const PathEntry &root_entry = hierarchy[0];
176
+ if (!root_entry.is_single()) {
177
+ return info;
178
+ }
179
+
180
+ const std::filesystem::path target(root_entry.single_value());
181
+ std::filesystem::directory_entry entry(target, ec);
182
+ if (ec) {
183
+ return info;
184
+ }
185
+
186
+ mode_t filetype = 0;
187
+ uint64_t size = 0;
188
+
189
+ ec.clear();
190
+ const bool is_regular = entry.is_regular_file(ec);
191
+ if (!ec && is_regular) {
192
+ ec.clear();
193
+ size = entry.file_size(ec);
194
+ if (ec) {
195
+ size = 0;
196
+ }
197
+ filetype = S_IFREG;
198
+ } else {
199
+ ec.clear();
200
+ const bool is_directory = entry.is_directory(ec);
201
+ if (!ec && is_directory) {
202
+ filetype = S_IFDIR;
203
+ } else {
204
+ ec.clear();
205
+ const bool is_symlink = entry.is_symlink(ec);
206
+ if (!ec && is_symlink) {
207
+ #ifdef S_IFLNK
208
+ filetype = S_IFLNK;
209
+ #endif
210
+ }
211
+ }
212
+ }
213
+
214
+ info.size = size;
215
+ info.filetype = filetype;
216
+ EntryMetadataMap metadata;
217
+ if (!allowed_keys.empty()) {
218
+ const auto wants = [&allowed_keys](std::string_view key) {
219
+ return allowed_keys.find(std::string(key)) != allowed_keys.end();
220
+ };
221
+
222
+ // Path hierarchy / directory entry derived metadata
223
+ if (wants("pathname")) {
224
+ const PathEntry &tail = hierarchy.back();
225
+ if (tail.is_single()) {
226
+ metadata["pathname"] = tail.single_value();
227
+ } else {
228
+ metadata["pathname"] = path_entry_display(tail);
229
+ }
230
+ }
231
+
232
+ if (wants("filetype")) {
233
+ metadata["filetype"] = static_cast<uint64_t>(filetype);
234
+ }
235
+
236
+ if (wants("mode")) {
237
+ std::error_code status_ec;
238
+ const auto status = entry.status(status_ec);
239
+ if (!status_ec) {
240
+ metadata["mode"] = static_cast<uint64_t>(status.permissions());
241
+ }
242
+ }
243
+
244
+ const bool needs_stat = (wants("size") && size == 0)
245
+ #if !defined(_WIN32)
246
+ || wants("uid") || wants("gid") || wants("uname") || wants("gname")
247
+ #endif
248
+ ;
249
+
250
+ struct stat stat_buffer;
251
+ bool have_stat = false;
252
+ if (needs_stat) {
253
+ const std::string native_path = entry.path().string();
254
+ have_stat = (::stat(native_path.c_str(), &stat_buffer) == 0);
255
+ }
256
+
257
+ if (wants("size")) {
258
+ uint64_t resolved = size;
259
+ if (resolved == 0 && have_stat) {
260
+ resolved = static_cast<uint64_t>(stat_buffer.st_size);
261
+ }
262
+ if (resolved > 0 || (size == 0 && have_stat)) {
263
+ metadata["size"] = resolved;
264
+ }
265
+ }
266
+
267
+ #if !defined(_WIN32)
268
+ if (have_stat) {
269
+ if (wants("uid")) {
270
+ metadata["uid"] = static_cast<int64_t>(stat_buffer.st_uid);
271
+ }
272
+ if (wants("gid")) {
273
+ metadata["gid"] = static_cast<int64_t>(stat_buffer.st_gid);
274
+ }
275
+ if (wants("uname")) {
276
+ std::string uname;
277
+ if (lookup_username(stat_buffer.st_uid, uname)) {
278
+ metadata["uname"] = std::move(uname);
279
+ }
280
+ }
281
+ if (wants("gname")) {
282
+ std::string gname;
283
+ if (lookup_groupname(stat_buffer.st_gid, gname)) {
284
+ metadata["gname"] = std::move(gname);
285
+ }
286
+ }
287
+ }
288
+ #endif
289
+ }
290
+
291
+ info.metadata = std::move(metadata);
292
+ return info;
293
+ }
294
+
295
+ } // namespace archive_r
@@ -1,46 +1,46 @@
1
- // SPDX-License-Identifier: MIT
2
- // Copyright (c) 2025 archive_r Team
3
-
4
- #pragma once
5
-
6
- #include <cstddef>
7
- #include <cstdio>
8
- #include <filesystem>
9
- #include <string>
10
- #include <unordered_set>
11
- #include <vector>
12
-
13
- #include "archive_r/multi_volume_stream_base.h"
14
- #include "archive_r/platform_compat.h"
15
- #include "archive_r/entry_metadata.h"
16
- #include "archive_r/path_hierarchy.h"
17
-
18
- namespace archive_r {
19
-
20
- class SystemFileStream : public MultiVolumeStreamBase {
21
- public:
22
- explicit SystemFileStream(PathHierarchy logical_path);
23
- ~SystemFileStream() override;
24
-
25
- private:
26
- void open_single_part(const PathHierarchy &single_part) override;
27
- void close_single_part() override;
28
- ssize_t read_from_single_part(void *buffer, size_t size) override;
29
- int64_t seek_within_single_part(int64_t offset, int whence) override;
30
- int64_t size_of_single_part(const PathHierarchy &single_part) override;
31
-
32
- void report_read_failure(int err);
33
-
34
- FILE *_handle;
35
- std::string _active_path;
36
- };
37
-
38
- struct FilesystemMetadataInfo {
39
- uint64_t size = 0;
40
- mode_t filetype = 0;
41
- EntryMetadataMap metadata;
42
- };
43
-
44
- FilesystemMetadataInfo collect_root_path_metadata(const PathHierarchy &hierarchy, const std::unordered_set<std::string> &allowed_keys);
45
-
46
- } // namespace archive_r
1
+ // SPDX-License-Identifier: MIT
2
+ // Copyright (c) 2025 archive_r Team
3
+
4
+ #pragma once
5
+
6
+ #include <cstddef>
7
+ #include <cstdio>
8
+ #include <filesystem>
9
+ #include <string>
10
+ #include <unordered_set>
11
+ #include <vector>
12
+
13
+ #include "archive_r/multi_volume_stream_base.h"
14
+ #include "archive_r/platform_compat.h"
15
+ #include "archive_r/entry_metadata.h"
16
+ #include "archive_r/path_hierarchy.h"
17
+
18
+ namespace archive_r {
19
+
20
+ class SystemFileStream : public MultiVolumeStreamBase {
21
+ public:
22
+ explicit SystemFileStream(PathHierarchy logical_path);
23
+ ~SystemFileStream() override;
24
+
25
+ private:
26
+ void open_single_part(const PathHierarchy &single_part) override;
27
+ void close_single_part() override;
28
+ ssize_t read_from_single_part(void *buffer, size_t size) override;
29
+ int64_t seek_within_single_part(int64_t offset, int whence) override;
30
+ int64_t size_of_single_part(const PathHierarchy &single_part) override;
31
+
32
+ void report_read_failure(int err);
33
+
34
+ FILE *_handle;
35
+ std::string _active_path;
36
+ };
37
+
38
+ struct FilesystemMetadataInfo {
39
+ uint64_t size = 0;
40
+ mode_t filetype = 0;
41
+ EntryMetadataMap metadata;
42
+ };
43
+
44
+ FilesystemMetadataInfo collect_root_path_metadata(const PathHierarchy &hierarchy, const std::unordered_set<std::string> &allowed_keys);
45
+
46
+ } // namespace archive_r