Skip to content

Commit 212cbec

Browse files
authored
Feature translate archives (#342)
1 parent 0c9d916 commit 212cbec

31 files changed

Lines changed: 654 additions & 205 deletions

CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,11 +65,13 @@ else ()
6565
endif ()
6666

6767
add_library(odr
68+
"src/odr/archive.cpp"
6869
"src/odr/document.cpp"
6970
"src/odr/document_element.cpp"
7071
"src/odr/document_path.cpp"
7172
"src/odr/exceptions.cpp"
7273
"src/odr/file.cpp"
74+
"src/odr/filesystem.cpp"
7375
"src/odr/html.cpp"
7476
"src/odr/open_document_reader.cpp"
7577
"src/odr/quantity.cpp"
@@ -108,6 +110,7 @@ add_library(odr
108110
"src/odr/internal/html/document.cpp"
109111
"src/odr/internal/html/document_style.cpp"
110112
"src/odr/internal/html/document_element.cpp"
113+
"src/odr/internal/html/filesystem.cpp"
111114
"src/odr/internal/html/html_writer.cpp"
112115
"src/odr/internal/html/image_file.cpp"
113116
"src/odr/internal/html/text_file.cpp"

cli/src/translate.cpp

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
#include <odr/exceptions.hpp>
12
#include <odr/file.hpp>
23
#include <odr/html.hpp>
34

@@ -7,34 +8,33 @@
78
using namespace odr;
89

910
int main(int argc, char **argv) {
10-
const std::string input{argv[1]};
11-
const std::string output{argv[2]};
11+
std::string input{argv[1]};
12+
std::string output{argv[2]};
1213

1314
std::optional<std::string> password;
1415
if (argc >= 4) {
1516
password = argv[3];
1617
}
1718

18-
DocumentFile document_file{input};
19-
20-
if (document_file.password_encrypted()) {
21-
if (password) {
22-
if (!document_file.decrypt(*password)) {
23-
std::cerr << "wrong password" << std::endl;
24-
return 1;
25-
}
26-
} else {
27-
std::cerr << "document encrypted but no password given" << std::endl;
28-
return 2;
29-
}
30-
}
31-
32-
auto document = document_file.document();
19+
File file{input};
3320

3421
HtmlConfig config;
3522
config.editable = true;
3623

37-
html::translate(document, output, config);
24+
PasswordCallback password_callback = [&]() {
25+
if (!password) {
26+
std::cerr << "document encrypted but no password given" << std::endl;
27+
std::exit(2);
28+
}
29+
return *password;
30+
};
31+
32+
try {
33+
html::translate(file, output, config, password_callback);
34+
} catch (const WrongPassword &e) {
35+
std::cerr << "wrong password" << std::endl;
36+
return 1;
37+
}
3838

3939
return 0;
4040
}

src/odr/archive.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#include <odr/archive.hpp>
2+
3+
#include <odr/filesystem.hpp>
4+
5+
#include <odr/internal/abstract/archive.hpp>
6+
#include <odr/internal/abstract/filesystem.hpp>
7+
#include <odr/internal/common/path.hpp>
8+
9+
namespace odr {
10+
11+
Archive::Archive(std::shared_ptr<internal::abstract::Archive> impl)
12+
: m_impl{std::move(impl)} {}
13+
14+
Archive::operator bool() const { return m_impl.operator bool(); }
15+
16+
Filesystem Archive::filesystem() const {
17+
return Filesystem(
18+
std::dynamic_pointer_cast<internal::abstract::ReadableFilesystem>(
19+
m_impl->filesystem()));
20+
}
21+
22+
void Archive::save(const std::string &path) const { m_impl->save(path); }
23+
24+
} // namespace odr

src/odr/archive.hpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
#ifndef ODR_ARCHIVE_H
2+
#define ODR_ARCHIVE_H
3+
4+
#include <memory>
5+
#include <string>
6+
7+
namespace odr::internal::abstract {
8+
class Archive;
9+
} // namespace odr::internal::abstract
10+
11+
namespace odr {
12+
class Filesystem;
13+
14+
class Archive {
15+
public:
16+
explicit Archive(std::shared_ptr<internal::abstract::Archive>);
17+
18+
[[nodiscard]] explicit operator bool() const;
19+
20+
[[nodiscard]] Filesystem filesystem() const;
21+
22+
void save(const std::string &path) const;
23+
24+
private:
25+
std::shared_ptr<internal::abstract::Archive> m_impl;
26+
};
27+
28+
} // namespace odr
29+
30+
#endif // ODR_ARCHIVE_H

src/odr/document.cpp

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
#include <odr/document_element.hpp>
44
#include <odr/file.hpp>
5+
#include <odr/filesystem.hpp>
6+
57
#include <odr/internal/abstract/document.hpp>
68
#include <odr/internal/common/path.hpp>
79

@@ -10,36 +12,36 @@
1012

1113
namespace odr {
1214

13-
Document::Document(std::shared_ptr<internal::abstract::Document> document)
14-
: m_document{std::move(document)} {
15-
if (!m_document) {
15+
Document::Document(std::shared_ptr<internal::abstract::Document> impl)
16+
: m_impl{std::move(impl)} {
17+
if (!m_impl) {
1618
throw std::runtime_error("document is null");
1719
}
1820
}
1921

20-
bool Document::editable() const noexcept { return m_document->is_editable(); }
22+
bool Document::editable() const noexcept { return m_impl->is_editable(); }
2123

2224
bool Document::savable(const bool encrypted) const noexcept {
23-
return m_document->is_savable(encrypted);
25+
return m_impl->is_savable(encrypted);
2426
}
2527

26-
void Document::save(const std::string &path) const { m_document->save(path); }
28+
void Document::save(const std::string &path) const { m_impl->save(path); }
2729

2830
void Document::save(const std::string &path,
2931
const std::string &password) const {
30-
m_document->save(path, password.c_str());
32+
m_impl->save(path, password.c_str());
3133
}
3234

33-
FileType Document::file_type() const noexcept {
34-
return m_document->file_type();
35-
}
35+
FileType Document::file_type() const noexcept { return m_impl->file_type(); }
3636

3737
DocumentType Document::document_type() const noexcept {
38-
return m_document->document_type();
38+
return m_impl->document_type();
3939
}
4040

4141
Element Document::root_element() const {
42-
return {m_document.get(), m_document->root_element()};
42+
return {m_impl.get(), m_impl->root_element()};
4343
}
4444

45+
Filesystem Document::files() const { return Filesystem(m_impl->files()); }
46+
4547
} // namespace odr

src/odr/document.hpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,11 @@ enum class FileType;
1313
enum class DocumentType;
1414
class DocumentFile;
1515
class Element;
16+
class Filesystem;
1617

1718
class Document final {
1819
public:
19-
explicit Document(std::shared_ptr<internal::abstract::Document> document);
20+
explicit Document(std::shared_ptr<internal::abstract::Document>);
2021

2122
[[nodiscard]] bool editable() const noexcept;
2223
[[nodiscard]] bool savable(bool encrypted = false) const noexcept;
@@ -29,8 +30,10 @@ class Document final {
2930

3031
[[nodiscard]] Element root_element() const;
3132

33+
[[nodiscard]] Filesystem files() const;
34+
3235
private:
33-
std::shared_ptr<internal::abstract::Document> m_document;
36+
std::shared_ptr<internal::abstract::Document> m_impl;
3437

3538
friend DocumentFile;
3639
};

src/odr/exceptions.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ UnknownCharset::UnknownCharset() : std::runtime_error("unknown charset") {}
3434

3535
NoImageFile::NoImageFile() : std::runtime_error("not an image file") {}
3636

37+
NoArchiveFile::NoArchiveFile() : std::runtime_error("not an archive file") {}
38+
3739
NoDocumentFile::NoDocumentFile() : std::runtime_error("not a document file") {}
3840

3941
NoOpenDocumentFile::NoOpenDocumentFile()

src/odr/exceptions.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,10 @@ struct NoImageFile final : public std::runtime_error {
6464
NoImageFile();
6565
};
6666

67+
struct NoArchiveFile final : public std::runtime_error {
68+
NoArchiveFile();
69+
};
70+
6771
struct NoDocumentFile final : public std::runtime_error {
6872
NoDocumentFile();
6973
};

src/odr/file.cpp

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include <odr/file.hpp>
22

3+
#include <odr/archive.hpp>
34
#include <odr/document.hpp>
45
#include <odr/exceptions.hpp>
56

@@ -25,12 +26,16 @@ FileMeta::FileMeta(const FileType type, const bool password_encrypted,
2526
: type{type}, password_encrypted{password_encrypted},
2627
document_meta{std::move(document_meta)} {}
2728

29+
File::File() = default;
30+
2831
File::File(std::shared_ptr<internal::abstract::File> impl)
2932
: m_impl{std::move(impl)} {}
3033

3134
File::File(const std::string &path)
3235
: m_impl{std::make_shared<internal::common::DiskFile>(path)} {}
3336

37+
File::operator bool() const { return m_impl.operator bool(); }
38+
3439
FileLocation File::location() const noexcept { return m_impl->location(); }
3540

3641
std::size_t File::size() const { return m_impl->size(); }
@@ -82,6 +87,8 @@ DecodedFile::DecodedFile(const std::string &path, FileType as)
8287
: DecodedFile(internal::open_strategy::open_file(
8388
std::make_shared<internal::common::DiskFile>(path), as)) {}
8489

90+
DecodedFile::operator bool() const { return m_impl.operator bool(); }
91+
8592
FileType DecodedFile::file_type() const noexcept {
8693
return m_impl->file_meta().type;
8794
}
@@ -99,7 +106,7 @@ TextFile DecodedFile::text_file() const {
99106
std::dynamic_pointer_cast<internal::abstract::TextFile>(m_impl)) {
100107
return TextFile(text_file);
101108
}
102-
throw NoImageFile();
109+
throw NoTextFile();
103110
}
104111

105112
ImageFile DecodedFile::image_file() const {
@@ -110,6 +117,14 @@ ImageFile DecodedFile::image_file() const {
110117
throw NoImageFile();
111118
}
112119

120+
ArchiveFile DecodedFile::archive_file() const {
121+
if (auto archive_file =
122+
std::dynamic_pointer_cast<internal::abstract::ArchiveFile>(m_impl)) {
123+
return ArchiveFile(archive_file);
124+
}
125+
throw NoArchiveFile();
126+
}
127+
113128
DocumentFile DecodedFile::document_file() const {
114129
if (auto document_file =
115130
std::dynamic_pointer_cast<internal::abstract::DocumentFile>(m_impl)) {
@@ -140,6 +155,11 @@ std::unique_ptr<std::istream> ImageFile::stream() const {
140155
return m_impl->file()->stream();
141156
}
142157

158+
ArchiveFile::ArchiveFile(std::shared_ptr<internal::abstract::ArchiveFile> impl)
159+
: DecodedFile(impl), m_impl{std::move(impl)} {}
160+
161+
Archive ArchiveFile::archive() const { return Archive(m_impl->archive()); }
162+
143163
FileType DocumentFile::type(const std::string &path) {
144164
return DocumentFile(path).file_type();
145165
}

0 commit comments

Comments
 (0)