diff options
Diffstat (limited to 'rbutil/rbutilqt/base/mspackutil.cpp')
-rw-r--r-- | rbutil/rbutilqt/base/mspackutil.cpp | 163 |
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 | |||
24 | MsPackUtil::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 | |||
33 | MsPackUtil::~MsPackUtil() | ||
34 | { | ||
35 | close(); | ||
36 | if(m_cabd) | ||
37 | mspack_destroy_cab_decompressor(m_cabd); | ||
38 | } | ||
39 | |||
40 | bool 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 | |||
53 | bool 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 | |||
61 | bool 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 | |||
123 | QStringList 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 | |||
145 | QString 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 | } | ||