KIO

udsentry.cpp
1 /* This file is part of the KDE project
2  Copyright (C) 2000-2005 David Faure <[email protected]>
3  Copyright (C) 2007 Norbert Frese <[email protected]>
4  Copyright (C) 2007 Thiago Macieira <[email protected]>
5  Copyright (C) 2013-2014 Frank Reininghaus <[email protected]>
6 
7  This library is free software; you can redistribute it and/or
8  modify it under the terms of the GNU Library General Public
9  License as published by the Free Software Foundation; either
10  version 2 of the License, or (at your option) any later version.
11 
12  This library is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  Library General Public License for more details.
16 
17  You should have received a copy of the GNU Library General Public License
18  along with this library; see the file COPYING.LIB. If not, write to
19  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20  Boston, MA 02110-1301, USA.
21 */
22 
23 #include "udsentry.h"
24 
25 #include <QString>
26 #include <QList>
27 #include <QDataStream>
28 #include <QVector>
29 #include <QDebug>
30 
31 #include <KUser>
32 
33 using namespace KIO;
34 
35 //BEGIN UDSEntryPrivate
36 /* ---------- UDSEntryPrivate ------------ */
37 
38 class KIO::UDSEntryPrivate : public QSharedData
39 {
40 public:
41  void reserve(int size);
42  void insert(uint udsField, const QString &value);
43  void replace(uint udsField, const QString &value);
44  void insert(uint udsField, long long value);
45  void replace(uint udsField, long long value);
46  int count() const;
47  QString stringValue(uint udsField) const;
48  long long numberValue(uint udsField, long long defaultValue = -1) const;
49 #if KIOCORE_BUILD_DEPRECATED_SINCE(5, 8)
50  QList<uint> listFields() const;
51 #endif
52  QVector<uint> fields() const;
53  bool contains(uint udsField) const;
54  void clear();
55  void save(QDataStream &s) const;
56  void load(QDataStream &s);
57  void debugUDSEntry(QDebug &stream) const;
62  static QString nameOfUdsField(uint field);
63 
64 private:
65  struct Field
66  {
67  inline Field() {}
68  inline Field(const uint index, const QString &value) : m_str(value), m_index(index) {}
69  inline Field(const uint index, long long value = 0) : m_long(value), m_index(index) {}
70 
71  QString m_str;
72  long long m_long = LLONG_MIN;
73  uint m_index = 0;
74  };
75  std::vector<Field> storage;
76 };
77 
78 void UDSEntryPrivate::reserve(int size)
79 {
80  storage.reserve(size);
81 }
82 
83 void UDSEntryPrivate::insert(uint udsField, const QString &value)
84 {
85  Q_ASSERT(udsField & KIO::UDSEntry::UDS_STRING);
86  Q_ASSERT(std::find_if(storage.cbegin(), storage.cend(),
87  [udsField](const Field &entry) {return entry.m_index == udsField;}) == storage.cend());
88  storage.emplace_back(udsField, value);
89 }
90 
91 void UDSEntryPrivate::replace(uint udsField, const QString &value)
92 {
93  Q_ASSERT(udsField & KIO::UDSEntry::UDS_STRING);
94  auto it = std::find_if(storage.begin(), storage.end(),
95  [udsField](const Field &entry) {return entry.m_index == udsField;});
96  if (it != storage.end()) {
97  it->m_str = value;
98  return;
99  }
100  storage.emplace_back(udsField, value);
101 }
102 
103 void UDSEntryPrivate::insert(uint udsField, long long value)
104 {
105  Q_ASSERT(udsField & KIO::UDSEntry::UDS_NUMBER);
106  Q_ASSERT(std::find_if(storage.cbegin(), storage.cend(),
107  [udsField](const Field &entry) {return entry.m_index == udsField;}) == storage.cend());
108  storage.emplace_back(udsField, value);
109 }
110 
111 void UDSEntryPrivate::replace(uint udsField, long long value)
112 {
113  Q_ASSERT(udsField & KIO::UDSEntry::UDS_NUMBER);
114  auto it = std::find_if(storage.begin(), storage.end(),
115  [udsField](const Field &entry) {return entry.m_index == udsField;});
116  if (it != storage.end()) {
117  it->m_long = value;
118  return;
119  }
120  storage.emplace_back(udsField, value);
121 }
122 
123 int UDSEntryPrivate::count() const
124 {
125  return storage.size();
126 }
127 
128 QString UDSEntryPrivate::stringValue(uint udsField) const
129 {
130  auto it = std::find_if(storage.cbegin(), storage.cend(),
131  [udsField](const Field &entry) {return entry.m_index == udsField;});
132  if (it != storage.cend()) {
133  return it->m_str;
134  }
135  return QString();
136 }
137 
138 long long UDSEntryPrivate::numberValue(uint udsField, long long defaultValue) const
139 {
140  auto it = std::find_if(storage.cbegin(), storage.cend(),
141  [udsField](const Field &entry) {return entry.m_index == udsField;});
142  if (it != storage.cend()) {
143  return it->m_long;
144  }
145  return defaultValue;
146 }
147 
148 #if KIOCORE_BUILD_DEPRECATED_SINCE(5, 8)
149 QList<uint> UDSEntryPrivate::listFields() const
150 {
151  QList<uint> res;
152  res.reserve(storage.size());
153  for (const Field &field : storage) {
154  res.append(field.m_index);
155  }
156  return res;
157 }
158 #endif
159 
160 QVector<uint> UDSEntryPrivate::fields() const
161 {
162  QVector<uint> res;
163  res.reserve(storage.size());
164  for (const Field &field : storage) {
165  res.append(field.m_index);
166  }
167  return res;
168 }
169 
170 bool UDSEntryPrivate::contains(uint udsField) const
171 {
172  auto it = std::find_if(storage.cbegin(), storage.cend(),
173  [udsField](const Field &entry) {return entry.m_index == udsField;});
174  return (it != storage.cend());
175 }
176 
177 void UDSEntryPrivate::clear()
178 {
179  storage.clear();
180 }
181 
182 void UDSEntryPrivate::save(QDataStream &s) const
183 {
184  s << static_cast<quint32>(storage.size());
185 
186  for (const Field &field : storage) {
187  uint uds = field.m_index;
188  s << uds;
189 
190  if (uds & KIO::UDSEntry::UDS_STRING) {
191  s << field.m_str;
192  } else if (uds & KIO::UDSEntry::UDS_NUMBER) {
193  s << field.m_long;
194  } else {
195  Q_ASSERT_X(false, "KIO::UDSEntry", "Found a field with an invalid type");
196  }
197  }
198 }
199 
200 void UDSEntryPrivate::load(QDataStream &s)
201 {
202  clear();
203 
204  quint32 size;
205  s >> size;
206  reserve(size);
207 
208  // We cache the loaded strings. Some of them, like, e.g., the user,
209  // will often be the same for many entries in a row. Caching them
210  // permits to use implicit sharing to save memory.
211  static QVector<QString> cachedStrings;
212  if (quint32(cachedStrings.size()) < size) {
213  cachedStrings.resize(size);
214  }
215 
216  for (quint32 i = 0; i < size; ++i) {
217  quint32 uds;
218  s >> uds;
219 
220  if (uds & KIO::UDSEntry::UDS_STRING) {
221  // If the QString is the same like the one we read for the
222  // previous UDSEntry at the i-th position, use an implicitly
223  // shared copy of the same QString to save memory.
224  QString buffer;
225  s >> buffer;
226 
227  if (buffer != cachedStrings.at(i)) {
228  cachedStrings[i] = buffer;
229  }
230 
231  insert(uds, cachedStrings.at(i));
232  } else if (uds & KIO::UDSEntry::UDS_NUMBER) {
233  long long value;
234  s >> value;
235  insert(uds, value);
236  } else {
237  Q_ASSERT_X(false, "KIO::UDSEntry", "Found a field with an invalid type");
238  }
239  }
240 }
241 
242 QString UDSEntryPrivate::nameOfUdsField(uint field)
243 {
244  switch (field) {
245  case UDSEntry::UDS_SIZE:
246  return QStringLiteral("UDS_SIZE");
248  return QStringLiteral("UDS_SIZE_LARGE");
249  case UDSEntry::UDS_USER:
250  return QStringLiteral("UDS_USER");
252  return QStringLiteral("UDS_ICON_NAME");
253  case UDSEntry::UDS_GROUP:
254  return QStringLiteral("UDS_GROUP");
255  case UDSEntry::UDS_NAME:
256  return QStringLiteral("UDS_NAME");
258  return QStringLiteral("UDS_LOCAL_PATH");
260  return QStringLiteral("UDS_HIDDEN");
262  return QStringLiteral("UDS_ACCESS");
264  return QStringLiteral("UDS_MODIFICATION_TIME");
266  return QStringLiteral("UDS_ACCESS_TIME");
268  return QStringLiteral("UDS_CREATION_TIME");
270  return QStringLiteral("UDS_FILE_TYPE");
272  return QStringLiteral("UDS_LINK_DEST");
273  case UDSEntry::UDS_URL:
274  return QStringLiteral("UDS_URL");
276  return QStringLiteral("UDS_MIME_TYPE");
278  return QStringLiteral("UDS_GUESSED_MIME_TYPE");
280  return QStringLiteral("UDS_XML_PROPERTIES");
282  return QStringLiteral("UDS_EXTENDED_ACL");
284  return QStringLiteral("UDS_ACL_STRING");
286  return QStringLiteral("UDS_DEFAULT_ACL_STRING");
288  return QStringLiteral("UDS_DISPLAY_NAME");
290  return QStringLiteral("UDS_TARGET_URL");
292  return QStringLiteral("UDS_DISPLAY_TYPE");
294  return QStringLiteral("UDS_ICON_OVERLAY_NAMES");
296  return QStringLiteral("UDS_COMMENT");
298  return QStringLiteral("UDS_DEVICE_ID");
299  case UDSEntry::UDS_INODE:
300  return QStringLiteral("UDS_INODE");
301  case UDSEntry::UDS_EXTRA:
302  return QStringLiteral("UDS_EXTRA");
304  return QStringLiteral("UDS_EXTRA_END");
305  default:
306  return QStringLiteral("Unknown uds field %1").arg(field);
307  }
308 }
309 
310 void UDSEntryPrivate::debugUDSEntry(QDebug &stream) const
311 {
312  QDebugStateSaver saver(stream);
313  stream.nospace() << "[";
314  for (const Field &field : storage) {
315  stream << " " << nameOfUdsField(field.m_index) << "=";
316  if (field.m_index & KIO::UDSEntry::UDS_STRING) {
317  stream << field.m_str;
318  } else if (field.m_index & KIO::UDSEntry::UDS_NUMBER) {
319  stream << field.m_long;
320  } else {
321  Q_ASSERT_X(false, "KIO::UDSEntry", "Found a field with an invalid type");
322  }
323  }
324  stream << " ]";
325 }
326 //END UDSEntryPrivate
327 
328 //BEGIN UDSEntry
329 /* ---------- UDSEntry ------------ */
330 
331 UDSEntry::UDSEntry()
332  : d(new UDSEntryPrivate())
333 {
334 }
335 
336 // BUG: this API doesn't allow to handle symlinks correctly (we need buff from QT_LSTAT for most things, but buff from QT_STAT for st_mode and st_size)
337 UDSEntry::UDSEntry(const QT_STATBUF &buff, const QString &name)
338  : d(new UDSEntryPrivate())
339 {
340 #ifndef Q_OS_WIN
341  d->reserve(10);
342 #else
343  d->reserve(8);
344 #endif
345  d->insert(UDS_NAME, name);
346  d->insert(UDS_SIZE, buff.st_size);
347  d->insert(UDS_DEVICE_ID, buff.st_dev);
348  d->insert(UDS_INODE, buff.st_ino);
349  d->insert(UDS_FILE_TYPE, buff.st_mode & QT_STAT_MASK); // extract file type
350  d->insert(UDS_ACCESS, buff.st_mode & 07777); // extract permissions
351  d->insert(UDS_MODIFICATION_TIME, buff.st_mtime);
352  d->insert(UDS_ACCESS_TIME, buff.st_atime);
353 #ifndef Q_OS_WIN
354  d->insert(UDS_USER, KUser(buff.st_uid).loginName());
355  d->insert(UDS_GROUP, KUserGroup(buff.st_gid).name());
356 #endif
357 }
358 
359 UDSEntry::UDSEntry(const UDSEntry&) = default;
360 UDSEntry::~UDSEntry() = default;
361 UDSEntry::UDSEntry(UDSEntry&&) = default;
362 UDSEntry& UDSEntry::operator=(const UDSEntry&) = default;
364 
366 {
367  return d->stringValue(field);
368 }
369 
370 long long UDSEntry::numberValue(uint field, long long defaultValue) const
371 {
372  return d->numberValue(field, defaultValue);
373 }
374 
375 bool UDSEntry::isDir() const
376 {
377  return (numberValue(UDS_FILE_TYPE) & QT_STAT_MASK) == QT_STAT_DIR;
378 }
379 
380 bool UDSEntry::isLink() const
381 {
382  return !stringValue(UDS_LINK_DEST).isEmpty();
383 }
384 
385 void UDSEntry::reserve(int size)
386 {
387  d->reserve(size);
388 }
389 
390 void UDSEntry::fastInsert(uint field, const QString &value)
391 {
392  d->insert(field, value);
393 }
394 
395 void UDSEntry::fastInsert(uint field, long long value)
396 {
397  d->insert(field, value);
398 }
399 
400 #if KIOCORE_BUILD_DEPRECATED_SINCE(5, 48)
401 void UDSEntry::insert(uint field, const QString &value)
402 {
403  d->replace(field, value);
404 }
405 #endif
406 
407 #if KIOCORE_BUILD_DEPRECATED_SINCE(5, 48)
408 void UDSEntry::insert(uint field, long long value)
409 {
410  d->replace(field, value);
411 }
412 #endif
413 
414 void UDSEntry::replace(uint field, const QString &value)
415 {
416  d->replace(field, value);
417 }
418 
419 void UDSEntry::replace(uint field, long long value)
420 {
421  d->replace(field, value);
422 }
423 
424 #if KIOCORE_BUILD_DEPRECATED_SINCE(5, 8)
426 {
427  return d->listFields();
428 }
429 #endif
430 
432 {
433  return d->fields();
434 }
435 
436 int UDSEntry::count() const
437 {
438  return d->count();
439 }
440 
441 bool UDSEntry::contains(uint field) const
442 {
443  return d->contains(field);
444 }
445 
447 {
448  d->clear();
449 }
450 //END UDSEntry
451 
452 KIOCORE_EXPORT QDebug operator<<(QDebug stream, const KIO::UDSEntry &entry)
453 {
454  entry.d->debugUDSEntry(stream);
455  return stream;
456 }
457 
458 KIOCORE_EXPORT QDataStream &operator<<(QDataStream &s, const KIO::UDSEntry &a)
459 {
460  a.d->save(s);
461  return s;
462 }
463 
464 KIOCORE_EXPORT QDataStream &operator>>(QDataStream &s, KIO::UDSEntry &a)
465 {
466  a.d->load(s);
467  return s;
468 }
469 
470 KIOCORE_EXPORT bool operator==(const KIO::UDSEntry &entry, const KIO::UDSEntry &other)
471 {
472  if (entry.count() != other.count()) {
473  return false;
474  }
475 
476  const QVector<uint> fields = entry.fields();
477  for (uint field : fields) {
478  if (!other.contains(field)) {
479  return false;
480  }
481 
482  if (field & UDSEntry::UDS_STRING) {
483  if (entry.stringValue(field) != other.stringValue(field)) {
484  return false;
485  }
486  } else {
487  if (entry.numberValue(field) != other.numberValue(field)) {
488  return false;
489  }
490  }
491  }
492 
493  return true;
494 }
495 
496 KIOCORE_EXPORT bool operator!=(const KIO::UDSEntry &entry, const KIO::UDSEntry &other)
497 {
498  return !(entry == other);
499 }
An alternative URL (If different from the caption).
Definition: udsentry.h:288
XML properties, e.g. for WebDAV.
Definition: udsentry.h:296
Indicates that the field is a QString.
Definition: udsentry.h:233
bool isLink() const
Definition: udsentry.cpp:380
This file is a shortcut or mount, pointing to an URL in a different hierarchy.
Definition: udsentry.h:313
void clear()
remove all fields
Definition: udsentry.cpp:446
QString name() const
void append(const T &value)
Device number for this file, used to detect hardlinks.
Definition: udsentry.h:339
Universal Directory Service.
Definition: udsentry.h:88
The access control list serialized into a single string.
Definition: udsentry.h:301
A namespace for KIO globals.
Definition: authinfo.h:34
QList< uint > listFields() const
List all fields.
Definition: udsentry.cpp:425
void reserve(int alloc)
void insert(uint field, const QString &value)
insert field with string value
Definition: udsentry.cpp:401
The default access control list serialized into a single string.
Definition: udsentry.h:304
void reserve(int size)
Calling this function before inserting items into an empty UDSEntry may save time and memory...
Definition: udsentry.cpp:385
File type, part of the mode returned by stat (for a link, this returns the file type of the pointed i...
Definition: udsentry.h:279
bool isDir() const
Definition: udsentry.cpp:375
QDebug & nospace()
A local file path if the ioslave display files sitting on the local filesystem (but in another hierar...
Definition: udsentry.h:264
QVector< uint > fields() const
A vector of fields being present for the current entry.
Definition: udsentry.cpp:431
Treat the file as a hidden file (if set to 1) or as a normal file (if set to 0).
Definition: udsentry.h:267
27 was used by the now removed UDS_NEPOMUK_QUERY
Definition: udsentry.h:335
bool insert(Part *part, qint64 *insertId=nullptr)
User-readable type of file (if not specified, the mimetype&#39;s description is used) ...
Definition: udsentry.h:318
A mime type to be used for displaying only.
Definition: udsentry.h:294
void clear()
User ID of the file owner.
Definition: udsentry.h:246
KDEGAMES_EXPORT QAction * load(const QObject *recvr, const char *slot, QObject *parent)
int count() const
count fields
Definition: udsentry.cpp:436
void append(const T &value)
void resize(int size)
Extra data (used only if you specified Columns/ColumnsTypes) NB: you cannot repeat this entry; use UD...
Definition: udsentry.h:351
long long numberValue(uint field, long long defaultValue=0) const
Definition: udsentry.cpp:370
Extra data (used only if you specified Columns/ColumnsTypes) NB: you cannot repeat this entry; use UD...
Definition: udsentry.h:355
QString loginName() const
bool isEmpty() const const
The last time the file was opened.
Definition: udsentry.h:273
QString stringValue(uint field) const
Definition: udsentry.cpp:365
const QList< QKeySequence > & save()
void replace(uint field, const QString &value)
Replace or insert field with string value.
Definition: udsentry.cpp:414
Inode number for this file, used to detect hardlinks.
Definition: udsentry.h:342
const QList< QKeySequence > & replace()
The last time the file was modified.
Definition: udsentry.h:271
void reserve(int size)
25 was used by the now removed UDS_NEPOMUK_URI
Definition: udsentry.h:327
bool contains(uint field) const
check existence of a field
Definition: udsentry.cpp:441
void fastInsert(uint field, const QString &value)
insert field with string value, it will assert if the field is already inserted.
Definition: udsentry.cpp:390
~UDSEntry()
Destructor.
const T & at(int i) const const
Indicates that the field is a number (long long)
Definition: udsentry.h:235
Access permissions (part of the mode returned by stat)
Definition: udsentry.h:269
Filename - as displayed in directory listings etc.
Definition: udsentry.h:261
Name of the file where the link points to Allows to check for a symlink (don&#39;t use S_ISLNK !) ...
Definition: udsentry.h:282
The time the file was created.
Definition: udsentry.h:275
Group ID of the file owner.
Definition: udsentry.h:251
void reserve(int size)
If set, contains the label to display instead of the &#39;real name&#39; in UDS_NAME.
Definition: udsentry.h:309
Indicates that the entry has extended ACL entries.
Definition: udsentry.h:299
A mime type; the slave should set it if it&#39;s known.
Definition: udsentry.h:290
int size() const const
UDSEntry & operator=(const UDSEntry &)
Copy assignment.
Size of the file.
Definition: udsentry.h:242
Name of the icon, that should be used for displaying.
Definition: udsentry.h:249
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Sun Jul 5 2020 23:01:08 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.