swift
compressutils.cpp
1 // SPDX-FileCopyrightText: Copyright (C) 2018 swift Project Community / Contributors
2 // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-swift-pilot-client-1
3 
4 #include "misc/compressutils.h"
5 
6 #include <QFileInfo>
7 #include <QProcess>
8 
9 #include "config/buildconfig.h"
10 #include "misc/fileutils.h"
11 #include "misc/stringutils.h"
12 #include "misc/swiftdirectories.h"
13 
14 using namespace swift::config;
15 
16 namespace swift::misc
17 {
18  QByteArray CCompressUtils::lengthHeader(qint32 size)
19  {
20  // Length header, unsigned, big-endian, 32-bit integer
21  QByteArray lengthHeader;
22  QDataStream stream(&lengthHeader, QIODevice::WriteOnly);
23  stream.setByteOrder(QDataStream::BigEndian);
24  stream << size;
25  Q_ASSERT_X(lengthHeader.size() == 4, Q_FUNC_INFO, "Wrong header size");
26  return lengthHeader;
27  }
28 
31  {
32  QString executable;
34  {
35  executable += CSwiftDirectories::binDirectory();
36  executable += '/';
37  }
38  executable += QStringLiteral("7za");
39  return executable;
40  }
41 
42  bool CCompressUtils::zip7Uncompress(const QString &file, const QString &directory, QStringList *stdOutAndError)
43  {
44  const QFileInfo fi(file);
45  if (!fi.exists()) { return false; }
46  if (!CCompressUtils::hasZip7(stdOutAndError)) { return false; }
47 
49  const QString d = directory.isEmpty() ? directory : win ? CFileUtils::toWindowsLocalPath(directory) : directory;
50  const QString f = win ? CFileUtils::toWindowsLocalPath(file) : file;
51 
52  // 7za.exe x -o"P:\Temp\XPlane" c:\Users\Foo\Downloads\xswiftbus-allos-0.8.4.802111947.7z
53 
54  QStringList args;
55  args << "x";
56  args << "-aoa";
57  if (!d.isEmpty()) { args << "-o" + d; }
58  args << f;
59 
60  QProcess zipProcess;
61  zipProcess.setProgram(getZip7Executable());
62  zipProcess.setArguments(args);
63  return runZip7Process(&zipProcess, stdOutAndError);
64  }
65 
66  bool CCompressUtils::hasZip7(QStringList *stdOutAndError)
67  {
68  // just display info
69  if (CBuildConfig::isRunningOnLinuxPlatform()) { return CCompressUtils::whichZip7(stdOutAndError); }
70 
71  QStringList args;
72  args << "i";
73  QProcess zipProcess;
74  zipProcess.setProgram(getZip7Executable());
75  zipProcess.setArguments(args);
76  return runZip7Process(&zipProcess, stdOutAndError);
77  }
78 
79  bool CCompressUtils::whichZip7(QStringList *stdOutAndError)
80  {
81  const QString cmd("which 7za");
82  QProcess zipProcess;
83  zipProcess.start(cmd);
84  if (!zipProcess.waitForStarted()) { return false; }
85  if (!zipProcess.waitForFinished()) { return false; }
86 
87  const QString pStdout = zipProcess.readAllStandardOutput();
88  const QString pStderr = zipProcess.readAllStandardError();
89  if (stdOutAndError)
90  {
91  stdOutAndError->clear();
92  stdOutAndError->push_back(pStdout);
93  stdOutAndError->push_back(pStderr);
94  }
95  const int r = zipProcess.exitCode();
96  return r == 0 && pStdout.contains("7za", Qt::CaseInsensitive);
97  }
98 
99  bool CCompressUtils::runZip7Process(QProcess *zipProcess, QStringList *stdOutAndError)
100  {
101  zipProcess->start();
102 
103  // If process does not even start, e.g. because no 7za exe found.
104  if (!zipProcess->waitForStarted())
105  {
106  if (stdOutAndError)
107  {
108  stdOutAndError->push_back("7za");
109  stdOutAndError->push_back("Command not found");
110  }
111  return false;
112  }
113 
114  // If process does not finish. Very unlikely.
115  if (!zipProcess->waitForFinished())
116  {
117  if (stdOutAndError)
118  {
119  stdOutAndError->push_back("7za");
120  stdOutAndError->push_back("Process did not finish.");
121  }
122  return false;
123  }
124 
125  if (stdOutAndError)
126  {
127  stdOutAndError->clear();
128  const QString pStdout = zipProcess->readAllStandardOutput();
129  const QString pStderr = zipProcess->readAllStandardError();
130  stdOutAndError->push_back(pStdout);
131  stdOutAndError->push_back(pStderr);
132  }
133 
134  return zipProcess->exitStatus() == QProcess::NormalExit;
135  }
136 } // namespace swift::misc
static constexpr bool isRunningOnMacOSPlatform()
Running on MacOS platform?
static constexpr bool isRunningOnWindowsNtPlatform()
Running on Windows NT platform?
static constexpr bool isRunningOnLinuxPlatform()
Running on Linux platform?
static QByteArray lengthHeader(qint32 size)
Length header.
Free functions in swift::misc.
QString getZip7Executable()
Returns the platform specific 7za command.