ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
quazipnewinfo.cpp
Go to the documentation of this file.
1 /*
2 Copyright (C) 2005-2014 Sergey A. Tachenov
3 
4 This file is part of QuaZIP.
5 
6 QuaZIP is free software: you can redistribute it and/or modify
7 it under the terms of the GNU Lesser General Public License as published by
8 the Free Software Foundation, either version 2.1 of the License, or
9 (at your option) any later version.
10 
11 QuaZIP is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU Lesser General Public License for more details.
15 
16 You should have received a copy of the GNU Lesser General Public License
17 along with QuaZIP. If not, see <http://www.gnu.org/licenses/>.
18 
19 See COPYING file for the full LGPL text.
20 
21 Original ZIP package is copyrighted by Gilles Vollant and contributors,
22 see quazip/(un)zip.h files for details. Basically it's the zlib license.
23 */
24 
25 #include "quazipnewinfo.h"
26 
27 #include <string.h>
28 
29 #include <QFileInfo>
30 
32  QFile::Permissions perm,
33  bool isDir,
34  bool isSymLink = false) {
35  quint32 uPerm = isDir ? 0040000 : 0100000;
36 
37  if (isSymLink) {
38 #ifdef Q_OS_WIN
39  uPerm = 0200000;
40 #else
41  uPerm = 0120000;
42 #endif
43  }
44 
45  if ((perm & QFile::ReadOwner) != 0) uPerm |= 0400;
46  if ((perm & QFile::WriteOwner) != 0) uPerm |= 0200;
47  if ((perm & QFile::ExeOwner) != 0) uPerm |= 0100;
48  if ((perm & QFile::ReadGroup) != 0) uPerm |= 0040;
49  if ((perm & QFile::WriteGroup) != 0) uPerm |= 0020;
50  if ((perm & QFile::ExeGroup) != 0) uPerm |= 0010;
51  if ((perm & QFile::ReadOther) != 0) uPerm |= 0004;
52  if ((perm & QFile::WriteOther) != 0) uPerm |= 0002;
53  if ((perm & QFile::ExeOther) != 0) uPerm |= 0001;
54  info->externalAttr = (info->externalAttr & ~0xFFFF0000u) | (uPerm << 16);
55 }
56 
57 template <typename FileInfo>
58 void QuaZipNewInfo_init(QuaZipNewInfo &self, const FileInfo &existing) {
59  self.name = existing.name;
60  self.dateTime = existing.dateTime;
61  self.internalAttr = existing.internalAttr;
62  self.externalAttr = existing.externalAttr;
63  self.comment = existing.comment;
64  self.extraLocal = existing.extra;
65  self.extraGlobal = existing.extra;
66  self.uncompressedSize = existing.uncompressedSize;
67 }
68 
70  QuaZipNewInfo_init(*this, existing);
71 }
72 
74  QuaZipNewInfo_init(*this, existing);
75 }
76 
78  : name(name),
79  dateTime(QDateTime::currentDateTime()),
80  internalAttr(0),
81  externalAttr(0),
82  uncompressedSize(0) {}
83 
84 QuaZipNewInfo::QuaZipNewInfo(const QString &name, const QString &file)
85  : name(name), internalAttr(0), externalAttr(0), uncompressedSize(0) {
86  QFileInfo info(file);
87  QDateTime lm = info.lastModified();
88  if (!info.exists()) {
89  dateTime = QDateTime::currentDateTime();
90  } else {
91  dateTime = lm;
92  QuaZipNewInfo_setPermissions(this, info.permissions(), info.isDir(),
93  info.isSymLink());
94  }
95 }
96 
97 void QuaZipNewInfo::setFileDateTime(const QString &file) {
98  QFileInfo info(file);
99  QDateTime lm = info.lastModified();
100  if (info.exists()) dateTime = lm;
101 }
102 
103 void QuaZipNewInfo::setFilePermissions(const QString &file) {
104  QFileInfo info = QFileInfo(file);
105  QFile::Permissions perm = info.permissions();
106  QuaZipNewInfo_setPermissions(this, perm, info.isDir(), info.isSymLink());
107 }
108 
109 void QuaZipNewInfo::setPermissions(QFile::Permissions permissions) {
110  QuaZipNewInfo_setPermissions(this, permissions, name.endsWith('/'));
111 }
112 
113 void QuaZipNewInfo::setFileNTFSTimes(const QString &fileName) {
114  QFileInfo fi(fileName);
115  if (!fi.exists()) {
116  qWarning("QuaZipNewInfo::setFileNTFSTimes(): '%s' doesn't exist",
117  fileName.toUtf8().constData());
118  return;
119  }
120  setFileNTFSmTime(fi.lastModified());
121  setFileNTFSaTime(fi.lastRead());
122 #if QT_DEPRECATED_SINCE(5, 10)
123  setFileNTFScTime(fi.birthTime());
124 #else
125  setFileNTFScTime(fi.created());
126 #endif
127 }
128 
129 static void setNTFSTime(QByteArray &extra,
130  const QDateTime &time,
131  int position,
132  int fineTicks) {
133  int ntfsPos = -1, timesPos = -1;
134  unsigned ntfsLength = 0, ntfsTimesLength = 0;
135  for (int i = 0; i <= extra.size() - 4;) {
136  unsigned type =
137  static_cast<unsigned>(static_cast<unsigned char>(extra.at(i))) |
138  (static_cast<unsigned>(
139  static_cast<unsigned char>(extra.at(i + 1)))
140  << 8);
141  i += 2;
142  unsigned length =
143  static_cast<unsigned>(static_cast<unsigned char>(extra.at(i))) |
144  (static_cast<unsigned>(
145  static_cast<unsigned char>(extra.at(i + 1)))
146  << 8);
147  i += 2;
148  if (type == QUAZIP_EXTRA_NTFS_MAGIC) {
149  ntfsPos = i - 4; // the beginning of the NTFS record
150  ntfsLength = length;
151  if (length <= 4) {
152  break; // no times in the NTFS record
153  }
154  i += 4; // reserved
155  while (i <= extra.size() - 4) {
156  unsigned tag =
157  static_cast<unsigned>(
158  static_cast<unsigned char>(extra.at(i))) |
159  (static_cast<unsigned>(
160  static_cast<unsigned char>(extra.at(i + 1)))
161  << 8);
162  i += 2;
163  unsigned tagsize =
164  static_cast<unsigned>(
165  static_cast<unsigned char>(extra.at(i))) |
166  (static_cast<unsigned>(
167  static_cast<unsigned char>(extra.at(i + 1)))
168  << 8);
169  i += 2;
170  if (tag == QUAZIP_EXTRA_NTFS_TIME_MAGIC) {
171  timesPos = i - 4; // the beginning of the NTFS times tag
172  ntfsTimesLength = tagsize;
173  break;
174  } else {
175  i += tagsize;
176  }
177  }
178  break; // I ain't going to search for yet another NTFS record!
179  } else {
180  i += length;
181  }
182  }
183  if (ntfsPos == -1) {
184  // No NTFS record, need to create one.
185  ntfsPos = extra.size();
186  ntfsLength = 32;
187  extra.resize(extra.size() + 4 + ntfsLength);
188  // the NTFS record header
189  extra[ntfsPos] = static_cast<char>(QUAZIP_EXTRA_NTFS_MAGIC);
190  extra[ntfsPos + 1] = static_cast<char>(QUAZIP_EXTRA_NTFS_MAGIC >> 8);
191  extra[ntfsPos + 2] = 32; // the 2-byte size in LittleEndian
192  extra[ntfsPos + 3] = 0;
193  // zero the record
194  memset(extra.data() + ntfsPos + 4, 0, 32);
195  timesPos = ntfsPos + 8;
196  // now set the tag data
197  extra[timesPos] = static_cast<char>(QUAZIP_EXTRA_NTFS_TIME_MAGIC);
198  extra[timesPos + 1] =
199  static_cast<char>(QUAZIP_EXTRA_NTFS_TIME_MAGIC >> 8);
200  // the size:
201  extra[timesPos + 2] = 24;
202  extra[timesPos + 3] = 0;
203  ntfsTimesLength = 24;
204  }
205  if (timesPos == -1) {
206  // No time tag in the NTFS record, need to add one.
207  timesPos = ntfsPos + 4 + ntfsLength;
208  extra.resize(extra.size() + 28);
209  // Now we need to move the rest of the field
210  // (possibly zero bytes, but memmove() is OK with that).
211  // 0 ......... ntfsPos .. ntfsPos + 4 ... timesPos
212  // <some data> <header> <NTFS record> <need-to-move data> <end>
213  memmove(extra.data() + timesPos + 28, extra.data() + timesPos,
214  extra.size() - 28 - timesPos);
215  ntfsLength += 28;
216  // now set the tag data
217  extra[timesPos] = static_cast<char>(QUAZIP_EXTRA_NTFS_TIME_MAGIC);
218  extra[timesPos + 1] =
219  static_cast<char>(QUAZIP_EXTRA_NTFS_TIME_MAGIC >> 8);
220  // the size:
221  extra[timesPos + 2] = 24;
222  extra[timesPos + 3] = 0;
223  // zero the record
224  memset(extra.data() + timesPos + 4, 0, 24);
225  ntfsTimesLength = 24;
226  }
227  if (ntfsTimesLength < 24) {
228  // Broken times field. OK, this is really unlikely, but just in case...
229  size_t timesEnd = timesPos + 4 + ntfsTimesLength;
230  extra.resize(extra.size() + (24 - ntfsTimesLength));
231  // Move it!
232  // 0 ......... timesPos .... timesPos + 4 .. timesEnd
233  // <some data> <time header> <broken times> <need-to-move data> <end>
234  memmove(extra.data() + timesEnd + (24 - ntfsTimesLength),
235  extra.data() + timesEnd,
236  extra.size() - (24 - ntfsTimesLength) - timesEnd);
237  // Now we have to increase the NTFS record and time tag lengths.
238  ntfsLength += (24 - ntfsTimesLength);
239  ntfsTimesLength = 24;
240  extra[ntfsPos + 2] = static_cast<char>(ntfsLength);
241  extra[ntfsPos + 3] = static_cast<char>(ntfsLength >> 8);
242  extra[timesPos + 2] = static_cast<char>(ntfsTimesLength);
243  extra[timesPos + 3] = static_cast<char>(ntfsTimesLength >> 8);
244  }
245  QDateTime base(QDate(1601, 1, 1), QTime(0, 0), Qt::UTC);
246 #if (QT_VERSION >= 0x040700)
247  quint64 ticks = base.msecsTo(time) * 10000 + fineTicks;
248 #else
249  QDateTime utc = time.toUTC();
250  quint64 ticks = (static_cast<qint64>(base.date().daysTo(utc.date())) *
251  Q_INT64_C(86400000) +
252  static_cast<qint64>(base.time().msecsTo(utc.time()))) *
253  Q_INT64_C(10000) +
254  fineTicks;
255 #endif
256  extra[timesPos + 4 + position] = static_cast<char>(ticks);
257  extra[timesPos + 5 + position] = static_cast<char>(ticks >> 8);
258  extra[timesPos + 6 + position] = static_cast<char>(ticks >> 16);
259  extra[timesPos + 7 + position] = static_cast<char>(ticks >> 24);
260  extra[timesPos + 8 + position] = static_cast<char>(ticks >> 32);
261  extra[timesPos + 9 + position] = static_cast<char>(ticks >> 40);
262  extra[timesPos + 10 + position] = static_cast<char>(ticks >> 48);
263  extra[timesPos + 11 + position] = static_cast<char>(ticks >> 56);
264 }
265 
266 void QuaZipNewInfo::setFileNTFSmTime(const QDateTime &mTime, int fineTicks) {
267  setNTFSTime(extraLocal, mTime, 0, fineTicks);
268  setNTFSTime(extraGlobal, mTime, 0, fineTicks);
269 }
270 
271 void QuaZipNewInfo::setFileNTFSaTime(const QDateTime &aTime, int fineTicks) {
272  setNTFSTime(extraLocal, aTime, 8, fineTicks);
273  setNTFSTime(extraGlobal, aTime, 8, fineTicks);
274 }
275 
276 void QuaZipNewInfo::setFileNTFScTime(const QDateTime &cTime, int fineTicks) {
277  setNTFSTime(extraLocal, cTime, 16, fineTicks);
278  setNTFSTime(extraGlobal, cTime, 16, fineTicks);
279 }
std::string name
char type
math::float3 position
__host__ __device__ float length(float2 v)
Definition: cutil_math.h:1162
#define QUAZIP_EXTRA_NTFS_TIME_MAGIC
Definition: quazip_global.h:57
#define QUAZIP_EXTRA_NTFS_MAGIC
Definition: quazip_global.h:56
void QuaZipNewInfo_init(QuaZipNewInfo &self, const FileInfo &existing)
static void QuaZipNewInfo_setPermissions(QuaZipNewInfo *info, QFile::Permissions perm, bool isDir, bool isSymLink=false)
static void setNTFSTime(QByteArray &extra, const QDateTime &time, int position, int fineTicks)
Information about a file inside archive (with zip64 support).
Information about a file inside archive.
Information about a file to be created.
Definition: quazipnewinfo.h:49
void setFilePermissions(const QString &file)
Sets the file permissions from the existing file.
void setFileNTFSaTime(const QDateTime &aTime, int fineTicks=0)
Sets the NTFS access time.
void setFileDateTime(const QString &file)
Sets the file timestamp from the existing file.
QString name
File name.
Definition: quazipnewinfo.h:54
void setFileNTFSmTime(const QDateTime &mTime, int fineTicks=0)
Sets the NTFS modification time.
void setFileNTFScTime(const QDateTime &cTime, int fineTicks=0)
Sets the NTFS creation time.
QuaZipNewInfo(const QString &name)
Constructs QuaZipNewInfo instance.
void setFileNTFSTimes(const QString &fileName)
Sets the NTFS times from an existing file.
QByteArray extraLocal
File local extra field.
Definition: quazipnewinfo.h:76
QByteArray extraGlobal
File global extra field.
Definition: quazipnewinfo.h:78
QDateTime dateTime
File timestamp.
Definition: quazipnewinfo.h:61
void setPermissions(QFile::Permissions permissions)
Sets the file permissions.
quint32 externalAttr
File external attributes.
Definition: quazipnewinfo.h:70