summaryrefslogtreecommitdiff
path: root/rbutil/rbutilqt/base/mspackutil.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'rbutil/rbutilqt/base/mspackutil.cpp')
-rw-r--r--rbutil/rbutilqt/base/mspackutil.cpp163
1 files changed, 163 insertions, 0 deletions
diff --git a/rbutil/rbutilqt/base/mspackutil.cpp b/rbutil/rbutilqt/base/mspackutil.cpp
new file mode 100644
index 0000000000..4bc7307cd9
--- /dev/null
+++ b/rbutil/rbutilqt/base/mspackutil.cpp
@@ -0,0 +1,163 @@
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 <QDebug>
21#include "mspackutil.h"
22#include "progressloggerinterface.h"
23
24MsPackUtil::MsPackUtil(QObject* parent)
25 :ArchiveUtil(parent)
26{
27 m_cabd = mspack_create_cab_decompressor(NULL);
28 m_cabinet = NULL;
29 if(!m_cabd)
30 qDebug() << "[MsPackUtil] 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 == NULL)
45 {
46 qDebug() << "[MsPackUtil] 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 != NULL;
51}
52
53bool MsPackUtil::close(void)
54{
55 if(m_cabd && m_cabinet)
56 m_cabd->close(m_cabd, m_cabinet);
57 m_cabinet = NULL;
58 return true;
59}
60
61bool MsPackUtil::extractArchive(const QString& dest, QString file)
62{
63 qDebug() << "[MsPackUtil] extractArchive" << dest << file;
64 if(!m_cabinet)
65 {
66 qDebug() << "[MsPackUtil] 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 == NULL)
80 {
81 qDebug() << "[MsPackUtil] 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 qDebug() << "[MsPackUtil] 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 qDebug() << "[MsPackUtil] mspack error: " << ret << "(" << errorStringMsPack(ret) << ")";
111 emit logProgress(1, 1);
112 return false;
113 }
114 found = true;
115 }
116 f = f->next;
117 }
118 emit logProgress(1, 1);
119
120 return found;
121}
122
123QStringList MsPackUtil::files(void)
124{
125 QStringList list;
126 if(!m_cabinet)
127 {
128 qDebug() << "[MsPackUtil] CAB file not open!";
129 return list;
130 }
131 struct mscabd_file *file = m_cabinet->files;
132 while(file)
133 {
134 QString name = QFile::decodeName(file->filename);
135 name.replace("\\", "/");
136 if(name.at(0) == '/')
137 name.remove(0, 1);
138 list.append(name);
139 file = file->next;
140 }
141
142 return list;
143}
144
145QString MsPackUtil::errorStringMsPack(int error) const
146{
147 switch(error)
148 {
149 case MSPACK_ERR_OK: return "Ok";
150 case MSPACK_ERR_ARGS: return "Bad arguments";
151 case MSPACK_ERR_OPEN: return "Open error";
152 case MSPACK_ERR_READ: return "Read error";
153 case MSPACK_ERR_WRITE: return "Write error";
154 case MSPACK_ERR_SEEK: return "Seek error";
155 case MSPACK_ERR_NOMEMORY: return "Out of memory";
156 case MSPACK_ERR_SIGNATURE: return "Bad signature";
157 case MSPACK_ERR_DATAFORMAT: return "Bad data format";
158 case MSPACK_ERR_CHECKSUM: return "Checksum error";
159 case MSPACK_ERR_CRUNCH: return "Compression error";
160 case MSPACK_ERR_DECRUNCH: return "Decompression error";
161 default: return "Unknown";
162 }
163}