?? qresource.cpp
字號:
}/*! Returns direct access to a read only segment of data that this resource represents. If the resource is compressed the data returns is compressed and qUncompress() must be used to access the data. If the resource is a directory 0 is returned. \sa size(), isCompressed(), isFile()*/const uchar *QResource::data() const{ Q_D(const QResource); d->ensureInitialized(); return d->data;}/*! Returns true if the resource represents a directory and thus may have children() in it, false if it represents a file. \sa isFile()*/bool QResource::isDir() const{ Q_D(const QResource); d->ensureInitialized(); return d->container;}/*! Returns a list of all resources in this directory, if the resource represents a file the list will be empty. \sa isDir()*/QStringList QResource::children() const{ Q_D(const QResource); d->ensureChildren(); return d->children;}/*! Adds \a path to the search paths searched in to find resources that are not specified with an absolute path. The \a path must be an absolute path (start with \c{/}). The default search path is to search only in the root (\c{:/}). The last path added will be consulted first upon next QResource creation.*/voidQResource::addSearchPath(const QString &path){ if (!path.startsWith(QLatin1Char('/'))) { qWarning("QDir::addResourceSearchPath: Search paths must be absolute (start with /) [%s]", path.toLocal8Bit().data()); return; } QMutexLocker lock(resourceMutex()); resourceSearchPaths()->prepend(path);}/*! Returns the current search path list. This list is consulted when creating a relative resource. \sa addSearchPath()*/QStringListQResource::searchPaths(){ QMutexLocker lock(resourceMutex()); return *resourceSearchPaths();}inline int QResourceRoot::hash(int node) const{ if(!node) //root return 0; const int offset = findOffset(node); int name_offset = (tree[offset+0] << 24) + (tree[offset+1] << 16) + (tree[offset+2] << 8) + (tree[offset+3] << 0); name_offset += 2; //jump past name length return (names[name_offset+0] << 24) + (names[name_offset+1] << 16) + (names[name_offset+2] << 8) + (names[name_offset+3] << 0);}inline QString QResourceRoot::name(int node) const{ if(!node) // root return QString(); const int offset = findOffset(node); QString ret; int name_offset = (tree[offset+0] << 24) + (tree[offset+1] << 16) + (tree[offset+2] << 8) + (tree[offset+3] << 0); const short name_length = (names[name_offset+0] << 8) + (names[name_offset+1] << 0); name_offset += 2; name_offset += 4; //jump past hash for(int i = 0; i < name_length*2; i+=2) ret += QChar(names[name_offset+i+1], names[name_offset+i]); return ret;}int QResourceRoot::findNode(const QString &_path, const QLocale &locale) const{ QString path = _path; { QString root = mappingRoot(); if(!root.isEmpty()) { if(root == path) { path = QLatin1String("/"); } else { if(!root.endsWith(QLatin1String("/"))) root += QLatin1String("/"); if(path.size() >= root.size() && path.startsWith(root)) path = path.mid(root.length()-1); if(path.isEmpty()) path = QLatin1String("/"); } } } if(path == QLatin1String("/")) return 0; //the root node is always first int child_count = (tree[6] << 24) + (tree[7] << 16) + (tree[8] << 8) + (tree[9] << 0); int child = (tree[10] << 24) + (tree[11] << 16) + (tree[12] << 8) + (tree[13] << 0); //now iterate up the tree int node = -1; QStringList segments = path.split(QLatin1Char('/'), QString::SkipEmptyParts); for(int i = 0; child_count && i < segments.size(); ++i) { const QString &segment = segments[i]; const int h = qHash(segment); //do the binary search for the hash int l = 0, r = child_count-1; int sub_node = (l+r+1)/2; while(r != l) { const int sub_node_hash = hash(child+sub_node); if(h == sub_node_hash) break; else if(h < sub_node_hash) r = sub_node - 1; else l = sub_node; sub_node = (l + r + 1) / 2; } sub_node += child; //now do the "harder" compares bool found = false; if(hash(sub_node) == h) { while(sub_node > child && hash(sub_node-1) == h) //backup for collisions --sub_node; for(; sub_node < child+child_count && hash(sub_node) == h; ++sub_node) { //here we go... if(name(sub_node) == segment) { found = true; int offset = findOffset(sub_node) + 4; //jump past name const short flags = (tree[offset+0] << 8) + (tree[offset+1] << 0); offset += 2; if(i == segments.size()-1) { if(!(flags & Directory)) { const short country = (tree[offset+0] << 8) + (tree[offset+1] << 0); offset += 2; const short language = (tree[offset+0] << 8) + (tree[offset+1] << 0); offset += 2; if(country == locale.country() && language == locale.language()) return sub_node; else if((country == QLocale::AnyCountry && language == locale.language()) || (country == QLocale::AnyCountry && language == QLocale::C && node == -1)) node = sub_node; continue; } else { return sub_node; } } if(!(flags & Directory)) return -1; child_count = (tree[offset+0] << 24) + (tree[offset+1] << 16) + (tree[offset+2] << 8) + (tree[offset+3] << 0); offset += 4; child = (tree[offset+0] << 24) + (tree[offset+1] << 16) + (tree[offset+2] << 8) + (tree[offset+3] << 0); break; } } } if(!found) break; } return node;}short QResourceRoot::flags(int node) const{ if(node == -1) return 0; const int offset = findOffset(node) + 4; //jump past name return (tree[offset+0] << 8) + (tree[offset+1] << 0);}const uchar *QResourceRoot::data(int node, qint64 *size) const{ if(node == -1) { *size = 0; return 0; } int offset = findOffset(node) + 4; //jump past name const short flags = (tree[offset+0] << 8) + (tree[offset+1] << 0); offset += 2; offset += 4; //jump past locale if(!(flags & Directory)) { const int data_offset = (tree[offset+0] << 24) + (tree[offset+1] << 16) + (tree[offset+2] << 8) + (tree[offset+3] << 0); const uint data_length = (payloads[data_offset+0] << 24) + (payloads[data_offset+1] << 16) + (payloads[data_offset+2] << 8) + (payloads[data_offset+3] << 0); const uchar *ret = payloads+data_offset+4; *size = data_length; return ret; } *size = 0; return 0;}QStringList QResourceRoot::children(int node) const{ if(node == -1) return QStringList(); int offset = findOffset(node) + 4; //jump past name const short flags = (tree[offset+0] << 8) + (tree[offset+1] << 0); offset += 2; QStringList ret; if(flags & Directory) { const int child_count = (tree[offset+0] << 24) + (tree[offset+1] << 16) + (tree[offset+2] << 8) + (tree[offset+3] << 0); offset += 4; const int child_off = (tree[offset+0] << 24) + (tree[offset+1] << 16) + (tree[offset+2] << 8) + (tree[offset+3] << 0); for(int i = child_off; i < child_off+child_count; ++i) ret << name(i); } return ret;}bool QResourceRoot::mappingRootSubdir(const QString &path, QString *match) const{ const QString root = mappingRoot(); if(!root.isEmpty()) { const QStringList root_segments = root.split(QLatin1Char('/'), QString::SkipEmptyParts), path_segments = path.split(QLatin1Char('/'), QString::SkipEmptyParts); if(path_segments.size() <= root_segments.size()) { int matched = 0; for(int i = 0; i < path_segments.size(); ++i) { if(root_segments[i] != path_segments[i]) break; ++matched; } if(matched == path_segments.size()) { if(match && root_segments.size() > matched) *match = root_segments.at(matched); return true; } } } return false;}Q_CORE_EXPORT bool qRegisterResourceData(int version, const unsigned char *tree, const unsigned char *name, const unsigned char *data){ QMutexLocker lock(resourceMutex()); if(version == 0x01 && resourceList()) { bool found = false; QResourceRoot res(tree, name, data); for(int i = 0; i < resourceList()->size(); ++i) { if(*resourceList()->at(i) == res) { found = true; break; } } if(!found) { QResourceRoot *root = new QResourceRoot(tree, name, data); root->ref.ref(); resourceList()->append(root); } return true; } return false;}Q_CORE_EXPORT bool qUnregisterResourceData(int version, const unsigned char *tree, const unsigned char *name, const unsigned char *data){ QMutexLocker lock(resourceMutex()); if(version == 0x01 && resourceList()) { QResourceRoot res(tree, name, data); for(int i = 0; i < resourceList()->size(); ) { if(*resourceList()->at(i) == res) { QResourceRoot *root = resourceList()->takeAt(i); if(!root->ref.deref()) delete root; } else { ++i; } } return true; } return false;}//run time resource creation#if defined(Q_OS_UNIX)#define QT_USE_MMAP#endif// most of the headers below are already included in qplatformdefs.h// also this lacks Large File support but that's probably irrelevant#if defined(QT_USE_MMAP)// for mmap#include <sys/mman.h>#include <errno.h>#endifclass QDynamicResourceRoot: public QResourceRoot{ QString root, fileName; // for mmap'ed files, this is what needs to be unmapped. uchar *unmapPointer; unsigned int unmapLength; bool fromMM;public: inline QDynamicResourceRoot(const QString &_root) : root(_root), unmapPointer(0), unmapLength(0) { } ~QDynamicResourceRoot() { if (unmapPointer && unmapLength) {#if defined(QT_USE_MMAP) if(fromMM) munmap((char*)unmapPointer, unmapLength); else#endif delete [] unmapPointer; unmapPointer = 0; unmapLength = 0; } } QString mappingFile() const { return fileName; } virtual QString mappingRoot() const { return root; } virtual bool isDynamicRoot() const { return true; } bool registerSelf(const QString &f) { bool ok = false;#ifdef QT_USE_MMAP#ifndef MAP_FILE#define MAP_FILE 0#endif#ifndef MAP_FAILED#define MAP_FAILED -1#endif int fd = QT_OPEN(QFile::encodeName(f), O_RDONLY,#if defined(Q_OS_WIN) _S_IREAD | _S_IWRITE#else 0666#endif ); if (fd >= 0) { struct stat st; if (!fstat(fd, &st)) { uchar *ptr; ptr = reinterpret_cast<uchar *>( mmap(0, st.st_size, // any address, whole file PROT_READ, // read-only memory MAP_FILE | MAP_PRIVATE, // swap-backed map from file fd, 0)); // from offset 0 of fd if (ptr && ptr != reinterpret_cast<uchar *>(MAP_FAILED)) { unmapPointer = ptr; unmapLength = st.st_size; fromMM = true; ok = true; } } ::close(fd); }#endif // QT_USE_MMAP if(!ok) { QFile file(f); if (!file.exists()) return false; unmapLength = file.size(); unmapPointer = new uchar[unmapLength]; if (file.open(QIODevice::ReadOnly)) ok = (unmapLength == (uint)file.read((char*)unmapPointer, unmapLength)); if (!ok) { delete [] unmapPointer; unmapPointer = 0; unmapLength = 0; return false; } fromMM = false; } if(!ok) { fileName = QString(); return false; } fileName = f;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -