summaryrefslogtreecommitdiff
path: root/utils/rbutilqt/quazip/quazipfileinfo.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'utils/rbutilqt/quazip/quazipfileinfo.cpp')
-rw-r--r--utils/rbutilqt/quazip/quazipfileinfo.cpp196
1 files changed, 196 insertions, 0 deletions
diff --git a/utils/rbutilqt/quazip/quazipfileinfo.cpp b/utils/rbutilqt/quazip/quazipfileinfo.cpp
new file mode 100644
index 0000000000..d5798ea771
--- /dev/null
+++ b/utils/rbutilqt/quazip/quazipfileinfo.cpp
@@ -0,0 +1,196 @@
1/*
2Copyright (C) 2005-2014 Sergey A. Tachenov
3
4This file is part of QuaZIP.
5
6QuaZIP is free software: you can redistribute it and/or modify
7it under the terms of the GNU Lesser General Public License as published by
8the Free Software Foundation, either version 2.1 of the License, or
9(at your option) any later version.
10
11QuaZIP is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU Lesser General Public License for more details.
15
16You should have received a copy of the GNU Lesser General Public License
17along with QuaZIP. If not, see <http://www.gnu.org/licenses/>.
18
19See COPYING file for the full LGPL text.
20
21Original ZIP package is copyrighted by Gilles Vollant and contributors,
22see quazip/(un)zip.h files for details. Basically it's the zlib license.
23*/
24
25#include "quazipfileinfo.h"
26
27#include <QtCore/QDataStream>
28
29static QFile::Permissions permissionsFromExternalAttr(quint32 externalAttr) {
30 quint32 uPerm = (externalAttr & 0xFFFF0000u) >> 16;
31 QFile::Permissions perm = QFile::Permissions();
32 if ((uPerm & 0400) != 0)
33 perm |= QFile::ReadOwner;
34 if ((uPerm & 0200) != 0)
35 perm |= QFile::WriteOwner;
36 if ((uPerm & 0100) != 0)
37 perm |= QFile::ExeOwner;
38 if ((uPerm & 0040) != 0)
39 perm |= QFile::ReadGroup;
40 if ((uPerm & 0020) != 0)
41 perm |= QFile::WriteGroup;
42 if ((uPerm & 0010) != 0)
43 perm |= QFile::ExeGroup;
44 if ((uPerm & 0004) != 0)
45 perm |= QFile::ReadOther;
46 if ((uPerm & 0002) != 0)
47 perm |= QFile::WriteOther;
48 if ((uPerm & 0001) != 0)
49 perm |= QFile::ExeOther;
50 return perm;
51
52}
53
54QFile::Permissions QuaZipFileInfo::getPermissions() const
55{
56 return permissionsFromExternalAttr(externalAttr);
57}
58
59QFile::Permissions QuaZipFileInfo64::getPermissions() const
60{
61 return permissionsFromExternalAttr(externalAttr);
62}
63
64bool QuaZipFileInfo64::toQuaZipFileInfo(QuaZipFileInfo &info) const
65{
66 bool noOverflow = true;
67 info.name = name;
68 info.versionCreated = versionCreated;
69 info.versionNeeded = versionNeeded;
70 info.flags = flags;
71 info.method = method;
72 info.dateTime = dateTime;
73 info.crc = crc;
74 if (compressedSize > 0xFFFFFFFFu) {
75 info.compressedSize = 0xFFFFFFFFu;
76 noOverflow = false;
77 } else {
78 info.compressedSize = compressedSize;
79 }
80 if (uncompressedSize > 0xFFFFFFFFu) {
81 info.uncompressedSize = 0xFFFFFFFFu;
82 noOverflow = false;
83 } else {
84 info.uncompressedSize = uncompressedSize;
85 }
86 info.diskNumberStart = diskNumberStart;
87 info.internalAttr = internalAttr;
88 info.externalAttr = externalAttr;
89 info.comment = comment;
90 info.extra = extra;
91 return noOverflow;
92}
93
94static QDateTime getNTFSTime(const QByteArray &extra, int position,
95 int *fineTicks)
96{
97 QDateTime dateTime;
98 QuaExtraFieldHash extraHash = QuaZipFileInfo64::parseExtraField(extra);
99 QList<QByteArray> ntfsExtraFields = extraHash[QUAZIP_EXTRA_NTFS_MAGIC];
100 if (ntfsExtraFields.isEmpty())
101 return dateTime;
102 QByteArray ntfsExtraField = ntfsExtraFields.at(0);
103 if (ntfsExtraField.length() <= 4)
104 return dateTime;
105 QByteArray ntfsAttributes = ntfsExtraField.mid(4);
106 QuaExtraFieldHash ntfsHash = QuaZipFileInfo64::parseExtraField(ntfsAttributes);
107 QList<QByteArray> ntfsTimeAttributes = ntfsHash[QUAZIP_EXTRA_NTFS_TIME_MAGIC];
108 if (ntfsTimeAttributes.isEmpty())
109 return dateTime;
110 QByteArray ntfsTimes = ntfsTimeAttributes.at(0);
111 if (ntfsTimes.size() < 24)
112 return dateTime;
113 QDataStream timeReader(ntfsTimes);
114 timeReader.setByteOrder(QDataStream::LittleEndian);
115 timeReader.device()->seek(position);
116 quint64 time;
117 timeReader >> time;
118 QDateTime base(QDate(1601, 1, 1), QTime(0, 0), Qt::UTC);
119 dateTime = base.addMSecs(time / 10000);
120 if (fineTicks != NULL) {
121 *fineTicks = static_cast<int>(time % 10000);
122 }
123 return dateTime;
124}
125
126QDateTime QuaZipFileInfo64::getNTFSmTime(int *fineTicks) const
127{
128 return getNTFSTime(extra, 0, fineTicks);
129}
130
131QDateTime QuaZipFileInfo64::getNTFSaTime(int *fineTicks) const
132{
133 return getNTFSTime(extra, 8, fineTicks);
134}
135
136QDateTime QuaZipFileInfo64::getNTFScTime(int *fineTicks) const
137{
138 return getNTFSTime(extra, 16, fineTicks);
139}
140
141QDateTime QuaZipFileInfo64::getExtTime(const QByteArray &extra, int flag)
142{
143 QDateTime dateTime;
144 QuaExtraFieldHash extraHash = QuaZipFileInfo64::parseExtraField(extra);
145 QList<QByteArray> extTimeFields = extraHash[QUAZIP_EXTRA_EXT_TIME_MAGIC];
146 if (extTimeFields.isEmpty())
147 return dateTime;
148 QByteArray extTimeField = extTimeFields.at(0);
149 if (extTimeField.length() < 1)
150 return dateTime;
151 QDataStream input(extTimeField);
152 input.setByteOrder(QDataStream::LittleEndian);
153 quint8 flags;
154 input >> flags;
155 int flagsRemaining = flags;
156 while (!input.atEnd()) {
157 int nextFlag = flagsRemaining & -flagsRemaining;
158 flagsRemaining &= flagsRemaining - 1;
159 qint32 time;
160 input >> time;
161 if (nextFlag == flag) {
162 QDateTime base(QDate(1970, 1, 1), QTime(0, 0), Qt::UTC);
163 dateTime = base.addSecs(time);
164 return dateTime;
165 }
166 }
167 return dateTime;
168}
169
170QDateTime QuaZipFileInfo64::getExtModTime() const
171{
172 return getExtTime(extra, 1);
173}
174
175QuaExtraFieldHash QuaZipFileInfo64::parseExtraField(const QByteArray &extraField)
176{
177 QDataStream input(extraField);
178 input.setByteOrder(QDataStream::LittleEndian);
179 QHash<quint16, QList<QByteArray> > result;
180 while (!input.atEnd()) {
181 quint16 id, size;
182 input >> id;
183 if (input.status() == QDataStream::ReadPastEnd)
184 return result;
185 input >> size;
186 if (input.status() == QDataStream::ReadPastEnd)
187 return result;
188 QByteArray data;
189 data.resize(size);
190 int read = input.readRawData(data.data(), data.size());
191 if (read < data.size())
192 return result;
193 result[id] << data;
194 }
195 return result;
196}