QGroundControl
Ground Control Station for MAVLink Drones
Loading...
Searching...
No Matches
QGCArchiveFile.cc
Go to the documentation of this file.
1#include "QGCArchiveFile.h"
3
4#include <archive.h>
5#include <archive_entry.h>
6
7QGC_LOGGING_CATEGORY(QGCArchiveFileLog, "Utilities.QGCArchiveFile")
8
9// ============================================================================
10// Constructors
11// ============================================================================
12
13QGCArchiveFile::QGCArchiveFile(const QString &archivePath, const QString &entryName, QObject *parent)
14 : QGCArchiveDeviceBase(archivePath, parent)
15 , _entryName(entryName)
16{
17}
18
19QGCArchiveFile::QGCArchiveFile(QIODevice *source, const QString &entryName, QObject *parent)
20 : QGCArchiveDeviceBase(source, parent)
21 , _entryName(entryName)
22{
23}
24
25// ============================================================================
26// QIODevice Interface
27// ============================================================================
28
29bool QGCArchiveFile::open(OpenMode mode)
30{
31 if (mode != ReadOnly) {
32 _errorString = QStringLiteral("QGCArchiveFile only supports ReadOnly mode");
33 return false;
34 }
35
36 if (_entryName.isEmpty()) {
37 _errorString = QStringLiteral("Entry name cannot be empty");
38 return false;
39 }
40
41 // Handle file path constructor
42 if (!_filePath.isEmpty()) {
43 if (!initSourceFromPath()) {
44 return false;
45 }
46 }
47
48 if (!initArchive()) {
49 return false;
50 }
51
52 if (!prepareForReading()) {
53 return false;
54 }
55
56 return QIODevice::open(mode);
57}
58
60{
61 return _entrySize >= 0 ? _entrySize : QIODevice::size();
62}
63
64// ============================================================================
65// Protected Implementation
66// ============================================================================
67
69{
70 _archive = archive_read_new();
71 if (!_archive) {
72 _errorString = QStringLiteral("Failed to create archive reader");
73 return false;
74 }
75
76 // All formats for archives
78
79 return openArchive();
80}
81
83{
84 return seekToEntry();
85}
86
88{
90 _entryFound = false;
91 _entrySize = -1;
92 _entryModified = QDateTime();
93}
94
95// ============================================================================
96// Private Methods
97// ============================================================================
98
99bool QGCArchiveFile::seekToEntry()
100{
101 struct archive_entry *entry = nullptr;
102 _entryFound = false;
103
104 while (archive_read_next_header(_archive, &entry) == ARCHIVE_OK) {
105 // Capture format info on first header
106 if (_formatName.isEmpty()) {
108 }
109
110 const QString currentEntry = QString::fromUtf8(archive_entry_pathname(entry));
111
112 if (currentEntry == _entryName) {
113 _entryFound = true;
114 _entrySize = archive_entry_size(entry);
115
116 // Get modification time if available
117 if (archive_entry_mtime_is_set(entry)) {
118 _entryModified = QDateTime::fromSecsSinceEpoch(archive_entry_mtime(entry));
119 }
120
121 qCDebug(QGCArchiveFileLog) << "Found entry:" << _entryName
122 << "size:" << _entrySize
123 << "modified:" << _entryModified;
124 return true;
125 }
126
127 // Skip this entry's data
128 archive_read_data_skip(_archive);
129 }
130
131 _errorString = QStringLiteral("Entry not found in archive: ") + _entryName;
132 return false;
133}
QIODevice for reading a single entry from an archive.
#define QGC_LOGGING_CATEGORY(name, categoryStr)
Base class for QIODevice wrappers that use libarchive for decompression.
void captureFormatInfo()
Capture format info from the archive after first header read.
void configureArchiveFormats(bool allFormats)
virtual void resetState()
Reset all state (called by close())
QIODevice for reading a single entry from an archive without full extraction.
QGCArchiveFile(const QString &archivePath, const QString &entryName, QObject *parent=nullptr)
bool open(OpenMode mode) override
void resetState() override
Reset all state (called by close())
qint64 size() const override
bool prepareForReading() override
bool initArchive() override