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)
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())
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