Line data Source code
1 : ///
2 : /// @file ar/internal/extractor.h
3 : /// @copyright (c) 2015 by Petr Zemek (s3rvac@gmail.com) and contributors
4 : /// @license MIT, see the @c LICENSE file for more details
5 : /// @brief %Extractor of files from an archive.
6 : ///
7 :
8 : #ifndef AR_INTERNAL_EXTRACTOR_H
9 : #define AR_INTERNAL_EXTRACTOR_H
10 :
11 : #include <cstddef>
12 : #include <map>
13 : #include <memory>
14 : #include <string>
15 :
16 : namespace ar {
17 :
18 : class Files;
19 :
20 : namespace internal {
21 :
22 : ///
23 : /// %Extractor of files from an archive.
24 : ///
25 20 : class Extractor {
26 : public:
27 : Extractor();
28 : ~Extractor();
29 :
30 : Files extract(const std::string& archiveContent);
31 :
32 : /// @name Disabled
33 : /// @{
34 : Extractor(const Extractor&) = delete;
35 : Extractor(Extractor&&) = delete;
36 : Extractor& operator=(const Extractor&) = delete;
37 : Extractor& operator=(Extractor&&) = delete;
38 : /// @}
39 :
40 : private:
41 : /// Mapping of an index into a file name.
42 : using FileNameTable = std::map<std::size_t, std::string>;
43 :
44 : private:
45 : void initializeWith(const std::string& archiveContent);
46 :
47 : /// @name Reading
48 : /// @{
49 : void readMagicString();
50 : void readLookupTable();
51 : bool hasLookupTableAt(std::size_t i) const;
52 : void readFileNameTable();
53 : void readFileNameIntoFileNameTable(std::size_t startOfTable);
54 : Files readFiles();
55 : std::unique_ptr<File> readFile();
56 : std::string readFileName();
57 : bool hasNameSpecifiedViaIndexIntoFileNameTableAt(std::size_t j) const;
58 : std::string readFileNameEndedWithSlash();
59 : std::string nameFromFileNameTableOnIndex(std::size_t index) const;
60 : void readFileTimestamp();
61 : void readFileOwnerId();
62 : void readFileGroupId();
63 : void readFileMode();
64 : std::size_t readFileSize();
65 : void readUntilEndOfFileHeader();
66 : std::string readFileContent(std::size_t fileSize);
67 :
68 : /// @name Utilities
69 : /// @{
70 : bool isValid(std::size_t j) const noexcept;
71 : std::string::value_type charAt(std::size_t j) const;
72 : void skipSpaces();
73 : void skipEndsOfLines();
74 : void skipSuccessiveChars(char c);
75 : std::size_t readNumber(const std::string& name);
76 : /// @}
77 :
78 : /// @name Validation
79 : /// @{
80 : void ensureFileNameIsNonEmpty(const std::string& fileName) const;
81 : void ensureIsValidFileNameTableIndex(FileNameTable::const_iterator it,
82 : std::size_t index) const;
83 : void ensureContainsSlashOnPosition(std::string::size_type pos) const;
84 : void ensureContainsFileHeaderOnPosition(std::string::size_type pos) const;
85 : void ensureContentOfGivenSizeWasRead(std::size_t readContentSize,
86 : std::size_t expectedContentSize) const;
87 : void ensureNumberWasRead(const std::string& numAsStr,
88 : const std::string& name) const;
89 : /// @}
90 :
91 : private:
92 : /// Content of the archive.
93 : std::string content;
94 :
95 : /// Current index to @c content.
96 : std::size_t i;
97 :
98 : /// Table containing names of files.
99 : FileNameTable fileNameTable;
100 : };
101 :
102 : } // namespace internal
103 : } // namespace ar
104 :
105 : #endif
|