summaryrefslogtreecommitdiff
path: root/utils/rbutilqt/base/mspackutil.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'utils/rbutilqt/base/mspackutil.cpp')
-rw-r--r--utils/rbutilqt/base/mspackutil.cpp164
1 files changed, 164 insertions, 0 deletions
diff --git a/utils/rbutilqt/base/mspackutil.cpp b/utils/rbutilqt/base/mspackutil.cpp
new file mode 100644
index 0000000000..b794272199
--- /dev/null
+++ b/utils/rbutilqt/base/mspackutil.cpp
@@ -0,0 +1,164 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2013 Amaury Pouly
10 *
11 * All files in this archive are subject to the GNU General Public License.
12 * See the file COPYING in the source tree root for full license agreement.
13 *
14 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
15 * KIND, either express or implied.
16 *
17 ****************************************************************************/
18
19#include <QtCore>
20#include "Logger.h"
21#include "mspackutil.h"
22#include "progressloggerinterface.h"
23
24MsPackUtil::MsPackUtil(QObject* parent)
25 :ArchiveUtil(parent)
26{
27 m_cabd = mspack_create_cab_decompressor(nullptr);
28 m_cabinet = nullptr;
29 if(!m_cabd)
30 LOG_ERROR() << "CAB decompressor creation failed!";
31}
32
33MsPackUtil::~MsPackUtil()
34{
35 close();
36 if(m_cabd)
37 mspack_destroy_cab_decompressor(m_cabd);
38}
39
40bool MsPackUtil::open(QString& mspackfile)
41{
42 close();
43
44 if(m_cabd == nullptr)
45 {
46 LOG_ERROR() << "No CAB decompressor available: cannot open file!";
47 return false;
48 }
49 m_cabinet = m_cabd->search(m_cabd, QFile::encodeName(mspackfile).constData());
50 return m_cabinet != nullptr;
51}
52
53bool MsPackUtil::close(void)
54{
55 if(m_cabd && m_cabinet)
56 m_cabd->close(m_cabd, m_cabinet);
57 m_cabinet = nullptr;
58 return true;
59}
60
61bool MsPackUtil::extractArchive(const QString& dest, QString file)
62{
63 LOG_INFO() << "extractArchive" << dest << file;
64 if(!m_cabinet)
65 {
66 LOG_ERROR() << "CAB file not open!";
67 return false;
68 }
69
70 // construct the filename when extracting a single file from an archive.
71 // if the given destination is a full path use it as output name,
72 // otherwise use it as path to place the file as named in the archive.
73 QString singleoutfile;
74 if(!file.isEmpty() && QFileInfo(dest).isDir())
75 singleoutfile = dest + "/" + file;
76 else if(!file.isEmpty())
77 singleoutfile = dest;
78 struct mscabd_file *f = m_cabinet->files;
79 if(f == nullptr)
80 {
81 LOG_WARNING() << "CAB doesn't contain file" << file;
82 return true;
83 }
84 bool found = false;
85 while(f)
86 {
87 QString name = QFile::decodeName(f->filename);
88 name.replace("\\", "/");
89 if(name.at(0) == '/')
90 name.remove(0, 1);
91 if(name == file || file.isEmpty())
92 {
93 QString path;
94 if(!singleoutfile.isEmpty())
95 path = singleoutfile;
96 else
97 path = dest + "/" + name;
98 // make sure the output path exists
99 if(!QDir().mkpath(QFileInfo(path).absolutePath()))
100 {
101 emit logItem(tr("Creating output path failed"), LOGERROR);
102 LOG_ERROR() << "creating output path failed for:" << path;
103 emit logProgress(1, 1);
104 return false;
105 }
106 int ret = m_cabd->extract(m_cabd, f, QFile::encodeName(path).constData());
107 if(ret != MSPACK_ERR_OK)
108 {
109 emit logItem(tr("Error during CAB operation"), LOGERROR);
110 LOG_ERROR() << "mspack error: " << ret
111 << "(" << errorStringMsPack(ret) << ")";
112 emit logProgress(1, 1);
113 return false;
114 }
115 found = true;
116 }
117 f = f->next;
118 }
119 emit logProgress(1, 1);
120
121 return found;
122}
123
124QStringList MsPackUtil::files(void)
125{
126 QStringList list;
127 if(!m_cabinet)
128 {
129 LOG_WARNING() << "CAB file not open!";
130 return list;
131 }
132 struct mscabd_file *file = m_cabinet->files;
133 while(file)
134 {
135 QString name = QFile::decodeName(file->filename);
136 name.replace("\\", "/");
137 if(name.at(0) == '/')
138 name.remove(0, 1);
139 list.append(name);
140 file = file->next;
141 }
142
143 return list;
144}
145
146QString MsPackUtil::errorStringMsPack(int error) const
147{
148 switch(error)
149 {
150 case MSPACK_ERR_OK: return "Ok";
151 case MSPACK_ERR_ARGS: return "Bad arguments";
152 case MSPACK_ERR_OPEN: return "Open error";
153 case MSPACK_ERR_READ: return "Read error";
154 case MSPACK_ERR_WRITE: return "Write error";
155 case MSPACK_ERR_SEEK: return "Seek error";
156 case MSPACK_ERR_NOMEMORY: return "Out of memory";
157 case MSPACK_ERR_SIGNATURE: return "Bad signature";
158 case MSPACK_ERR_DATAFORMAT: return "Bad data format";
159 case MSPACK_ERR_CHECKSUM: return "Checksum error";
160 case MSPACK_ERR_CRUNCH: return "Compression error";
161 case MSPACK_ERR_DECRUNCH: return "Decompression error";
162 default: return "Unknown";
163 }
164}