11#include < odr/internal/cfb/cfb_archive.hpp>
22
3+ #include < odr/exceptions.hpp>
34#include < odr/internal/cfb/cfb_util.hpp>
5+ #include < odr/internal/common/filesystem.hpp>
46#include < odr/internal/util/string_util.hpp>
57
68namespace odr ::internal::abstract {
@@ -13,192 +15,23 @@ class MemoryFile;
1315
1416namespace odr ::internal::cfb {
1517
16- ReadonlyCfbArchive::Entry::Entry (const ReadonlyCfbArchive &parent,
17- const impl::CompoundFileEntry &entry)
18- : m_parent{&parent}, m_entry{&entry}, m_path{" /" } {}
18+ CfbArchive::CfbArchive (std::shared_ptr<util::Archive> archive)
19+ : m_cfb{std::move (archive)} {}
1920
20- ReadonlyCfbArchive::Entry::Entry (const ReadonlyCfbArchive &parent,
21- const impl::CompoundFileEntry &entry,
22- const common::Path &parent_path)
23- : m_parent{&parent}, m_entry{&entry}, m_path{parent_path.join (name ())} {}
21+ std::shared_ptr<abstract::Filesystem> CfbArchive::filesystem () const {
22+ auto filesystem = std::make_shared<common::VirtualFilesystem>();
2423
25- bool ReadonlyCfbArchive::Entry::operator ==(const Entry &other) const {
26- return m_entry == other.m_entry ;
27- }
28-
29- bool ReadonlyCfbArchive::Entry::operator !=(const Entry &other) const {
30- return m_entry != other.m_entry ;
31- }
32-
33- bool ReadonlyCfbArchive::Entry::is_file () const { return m_entry->is_stream (); }
34-
35- bool ReadonlyCfbArchive::Entry::is_directory () const {
36- return !m_entry->is_stream ();
37- }
38-
39- common::Path ReadonlyCfbArchive::Entry::path () const { return m_path; }
40-
41- std::unique_ptr<abstract::File> ReadonlyCfbArchive::Entry::file () const {
42- if (!is_file ()) {
43- return {};
44- }
45- return std::make_unique<util::FileInCfb>(m_parent->m_cfb , *m_entry);
46- }
47-
48- std::string ReadonlyCfbArchive::Entry::name () const {
49- return odr::internal::util::string::c16str_to_string (
50- reinterpret_cast <const char16_t *>(m_entry->name ), m_entry->name_len - 2 );
51- }
52-
53- std::optional<ReadonlyCfbArchive::Entry>
54- ReadonlyCfbArchive::Entry::left () const {
55- auto left = m_parent->m_cfb ->cfb ().get_entry (m_entry->left_sibling_id );
56- if (left == nullptr ) {
57- return {};
58- }
59- return Entry (*m_parent, *left, m_path.parent ());
60- }
61-
62- std::optional<ReadonlyCfbArchive::Entry>
63- ReadonlyCfbArchive::Entry::right () const {
64- auto right = m_parent->m_cfb ->cfb ().get_entry (m_entry->right_sibling_id );
65- if (right == nullptr ) {
66- return {};
67- }
68- return Entry (*m_parent, *right, m_path.parent ());
69- }
70-
71- std::optional<ReadonlyCfbArchive::Entry>
72- ReadonlyCfbArchive::Entry::child () const {
73- auto child = m_parent->m_cfb ->cfb ().get_entry (m_entry->child_id );
74- if (child == nullptr ) {
75- return {};
76- }
77- return Entry (*m_parent, *child, m_path);
78- }
79-
80- ReadonlyCfbArchive::Iterator::Iterator () = default ;
81-
82- ReadonlyCfbArchive::Iterator::Iterator (const ReadonlyCfbArchive &parent,
83- const impl::CompoundFileEntry &entry)
84- : m_entry{Entry (parent, entry)} {
85- dig_left_ ();
86- }
87-
88- ReadonlyCfbArchive::Iterator::Iterator (const ReadonlyCfbArchive &parent,
89- const impl::CompoundFileEntry &entry,
90- const common::Path &parent_path)
91- : m_entry{Entry (parent, entry, parent_path)} {
92- dig_left_ ();
93- }
94-
95- void ReadonlyCfbArchive::Iterator::dig_left_ () {
96- if (!m_entry) {
97- return ;
98- }
99-
100- while (true ) {
101- auto left = m_entry->left ();
102- if (!left) {
103- break ;
24+ for (const auto &e : *m_cfb) {
25+ if (e.is_directory ()) {
26+ filesystem->create_directory (e.path ());
27+ } else if (e.is_file ()) {
28+ filesystem->copy (e.file (), e.path ());
10429 }
105- m_ancestors.push_back (*m_entry);
106- m_entry = left;
107- }
108- }
109-
110- void ReadonlyCfbArchive::Iterator::next_ () {
111- if (!m_entry) {
112- return ;
11330 }
11431
115- auto child = m_entry->child ();
116- if (child) {
117- m_directories.push_back (*m_entry);
118- m_entry = child;
119- dig_left_ ();
120- return ;
121- }
122-
123- next_flat_ ();
124- }
125-
126- void ReadonlyCfbArchive::Iterator::next_flat_ () {
127- if (!m_entry) {
128- return ;
129- }
130-
131- auto right = m_entry->right ();
132- if (right) {
133- m_entry = right;
134- dig_left_ ();
135- return ;
136- }
137-
138- if (!m_ancestors.empty ()) {
139- m_entry = m_ancestors.back ();
140- m_ancestors.pop_back ();
141- return ;
142- }
143-
144- if (!m_directories.empty ()) {
145- m_entry = m_directories.back ();
146- m_directories.pop_back ();
147- next_flat_ ();
148- return ;
149- }
150-
151- m_entry = {};
152- }
153-
154- ReadonlyCfbArchive::Iterator::reference
155- ReadonlyCfbArchive::Iterator::operator *() const {
156- return *m_entry;
157- }
158-
159- ReadonlyCfbArchive::Iterator::pointer
160- ReadonlyCfbArchive::Iterator::operator ->() const {
161- return &*m_entry;
32+ return filesystem;
16233}
16334
164- bool ReadonlyCfbArchive::Iterator::operator ==(const Iterator &other) const {
165- return m_entry == other.m_entry ;
166- }
167-
168- bool ReadonlyCfbArchive::Iterator::operator !=(const Iterator &other) const {
169- return m_entry != other.m_entry ;
170- }
171-
172- ReadonlyCfbArchive::Iterator &ReadonlyCfbArchive::Iterator::operator ++() {
173- next_ ();
174- return *this ;
175- }
176-
177- ReadonlyCfbArchive::Iterator ReadonlyCfbArchive::Iterator::operator ++(int ) {
178- Iterator tmp = *this ;
179- ++(*this );
180- return tmp;
181- }
182-
183- ReadonlyCfbArchive::ReadonlyCfbArchive (
184- const std::shared_ptr<common::MemoryFile> &file)
185- : m_cfb{std::make_shared<util::Archive>(file)} {}
186-
187- ReadonlyCfbArchive::Iterator ReadonlyCfbArchive::begin () const {
188- return {*this , *m_cfb->cfb ().get_root_entry ()};
189- }
190-
191- ReadonlyCfbArchive::Iterator ReadonlyCfbArchive::end () const { return {}; }
192-
193- ReadonlyCfbArchive::Iterator
194- ReadonlyCfbArchive::find (const common::Path &path) const {
195- for (auto it = begin (); it != end (); ++it) {
196- if (it->path () == path) {
197- return it;
198- }
199- }
200-
201- return end ();
202- }
35+ void CfbArchive::save (std::ostream &out) const { throw UnsupportedOperation (); }
20336
20437} // namespace odr::internal::cfb
0 commit comments