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.
- checksums.yaml +4 -4
- data/{LICENSE → LICENSE.txt} +77 -77
- data/README.md +103 -103
- data/ext/archive_r/Makefile +48 -45
- data/ext/archive_r/archive_r-x64-mingw-ucrt.def +2 -0
- data/ext/archive_r/archive_r_ext.cc +1106 -1106
- data/ext/archive_r/archive_r_ext.o +0 -0
- data/ext/archive_r/extconf.rb +120 -120
- data/ext/archive_r/mkmf.log +23 -18
- data/ext/archive_r/vendor/archive_r/LICENSE.txt +77 -77
- data/ext/archive_r/vendor/archive_r/include/archive_r/data_stream.h +52 -52
- data/ext/archive_r/vendor/archive_r/include/archive_r/entry.h +166 -166
- data/ext/archive_r/vendor/archive_r/include/archive_r/entry_fault.h +34 -34
- data/ext/archive_r/vendor/archive_r/include/archive_r/entry_metadata.h +56 -56
- data/ext/archive_r/vendor/archive_r/include/archive_r/multi_volume_stream_base.h +46 -46
- data/ext/archive_r/vendor/archive_r/include/archive_r/path_hierarchy.h +109 -109
- data/ext/archive_r/vendor/archive_r/include/archive_r/path_hierarchy_utils.h +37 -37
- data/ext/archive_r/vendor/archive_r/include/archive_r/platform_compat.h +19 -19
- data/ext/archive_r/vendor/archive_r/include/archive_r/traverser.h +122 -122
- data/ext/archive_r/vendor/archive_r/src/archive_stack_cursor.cc +330 -330
- data/ext/archive_r/vendor/archive_r/src/archive_stack_cursor.h +97 -97
- data/ext/archive_r/vendor/archive_r/src/archive_stack_orchestrator.cc +162 -162
- data/ext/archive_r/vendor/archive_r/src/archive_stack_orchestrator.h +54 -54
- data/ext/archive_r/vendor/archive_r/src/archive_type.cc +552 -552
- data/ext/archive_r/vendor/archive_r/src/archive_type.h +77 -77
- data/ext/archive_r/vendor/archive_r/src/data_stream.cc +35 -35
- data/ext/archive_r/vendor/archive_r/src/entry.cc +253 -253
- data/ext/archive_r/vendor/archive_r/src/entry_fault.cc +26 -26
- data/ext/archive_r/vendor/archive_r/src/entry_fault_error.cc +54 -54
- data/ext/archive_r/vendor/archive_r/src/entry_fault_error.h +32 -32
- data/ext/archive_r/vendor/archive_r/src/entry_impl.h +57 -57
- data/ext/archive_r/vendor/archive_r/src/multi_volume_manager.cc +81 -81
- data/ext/archive_r/vendor/archive_r/src/multi_volume_manager.h +41 -41
- data/ext/archive_r/vendor/archive_r/src/multi_volume_stream_base.cc +199 -199
- data/ext/archive_r/vendor/archive_r/src/path_hierarchy.cc +151 -151
- data/ext/archive_r/vendor/archive_r/src/path_hierarchy_utils.cc +304 -304
- data/ext/archive_r/vendor/archive_r/src/simple_profiler.h +120 -120
- data/ext/archive_r/vendor/archive_r/src/system_file_stream.cc +295 -295
- data/ext/archive_r/vendor/archive_r/src/system_file_stream.h +46 -46
- data/ext/archive_r/vendor/archive_r/src/traverser.cc +314 -314
- data/lib/archive_r.rb +105 -105
- metadata +11 -8
- data/ext/archive_r/archive_r.bundle +0 -0
|
@@ -1,109 +1,109 @@
|
|
|
1
|
-
// SPDX-License-Identifier: MIT
|
|
2
|
-
// Copyright (c) 2025 archive_r Team
|
|
3
|
-
|
|
4
|
-
#pragma once
|
|
5
|
-
|
|
6
|
-
#include <cstddef>
|
|
7
|
-
#include <stdexcept>
|
|
8
|
-
#include <string>
|
|
9
|
-
#include <utility>
|
|
10
|
-
#include <variant>
|
|
11
|
-
#include <vector>
|
|
12
|
-
|
|
13
|
-
namespace archive_r {
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* @brief Represents a single component within a logical path hierarchy.
|
|
17
|
-
*
|
|
18
|
-
* A component can be one of three shapes:
|
|
19
|
-
* - single string value (most common)
|
|
20
|
-
* - multi-volume part list (split archives that share a common base name)
|
|
21
|
-
* - nested list of child entries (used for synthetic grouping)
|
|
22
|
-
*/
|
|
23
|
-
class PathEntry {
|
|
24
|
-
public:
|
|
25
|
-
struct Parts {
|
|
26
|
-
std::vector<std::string> values;
|
|
27
|
-
enum class Ordering { Natural, Given } ordering = Ordering::Natural;
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
using NodeList = std::vector<PathEntry>;
|
|
31
|
-
|
|
32
|
-
PathEntry() = default;
|
|
33
|
-
|
|
34
|
-
explicit PathEntry(std::string value)
|
|
35
|
-
: _value(std::move(value)) {}
|
|
36
|
-
|
|
37
|
-
explicit PathEntry(Parts parts)
|
|
38
|
-
: _value(std::move(parts)) {}
|
|
39
|
-
|
|
40
|
-
explicit PathEntry(NodeList nodes)
|
|
41
|
-
: _value(std::move(nodes)) {}
|
|
42
|
-
|
|
43
|
-
static PathEntry single(std::string entry) { return PathEntry(std::move(entry)); }
|
|
44
|
-
|
|
45
|
-
static PathEntry multi_volume(std::vector<std::string> entries, Parts::Ordering ordering = Parts::Ordering::Natural) {
|
|
46
|
-
Parts parts{ std::move(entries), ordering };
|
|
47
|
-
if (parts.values.empty()) {
|
|
48
|
-
throw std::invalid_argument("multi-volume parts cannot be empty");
|
|
49
|
-
}
|
|
50
|
-
return PathEntry(std::move(parts));
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
static PathEntry nested(NodeList hierarchies) {
|
|
54
|
-
if (hierarchies.empty()) {
|
|
55
|
-
throw std::invalid_argument("nested hierarchies cannot be empty");
|
|
56
|
-
}
|
|
57
|
-
return PathEntry(std::move(hierarchies));
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
bool is_single() const { return std::holds_alternative<std::string>(_value); }
|
|
61
|
-
bool is_multi_volume() const { return std::holds_alternative<Parts>(_value); }
|
|
62
|
-
bool is_nested() const { return std::holds_alternative<NodeList>(_value); }
|
|
63
|
-
const std::string &single_value() const { return std::get<std::string>(_value); }
|
|
64
|
-
const Parts &multi_volume_parts() const { return std::get<Parts>(_value); }
|
|
65
|
-
Parts &multi_volume_parts_mut() { return std::get<Parts>(_value); }
|
|
66
|
-
const NodeList &nested_nodes() const { return std::get<NodeList>(_value); }
|
|
67
|
-
NodeList &nested_nodes_mut() { return std::get<NodeList>(_value); }
|
|
68
|
-
|
|
69
|
-
private:
|
|
70
|
-
std::variant<std::string, Parts, NodeList> _value;
|
|
71
|
-
};
|
|
72
|
-
|
|
73
|
-
using PathHierarchy = std::vector<PathEntry>;
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* Compare two entries using the ordering enforced throughout archive_r.
|
|
77
|
-
*
|
|
78
|
-
* Ordering rules:
|
|
79
|
-
* 1. Entry categories are ordered single < multi-volume < nested node-list.
|
|
80
|
-
* 2. Single entries compare by string value.
|
|
81
|
-
* 3. Multi-volume entries first compare their ordering flag (Natural < Given),
|
|
82
|
-
* then compare corresponding part names lexicographically, finally by list length.
|
|
83
|
-
* 4. Nested node-lists compare child entries pairwise using the same rules.
|
|
84
|
-
*/
|
|
85
|
-
int compare_entries(const PathEntry &lhs, const PathEntry &rhs);
|
|
86
|
-
|
|
87
|
-
/** Compare complete hierarchies lexicographically using compare_entries on each level. */
|
|
88
|
-
int compare_hierarchies(const PathHierarchy &lhs, const PathHierarchy &rhs);
|
|
89
|
-
|
|
90
|
-
/** Shorthand equality helpers for entries and hierarchies. */
|
|
91
|
-
bool entries_equal(const PathEntry &lhs, const PathEntry &rhs);
|
|
92
|
-
bool hierarchies_equal(const PathHierarchy &lhs, const PathHierarchy &rhs);
|
|
93
|
-
|
|
94
|
-
/** Strict-weak-order functor suitable for associative containers. */
|
|
95
|
-
struct PathHierarchyLess {
|
|
96
|
-
bool operator()(const PathHierarchy &lhs, const PathHierarchy &rhs) const;
|
|
97
|
-
};
|
|
98
|
-
|
|
99
|
-
/** Build a hierarchy containing a single leaf component. */
|
|
100
|
-
PathHierarchy make_single_path(const std::string &root);
|
|
101
|
-
|
|
102
|
-
/** Append helpers for single and multi-volume components. */
|
|
103
|
-
void append_single(PathHierarchy &hierarchy, std::string value);
|
|
104
|
-
void append_multi_volume(PathHierarchy &hierarchy, std::vector<std::string> parts, PathEntry::Parts::Ordering ordering = PathEntry::Parts::Ordering::Natural);
|
|
105
|
-
|
|
106
|
-
/** Extract prefix/slice helpers. */
|
|
107
|
-
PathHierarchy pathhierarchy_prefix_until(const PathHierarchy &hierarchy, size_t inclusive_index);
|
|
108
|
-
PathHierarchy parent_hierarchy(const PathHierarchy &hierarchy);
|
|
109
|
-
} // 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 <stdexcept>
|
|
8
|
+
#include <string>
|
|
9
|
+
#include <utility>
|
|
10
|
+
#include <variant>
|
|
11
|
+
#include <vector>
|
|
12
|
+
|
|
13
|
+
namespace archive_r {
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* @brief Represents a single component within a logical path hierarchy.
|
|
17
|
+
*
|
|
18
|
+
* A component can be one of three shapes:
|
|
19
|
+
* - single string value (most common)
|
|
20
|
+
* - multi-volume part list (split archives that share a common base name)
|
|
21
|
+
* - nested list of child entries (used for synthetic grouping)
|
|
22
|
+
*/
|
|
23
|
+
class PathEntry {
|
|
24
|
+
public:
|
|
25
|
+
struct Parts {
|
|
26
|
+
std::vector<std::string> values;
|
|
27
|
+
enum class Ordering { Natural, Given } ordering = Ordering::Natural;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
using NodeList = std::vector<PathEntry>;
|
|
31
|
+
|
|
32
|
+
PathEntry() = default;
|
|
33
|
+
|
|
34
|
+
explicit PathEntry(std::string value)
|
|
35
|
+
: _value(std::move(value)) {}
|
|
36
|
+
|
|
37
|
+
explicit PathEntry(Parts parts)
|
|
38
|
+
: _value(std::move(parts)) {}
|
|
39
|
+
|
|
40
|
+
explicit PathEntry(NodeList nodes)
|
|
41
|
+
: _value(std::move(nodes)) {}
|
|
42
|
+
|
|
43
|
+
static PathEntry single(std::string entry) { return PathEntry(std::move(entry)); }
|
|
44
|
+
|
|
45
|
+
static PathEntry multi_volume(std::vector<std::string> entries, Parts::Ordering ordering = Parts::Ordering::Natural) {
|
|
46
|
+
Parts parts{ std::move(entries), ordering };
|
|
47
|
+
if (parts.values.empty()) {
|
|
48
|
+
throw std::invalid_argument("multi-volume parts cannot be empty");
|
|
49
|
+
}
|
|
50
|
+
return PathEntry(std::move(parts));
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
static PathEntry nested(NodeList hierarchies) {
|
|
54
|
+
if (hierarchies.empty()) {
|
|
55
|
+
throw std::invalid_argument("nested hierarchies cannot be empty");
|
|
56
|
+
}
|
|
57
|
+
return PathEntry(std::move(hierarchies));
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
bool is_single() const { return std::holds_alternative<std::string>(_value); }
|
|
61
|
+
bool is_multi_volume() const { return std::holds_alternative<Parts>(_value); }
|
|
62
|
+
bool is_nested() const { return std::holds_alternative<NodeList>(_value); }
|
|
63
|
+
const std::string &single_value() const { return std::get<std::string>(_value); }
|
|
64
|
+
const Parts &multi_volume_parts() const { return std::get<Parts>(_value); }
|
|
65
|
+
Parts &multi_volume_parts_mut() { return std::get<Parts>(_value); }
|
|
66
|
+
const NodeList &nested_nodes() const { return std::get<NodeList>(_value); }
|
|
67
|
+
NodeList &nested_nodes_mut() { return std::get<NodeList>(_value); }
|
|
68
|
+
|
|
69
|
+
private:
|
|
70
|
+
std::variant<std::string, Parts, NodeList> _value;
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
using PathHierarchy = std::vector<PathEntry>;
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Compare two entries using the ordering enforced throughout archive_r.
|
|
77
|
+
*
|
|
78
|
+
* Ordering rules:
|
|
79
|
+
* 1. Entry categories are ordered single < multi-volume < nested node-list.
|
|
80
|
+
* 2. Single entries compare by string value.
|
|
81
|
+
* 3. Multi-volume entries first compare their ordering flag (Natural < Given),
|
|
82
|
+
* then compare corresponding part names lexicographically, finally by list length.
|
|
83
|
+
* 4. Nested node-lists compare child entries pairwise using the same rules.
|
|
84
|
+
*/
|
|
85
|
+
int compare_entries(const PathEntry &lhs, const PathEntry &rhs);
|
|
86
|
+
|
|
87
|
+
/** Compare complete hierarchies lexicographically using compare_entries on each level. */
|
|
88
|
+
int compare_hierarchies(const PathHierarchy &lhs, const PathHierarchy &rhs);
|
|
89
|
+
|
|
90
|
+
/** Shorthand equality helpers for entries and hierarchies. */
|
|
91
|
+
bool entries_equal(const PathEntry &lhs, const PathEntry &rhs);
|
|
92
|
+
bool hierarchies_equal(const PathHierarchy &lhs, const PathHierarchy &rhs);
|
|
93
|
+
|
|
94
|
+
/** Strict-weak-order functor suitable for associative containers. */
|
|
95
|
+
struct PathHierarchyLess {
|
|
96
|
+
bool operator()(const PathHierarchy &lhs, const PathHierarchy &rhs) const;
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
/** Build a hierarchy containing a single leaf component. */
|
|
100
|
+
PathHierarchy make_single_path(const std::string &root);
|
|
101
|
+
|
|
102
|
+
/** Append helpers for single and multi-volume components. */
|
|
103
|
+
void append_single(PathHierarchy &hierarchy, std::string value);
|
|
104
|
+
void append_multi_volume(PathHierarchy &hierarchy, std::vector<std::string> parts, PathEntry::Parts::Ordering ordering = PathEntry::Parts::Ordering::Natural);
|
|
105
|
+
|
|
106
|
+
/** Extract prefix/slice helpers. */
|
|
107
|
+
PathHierarchy pathhierarchy_prefix_until(const PathHierarchy &hierarchy, size_t inclusive_index);
|
|
108
|
+
PathHierarchy parent_hierarchy(const PathHierarchy &hierarchy);
|
|
109
|
+
} // namespace archive_r
|
|
@@ -1,37 +1,37 @@
|
|
|
1
|
-
// SPDX-License-Identifier: MIT
|
|
2
|
-
// Copyright (c) 2025 archive_r Team
|
|
3
|
-
|
|
4
|
-
#pragma once
|
|
5
|
-
|
|
6
|
-
#include "archive_r/path_hierarchy.h"
|
|
7
|
-
#include <cstddef>
|
|
8
|
-
#include <string>
|
|
9
|
-
#include <vector>
|
|
10
|
-
|
|
11
|
-
namespace archive_r {
|
|
12
|
-
|
|
13
|
-
/** Return pointer to the Nth single value of an entry (nullptr if absent). */
|
|
14
|
-
const std::string *path_entry_component_at(const PathEntry &entry, std::size_t index);
|
|
15
|
-
|
|
16
|
-
/** Convenience helpers for multi-volume PathHierarchy nodes. */
|
|
17
|
-
std::size_t pathhierarchy_volume_size(const PathHierarchy &logical);
|
|
18
|
-
std::string pathhierarchy_volume_entry_name(const PathHierarchy &logical, std::size_t index);
|
|
19
|
-
bool pathhierarchy_is_multivolume(const PathHierarchy &hierarchy);
|
|
20
|
-
PathHierarchy pathhierarchy_select_single_part(const PathHierarchy &logical, std::size_t index);
|
|
21
|
-
|
|
22
|
-
/** Combine sibling hierarchies that differ only by their terminal part list. */
|
|
23
|
-
PathHierarchy merge_multi_volume_sources(const std::vector<PathHierarchy> &sources);
|
|
24
|
-
|
|
25
|
-
/** Sort hierarchies using PathHierarchyLess semantics. */
|
|
26
|
-
void sort_hierarchies(std::vector<PathHierarchy> &hierarchies);
|
|
27
|
-
|
|
28
|
-
/** Render helpers converting entries to flattened strings for diagnostics. */
|
|
29
|
-
bool flatten_entry_to_string(const PathEntry &entry, std::string &output);
|
|
30
|
-
bool entry_name_from_component(const PathEntry &entry, std::string &output);
|
|
31
|
-
|
|
32
|
-
/** Human readable pretty-printers used in logging and debug output. */
|
|
33
|
-
std::string path_entry_display(const PathEntry &entry);
|
|
34
|
-
std::string hierarchy_display(const PathHierarchy &hierarchy);
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
} // namespace archive_r
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
// Copyright (c) 2025 archive_r Team
|
|
3
|
+
|
|
4
|
+
#pragma once
|
|
5
|
+
|
|
6
|
+
#include "archive_r/path_hierarchy.h"
|
|
7
|
+
#include <cstddef>
|
|
8
|
+
#include <string>
|
|
9
|
+
#include <vector>
|
|
10
|
+
|
|
11
|
+
namespace archive_r {
|
|
12
|
+
|
|
13
|
+
/** Return pointer to the Nth single value of an entry (nullptr if absent). */
|
|
14
|
+
const std::string *path_entry_component_at(const PathEntry &entry, std::size_t index);
|
|
15
|
+
|
|
16
|
+
/** Convenience helpers for multi-volume PathHierarchy nodes. */
|
|
17
|
+
std::size_t pathhierarchy_volume_size(const PathHierarchy &logical);
|
|
18
|
+
std::string pathhierarchy_volume_entry_name(const PathHierarchy &logical, std::size_t index);
|
|
19
|
+
bool pathhierarchy_is_multivolume(const PathHierarchy &hierarchy);
|
|
20
|
+
PathHierarchy pathhierarchy_select_single_part(const PathHierarchy &logical, std::size_t index);
|
|
21
|
+
|
|
22
|
+
/** Combine sibling hierarchies that differ only by their terminal part list. */
|
|
23
|
+
PathHierarchy merge_multi_volume_sources(const std::vector<PathHierarchy> &sources);
|
|
24
|
+
|
|
25
|
+
/** Sort hierarchies using PathHierarchyLess semantics. */
|
|
26
|
+
void sort_hierarchies(std::vector<PathHierarchy> &hierarchies);
|
|
27
|
+
|
|
28
|
+
/** Render helpers converting entries to flattened strings for diagnostics. */
|
|
29
|
+
bool flatten_entry_to_string(const PathEntry &entry, std::string &output);
|
|
30
|
+
bool entry_name_from_component(const PathEntry &entry, std::string &output);
|
|
31
|
+
|
|
32
|
+
/** Human readable pretty-printers used in logging and debug output. */
|
|
33
|
+
std::string path_entry_display(const PathEntry &entry);
|
|
34
|
+
std::string hierarchy_display(const PathHierarchy &hierarchy);
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
} // namespace archive_r
|
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
// SPDX-License-Identifier: MIT
|
|
2
|
-
// Copyright (c) 2025 archive_r Team
|
|
3
|
-
|
|
4
|
-
#pragma once
|
|
5
|
-
|
|
6
|
-
#include <sys/types.h>
|
|
7
|
-
|
|
8
|
-
#if defined(_WIN32)
|
|
9
|
-
# include <sys/stat.h>
|
|
10
|
-
# if !defined(_SSIZE_T_DEFINED)
|
|
11
|
-
# include <BaseTsd.h>
|
|
12
|
-
using ssize_t = SSIZE_T;
|
|
13
|
-
# define _SSIZE_T_DEFINED
|
|
14
|
-
# endif
|
|
15
|
-
# if !defined(_MODE_T_DEFINED)
|
|
16
|
-
using mode_t = unsigned short; // MSVC does not expose POSIX mode_t by default
|
|
17
|
-
# define _MODE_T_DEFINED
|
|
18
|
-
# endif
|
|
19
|
-
#endif
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
// Copyright (c) 2025 archive_r Team
|
|
3
|
+
|
|
4
|
+
#pragma once
|
|
5
|
+
|
|
6
|
+
#include <sys/types.h>
|
|
7
|
+
|
|
8
|
+
#if defined(_WIN32)
|
|
9
|
+
# include <sys/stat.h>
|
|
10
|
+
# if !defined(_SSIZE_T_DEFINED)
|
|
11
|
+
# include <BaseTsd.h>
|
|
12
|
+
using ssize_t = SSIZE_T;
|
|
13
|
+
# define _SSIZE_T_DEFINED
|
|
14
|
+
# endif
|
|
15
|
+
# if !defined(_MODE_T_DEFINED)
|
|
16
|
+
using mode_t = unsigned short; // MSVC does not expose POSIX mode_t by default
|
|
17
|
+
# define _MODE_T_DEFINED
|
|
18
|
+
# endif
|
|
19
|
+
#endif
|
|
@@ -1,122 +1,122 @@
|
|
|
1
|
-
// SPDX-License-Identifier: MIT
|
|
2
|
-
// Copyright (c) 2025 archive_r Team
|
|
3
|
-
|
|
4
|
-
#pragma once
|
|
5
|
-
|
|
6
|
-
#include "archive_r/entry_fault.h"
|
|
7
|
-
#include "archive_r/path_hierarchy.h"
|
|
8
|
-
#include "entry.h"
|
|
9
|
-
#include <memory>
|
|
10
|
-
#include <string>
|
|
11
|
-
#include <vector>
|
|
12
|
-
|
|
13
|
-
namespace archive_r {
|
|
14
|
-
|
|
15
|
-
struct TraverserOptions {
|
|
16
|
-
std::vector<std::string> passphrases; ///< Passphrases for encrypted archives
|
|
17
|
-
std::vector<std::string> formats; ///< Specific archive formats to enable (empty = all)
|
|
18
|
-
std::vector<std::string> metadata_keys; ///< Metadata keys to capture for entries
|
|
19
|
-
bool descend_archives = true; ///< Whether to descend into archives by default
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* @brief Iterator-based traversal for archives and directories
|
|
24
|
-
*
|
|
25
|
-
* Traverser provides a unified iterator-based interface for traversing
|
|
26
|
-
* entries within archives and directories, including support for nested
|
|
27
|
-
* archives and automatic descent.
|
|
28
|
-
*
|
|
29
|
-
* Supports multiple archive formats via libarchive (tar, zip, gzip, etc.)
|
|
30
|
-
* and filesystem directories.
|
|
31
|
-
*
|
|
32
|
-
* Uses std::filesystem for directory traversal and ArchiveStackOrchestrator for archives.
|
|
33
|
-
|
|
34
|
-
* @see Entry, ArchiveStackOrchestrator
|
|
35
|
-
*
|
|
36
|
-
* Usage:
|
|
37
|
-
* Traverser traverser({make_single_path("archive.tar.gz")}); // or directory path
|
|
38
|
-
* for (Entry& entry : traverser) {
|
|
39
|
-
* // Process entry
|
|
40
|
-
* }
|
|
41
|
-
*
|
|
42
|
-
* @note Thread Safety
|
|
43
|
-
* Traverser instances are not thread-safe. To use the traverser in a
|
|
44
|
-
* multi-threaded environment, create a separate Traverser instance for each
|
|
45
|
-
* thread. Do not share a single instance across multiple threads.
|
|
46
|
-
*/
|
|
47
|
-
class Traverser {
|
|
48
|
-
public:
|
|
49
|
-
/**
|
|
50
|
-
* @brief Construct traverser for archives or directories
|
|
51
|
-
* @param paths Paths to archive files or directories
|
|
52
|
-
*
|
|
53
|
-
* Provide one or more paths to traverse. Single-path traversal can be
|
|
54
|
-
* achieved by passing a container with one element:
|
|
55
|
-
* Traverser traverser({make_single_path("archive.tar.gz")});
|
|
56
|
-
*/
|
|
57
|
-
explicit Traverser(std::vector<PathHierarchy> paths, TraverserOptions options = {});
|
|
58
|
-
|
|
59
|
-
~Traverser();
|
|
60
|
-
|
|
61
|
-
// Non-copyable
|
|
62
|
-
Traverser(const Traverser &) = delete;
|
|
63
|
-
Traverser &operator=(const Traverser &) = delete;
|
|
64
|
-
|
|
65
|
-
// ========================================================================
|
|
66
|
-
// Iterator API
|
|
67
|
-
// ========================================================================
|
|
68
|
-
|
|
69
|
-
/**
|
|
70
|
-
* @brief Forward iterator for traversing entries
|
|
71
|
-
*
|
|
72
|
-
* Satisfies InputIterator requirements:
|
|
73
|
-
* - Move-only (non-copyable)
|
|
74
|
-
* - Equality comparable
|
|
75
|
-
* - Dereferenceable (returns Entry&)
|
|
76
|
-
* - Incrementable
|
|
77
|
-
*/
|
|
78
|
-
class Iterator {
|
|
79
|
-
public:
|
|
80
|
-
using iterator_category = std::input_iterator_tag;
|
|
81
|
-
using value_type = Entry;
|
|
82
|
-
using difference_type = std::ptrdiff_t;
|
|
83
|
-
using pointer = Entry *;
|
|
84
|
-
using reference = Entry &;
|
|
85
|
-
|
|
86
|
-
reference operator*();
|
|
87
|
-
pointer operator->();
|
|
88
|
-
Iterator &operator++();
|
|
89
|
-
bool operator==(const Iterator &other) const;
|
|
90
|
-
bool operator!=(const Iterator &other) const;
|
|
91
|
-
|
|
92
|
-
~Iterator();
|
|
93
|
-
Iterator(const Iterator &) = delete;
|
|
94
|
-
Iterator &operator=(const Iterator &) = delete;
|
|
95
|
-
Iterator(Iterator &&) noexcept;
|
|
96
|
-
Iterator &operator=(Iterator &&) noexcept;
|
|
97
|
-
|
|
98
|
-
private:
|
|
99
|
-
friend class Traverser;
|
|
100
|
-
class Impl;
|
|
101
|
-
std::unique_ptr<Impl> _impl;
|
|
102
|
-
explicit Iterator(std::unique_ptr<Impl> impl);
|
|
103
|
-
};
|
|
104
|
-
|
|
105
|
-
/**
|
|
106
|
-
* @brief Get iterator to first entry
|
|
107
|
-
* @return Iterator pointing to first entry
|
|
108
|
-
*/
|
|
109
|
-
Iterator begin();
|
|
110
|
-
|
|
111
|
-
/**
|
|
112
|
-
* @brief Get end iterator
|
|
113
|
-
* @return End iterator (sentinel)
|
|
114
|
-
*/
|
|
115
|
-
Iterator end();
|
|
116
|
-
|
|
117
|
-
private:
|
|
118
|
-
std::vector<PathHierarchy> _initial_paths; ///< Initial paths provided to constructor
|
|
119
|
-
TraverserOptions _options; ///< Options controlling archive handling
|
|
120
|
-
};
|
|
121
|
-
|
|
122
|
-
} // namespace archive_r
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
// Copyright (c) 2025 archive_r Team
|
|
3
|
+
|
|
4
|
+
#pragma once
|
|
5
|
+
|
|
6
|
+
#include "archive_r/entry_fault.h"
|
|
7
|
+
#include "archive_r/path_hierarchy.h"
|
|
8
|
+
#include "entry.h"
|
|
9
|
+
#include <memory>
|
|
10
|
+
#include <string>
|
|
11
|
+
#include <vector>
|
|
12
|
+
|
|
13
|
+
namespace archive_r {
|
|
14
|
+
|
|
15
|
+
struct TraverserOptions {
|
|
16
|
+
std::vector<std::string> passphrases; ///< Passphrases for encrypted archives
|
|
17
|
+
std::vector<std::string> formats; ///< Specific archive formats to enable (empty = all)
|
|
18
|
+
std::vector<std::string> metadata_keys; ///< Metadata keys to capture for entries
|
|
19
|
+
bool descend_archives = true; ///< Whether to descend into archives by default
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* @brief Iterator-based traversal for archives and directories
|
|
24
|
+
*
|
|
25
|
+
* Traverser provides a unified iterator-based interface for traversing
|
|
26
|
+
* entries within archives and directories, including support for nested
|
|
27
|
+
* archives and automatic descent.
|
|
28
|
+
*
|
|
29
|
+
* Supports multiple archive formats via libarchive (tar, zip, gzip, etc.)
|
|
30
|
+
* and filesystem directories.
|
|
31
|
+
*
|
|
32
|
+
* Uses std::filesystem for directory traversal and ArchiveStackOrchestrator for archives.
|
|
33
|
+
|
|
34
|
+
* @see Entry, ArchiveStackOrchestrator
|
|
35
|
+
*
|
|
36
|
+
* Usage:
|
|
37
|
+
* Traverser traverser({make_single_path("archive.tar.gz")}); // or directory path
|
|
38
|
+
* for (Entry& entry : traverser) {
|
|
39
|
+
* // Process entry
|
|
40
|
+
* }
|
|
41
|
+
*
|
|
42
|
+
* @note Thread Safety
|
|
43
|
+
* Traverser instances are not thread-safe. To use the traverser in a
|
|
44
|
+
* multi-threaded environment, create a separate Traverser instance for each
|
|
45
|
+
* thread. Do not share a single instance across multiple threads.
|
|
46
|
+
*/
|
|
47
|
+
class Traverser {
|
|
48
|
+
public:
|
|
49
|
+
/**
|
|
50
|
+
* @brief Construct traverser for archives or directories
|
|
51
|
+
* @param paths Paths to archive files or directories
|
|
52
|
+
*
|
|
53
|
+
* Provide one or more paths to traverse. Single-path traversal can be
|
|
54
|
+
* achieved by passing a container with one element:
|
|
55
|
+
* Traverser traverser({make_single_path("archive.tar.gz")});
|
|
56
|
+
*/
|
|
57
|
+
explicit Traverser(std::vector<PathHierarchy> paths, TraverserOptions options = {});
|
|
58
|
+
|
|
59
|
+
~Traverser();
|
|
60
|
+
|
|
61
|
+
// Non-copyable
|
|
62
|
+
Traverser(const Traverser &) = delete;
|
|
63
|
+
Traverser &operator=(const Traverser &) = delete;
|
|
64
|
+
|
|
65
|
+
// ========================================================================
|
|
66
|
+
// Iterator API
|
|
67
|
+
// ========================================================================
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* @brief Forward iterator for traversing entries
|
|
71
|
+
*
|
|
72
|
+
* Satisfies InputIterator requirements:
|
|
73
|
+
* - Move-only (non-copyable)
|
|
74
|
+
* - Equality comparable
|
|
75
|
+
* - Dereferenceable (returns Entry&)
|
|
76
|
+
* - Incrementable
|
|
77
|
+
*/
|
|
78
|
+
class Iterator {
|
|
79
|
+
public:
|
|
80
|
+
using iterator_category = std::input_iterator_tag;
|
|
81
|
+
using value_type = Entry;
|
|
82
|
+
using difference_type = std::ptrdiff_t;
|
|
83
|
+
using pointer = Entry *;
|
|
84
|
+
using reference = Entry &;
|
|
85
|
+
|
|
86
|
+
reference operator*();
|
|
87
|
+
pointer operator->();
|
|
88
|
+
Iterator &operator++();
|
|
89
|
+
bool operator==(const Iterator &other) const;
|
|
90
|
+
bool operator!=(const Iterator &other) const;
|
|
91
|
+
|
|
92
|
+
~Iterator();
|
|
93
|
+
Iterator(const Iterator &) = delete;
|
|
94
|
+
Iterator &operator=(const Iterator &) = delete;
|
|
95
|
+
Iterator(Iterator &&) noexcept;
|
|
96
|
+
Iterator &operator=(Iterator &&) noexcept;
|
|
97
|
+
|
|
98
|
+
private:
|
|
99
|
+
friend class Traverser;
|
|
100
|
+
class Impl;
|
|
101
|
+
std::unique_ptr<Impl> _impl;
|
|
102
|
+
explicit Iterator(std::unique_ptr<Impl> impl);
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* @brief Get iterator to first entry
|
|
107
|
+
* @return Iterator pointing to first entry
|
|
108
|
+
*/
|
|
109
|
+
Iterator begin();
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* @brief Get end iterator
|
|
113
|
+
* @return End iterator (sentinel)
|
|
114
|
+
*/
|
|
115
|
+
Iterator end();
|
|
116
|
+
|
|
117
|
+
private:
|
|
118
|
+
std::vector<PathHierarchy> _initial_paths; ///< Initial paths provided to constructor
|
|
119
|
+
TraverserOptions _options; ///< Options controlling archive handling
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
} // namespace archive_r
|