qresource.cpp

Absolute File Name:/home/qt/qt5_coco/qt5/qtbase/src/corelib/io/qresource.cpp
Source codeSwitch to Preprocessed file
LineSourceCount
1/****************************************************************************-
2**-
3** Copyright (C) 2016 The Qt Company Ltd.-
4** Contact: https://www.qt.io/licensing/-
5**-
6** This file is part of the QtCore module of the Qt Toolkit.-
7**-
8** $QT_BEGIN_LICENSE:LGPL$-
9** Commercial License Usage-
10** Licensees holding valid commercial Qt licenses may use this file in-
11** accordance with the commercial license agreement provided with the-
12** Software or, alternatively, in accordance with the terms contained in-
13** a written agreement between you and The Qt Company. For licensing terms-
14** and conditions see https://www.qt.io/terms-conditions. For further-
15** information use the contact form at https://www.qt.io/contact-us.-
16**-
17** GNU Lesser General Public License Usage-
18** Alternatively, this file may be used under the terms of the GNU Lesser-
19** General Public License version 3 as published by the Free Software-
20** Foundation and appearing in the file LICENSE.LGPL3 included in the-
21** packaging of this file. Please review the following information to-
22** ensure the GNU Lesser General Public License version 3 requirements-
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.-
24**-
25** GNU General Public License Usage-
26** Alternatively, this file may be used under the terms of the GNU-
27** General Public License version 2.0 or (at your option) the GNU General-
28** Public license version 3 or any later version approved by the KDE Free-
29** Qt Foundation. The licenses are as published by the Free Software-
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3-
31** included in the packaging of this file. Please review the following-
32** information to ensure the GNU General Public License requirements will-
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and-
34** https://www.gnu.org/licenses/gpl-3.0.html.-
35**-
36** $QT_END_LICENSE$-
37**-
38****************************************************************************/-
39-
40#include "qresource.h"-
41#include "qresource_p.h"-
42#include "qresource_iterator_p.h"-
43#include "qset.h"-
44#include "qmutex.h"-
45#include "qdebug.h"-
46#include "qlocale.h"-
47#include "qglobal.h"-
48#include "qvector.h"-
49#include "qdatetime.h"-
50#include "qbytearray.h"-
51#include "qstringlist.h"-
52#include <qshareddata.h>-
53#include <qplatformdefs.h>-
54#include "private/qabstractfileengine_p.h"-
55-
56#ifdef Q_OS_UNIX-
57# include "private/qcore_unix_p.h"-
58#endif-
59-
60//#define DEBUG_RESOURCE_MATCH-
61-
62QT_BEGIN_NAMESPACE-
63-
64-
65class QStringSplitter-
66{-
67public:-
68 QStringSplitter(const QString &s)-
69 : m_string(s), m_data(m_string.constData()), m_len(s.length()), m_pos(0)-
70 {-
71 m_splitChar = QLatin1Char('/');-
72 }-
73-
74 inline bool hasNext() {-
75 while (m_pos < m_len && m_data[m_pos] == m_splitChar)-
76 ++m_pos;-
77 return m_pos < m_len;-
78 }-
79-
80 inline QStringRef next() {-
81 int start = m_pos;-
82 while (m_pos < m_len && m_data[m_pos] != m_splitChar)-
83 ++m_pos;-
84 return QStringRef(&m_string, start, m_pos - start);-
85 }-
86-
87 QString m_string;-
88 const QChar *m_data;-
89 QChar m_splitChar;-
90 int m_len;-
91 int m_pos;-
92};-
93-
94-
95//resource glue-
96class QResourceRoot-
97{-
98 enum Flags-
99 {-
100 Compressed = 0x01,-
101 Directory = 0x02-
102 };-
103 const uchar *tree, *names, *payloads;-
104 inline int findOffset(int node) const { return node * 14; } //sizeof each tree element-
105 uint hash(int node) const;-
106 QString name(int node) const;-
107 short flags(int node) const;-
108public:-
109 mutable QAtomicInt ref;-
110-
111 inline QResourceRoot(): tree(0), names(0), payloads(0) {}-
112 inline QResourceRoot(const uchar *t, const uchar *n, const uchar *d) { setSource(t, n, d); }-
113 virtual ~QResourceRoot() { }-
114 int findNode(const QString &path, const QLocale &locale=QLocale()) const;-
115 inline bool isContainer(int node) const { return flags(node) & Directory; }-
116 inline bool isCompressed(int node) const { return flags(node) & Compressed; }-
117 const uchar *data(int node, qint64 *size) const;-
118 QStringList children(int node) const;-
119 virtual QString mappingRoot() const { return QString(); }-
120 bool mappingRootSubdir(const QString &path, QString *match=0) const;-
121 inline bool operator==(const QResourceRoot &other) const-
122 { return tree == other.tree && names == other.names && payloads == other.payloads; }-
123 inline bool operator!=(const QResourceRoot &other) const-
124 { return !operator==(other); }-
125 enum ResourceRootType { Resource_Builtin, Resource_File, Resource_Buffer };-
126 virtual ResourceRootType type() const { return Resource_Builtin; }-
127-
128protected:-
129 inline void setSource(const uchar *t, const uchar *n, const uchar *d) {-
130 tree = t;-
131 names = n;-
132 payloads = d;-
133 }-
134};-
135-
136static QString cleanPath(const QString &_path)-
137{-
138 QString path = QDir::cleanPath(_path);-
139 // QDir::cleanPath does not remove two trailing slashes under _Windows_-
140 // due to support for UNC paths. Remove those manually.-
141 if (path.startsWith(QLatin1String("//")))-
142 path.remove(0, 1);-
143 return path;-
144}-
145-
146Q_DECLARE_TYPEINFO(QResourceRoot, Q_MOVABLE_TYPE);-
147-
148Q_GLOBAL_STATIC_WITH_ARGS(QMutex, resourceMutex, (QMutex::Recursive))-
149-
150typedef QList<QResourceRoot*> ResourceList;-
151Q_GLOBAL_STATIC(ResourceList, resourceList)-
152-
153Q_GLOBAL_STATIC(QStringList, resourceSearchPaths)-
154-
155/*!-
156 \class QResource-
157 \inmodule QtCore-
158 \brief The QResource class provides an interface for reading directly from resources.-
159-
160 \ingroup io-
161-
162 \reentrant-
163 \since 4.2-
164-
165 QResource is an object that represents a set of data (and possibly-
166 children) relating to a single resource entity. QResource gives direct-
167 access to the bytes in their raw format. In this way direct access-
168 allows reading data without buffer copying or indirection. Indirection-
169 is often useful when interacting with the resource entity as if it is a-
170 file, this can be achieved with QFile. The data and children behind a-
171 QResource are normally compiled into an application/library, but it is-
172 also possible to load a resource at runtime. When loaded at run time-
173 the resource file will be loaded as one big set of data and then given-
174 out in pieces via references into the resource tree.-
175-
176 A QResource can either be loaded with an absolute path, either treated-
177 as a file system rooted with a \c{/} character, or in resource notation-
178 rooted with a \c{:} character. A relative resource can also be opened-
179 which will be found in the list of paths returned by QDir::searchPaths().-
180-
181 A QResource that is representing a file will have data backing it, this-
182 data can possibly be compressed, in which case qUncompress() must be-
183 used to access the real data; this happens implicitly when accessed-
184 through a QFile. A QResource that is representing a directory will have-
185 only children and no data.-
186-
187 \section1 Dynamic Resource Loading-
188-
189 A resource can be left out of an application's binary and loaded when-
190 it is needed at run-time by using the registerResource() function. The-
191 resource file passed into registerResource() must be a binary resource-
192 as created by rcc. Further information about binary resources can be-
193 found in \l{The Qt Resource System} documentation.-
194-
195 This can often be useful when loading a large set of application icons-
196 that may change based on a setting, or that can be edited by a user and-
197 later recreated. The resource is immediately loaded into memory, either-
198 as a result of a single file read operation, or as a memory mapped file.-
199-
200 This approach can prove to be a significant performance gain as only a-
201 single file will be loaded, and pieces of data will be given out via the-
202 path requested in setFileName().-
203-
204 The unregisterResource() function removes a reference to a particular-
205 file. If there are QResource objects that currently reference resources related-
206 to the unregistered file, they will continue to be valid but the resource-
207 file itself will be removed from the resource roots, and thus no further-
208 QResource can be created pointing into this resource data. The resource-
209 itself will be unmapped from memory when the last QResource that points-
210 to it is destroyed.-
211-
212 \sa {The Qt Resource System}, QFile, QDir, QFileInfo-
213*/-
214-
215class QResourcePrivate {-
216public:-
217 inline QResourcePrivate(QResource *_q) : q_ptr(_q) { clear(); }-
218 inline ~QResourcePrivate() { clear(); }-
219-
220 void ensureInitialized() const;-
221 void ensureChildren() const;-
222-
223 bool load(const QString &file);-
224 void clear();-
225-
226 QLocale locale;-
227 QString fileName, absoluteFilePath;-
228 QList<QResourceRoot*> related;-
229 uint container : 1;-
230 mutable uint compressed : 1;-
231 mutable qint64 size;-
232 mutable const uchar *data;-
233 mutable QStringList children;-
234-
235 QResource *q_ptr;-
236 Q_DECLARE_PUBLIC(QResource)-
237};-
238-
239void-
240QResourcePrivate::clear()-
241{-
242 absoluteFilePath.clear();-
243 compressed = 0;-
244 data = 0;-
245 size = 0;-
246 children.clear();-
247 container = 0;-
248 for(int i = 0; i < related.size(); ++i) {-
249 QResourceRoot *root = related.at(i);-
250 if(!root->ref.deref())-
251 delete root;-
252 }-
253 related.clear();-
254}-
255-
256bool-
257QResourcePrivate::load(const QString &file)-
258{-
259 related.clear();-
260 QMutexLocker lock(resourceMutex());-
261 const ResourceList *list = resourceList();-
262 QString cleaned = cleanPath(file);-
263 for(int i = 0; i < list->size(); ++i) {-
264 QResourceRoot *res = list->at(i);-
265 const int node = res->findNode(cleaned, locale);-
266 if(node != -1) {-
267 if(related.isEmpty()) {-
268 container = res->isContainer(node);-
269 if(!container) {-
270 data = res->data(node, &size);-
271 compressed = res->isCompressed(node);-
272 } else {-
273 data = 0;-
274 size = 0;-
275 compressed = 0;-
276 }-
277 } else if(res->isContainer(node) != container) {-
278 qWarning("QResourceInfo: Resource [%s] has both data and children!", file.toLatin1().constData());-
279 }-
280 res->ref.ref();-
281 related.append(res);-
282 } else if(res->mappingRootSubdir(file)) {-
283 container = true;-
284 data = 0;-
285 size = 0;-
286 compressed = 0;-
287 res->ref.ref();-
288 related.append(res);-
289 }-
290 }-
291 return !related.isEmpty();-
292}-
293-
294void-
295QResourcePrivate::ensureInitialized() const-
296{-
297 if(!related.isEmpty())-
298 return;-
299 QResourcePrivate *that = const_cast<QResourcePrivate *>(this);-
300 if(fileName == QLatin1String(":"))-
301 that->fileName += QLatin1Char('/');-
302 that->absoluteFilePath = fileName;-
303 if(!that->absoluteFilePath.startsWith(QLatin1Char(':')))-
304 that->absoluteFilePath.prepend(QLatin1Char(':'));-
305-
306 QString path = fileName;-
307 if(path.startsWith(QLatin1Char(':')))-
308 path = path.mid(1);-
309-
310 if(path.startsWith(QLatin1Char('/'))) {-
311 that->load(path);-
312 } else {-
313 QMutexLocker lock(resourceMutex());-
314 QStringList searchPaths = *resourceSearchPaths();-
315 searchPaths << QLatin1String("");-
316 for(int i = 0; i < searchPaths.size(); ++i) {-
317 const QString searchPath(searchPaths.at(i) + QLatin1Char('/') + path);-
318 if(that->load(searchPath)) {-
319 that->absoluteFilePath = QLatin1Char(':') + searchPath;-
320 break;-
321 }-
322 }-
323 }-
324}-
325-
326void-
327QResourcePrivate::ensureChildren() const-
328{-
329 ensureInitialized();-
330 if(!children.isEmpty() || !container || related.isEmpty())-
331 return;-
332-
333 QString path = absoluteFilePath, k;-
334 if(path.startsWith(QLatin1Char(':')))-
335 path = path.mid(1);-
336 QSet<QString> kids;-
337 QString cleaned = cleanPath(path);-
338 for(int i = 0; i < related.size(); ++i) {-
339 QResourceRoot *res = related.at(i);-
340 if(res->mappingRootSubdir(path, &k) && !k.isEmpty()) {-
341 if(!kids.contains(k)) {-
342 children += k;-
343 kids.insert(k);-
344 }-
345 } else {-
346 const int node = res->findNode(cleaned);-
347 if(node != -1) {-
348 QStringList related_children = res->children(node);-
349 for(int kid = 0; kid < related_children.size(); ++kid) {-
350 k = related_children.at(kid);-
351 if(!kids.contains(k)) {-
352 children += k;-
353 kids.insert(k);-
354 }-
355 }-
356 }-
357 }-
358 }-
359}-
360-
361/*!-
362 Constructs a QResource pointing to \a file. \a locale is used to-
363 load a specific localization of a resource data.-
364-
365 \sa QFileInfo, QDir::searchPaths(), setFileName(), setLocale()-
366*/-
367-
368QResource::QResource(const QString &file, const QLocale &locale) : d_ptr(new QResourcePrivate(this))-
369{-
370 Q_D(QResource);-
371 d->fileName = file;-
372 d->locale = locale;-
373}-
374-
375/*!-
376 Releases the resources of the QResource object.-
377*/-
378QResource::~QResource()-
379{-
380}-
381-
382/*!-
383 Sets a QResource to only load the localization of resource to for \a-
384 locale. If a resource for the specific locale is not found then the-
385 C locale is used.-
386-
387 \sa setFileName()-
388*/-
389-
390void QResource::setLocale(const QLocale &locale)-
391{-
392 Q_D(QResource);-
393 d->clear();-
394 d->locale = locale;-
395}-
396-
397/*!-
398 Returns the locale used to locate the data for the QResource.-
399*/-
400-
401QLocale QResource::locale() const-
402{-
403 Q_D(const QResource);-
404 return d->locale;-
405}-
406-
407/*!-
408 Sets a QResource to point to \a file. \a file can either be absolute,-
409 in which case it is opened directly, if relative then the file will be-
410 tried to be found in QDir::searchPaths().-
411-
412 \sa absoluteFilePath()-
413*/-
414-
415void QResource::setFileName(const QString &file)-
416{-
417 Q_D(QResource);-
418 d->clear();-
419 d->fileName = file;-
420}-
421-
422/*!-
423 Returns the full path to the file that this QResource represents as it-
424 was passed.-
425-
426 \sa absoluteFilePath()-
427*/-
428-
429QString QResource::fileName() const-
430{-
431 Q_D(const QResource);-
432 d->ensureInitialized();-
433 return d->fileName;-
434}-
435-
436/*!-
437 Returns the real path that this QResource represents, if the resource-
438 was found via the QDir::searchPaths() it will be indicated in the path.-
439-
440 \sa fileName()-
441*/-
442-
443QString QResource::absoluteFilePath() const-
444{-
445 Q_D(const QResource);-
446 d->ensureInitialized();-
447 return d->absoluteFilePath;-
448}-
449-
450/*!-
451 Returns \c true if the resource really exists in the resource hierarchy,-
452 false otherwise.-
453-
454*/-
455-
456bool QResource::isValid() const-
457{-
458 Q_D(const QResource);-
459 d->ensureInitialized();-
460 return !d->related.isEmpty();-
461}-
462-
463/*!-
464 \fn bool QResource::isFile() const-
465-
466 Returns \c true if the resource represents a file and thus has data-
467 backing it, false if it represents a directory.-
468-
469 \sa isDir()-
470*/-
471-
472-
473/*!-
474 Returns \c true if the resource represents a file and the data backing it-
475 is in a compressed format, false otherwise.-
476-
477 \sa data(), isFile()-
478*/-
479-
480bool QResource::isCompressed() const-
481{-
482 Q_D(const QResource);-
483 d->ensureInitialized();-
484 return d->compressed;-
485}-
486-
487/*!-
488 Returns the size of the data backing the resource.-
489-
490 \sa data(), isFile()-
491*/-
492-
493qint64 QResource::size() const-
494{-
495 Q_D(const QResource);-
496 d->ensureInitialized();-
497 return d->size;-
498}-
499-
500/*!-
501 Returns direct access to a read only segment of data that this resource-
502 represents. If the resource is compressed the data returns is-
503 compressed and qUncompress() must be used to access the data. If the-
504 resource is a directory 0 is returned.-
505-
506 \sa size(), isCompressed(), isFile()-
507*/-
508-
509const uchar *QResource::data() const-
510{-
511 Q_D(const QResource);-
512 d->ensureInitialized();-
513 return d->data;-
514}-
515-
516/*!-
517 Returns \c true if the resource represents a directory and thus may have-
518 children() in it, false if it represents a file.-
519-
520 \sa isFile()-
521*/-
522-
523bool QResource::isDir() const-
524{-
525 Q_D(const QResource);-
526 d->ensureInitialized();-
527 return d->container;-
528}-
529-
530/*!-
531 Returns a list of all resources in this directory, if the resource-
532 represents a file the list will be empty.-
533-
534 \sa isDir()-
535*/-
536-
537QStringList QResource::children() const-
538{-
539 Q_D(const QResource);-
540 d->ensureChildren();-
541 return d->children;-
542}-
543-
544/*!-
545 \obsolete-
546-
547 Use QDir::addSearchPath() with a prefix instead.-
548-
549 Adds \a path to the search paths searched in to find resources that are-
550 not specified with an absolute path. The \a path must be an absolute-
551 path (start with \c{/}).-
552-
553 The default search path is to search only in the root (\c{:/}). The last-
554 path added will be consulted first upon next QResource creation.-
555*/-
556void-
557QResource::addSearchPath(const QString &path)-
558{-
559 if (!path.startsWith(QLatin1Char('/'))) {-
560 qWarning("QResource::addResourceSearchPath: Search paths must be absolute (start with /) [%s]",-
561 path.toLocal8Bit().data());-
562 return;-
563 }-
564 QMutexLocker lock(resourceMutex());-
565 resourceSearchPaths()->prepend(path);-
566}-
567-
568/*!-
569 \obsolete-
570-
571 Use QDir::searchPaths() instead.-
572-
573 Returns the current search path list. This list is consulted when-
574 creating a relative resource.-
575-
576 \sa QDir::addSearchPath(), QDir::setSearchPaths()-
577*/-
578-
579QStringList-
580QResource::searchPaths()-
581{-
582 QMutexLocker lock(resourceMutex());-
583 return *resourceSearchPaths();-
584}-
585-
586inline uint QResourceRoot::hash(int node) const-
587{-
588 if(!node) //root-
589 return 0;-
590 const int offset = findOffset(node);-
591 int name_offset = (tree[offset+0] << 24) + (tree[offset+1] << 16) +-
592 (tree[offset+2] << 8) + (tree[offset+3] << 0);-
593 name_offset += 2; //jump past name length-
594 return (names[name_offset+0] << 24) + (names[name_offset+1] << 16) +-
595 (names[name_offset+2] << 8) + (names[name_offset+3] << 0);-
596}-
597inline QString QResourceRoot::name(int node) const-
598{-
599 if(!node) // root-
600 return QString();-
601 const int offset = findOffset(node);-
602-
603 QString ret;-
604 int name_offset = (tree[offset+0] << 24) + (tree[offset+1] << 16) +-
605 (tree[offset+2] << 8) + (tree[offset+3] << 0);-
606 const short name_length = (names[name_offset+0] << 8) +-
607 (names[name_offset+1] << 0);-
608 name_offset += 2;-
609 name_offset += 4; //jump past hash-
610-
611 ret.resize(name_length);-
612 QChar *strData = ret.data();-
613 for(int i = 0; i < name_length*2; i+=2) {-
614 QChar c(names[name_offset+i+1], names[name_offset+i]);-
615 *strData = c;-
616 ++strData;-
617 }-
618 return ret;-
619}-
620-
621int QResourceRoot::findNode(const QString &_path, const QLocale &locale) const-
622{-
623 QString path = _path;-
624 {-
625 QString root = mappingRoot();-
626 if(!root.isEmpty()) {-
627 if(root == path) {-
628 path = QLatin1Char('/');-
629 } else {-
630 if(!root.endsWith(QLatin1Char('/')))-
631 root += QLatin1Char('/');-
632 if(path.size() >= root.size() && path.startsWith(root))-
633 path = path.mid(root.length()-1);-
634 if(path.isEmpty())-
635 path = QLatin1Char('/');-
636 }-
637 }-
638 }-
639#ifdef DEBUG_RESOURCE_MATCH-
640 qDebug() << "!!!!" << "START" << path << locale.country() << locale.language();-
641#endif-
642-
643 if(path == QLatin1String("/"))-
644 return 0;-
645-
646 //the root node is always first-
647 int child_count = (tree[6] << 24) + (tree[7] << 16) +-
648 (tree[8] << 8) + (tree[9] << 0);-
649 int child = (tree[10] << 24) + (tree[11] << 16) +-
650 (tree[12] << 8) + (tree[13] << 0);-
651-
652 //now iterate up the tree-
653 int node = -1;-
654-
655 QStringSplitter splitter(path);-
656 while (child_count && splitter.hasNext()) {-
657 QStringRef segment = splitter.next();-
658-
659#ifdef DEBUG_RESOURCE_MATCH-
660 qDebug() << " CHILDREN" << segment;-
661 for(int j = 0; j < child_count; ++j) {-
662 qDebug() << " " << child+j << " :: " << name(child+j);-
663 }-
664#endif-
665 const uint h = qt_hash(segment);-
666-
667 //do the binary search for the hash-
668 int l = 0, r = child_count-1;-
669 int sub_node = (l+r+1)/2;-
670 while(r != l) {-
671 const uint sub_node_hash = hash(child+sub_node);-
672 if(h == sub_node_hash)-
673 break;-
674 else if(h < sub_node_hash)-
675 r = sub_node - 1;-
676 else-
677 l = sub_node;-
678 sub_node = (l + r + 1) / 2;-
679 }-
680 sub_node += child;-
681-
682 //now do the "harder" compares-
683 bool found = false;-
684 if(hash(sub_node) == h) {-
685 while(sub_node > child && hash(sub_node-1) == h) //backup for collisions-
686 --sub_node;-
687 for(; sub_node < child+child_count && hash(sub_node) == h; ++sub_node) { //here we go...-
688 if(name(sub_node) == segment) {-
689 found = true;-
690 int offset = findOffset(sub_node);-
691#ifdef DEBUG_RESOURCE_MATCH-
692 qDebug() << " TRY" << sub_node << name(sub_node) << offset;-
693#endif-
694 offset += 4; //jump past name-
695-
696 const short flags = (tree[offset+0] << 8) +-
697 (tree[offset+1] << 0);-
698 offset += 2;-
699-
700 if(!splitter.hasNext()) {-
701 if(!(flags & Directory)) {-
702 const short country = (tree[offset+0] << 8) +-
703 (tree[offset+1] << 0);-
704 offset += 2;-
705-
706 const short language = (tree[offset+0] << 8) +-
707 (tree[offset+1] << 0);-
708 offset += 2;-
709#ifdef DEBUG_RESOURCE_MATCH-
710 qDebug() << " " << "LOCALE" << country << language;-
711#endif-
712 if(country == locale.country() && language == locale.language()) {-
713#ifdef DEBUG_RESOURCE_MATCH-
714 qDebug() << "!!!!" << "FINISHED" << __LINE__ << sub_node;-
715#endif-
716 return sub_node;-
717 } else if((country == QLocale::AnyCountry && language == locale.language()) ||-
718 (country == QLocale::AnyCountry && language == QLocale::C && node == -1)) {-
719 node = sub_node;-
720 }-
721 continue;-
722 } else {-
723#ifdef DEBUG_RESOURCE_MATCH-
724 qDebug() << "!!!!" << "FINISHED" << __LINE__ << sub_node;-
725#endif-
726-
727 return sub_node;-
728 }-
729 }-
730-
731 if(!(flags & Directory))-
732 return -1;-
733-
734 child_count = (tree[offset+0] << 24) + (tree[offset+1] << 16) +-
735 (tree[offset+2] << 8) + (tree[offset+3] << 0);-
736 offset += 4;-
737 child = (tree[offset+0] << 24) + (tree[offset+1] << 16) +-
738 (tree[offset+2] << 8) + (tree[offset+3] << 0);-
739 break;-
740 }-
741 }-
742 }-
743 if(!found)-
744 break;-
745 }-
746#ifdef DEBUG_RESOURCE_MATCH-
747 qDebug() << "!!!!" << "FINISHED" << __LINE__ << node;-
748#endif-
749 return node;-
750}-
751short QResourceRoot::flags(int node) const-
752{-
753 if(node == -1)-
754 return 0;-
755 const int offset = findOffset(node) + 4; //jump past name-
756 return (tree[offset+0] << 8) + (tree[offset+1] << 0);-
757}-
758const uchar *QResourceRoot::data(int node, qint64 *size) const-
759{-
760 if(node == -1) {-
761 *size = 0;-
762 return 0;-
763 }-
764 int offset = findOffset(node) + 4; //jump past name-
765-
766 const short flags = (tree[offset+0] << 8) + (tree[offset+1] << 0);-
767 offset += 2;-
768-
769 offset += 4; //jump past locale-
770-
771 if(!(flags & Directory)) {-
772 const int data_offset = (tree[offset+0] << 24) + (tree[offset+1] << 16) +-
773 (tree[offset+2] << 8) + (tree[offset+3] << 0);-
774 const uint data_length = (payloads[data_offset+0] << 24) + (payloads[data_offset+1] << 16) +-
775 (payloads[data_offset+2] << 8) + (payloads[data_offset+3] << 0);-
776 const uchar *ret = payloads+data_offset+4;-
777 *size = data_length;-
778 return ret;-
779 }-
780 *size = 0;-
781 return 0;-
782}-
783QStringList QResourceRoot::children(int node) const-
784{-
785 if(node == -1)-
786 return QStringList();-
787 int offset = findOffset(node) + 4; //jump past name-
788-
789 const short flags = (tree[offset+0] << 8) + (tree[offset+1] << 0);-
790 offset += 2;-
791-
792 QStringList ret;-
793 if(flags & Directory) {-
794 const int child_count = (tree[offset+0] << 24) + (tree[offset+1] << 16) +-
795 (tree[offset+2] << 8) + (tree[offset+3] << 0);-
796 offset += 4;-
797 const int child_off = (tree[offset+0] << 24) + (tree[offset+1] << 16) +-
798 (tree[offset+2] << 8) + (tree[offset+3] << 0);-
799 ret.reserve(child_count);-
800 for(int i = child_off; i < child_off+child_count; ++i)-
801 ret << name(i);-
802 }-
803 return ret;-
804}-
805bool QResourceRoot::mappingRootSubdir(const QString &path, QString *match) const-
806{-
807 const QString root = mappingRoot();-
808 if(!root.isEmpty()) {-
809 const QVector<QStringRef> root_segments = root.splitRef(QLatin1Char('/'), QString::SkipEmptyParts),-
810 path_segments = path.splitRef(QLatin1Char('/'), QString::SkipEmptyParts);-
811 if(path_segments.size() <= root_segments.size()) {-
812 int matched = 0;-
813 for(int i = 0; i < path_segments.size(); ++i) {-
814 if(root_segments[i] != path_segments[i])-
815 break;-
816 ++matched;-
817 }-
818 if(matched == path_segments.size()) {-
819 if(match && root_segments.size() > matched)-
820 *match = root_segments.at(matched).toString();-
821 return true;-
822 }-
823 }-
824 }-
825 return false;-
826}-
827-
828Q_CORE_EXPORT bool qRegisterResourceData(int version, const unsigned char *tree,-
829 const unsigned char *name, const unsigned char *data)-
830{-
831 QMutexLocker lock(resourceMutex());-
832 if(version == 0x01 && resourceList()) {-
833 bool found = false;-
834 QResourceRoot res(tree, name, data);-
835 for(int i = 0; i < resourceList()->size(); ++i) {-
836 if(*resourceList()->at(i) == res) {-
837 found = true;-
838 break;-
839 }-
840 }-
841 if(!found) {-
842 QResourceRoot *root = new QResourceRoot(tree, name, data);-
843 root->ref.ref();-
844 resourceList()->append(root);-
845 }-
846 return true;-
847 }-
848 return false;-
849}-
850-
851Q_CORE_EXPORT bool qUnregisterResourceData(int version, const unsigned char *tree,-
852 const unsigned char *name, const unsigned char *data)-
853{-
854 QMutexLocker lock(resourceMutex());-
855 if(version == 0x01 && resourceList()) {-
856 QResourceRoot res(tree, name, data);-
857 for(int i = 0; i < resourceList()->size(); ) {-
858 if(*resourceList()->at(i) == res) {-
859 QResourceRoot *root = resourceList()->takeAt(i);-
860 if(!root->ref.deref())-
861 delete root;-
862 } else {-
863 ++i;-
864 }-
865 }-
866 return true;-
867 }-
868 return false;-
869}-
870-
871//run time resource creation-
872-
873class QDynamicBufferResourceRoot: public QResourceRoot-
874{-
875 QString root;-
876 const uchar *buffer;-
877-
878public:-
879 inline QDynamicBufferResourceRoot(const QString &_root) : root(_root), buffer(0) { }-
880 inline ~QDynamicBufferResourceRoot() { }-
881 inline const uchar *mappingBuffer() const { return buffer; }-
882 virtual QString mappingRoot() const Q_DECL_OVERRIDE { return root; }-
883 virtual ResourceRootType type() const Q_DECL_OVERRIDE { return Resource_Buffer; }-
884-
885 // size == -1 means "unknown"-
886 bool registerSelf(const uchar *b, int size)-
887 {-
888 // 5 int "pointers"-
889 if (size >= 0 && size < 20)-
890 return false;-
891-
892 //setup the data now-
893 int offset = 0;-
894-
895 //magic number-
896 if(b[offset+0] != 'q' || b[offset+1] != 'r' ||-
897 b[offset+2] != 'e' || b[offset+3] != 's') {-
898 return false;-
899 }-
900 offset += 4;-
901-
902 const int version = (b[offset+0] << 24) + (b[offset+1] << 16) +-
903 (b[offset+2] << 8) + (b[offset+3] << 0);-
904 offset += 4;-
905-
906 const int tree_offset = (b[offset+0] << 24) + (b[offset+1] << 16) +-
907 (b[offset+2] << 8) + (b[offset+3] << 0);-
908 offset += 4;-
909-
910 const int data_offset = (b[offset+0] << 24) + (b[offset+1] << 16) +-
911 (b[offset+2] << 8) + (b[offset+3] << 0);-
912 offset += 4;-
913-
914 const int name_offset = (b[offset+0] << 24) + (b[offset+1] << 16) +-
915 (b[offset+2] << 8) + (b[offset+3] << 0);-
916 offset += 4;-
917-
918 // Some sanity checking for sizes. This is _not_ a security measure.-
919 if (size >= 0 && (tree_offset >= size || data_offset >= size || name_offset >= size))-
920 return false;-
921-
922 if(version == 0x01) {-
923 buffer = b;-
924 setSource(b+tree_offset, b+name_offset, b+data_offset);-
925 return true;-
926 }-
927 return false;-
928 }-
929};-
930-
931#if defined(Q_OS_UNIX) && !defined (Q_OS_NACL) && !defined(Q_OS_INTEGRITY)-
932#define QT_USE_MMAP-
933#endif-
934-
935// most of the headers below are already included in qplatformdefs.h-
936// also this lacks Large File support but that's probably irrelevant-
937#if defined(QT_USE_MMAP)-
938// for mmap-
939QT_BEGIN_INCLUDE_NAMESPACE-
940#include <sys/mman.h>-
941#include <errno.h>-
942QT_END_INCLUDE_NAMESPACE-
943#endif-
944-
945-
946-
947class QDynamicFileResourceRoot: public QDynamicBufferResourceRoot-
948{-
949 QString fileName;-
950 // for mmap'ed files, this is what needs to be unmapped.-
951 uchar *unmapPointer;-
952 unsigned int unmapLength;-
953-
954public:-
955 inline QDynamicFileResourceRoot(const QString &_root) : QDynamicBufferResourceRoot(_root), unmapPointer(0), unmapLength(0) { }-
956 ~QDynamicFileResourceRoot() {-
957#if defined(QT_USE_MMAP)-
958 if (unmapPointer) {-
959 munmap((char*)unmapPointer, unmapLength);-
960 unmapPointer = 0;-
961 unmapLength = 0;-
962 } else-
963#endif-
964 {-
965 delete [] mappingBuffer();-
966 }-
967 }-
968 QString mappingFile() const { return fileName; }-
969 virtual ResourceRootType type() const Q_DECL_OVERRIDE { return Resource_File; }-
970-
971 bool registerSelf(const QString &f) {-
972 bool fromMM = false;-
973 uchar *data = 0;-
974 unsigned int data_len = 0;-
975-
976#ifdef QT_USE_MMAP-
977-
978#ifndef MAP_FILE-
979#define MAP_FILE 0-
980#endif-
981#ifndef MAP_FAILED-
982#define MAP_FAILED -1-
983#endif-
984-
985 int fd = QT_OPEN(QFile::encodeName(f), O_RDONLY,-
986#if defined(Q_OS_WIN)-
987 _S_IREAD | _S_IWRITE-
988#else-
989 0666-
990#endif-
991 );-
992 if (fd >= 0) {-
993 QT_STATBUF st;-
994 if (!QT_FSTAT(fd, &st)) {-
995 uchar *ptr;-
996 ptr = reinterpret_cast<uchar *>(-
997 mmap(0, st.st_size, // any address, whole file-
998 PROT_READ, // read-only memory-
999 MAP_FILE | MAP_PRIVATE, // swap-backed map from file-
1000 fd, 0)); // from offset 0 of fd-
1001 if (ptr && ptr != reinterpret_cast<uchar *>(MAP_FAILED)) {-
1002 data = ptr;-
1003 data_len = st.st_size;-
1004 fromMM = true;-
1005 }-
1006 }-
1007 ::close(fd);-
1008 }-
1009#endif // QT_USE_MMAP-
1010 if(!data) {-
1011 QFile file(f);-
1012 if (!file.exists())-
1013 return false;-
1014 data_len = file.size();-
1015 data = new uchar[data_len];-
1016-
1017 bool ok = false;-
1018 if (file.open(QIODevice::ReadOnly))-
1019 ok = (data_len == (uint)file.read((char*)data, data_len));-
1020 if (!ok) {-
1021 delete [] data;-
1022 data = 0;-
1023 data_len = 0;-
1024 return false;-
1025 }-
1026 fromMM = false;-
1027 }-
1028 if (data && QDynamicBufferResourceRoot::registerSelf(data, data_len)) {-
1029 if(fromMM) {-
1030 unmapPointer = data;-
1031 unmapLength = data_len;-
1032 }-
1033 fileName = f;-
1034 return true;-
1035 }-
1036 return false;-
1037 }-
1038};-
1039-
1040static QString qt_resource_fixResourceRoot(QString r) {-
1041 if(!r.isEmpty()) {-
1042 if(r.startsWith(QLatin1Char(':')))-
1043 r = r.mid(1);-
1044 if(!r.isEmpty())-
1045 r = QDir::cleanPath(r);-
1046 }-
1047 return r;-
1048}-
1049-
1050-
1051/*!-
1052 \fn bool QResource::registerResource(const QString &rccFileName, const QString &mapRoot)-
1053-
1054 Registers the resource with the given \a rccFileName at the location in the-
1055 resource tree specified by \a mapRoot, and returns \c true if the file is-
1056 successfully opened; otherwise returns \c false.-
1057-
1058 \sa unregisterResource()-
1059*/-
1060-
1061bool-
1062QResource::registerResource(const QString &rccFilename, const QString &resourceRoot)-
1063{-
1064 QString r = qt_resource_fixResourceRoot(resourceRoot);-
1065 if(!r.isEmpty() && r[0] != QLatin1Char('/')) {-
1066 qWarning("QDir::registerResource: Registering a resource [%s] must be rooted in an absolute path (start with /) [%s]",-
1067 rccFilename.toLocal8Bit().data(), resourceRoot.toLocal8Bit().data());-
1068 return false;-
1069 }-
1070-
1071 QDynamicFileResourceRoot *root = new QDynamicFileResourceRoot(r);-
1072 if(root->registerSelf(rccFilename)) {-
1073 root->ref.ref();-
1074 QMutexLocker lock(resourceMutex());-
1075 resourceList()->append(root);-
1076 return true;-
1077 }-
1078 delete root;-
1079 return false;-
1080}-
1081-
1082/*!-
1083 \fn bool QResource::unregisterResource(const QString &rccFileName, const QString &mapRoot)-
1084-
1085 Unregisters the resource with the given \a rccFileName at the location in-
1086 the resource tree specified by \a mapRoot, and returns \c true if the-
1087 resource is successfully unloaded and no references exist for the-
1088 resource; otherwise returns \c false.-
1089-
1090 \sa registerResource()-
1091*/-
1092-
1093bool-
1094QResource::unregisterResource(const QString &rccFilename, const QString &resourceRoot)-
1095{-
1096 QString r = qt_resource_fixResourceRoot(resourceRoot);-
1097-
1098 QMutexLocker lock(resourceMutex());-
1099 ResourceList *list = resourceList();-
1100 for(int i = 0; i < list->size(); ++i) {-
1101 QResourceRoot *res = list->at(i);-
1102 if(res->type() == QResourceRoot::Resource_File) {-
1103 QDynamicFileResourceRoot *root = reinterpret_cast<QDynamicFileResourceRoot*>(res);-
1104 if (root->mappingFile() == rccFilename && root->mappingRoot() == r) {-
1105 resourceList()->removeAt(i);-
1106 if(!root->ref.deref()) {-
1107 delete root;-
1108 return true;-
1109 }-
1110 return false;-
1111 }-
1112 }-
1113 }-
1114 return false;-
1115}-
1116-
1117-
1118/*!-
1119 \fn bool QResource::registerResource(const uchar *rccData, const QString &mapRoot)-
1120 \since 4.3-
1121-
1122 Registers the resource with the given \a rccData at the location in the-
1123 resource tree specified by \a mapRoot, and returns \c true if the file is-
1124 successfully opened; otherwise returns \c false.-
1125-
1126 \warning The data must remain valid throughout the life of any QFile-
1127 that may reference the resource data.-
1128-
1129 \sa unregisterResource()-
1130*/-
1131-
1132bool-
1133QResource::registerResource(const uchar *rccData, const QString &resourceRoot)-
1134{-
1135 QString r = qt_resource_fixResourceRoot(resourceRoot);-
1136 if(!r.isEmpty() && r[0] != QLatin1Char('/')) {-
1137 qWarning("QDir::registerResource: Registering a resource [%p] must be rooted in an absolute path (start with /) [%s]",-
1138 rccData, resourceRoot.toLocal8Bit().data());-
1139 return false;-
1140 }-
1141-
1142 QDynamicBufferResourceRoot *root = new QDynamicBufferResourceRoot(r);-
1143 if (root->registerSelf(rccData, -1)) {-
1144 root->ref.ref();-
1145 QMutexLocker lock(resourceMutex());-
1146 resourceList()->append(root);-
1147 return true;-
1148 }-
1149 delete root;-
1150 return false;-
1151}-
1152-
1153/*!-
1154 \fn bool QResource::unregisterResource(const uchar *rccData, const QString &mapRoot)-
1155 \since 4.3-
1156-
1157 Unregisters the resource with the given \a rccData at the location in the-
1158 resource tree specified by \a mapRoot, and returns \c true if the resource is-
1159 successfully unloaded and no references exist into the resource; otherwise returns \c false.-
1160-
1161 \sa registerResource()-
1162*/-
1163-
1164bool-
1165QResource::unregisterResource(const uchar *rccData, const QString &resourceRoot)-
1166{-
1167 QString r = qt_resource_fixResourceRoot(resourceRoot);-
1168-
1169 QMutexLocker lock(resourceMutex());-
1170 ResourceList *list = resourceList();-
1171 for(int i = 0; i < list->size(); ++i) {-
1172 QResourceRoot *res = list->at(i);-
1173 if(res->type() == QResourceRoot::Resource_Buffer) {-
1174 QDynamicBufferResourceRoot *root = reinterpret_cast<QDynamicBufferResourceRoot*>(res);-
1175 if (root->mappingBuffer() == rccData && root->mappingRoot() == r) {-
1176 resourceList()->removeAt(i);-
1177 if(!root->ref.deref()) {-
1178 delete root;-
1179 return true;-
1180 }-
1181 return false;-
1182 }-
1183 }-
1184 }-
1185 return false;-
1186}-
1187-
1188#if !defined(QT_BOOTSTRAPPED)-
1189//resource engine-
1190class QResourceFileEnginePrivate : public QAbstractFileEnginePrivate-
1191{-
1192protected:-
1193 Q_DECLARE_PUBLIC(QResourceFileEngine)-
1194private:-
1195 uchar *map(qint64 offset, qint64 size, QFile::MemoryMapFlags flags);-
1196 bool unmap(uchar *ptr);-
1197 void uncompress() const;-
1198 qint64 offset;-
1199 QResource resource;-
1200 mutable QByteArray uncompressed;-
1201protected:-
1202 QResourceFileEnginePrivate() : offset(0) { }-
1203};-
1204-
1205bool QResourceFileEngine::mkdir(const QString &, bool) const-
1206{-
1207 return false;-
1208}-
1209-
1210bool QResourceFileEngine::rmdir(const QString &, bool) const-
1211{-
1212 return false;-
1213}-
1214-
1215bool QResourceFileEngine::setSize(qint64)-
1216{-
1217 return false;-
1218}-
1219-
1220QStringList QResourceFileEngine::entryList(QDir::Filters filters, const QStringList &filterNames) const-
1221{-
1222 return QAbstractFileEngine::entryList(filters, filterNames);-
1223}-
1224-
1225bool QResourceFileEngine::caseSensitive() const-
1226{-
1227 return true;-
1228}-
1229-
1230QResourceFileEngine::QResourceFileEngine(const QString &file) :-
1231 QAbstractFileEngine(*new QResourceFileEnginePrivate)-
1232{-
1233 Q_D(QResourceFileEngine);-
1234 d->resource.setFileName(file);-
if(d->resource.isCompressed() && d->resource.size()) {
#ifndef QT_NO_COMPRESS
d->uncompressed = qUncompress(d->resource.data(), d->resource.size());
#else
Q_ASSERT(!"QResourceFileEngine::open: Qt built without support for compression");
#endif
executed 48997 times by 114 tests: end of block
Executed by:
  • tst_QAbstractFileEngine
  • tst_QAbstractItemView
  • tst_QAbstractScrollArea
  • tst_QAccessibility
  • tst_QApplication
  • tst_QButtonGroup
  • tst_QCalendarWidget
  • tst_QColorDialog
  • tst_QColumnView
  • tst_QComboBox
  • tst_QCommandLineParser
  • tst_QCommandLinkButton
  • tst_QCompleter
  • tst_QCoreApplication
  • tst_QDBusConnectionNoBus
  • tst_QDBusConnectionNoLibDBus1
  • tst_QDBusConnection_Delayed
  • tst_QDateTimeEdit
  • tst_QDialog
  • tst_QDir
  • tst_QDirIterator
  • tst_QDnsLookup_Appless
  • tst_QDoubleSpinBox
  • tst_QErrorMessage
  • tst_QFile
  • ...
}
executed 48997 times by 114 tests: end of block
Executed by:
  • tst_QAbstractFileEngine
  • tst_QAbstractItemView
  • tst_QAbstractScrollArea
  • tst_QAccessibility
  • tst_QApplication
  • tst_QButtonGroup
  • tst_QCalendarWidget
  • tst_QColorDialog
  • tst_QColumnView
  • tst_QComboBox
  • tst_QCommandLineParser
  • tst_QCommandLinkButton
  • tst_QCompleter
  • tst_QCoreApplication
  • tst_QDBusConnectionNoBus
  • tst_QDBusConnectionNoLibDBus1
  • tst_QDBusConnection_Delayed
  • tst_QDateTimeEdit
  • tst_QDialog
  • tst_QDir
  • tst_QDirIterator
  • tst_QDnsLookup_Appless
  • tst_QDoubleSpinBox
  • tst_QErrorMessage
  • tst_QFile
  • ...
}
executed 48997 times by 114 tests: end of block
Executed by:
  • tst_QAbstractFileEngine
  • tst_QAbstractItemView
  • tst_QAbstractScrollArea
  • tst_QAccessibility
  • tst_QApplication
  • tst_QButtonGroup
  • tst_QCalendarWidget
  • tst_QColorDialog
  • tst_QColumnView
  • tst_QComboBox
  • tst_QCommandLineParser
  • tst_QCommandLinkButton
  • tst_QCompleter
  • tst_QCoreApplication
  • tst_QDBusConnectionNoBus
  • tst_QDBusConnectionNoLibDBus1
  • tst_QDBusConnection_Delayed
  • tst_QDateTimeEdit
  • tst_QDialog
  • tst_QDir
  • tst_QDirIterator
  • tst_QDnsLookup_Appless
  • tst_QDoubleSpinBox
  • tst_QErrorMessage
  • tst_QFile
  • ...
1236-
1237QResourceFileEngine::~QResourceFileEngine()-
1238{-
1239}-
1240-
1241void QResourceFileEngine::setFileName(const QString &file)-
1242{-
1243 Q_D(QResourceFileEngine);-
1244 d->resource.setFileName(file);-
1245}-
1246-
1247bool QResourceFileEngine::open(QIODevice::OpenMode flags)-
1248{-
1249 Q_D(QResourceFileEngine);-
1250 if (d->resource.fileName().isEmpty()) {
d->resource.fi...me().isEmpty()Description
TRUEnever evaluated
FALSEevaluated 14854 times by 83 tests
Evaluated by:
  • tst_QAbstractFileEngine
  • tst_QAbstractItemView
  • tst_QAbstractScrollArea
  • tst_QAccessibility
  • tst_QButtonGroup
  • tst_QCalendarWidget
  • tst_QColorDialog
  • tst_QColumnView
  • tst_QComboBox
  • tst_QCommandLinkButton
  • tst_QCompleter
  • tst_QDateTimeEdit
  • tst_QDialog
  • tst_QDoubleSpinBox
  • tst_QFile
  • tst_QFileDialog2
  • tst_QFileIconProvider
  • tst_QFileInfo
  • tst_QFileSystemModel
  • tst_QFiledialog
  • tst_QFocusEvent
  • tst_QFontComboBox
  • tst_QFontDialog
  • tst_QFontMetrics
  • tst_QGlyphRun
  • ...
0-14854
1251 qWarning("QResourceFileEngine::open: Missing file name");-
1252 return false;
never executed: return false;
0
1253 }-
1254 if(flags & QIODevice::WriteOnly)
flags & QIODevice::WriteOnlyDescription
TRUEevaluated 3 times by 1 test
Evaluated by:
  • tst_QSettings
FALSEevaluated 14851 times by 83 tests
Evaluated by:
  • tst_QAbstractFileEngine
  • tst_QAbstractItemView
  • tst_QAbstractScrollArea
  • tst_QAccessibility
  • tst_QButtonGroup
  • tst_QCalendarWidget
  • tst_QColorDialog
  • tst_QColumnView
  • tst_QComboBox
  • tst_QCommandLinkButton
  • tst_QCompleter
  • tst_QDateTimeEdit
  • tst_QDialog
  • tst_QDoubleSpinBox
  • tst_QFile
  • tst_QFileDialog2
  • tst_QFileIconProvider
  • tst_QFileInfo
  • tst_QFileSystemModel
  • tst_QFiledialog
  • tst_QFocusEvent
  • tst_QFontComboBox
  • tst_QFontDialog
  • tst_QFontMetrics
  • tst_QGlyphRun
  • ...
3-14851
1255 return false;
executed 3 times by 1 test: return false;
Executed by:
  • tst_QSettings
3
1256 d->uncompress();-
1257 if (!d->resource.isValid()) {
!d->resource.isValid()Description
TRUEevaluated 212 times by 7 tests
Evaluated by:
  • tst_QFile
  • tst_QImageReader
  • tst_QPlainTextEdit
  • tst_QTextBrowser
  • tst_QTextDocument
  • tst_QTextEdit
  • tst_Selftests
FALSEevaluated 14639 times by 81 tests
Evaluated by:
  • tst_QAbstractFileEngine
  • tst_QAbstractItemView
  • tst_QAbstractScrollArea
  • tst_QAccessibility
  • tst_QButtonGroup
  • tst_QCalendarWidget
  • tst_QColorDialog
  • tst_QColumnView
  • tst_QComboBox
  • tst_QCommandLinkButton
  • tst_QCompleter
  • tst_QDateTimeEdit
  • tst_QDialog
  • tst_QDoubleSpinBox
  • tst_QFile
  • tst_QFileDialog2
  • tst_QFileIconProvider
  • tst_QFileInfo
  • tst_QFileSystemModel
  • tst_QFiledialog
  • tst_QFocusEvent
  • tst_QFontComboBox
  • tst_QFontDialog
  • tst_QFontMetrics
  • tst_QGlyphRun
  • ...
212-14639
1258 d->errorString = qt_error_string(ENOENT);-
1259 return false;
executed 212 times by 7 tests: return false;
Executed by:
  • tst_QFile
  • tst_QImageReader
  • tst_QPlainTextEdit
  • tst_QTextBrowser
  • tst_QTextDocument
  • tst_QTextEdit
  • tst_Selftests
212
1260 }-
1261 return true;
executed 14639 times by 81 tests: return true;
Executed by:
  • tst_QAbstractFileEngine
  • tst_QAbstractItemView
  • tst_QAbstractScrollArea
  • tst_QAccessibility
  • tst_QButtonGroup
  • tst_QCalendarWidget
  • tst_QColorDialog
  • tst_QColumnView
  • tst_QComboBox
  • tst_QCommandLinkButton
  • tst_QCompleter
  • tst_QDateTimeEdit
  • tst_QDialog
  • tst_QDoubleSpinBox
  • tst_QFile
  • tst_QFileDialog2
  • tst_QFileIconProvider
  • tst_QFileInfo
  • tst_QFileSystemModel
  • tst_QFiledialog
  • tst_QFocusEvent
  • tst_QFontComboBox
  • tst_QFontDialog
  • tst_QFontMetrics
  • tst_QGlyphRun
  • ...
14639
1262}-
1263-
1264bool QResourceFileEngine::close()-
1265{-
1266 Q_D(QResourceFileEngine);-
1267 d->offset = 0;-
1268 d->uncompressed.clear();-
1269 return true;-
1270}-
1271-
1272bool QResourceFileEngine::flush()-
1273{-
1274 return true;-
1275}-
1276-
1277qint64 QResourceFileEngine::read(char *data, qint64 len)-
1278{-
1279 Q_D(QResourceFileEngine);-
1280 if(len > size()-d->offset)-
1281 len = size()-d->offset;-
1282 if(len <= 0)-
1283 return 0;-
1284 if(d->resource.isCompressed())-
1285 memcpy(data, d->uncompressed.constData()+d->offset, len);-
1286 else-
1287 memcpy(data, d->resource.data()+d->offset, len);-
1288 d->offset += len;-
1289 return len;-
1290}-
1291-
1292qint64 QResourceFileEngine::write(const char *, qint64)-
1293{-
1294 return -1;-
1295}-
1296-
1297bool QResourceFileEngine::remove()-
1298{-
1299 return false;-
1300}-
1301-
1302bool QResourceFileEngine::copy(const QString &)-
1303{-
1304 return false;-
1305}-
1306-
1307bool QResourceFileEngine::rename(const QString &)-
1308{-
1309 return false;-
1310}-
1311-
1312bool QResourceFileEngine::link(const QString &)-
1313{-
1314 return false;-
1315}-
1316-
1317qint64 QResourceFileEngine::size() const-
1318{-
1319 Q_D(const QResourceFileEngine);-
1320 if(!d->resource.isValid())
!d->resource.isValid()Description
TRUEnever evaluated
FALSEevaluated 179590 times by 81 tests
Evaluated by:
  • tst_QAbstractFileEngine
  • tst_QAbstractItemView
  • tst_QAbstractScrollArea
  • tst_QAccessibility
  • tst_QButtonGroup
  • tst_QCalendarWidget
  • tst_QColorDialog
  • tst_QColumnView
  • tst_QComboBox
  • tst_QCommandLinkButton
  • tst_QCompleter
  • tst_QDateTimeEdit
  • tst_QDialog
  • tst_QDoubleSpinBox
  • tst_QFile
  • tst_QFileDialog2
  • tst_QFileIconProvider
  • tst_QFileInfo
  • tst_QFileSystemModel
  • tst_QFiledialog
  • tst_QFocusEvent
  • tst_QFontComboBox
  • tst_QFontDialog
  • tst_QFontMetrics
  • tst_QGlyphRun
  • ...
0-179590
1321 return 0;
never executed: return 0;
0
1322 if (d->resource.isCompressed()) {
d->resource.isCompressed()Description
TRUEevaluated 2845 times by 8 tests
Evaluated by:
  • tst_QFileInfo
  • tst_QIcon
  • tst_QImageReader
  • tst_QKeySequence
  • tst_QMimeDatabase
  • tst_QResourceEngine
  • tst_Selftests
  • tst_rcc
FALSEevaluated 176745 times by 80 tests
Evaluated by:
  • tst_QAbstractFileEngine
  • tst_QAbstractItemView
  • tst_QAbstractScrollArea
  • tst_QAccessibility
  • tst_QButtonGroup
  • tst_QCalendarWidget
  • tst_QColorDialog
  • tst_QColumnView
  • tst_QComboBox
  • tst_QCommandLinkButton
  • tst_QCompleter
  • tst_QDateTimeEdit
  • tst_QDialog
  • tst_QDoubleSpinBox
  • tst_QFile
  • tst_QFileDialog2
  • tst_QFileIconProvider
  • tst_QFileInfo
  • tst_QFileSystemModel
  • tst_QFiledialog
  • tst_QFocusEvent
  • tst_QFontComboBox
  • tst_QFontDialog
  • tst_QFontMetrics
  • tst_QGlyphRun
  • ...
2845-176745
1323 d->uncompress();-
1324 return d->uncompressed.size();
executed 2845 times by 8 tests: return d->uncompressed.size();
Executed by:
  • tst_QFileInfo
  • tst_QIcon
  • tst_QImageReader
  • tst_QKeySequence
  • tst_QMimeDatabase
  • tst_QResourceEngine
  • tst_Selftests
  • tst_rcc
2845
1325 }-
1326 return d->resource.size();
executed 176745 times by 80 tests: return d->resource.size();
Executed by:
  • tst_QAbstractFileEngine
  • tst_QAbstractItemView
  • tst_QAbstractScrollArea
  • tst_QAccessibility
  • tst_QButtonGroup
  • tst_QCalendarWidget
  • tst_QColorDialog
  • tst_QColumnView
  • tst_QComboBox
  • tst_QCommandLinkButton
  • tst_QCompleter
  • tst_QDateTimeEdit
  • tst_QDialog
  • tst_QDoubleSpinBox
  • tst_QFile
  • tst_QFileDialog2
  • tst_QFileIconProvider
  • tst_QFileInfo
  • tst_QFileSystemModel
  • tst_QFiledialog
  • tst_QFocusEvent
  • tst_QFontComboBox
  • tst_QFontDialog
  • tst_QFontMetrics
  • tst_QGlyphRun
  • ...
176745
1327}-
1328-
1329qint64 QResourceFileEngine::pos() const-
1330{-
1331 Q_D(const QResourceFileEngine);-
1332 return d->offset;-
1333}-
1334-
1335bool QResourceFileEngine::atEnd() const-
1336{-
1337 Q_D(const QResourceFileEngine);-
1338 if(!d->resource.isValid())-
1339 return true;-
1340 return d->offset == size();-
1341}-
1342-
1343bool QResourceFileEngine::seek(qint64 pos)-
1344{-
1345 Q_D(QResourceFileEngine);-
1346 if(!d->resource.isValid())-
1347 return false;-
1348-
1349 if(d->offset > size())-
1350 return false;-
1351 d->offset = pos;-
1352 return true;-
1353}-
1354-
1355bool QResourceFileEngine::isSequential() const-
1356{-
1357 return false;-
1358}-
1359-
1360QAbstractFileEngine::FileFlags QResourceFileEngine::fileFlags(QAbstractFileEngine::FileFlags type) const-
1361{-
1362 Q_D(const QResourceFileEngine);-
1363 QAbstractFileEngine::FileFlags ret = 0;-
1364 if(!d->resource.isValid())-
1365 return ret;-
1366-
1367 if(type & PermsMask)-
1368 ret |= QAbstractFileEngine::FileFlags(ReadOwnerPerm|ReadUserPerm|ReadGroupPerm|ReadOtherPerm);-
1369 if(type & TypesMask) {-
1370 if(d->resource.isDir())-
1371 ret |= DirectoryType;-
1372 else-
1373 ret |= FileType;-
1374 }-
1375 if(type & FlagsMask) {-
1376 ret |= ExistsFlag;-
1377 if(d->resource.absoluteFilePath() == QLatin1String(":/"))-
1378 ret |= RootFlag;-
1379 }-
1380 return ret;-
1381}-
1382-
1383bool QResourceFileEngine::setPermissions(uint)-
1384{-
1385 return false;-
1386}-
1387-
1388QString QResourceFileEngine::fileName(FileName file) const-
1389{-
1390 Q_D(const QResourceFileEngine);-
1391 if(file == BaseName) {-
1392 int slash = d->resource.fileName().lastIndexOf(QLatin1Char('/'));-
1393 if (slash == -1)-
1394 return d->resource.fileName();-
1395 return d->resource.fileName().mid(slash + 1);-
1396 } else if(file == PathName || file == AbsolutePathName) {-
1397 const QString path = (file == AbsolutePathName) ? d->resource.absoluteFilePath() : d->resource.fileName();-
1398 const int slash = path.lastIndexOf(QLatin1Char('/'));-
1399 if (slash == -1)-
1400 return QLatin1String(":");-
1401 else if (slash <= 1)-
1402 return QLatin1String(":/");-
1403 return path.left(slash);-
1404-
1405 } else if(file == CanonicalName || file == CanonicalPathName) {-
1406 const QString absoluteFilePath = d->resource.absoluteFilePath();-
1407 if(file == CanonicalPathName) {-
1408 const int slash = absoluteFilePath.lastIndexOf(QLatin1Char('/'));-
1409 if (slash != -1)-
1410 return absoluteFilePath.left(slash);-
1411 }-
1412 return absoluteFilePath;-
1413 }-
1414 return d->resource.fileName();-
1415}-
1416-
1417bool QResourceFileEngine::isRelativePath() const-
1418{-
1419 return false;-
1420}-
1421-
1422uint QResourceFileEngine::ownerId(FileOwner) const-
1423{-
1424 static const uint nobodyID = (uint) -2;-
1425 return nobodyID;-
1426}-
1427-
1428QString QResourceFileEngine::owner(FileOwner) const-
1429{-
1430 return QString();-
1431}-
1432-
1433QDateTime QResourceFileEngine::fileTime(FileTime) const-
1434{-
1435 return QDateTime();-
1436}-
1437-
1438/*!-
1439 \internal-
1440*/-
1441QAbstractFileEngine::Iterator *QResourceFileEngine::beginEntryList(QDir::Filters filters,-
1442 const QStringList &filterNames)-
1443{-
1444 return new QResourceFileEngineIterator(filters, filterNames);-
1445}-
1446-
1447/*!-
1448 \internal-
1449*/-
1450QAbstractFileEngine::Iterator *QResourceFileEngine::endEntryList()-
1451{-
1452 return 0;-
1453}-
1454-
1455bool QResourceFileEngine::extension(Extension extension, const ExtensionOption *option, ExtensionReturn *output)-
1456{-
1457 Q_D(QResourceFileEngine);-
1458 if (extension == MapExtension) {-
1459 const MapExtensionOption *options = (const MapExtensionOption*)(option);-
1460 MapExtensionReturn *returnValue = static_cast<MapExtensionReturn*>(output);-
1461 returnValue->address = d->map(options->offset, options->size, options->flags);-
1462 return (returnValue->address != 0);-
1463 }-
1464 if (extension == UnMapExtension) {-
1465 const UnMapExtensionOption *options = (const UnMapExtensionOption*)option;-
1466 return d->unmap(options->address);-
1467 }-
1468 return false;-
1469}-
1470-
1471bool QResourceFileEngine::supportsExtension(Extension extension) const-
1472{-
1473 return (extension == UnMapExtension || extension == MapExtension);-
1474}-
1475-
1476uchar *QResourceFileEnginePrivate::map(qint64 offset, qint64 size, QFile::MemoryMapFlags flags)-
1477{-
1478 Q_Q(QResourceFileEngine);-
1479 Q_UNUSED(flags);-
1480 if (offset < 0 || size <= 0 || !resource.isValid() || offset + size > resource.size()) {-
1481 q->setError(QFile::UnspecifiedError, QString());-
1482 return 0;-
1483 }-
1484 uchar *address = const_cast<uchar *>(resource.data());-
1485 return (address + offset);-
1486}-
1487-
1488bool QResourceFileEnginePrivate::unmap(uchar *ptr)-
1489{-
1490 Q_UNUSED(ptr);-
1491 return true;-
1492}-
1493-
1494void QResourceFileEnginePrivate::uncompress() const-
1495{-
1496 if (resource.isCompressed() && uncompressed.isEmpty() && resource.size()) {
resource.isCompressed()Description
TRUEevaluated 3458 times by 8 tests
Evaluated by:
  • tst_QFileInfo
  • tst_QIcon
  • tst_QImageReader
  • tst_QKeySequence
  • tst_QMimeDatabase
  • tst_QResourceEngine
  • tst_Selftests
  • tst_rcc
FALSEevaluated 14238 times by 82 tests
Evaluated by:
  • tst_QAbstractFileEngine
  • tst_QAbstractItemView
  • tst_QAbstractScrollArea
  • tst_QAccessibility
  • tst_QButtonGroup
  • tst_QCalendarWidget
  • tst_QColorDialog
  • tst_QColumnView
  • tst_QComboBox
  • tst_QCommandLinkButton
  • tst_QCompleter
  • tst_QDateTimeEdit
  • tst_QDialog
  • tst_QDoubleSpinBox
  • tst_QFile
  • tst_QFileDialog2
  • tst_QFileIconProvider
  • tst_QFileInfo
  • tst_QFileSystemModel
  • tst_QFiledialog
  • tst_QFocusEvent
  • tst_QFontComboBox
  • tst_QFontDialog
  • tst_QFontMetrics
  • tst_QGlyphRun
  • ...
uncompressed.isEmpty()Description
TRUEevaluated 619 times by 8 tests
Evaluated by:
  • tst_QFileInfo
  • tst_QIcon
  • tst_QImageReader
  • tst_QKeySequence
  • tst_QMimeDatabase
  • tst_QResourceEngine
  • tst_Selftests
  • tst_rcc
FALSEevaluated 2839 times by 8 tests
Evaluated by:
  • tst_QFileInfo
  • tst_QIcon
  • tst_QImageReader
  • tst_QKeySequence
  • tst_QMimeDatabase
  • tst_QResourceEngine
  • tst_Selftests
  • tst_rcc
resource.size()Description
TRUEevaluated 619 times by 8 tests
Evaluated by:
  • tst_QFileInfo
  • tst_QIcon
  • tst_QImageReader
  • tst_QKeySequence
  • tst_QMimeDatabase
  • tst_QResourceEngine
  • tst_Selftests
  • tst_rcc
FALSEnever evaluated
0-14238
1497#ifndef QT_NO_COMPRESS-
1498 uncompressed = qUncompress(resource.data(), resource.size());-
1499#else-
1500 Q_ASSERT(!"QResourceFileEngine::open: Qt built without support for compression");-
1501#endif-
1502 }
executed 619 times by 8 tests: end of block
Executed by:
  • tst_QFileInfo
  • tst_QIcon
  • tst_QImageReader
  • tst_QKeySequence
  • tst_QMimeDatabase
  • tst_QResourceEngine
  • tst_Selftests
  • tst_rcc
619
1503}
executed 17696 times by 83 tests: end of block
Executed by:
  • tst_QAbstractFileEngine
  • tst_QAbstractItemView
  • tst_QAbstractScrollArea
  • tst_QAccessibility
  • tst_QButtonGroup
  • tst_QCalendarWidget
  • tst_QColorDialog
  • tst_QColumnView
  • tst_QComboBox
  • tst_QCommandLinkButton
  • tst_QCompleter
  • tst_QDateTimeEdit
  • tst_QDialog
  • tst_QDoubleSpinBox
  • tst_QFile
  • tst_QFileDialog2
  • tst_QFileIconProvider
  • tst_QFileInfo
  • tst_QFileSystemModel
  • tst_QFiledialog
  • tst_QFocusEvent
  • tst_QFontComboBox
  • tst_QFontDialog
  • tst_QFontMetrics
  • tst_QGlyphRun
  • ...
17696
1504-
1505#endif // !defined(QT_BOOTSTRAPPED)-
1506-
1507QT_END_NAMESPACE-
Source codeSwitch to Preprocessed file

Generated by Squish Coco Non-Commercial 4.3.0-BETA-master-30-08-2018-4cb69e9