//static bool QFileSystemEngine::createDirectory(const QFileSystemEntry &entry, bool createParents) { QString abspath = absoluteName(entry).nativeFilePath(); if (!abspath.endsWith(QLatin1Char('\\'))) abspath.append(QLatin1Char('\\')); TInt r; if (createParents) r = qt_s60GetRFs().MkDirAll(qt_QString2TPtrC(abspath)); else r = qt_s60GetRFs().MkDir(qt_QString2TPtrC(abspath)); if (createParents && r == KErrAlreadyExists) return true; //# Qt5 - QDir::mkdir returns false for existing dir, QDir::mkpath returns true (should be made consistent in Qt 5) return (r == KErrNone); }
//static bool QFileSystemEngine::removeFile(const QFileSystemEntry &entry, QSystemError &error) { QString targetpath = absoluteName(entry).nativeFilePath(); RFs& fs(qt_s60GetRFs()); TInt err = fs.Delete(qt_QString2TPtrC(targetpath)); if (err == KErrNone) return true; error = QSystemError(err, QSystemError::NativeError); return false; }
//static bool QFileSystemEngine::renameFile(const QFileSystemEntry &source, const QFileSystemEntry &target, QSystemError &error) { QString sourcepath = absoluteName(source).nativeFilePath(); QString targetpath = absoluteName(target).nativeFilePath(); RFs& fs(qt_s60GetRFs()); TInt err = fs.Rename(qt_QString2TPtrC(sourcepath), qt_QString2TPtrC(targetpath)); if (err == KErrNone) return true; error = QSystemError(err, QSystemError::NativeError); return false; }
//static bool QFileSystemEngine::createDirectory(const QFileSystemEntry &entry, bool createParents) { QString abspath = absoluteName(entry).nativeFilePath(); if (!abspath.endsWith(QLatin1Char('\\'))) abspath.append(QLatin1Char('\\')); TInt r; TPtrC symPath(qt_QString2TPtrC(abspath)); if (createParents) r = qt_s60GetRFs().MkDirAll(symPath); else r = qt_s60GetRFs().MkDir(symPath); if (createParents && r == KErrAlreadyExists) return true; //# Qt5 - QDir::mkdir returns false for existing dir, QDir::mkpath returns true (should be made consistent in Qt 5) if (createParents && r == KErrPermissionDenied) { // check for already exists, which is not returned from RFs when it denies permission TEntry entry; if (qt_s60GetRFs().Entry(symPath, entry) == KErrNone) r = KErrNone; } return (r == KErrNone); }
//static QFileSystemEntry QFileSystemEngine::currentPath() { TFileName fn; QFileSystemEntry ret; TInt r = qt_s60GetRFs().SessionPath(fn); if(r == KErrNone) { //remove terminating slash from non root paths (session path is clean, absolute and always ends in a \) if(fn.Length() > 3 && fn[fn.Length() - 1] == '\\') fn.SetLength(fn.Length() - 1); ret = QFileSystemEntry(qt_TDesC2QString(fn), QFileSystemEntry::FromNativePath()); } return ret; }
QT_BEGIN_NAMESPACE QFileSystemIterator::QFileSystemIterator(const QFileSystemEntry &path, QDir::Filters filters, const QStringList &nameFilters, QDirIterator::IteratorFlags iteratorFlags) : lastError(KErrNone), entryIndex(-1) { RFs& fs = qt_s60GetRFs(); nativePath = path.nativeFilePath(); if (!nativePath.endsWith(QLatin1Char('\\'))) nativePath.append(QLatin1Char('\\')); QString absPath = QFileSystemEngine::absoluteName(path).nativeFilePath(); if (!absPath.endsWith(QLatin1Char('\\'))) absPath.append(QLatin1Char('\\')); int pathLen = absPath.length(); if (pathLen > KMaxFileName) { lastError = KErrBadName; return; } //set up server side filtering to reduce IPCs //RDir won't accept all valid name filters e.g. "*. bar" if (nameFilters.count() == 1 && !(filters & QDir::AllDirs) && iteratorFlags == QDirIterator::NoIteratorFlags && pathLen + nameFilters[0].length() <= KMaxFileName) { //server side supports one mask - skip this for recursive mode or if only files should be filtered absPath.append(nameFilters[0]); } TUint symbianMask = 0; if ((filters & QDir::Dirs) || (filters & QDir::AllDirs) || (iteratorFlags & QDirIterator::Subdirectories)) symbianMask |= KEntryAttDir; //include directories if (filters & QDir::Hidden) symbianMask |= KEntryAttHidden; if (filters & QDir::System) symbianMask |= KEntryAttSystem; //Do not use KEntryAttMatchExclusive to optimise to return only //directories for QDir::Dirs. There may be a file which is actually //a "mount point" for a file engine and needs to be returned so it //can be overriden to be a directory, see QTBUG-23688 if (symbianMask == 0 && ((filters & QDir::PermissionMask) == QDir::Writable)) { symbianMask = KEntryAttMatchExclude | KEntryAttReadOnly; } lastError = dirHandle.Open(fs, qt_QString2TPtrC(absPath), symbianMask); }
//static bool QFileSystemEngine::copyFile(const QFileSystemEntry &source, const QFileSystemEntry &target, QSystemError &error) { //CFileMan is allocated each time because it is not thread-safe CFileMan *fm = 0; TRAPD(err, fm = CFileMan::NewL(qt_s60GetRFs())); if (err == KErrNone) { err = fm->Copy(qt_QString2TPtrC(absoluteName(source).nativeFilePath()), qt_QString2TPtrC(absoluteName(target).nativeFilePath()), 0); delete fm; } if (err == KErrNone) return true; error = QSystemError(err, QSystemError::NativeError); return false; }
/*! \property QPluginLoader::fileName \brief the file name of the plugin To be loadable, the file's suffix must be a valid suffix for a loadable library in accordance with the platform, e.g. \c .so on Unix, \c .dylib on Mac OS X, and \c .dll on Windows. The suffix can be verified with QLibrary::isLibrary(). If the file name does not exist, it will not be set. This property will then contain an empty string. By default, this property contains an empty string. Note: In Symbian the \a fileName must point to plugin stub file. \sa load() */ void QPluginLoader::setFileName(const QString &fileName) { #if defined(QT_SHARED) QLibrary::LoadHints lh; if (d) { lh = d->loadHints; d->release(); d = 0; did_load = false; } #if defined(Q_OS_SYMBIAN) // In Symbian we actually look for plugin stub, so modify the filename // to make canonicalFilePath find the file, if .dll is specified. QFileInfo fi(fileName); if (fi.suffix() == QLatin1String("dll")) { QString stubName = fileName; stubName.chop(3); stubName += QLatin1String("qtplugin"); fi = QFileInfo(stubName); } QString fn = fi.canonicalFilePath(); // If not found directly, check also all the available drives if (!fn.length()) { QString stubPath(fi.fileName().length() ? fi.absoluteFilePath() : QString()); if (stubPath.length() > 1) { if (stubPath.at(1).toAscii() == ':') stubPath.remove(0,2); QFileInfoList driveList(QDir::drives()); RFs rfs = qt_s60GetRFs(); foreach(const QFileInfo& drive, driveList) { QString testFilePath(drive.absolutePath() + stubPath); testFilePath = QDir::cleanPath(testFilePath); // Use native Symbian code to check for file existence, because checking // for file from under non-existent protected dir like E:/private/<uid> using // QFile::exists causes platform security violations on most apps. QString nativePath = QDir::toNativeSeparators(testFilePath); TPtrC ptr(qt_QString2TPtrC(nativePath)); TUint attributes; TInt err = rfs.Att(ptr, attributes); if (err == KErrNone) { fn = testFilePath; break; } } }
//static bool QFileSystemEngine::removeDirectory(const QFileSystemEntry &entry, bool removeEmptyParents) { QString abspath = absoluteName(entry).nativeFilePath(); if (!abspath.endsWith(QLatin1Char('\\'))) abspath.append(QLatin1Char('\\')); TPtrC dir(qt_QString2TPtrC(abspath)); RFs& fs = qt_s60GetRFs(); bool ok = false; //behaviour of FS file engine: //returns true if the directory could be removed //success/failure of removing parent directories does not matter while (KErrNone == fs.RmDir(dir)) { ok = true; if (!removeEmptyParents) break; //RFs::RmDir treats "c:\foo\bar" and "c:\foo\" the same, so it is sufficient to remove the last \ to the end dir.Set(dir.Left(dir.LocateReverse(TChar('\\')))); } return ok; }
const QMimeData* QClipboard::mimeData(Mode mode) const { if (mode != Clipboard) return 0; QClipboardData *d = clipboardData(); bool dataExists(false); if (d) { TRAPD(err,{ RFs fs = qt_s60GetRFs(); CClipboard* cb = CClipboard::NewForReadingLC(fs); Q_ASSERT(cb); //stream for qt RStoreReadStream stream; TStreamId stid = (cb->StreamDictionary()).At(KQtCbDataStream); if (stid != 0) { stream.OpenLC(cb->Store(),stid); QT_TRYCATCH_LEAVING(readFromStreamLX(d->source(),stream)); CleanupStack::PopAndDestroy(&stream); dataExists = true; } else { //symbian clipboard RStoreReadStream symbianStream; TStreamId symbianStId = (cb->StreamDictionary()).At(KClipboardUidTypePlainText); if (symbianStId != 0) { symbianStream.OpenLC(cb->Store(), symbianStId); QT_TRYCATCH_LEAVING(readSymbianStoreLX(d->source(), cb)); CleanupStack::PopAndDestroy(&symbianStream); dataExists = true; } } CleanupStack::PopAndDestroy(cb); }); if (err != KErrNone){ qDebug()<< "clipboard is empty/err: " << err; } if (dataExists) { return d->source(); } }
//static bool QFileSystemEngine::setPermissions(const QFileSystemEntry &entry, QFile::Permissions permissions, QSystemError &error, QFileSystemMetaData *data) { QString targetpath = absoluteName(entry).nativeFilePath(); TUint setmask = 0; TUint clearmask = 0; RFs& fs(qt_s60GetRFs()); if (permissions & (QFile::WriteOwner | QFile::WriteUser | QFile::WriteGroup | QFile::WriteOther)) clearmask = KEntryAttReadOnly; //if anyone can write, it's not read-only else setmask = KEntryAttReadOnly; TInt err = fs.SetAtt(qt_QString2TPtrC(targetpath), setmask, clearmask); if (data && !err) { data->entryFlags &= ~QFileSystemMetaData::Permissions; data->entryFlags |= QFileSystemMetaData::MetaDataFlag(uint(permissions)); data->knownFlagsMask |= QFileSystemMetaData::Permissions; } if (err == KErrNone) return true; error = QSystemError(err, QSystemError::NativeError); return false; }
const QMimeData* QClipboard::mimeData(Mode mode) const { if (mode != Clipboard) return 0; QClipboardData *d = clipboardData(); if (d) { TRAPD(err,{ RFs fs = qt_s60GetRFs(); CClipboard* cb = CClipboard::NewForReadingLC(fs); Q_ASSERT(cb); RStoreReadStream stream; TStreamId stid = (cb->StreamDictionary()).At(KQtCbDataStream); stream.OpenLC(cb->Store(),stid); QT_TRYCATCH_LEAVING(readFromStreamLX(d->source(),stream)); CleanupStack::PopAndDestroy(2,cb); return d->source(); }); if (err != KErrNone){ qDebug()<< "clipboard is empty/err: " << err; } }
QFileInfoList QFSFileEngine::drives() { QFileInfoList ret; #if defined(Q_OS_SYMBIAN) TDriveList driveList; RFs rfs = qt_s60GetRFs(); TInt err = rfs.DriveList(driveList); if (err == KErrNone) { char driveName[] = "A:/"; for (char i = 0; i < KMaxDrives; i++) { if (driveList[i]) { driveName[0] = 'A' + i; ret.append(QFileInfo(QLatin1String(driveName))); } } } else { qWarning("QFSFileEngine::drives: Getting drives failed"); } #else ret.append(QFileInfo(rootPath())); #endif return ret; }
bool QFSFileEngine::setSize(qint64 size) { Q_D(QFSFileEngine); bool ret = false; TInt err = KErrNone; if (d->symbianFile.SubSessionHandle()) { TInt err = d->symbianFile.SetSize(size); ret = (err == KErrNone); if (ret && d->symbianFilePos > size) d->symbianFilePos = size; } else if (d->fd != -1) ret = QT_FTRUNCATE(d->fd, size) == 0; else if (d->fh) ret = QT_FTRUNCATE(QT_FILENO(d->fh), size) == 0; else { RFile tmp; QString symbianFilename(d->fileEntry.nativeFilePath()); err = tmp.Open(qt_s60GetRFs(), qt_QString2TPtrC(symbianFilename), EFileWrite); if (err == KErrNone) { err = tmp.SetSize(size); tmp.Close(); } ret = (err == KErrNone); } if (!ret) { QSystemError error; if (err) error = QSystemError(err, QSystemError::NativeError); else error = QSystemError(errno, QSystemError::StandardLibraryError); setError(QFile::ResizeError, error.toString()); } return ret; }
//static bool QFileSystemEngine::setCurrentPath(const QFileSystemEntry &entry) { QFileSystemMetaData meta; QFileSystemEntry absname = absoluteName(entry); fillMetaData(absname, meta, QFileSystemMetaData::ExistsAttribute | QFileSystemMetaData::DirectoryType); if(!(meta.exists() && meta.isDirectory())) return false; RFs& fs = qt_s60GetRFs(); QString abspath = absname.nativeFilePath(); if(!abspath.endsWith(QLatin1Char('\\'))) abspath.append(QLatin1Char('\\')); TInt r = fs.SetSessionPath(qt_QString2TPtrC(abspath)); //SetSessionPath succeeds for non existent directory, which is why it's checked above if (r == KErrNone) { __ASSERT_COMPILE(sizeof(wchar_t) == sizeof(unsigned short)); //attempt to set open C to the same path r = ::wchdir(reinterpret_cast<const wchar_t *>(absname.filePath().utf16())); if (r < 0) qWarning("failed to sync path to open C"); return true; } return false; }
//static bool QFileSystemEngine::fillMetaData(const QFileSystemEntry &entry, QFileSystemMetaData &data, QFileSystemMetaData::MetaDataFlags what) { if (what & QFileSystemMetaData::SymbianTEntryFlags) { RFs& fs(qt_s60GetRFs()); TInt err; QFileSystemEntry absentry(absoluteName(entry)); if (entry.isEmpty()) { err = KErrNotFound; } else if (absentry.isRoot()) { //Root directories don't have an entry, and Entry() returns KErrBadName. //Therefore get information about the volume instead. TInt drive; err = RFs::CharToDrive(TChar(absentry.nativeFilePath().at(0).unicode()), drive); if (!err) { TVolumeInfo info; err = fs.Volume(info, drive); if (!err) data.fillFromVolumeInfo(info); } } else { TEntry ent; err = fs.Entry(qt_QString2TPtrC(absentry.nativeFilePath()), ent); if (!err) data.fillFromTEntry(ent); } if (err) { data.size_ = 0; data.modificationTime_ = TTime(0); data.entryFlags &= ~(QFileSystemMetaData::SymbianTEntryFlags); } //files in /sys/bin on any drive are executable, even though we don't normally have permission to check whether they exist or not if(absentry.filePath().midRef(1,10).compare(QLatin1String(":/sys/bin/"), Qt::CaseInsensitive) == 0) data.entryFlags |= QFileSystemMetaData::ExecutePermissions; } return data.hasFlags(what); }
/*! \internal Generates a unique file path and returns a native handle to the open file. \a path is used as a template when generating unique paths, \a pos identifies the position of the first character that will be replaced in the template and \a length the number of characters that may be substituted. Returns an open handle to the newly created file if successful, an invalid handle otherwise. In both cases, the string in \a path will be changed and contain the generated path name. */ static bool createFileFromTemplate(NativeFileHandle &file, QFileSystemEntry::NativePath &path, size_t pos, size_t length, QSystemError &error) { Q_ASSERT(length != 0); Q_ASSERT(pos < size_t(path.length())); Q_ASSERT(length <= size_t(path.length()) - pos); Char *const placeholderStart = (Char *)path.data() + pos; Char *const placeholderEnd = placeholderStart + length; // Initialize placeholder with random chars + PID. { Char *rIter = placeholderEnd; #if defined(QT_BUILD_CORE_LIB) quint64 pid = quint64(QCoreApplication::applicationPid()); do { *--rIter = Latin1Char((pid % 10) + '0'); pid /= 10; } while (rIter != placeholderStart && pid != 0); #endif while (rIter != placeholderStart) { char ch = char((qrand() & 0xffff) % (26 + 26)); if (ch < 26) *--rIter = Latin1Char(ch + 'A'); else *--rIter = Latin1Char(ch - 26 + 'a'); } } #ifdef Q_OS_SYMBIAN RFs& fs = qt_s60GetRFs(); #endif for (;;) { // Atomically create file and obtain handle #if defined(Q_OS_WIN) file = CreateFile((const wchar_t *)path.constData(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL); if (file != INVALID_HANDLE_VALUE) return true; DWORD err = GetLastError(); if (err != ERROR_FILE_EXISTS) { error = QSystemError(err, QSystemError::NativeError); return false; } #elif defined(Q_OS_SYMBIAN) TInt err = file.Create(fs, qt_QString2TPtrC(path), EFileRead | EFileWrite | EFileShareReadersOrWriters); if (err == KErrNone) return true; if (err != KErrAlreadyExists) { error = QSystemError(err, QSystemError::NativeError); return false; } #else // POSIX file = QT_OPEN(path.constData(), QT_OPEN_CREAT | O_EXCL | QT_OPEN_RDWR | QT_OPEN_LARGEFILE, 0600); if (file != -1) return true; int err = errno; if (err != EEXIST) { error = QSystemError(err, QSystemError::NativeError); return false; } #endif /* tricky little algorwwithm for backward compatibility */ for (Char *iter = placeholderStart;;) { // Character progression: [0-9] => 'a' ... 'z' => 'A' .. 'Z' // String progression: "ZZaiC" => "aabiC" switch (char(*iter)) { case 'Z': // Rollover, advance next character *iter = Latin1Char('a'); if (++iter == placeholderEnd) { // Out of alternatives. Return file exists error, previously set. error = QSystemError(err, QSystemError::NativeError); return false; } continue; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': *iter = Latin1Char('a'); break; case 'z': // increment 'z' to 'A' *iter = Latin1Char('A'); break; default: ++*iter; break; } break; } } Q_ASSERT(false); }
QString QDesktopServices::storageLocation(StandardLocation type) { TFileName path; switch (type) { case DesktopLocation: qWarning("No desktop concept in Symbian OS"); // But lets still use some feasible default path.Append(writableDataRoot()); break; case DocumentsLocation: path.Append(writableDataRoot()); break; case FontsLocation: path.Append(KFontsDir); break; case ApplicationsLocation: path.Append(exeDrive().Name()); path.Append(KSysBin); break; case MusicLocation: path.Append(writableDataRoot()); #ifdef Q_OS_SYMBIAN path.Append(PathInfo::SoundsPath()); #endif break; case MoviesLocation: path.Append(writableDataRoot()); #ifdef Q_OS_SYMBIAN path.Append(PathInfo::VideosPath()); #endif break; case PicturesLocation: path.Append(writableDataRoot()); #ifdef Q_OS_SYMBIAN path.Append(PathInfo::ImagesPath()); #endif break; case TempLocation: return QDir::tempPath(); break; case HomeLocation: path.Append(writableDataRoot()); //return QDir::homePath(); break; break; case DataLocation: qt_s60GetRFs().PrivatePath(path); path.Insert(0, writableExeDrive().Name()); break; case CacheLocation: qt_s60GetRFs().PrivatePath(path); path.Insert(0, writableExeDrive().Name()); path.Append(KCacheSubDir); break; default: // Lets use feasible default path.Append(writableDataRoot()); break; } // Convert to cross-platform format and clean the path QString nativePath = QString::fromUtf16(path.Ptr(), path.Length()); QString qtPath = QDir::fromNativeSeparators(nativePath); qtPath = QDir::cleanPath(qtPath); // Note: The storage location returned can be a directory that does not exist; // i.e., it may need to be created by the system or the user. return qtPath; }
/*! \internal */ bool QFSFileEnginePrivate::nativeOpen(QIODevice::OpenMode openMode) { Q_Q(QFSFileEngine); fh = 0; fd = -1; QString fn(QFileSystemEngine::absoluteName(fileEntry).nativeFilePath()); RFs& fs = qt_s60GetRFs(); TUint symbianMode = 0; if(openMode & QIODevice::ReadOnly) symbianMode |= EFileRead; if(openMode & QIODevice::WriteOnly) symbianMode |= EFileWrite; if(openMode & QIODevice::Text) symbianMode |= EFileStreamText; if (openMode & QFile::Unbuffered) { if (openMode & QIODevice::WriteOnly) symbianMode |= 0x00001000; //EFileWriteDirectIO; // ### Unbuffered read is not used, because it prevents file open in /resource // ### and has no obvious benefits } else { if (openMode & QIODevice::WriteOnly) symbianMode |= 0x00000800; //EFileWriteBuffered; // use implementation defaults for read buffering } // Until Qt supports file sharing, we can't support EFileShareReadersOrWriters safely, // but Qt does this on other platforms and autotests rely on it. // The reason is that Unix locks are only advisory - the application needs to test the // lock after opening the file. Symbian and Windows locks are mandatory - opening a // locked file will fail. symbianMode |= EFileShareReadersOrWriters; TInt r; //note QIODevice::Truncate only has meaning for read/write access //write-only files are always truncated unless append is specified //reference openModeToOpenFlags in qfsfileengine_unix.cpp if ((openMode & QIODevice::Truncate) || (!(openMode & QIODevice::ReadOnly) && !(openMode & QIODevice::Append))) { r = symbianFile.Replace(fs, qt_QString2TPtrC(fn), symbianMode); } else { r = symbianFile.Open(fs, qt_QString2TPtrC(fn), symbianMode); if (r == KErrNotFound && (openMode & QIODevice::WriteOnly)) { r = symbianFile.Create(fs, qt_QString2TPtrC(fn), symbianMode); } } if (r == KErrNone) { #ifdef SYMBIAN_ENABLE_64_BIT_FILE_SERVER_API TInt64 size; #else TInt size; #endif r = symbianFile.Size(size); if (r==KErrNone) { if (openMode & QIODevice::Append) symbianFilePos = size; else symbianFilePos = 0; //TODO: port this (QFileSystemMetaData in open?) //cachedSize = size; } } if (r != KErrNone) { q->setError(QFile::OpenError, QSystemError(r, QSystemError::NativeError).toString()); symbianFile.Close(); return false; } closeFileHandle = true; return true; }
uchar *QFSFileEnginePrivate::map(qint64 offset, qint64 size, QFile::MemoryMapFlags flags) { Q_Q(QFSFileEngine); Q_UNUSED(flags); if (openMode == QIODevice::NotOpen) { q->setError(QFile::PermissionsError, qt_error_string(int(EACCES))); return 0; } if (offset < 0 || offset != qint64(QT_OFF_T(offset)) || size < 0 || quint64(size) > quint64(size_t(-1))) { q->setError(QFile::UnspecifiedError, qt_error_string(int(EINVAL))); return 0; } // If we know the mapping will extend beyond EOF, fail early to avoid // undefined behavior. Otherwise, let mmap have its say. if (doStat(QFileSystemMetaData::SizeAttribute) && (QT_OFF_T(size) > metaData.size() - QT_OFF_T(offset))) qWarning("QFSFileEngine::map: Mapping a file beyond its size is not portable"); int access = 0; if (openMode & QIODevice::ReadOnly) access |= PROT_READ; if (openMode & QIODevice::WriteOnly) access |= PROT_WRITE; #if defined(Q_OS_INTEGRITY) int pageSize = sysconf(_SC_PAGESIZE); #else int pageSize = getpagesize(); #endif int extra = offset % pageSize; if (quint64(size + extra) > quint64((size_t)-1)) { q->setError(QFile::UnspecifiedError, qt_error_string(int(EINVAL))); return 0; } size_t realSize = (size_t)size + extra; QT_OFF_T realOffset = QT_OFF_T(offset); realOffset &= ~(QT_OFF_T(pageSize - 1)); #ifdef QT_SYMBIAN_USE_NATIVE_FILEMAP TInt nativeMapError = KErrNone; RFileMap mapping; TUint mode(EFileMapRemovableMedia); TUint64 nativeOffset = offset & ~(mapping.PageSizeInBytes() - 1); //If the file was opened for write or read/write, then open the map for read/write if (openMode & QIODevice::WriteOnly) mode |= EFileMapWrite; if (symbianFile.SubSessionHandle()) { nativeMapError = mapping.Open(symbianFile, nativeOffset, size, mode); } else { //map file by name if we don't have a native handle QString fn = QFileSystemEngine::absoluteName(fileEntry).nativeFilePath(); TUint filemode = EFileShareReadersOrWriters | EFileRead; if (openMode & QIODevice::WriteOnly) filemode |= EFileWrite; nativeMapError = mapping.Open(qt_s60GetRFs(), qt_QString2TPtrC(fn), filemode, nativeOffset, size, mode); } if (nativeMapError == KErrNone) { QScopedResource<RFileMap> ptr(mapping); //will call Close if adding to mapping throws an exception uchar *address = mapping.Base() + (offset - nativeOffset); maps[address] = mapping; ptr.take(); return address; } QFile::FileError reportedError = QFile::UnspecifiedError; switch (nativeMapError) { case KErrAccessDenied: case KErrPermissionDenied: reportedError = QFile::PermissionsError; break; case KErrNoMemory: reportedError = QFile::ResourceError; break; } q->setError(reportedError, QSystemError(nativeMapError, QSystemError::NativeError).toString()); return 0; #else #ifdef Q_OS_SYMBIAN //older phones & emulator don't support native mapping, so need to keep the open C way around for those. void *mapAddress; TRAPD(err, mapAddress = QT_MMAP((void*)0, realSize, access, MAP_SHARED, getMapHandle(), realOffset)); if (err != KErrNone) { qWarning("OpenC bug: leave from mmap %d", err); mapAddress = MAP_FAILED; errno = EINVAL; } #else void *mapAddress = QT_MMAP((void*)0, realSize, access, MAP_SHARED, nativeHandle(), realOffset); #endif if (MAP_FAILED != mapAddress) { uchar *address = extra + static_cast<uchar*>(mapAddress); maps[address] = QPair<int,size_t>(extra, realSize); return address; } switch(errno) { case EBADF: q->setError(QFile::PermissionsError, qt_error_string(int(EACCES))); break; case ENFILE: case ENOMEM: q->setError(QFile::ResourceError, qt_error_string(int(errno))); break; case EINVAL: // size are out of bounds default: q->setError(QFile::UnspecifiedError, qt_error_string(int(errno))); break; } return 0; #endif }
bool QTranslator::load(const QString & filename, const QString & directory, const QString & search_delimiters, const QString & suffix) { Q_D(QTranslator); d->clear(); QString fname = filename; QString prefix; if (QFileInfo(filename).isRelative()) { #ifdef Q_OS_SYMBIAN //TFindFile doesn't like path in the filename QString dir(directory); int slash = filename.lastIndexOf(QLatin1Char('/')); slash = qMax(slash, filename.lastIndexOf(QLatin1Char('\\'))); if (slash >=0) { //so move the path component into the directory prefix if (dir.isEmpty()) dir = filename.left(slash + 1); else dir = dir + QLatin1Char('/') + filename.left(slash + 1); fname = fname.mid(slash + 1); } if (dir.isEmpty()) prefix = QCoreApplication::applicationDirPath(); else prefix = QFileInfo(dir).absoluteFilePath(); //TFindFile doesn't like dirty paths if (prefix.length() > 2 && prefix.at(1) == QLatin1Char(':') && prefix.at(0).isLetter()) prefix[0] = QLatin1Char('Y'); #else prefix = directory; #endif if (prefix.length() && !prefix.endsWith(QLatin1Char('/'))) prefix += QLatin1Char('/'); } #ifdef Q_OS_SYMBIAN QString nativePrefix = QDir::toNativeSeparators(prefix); #endif QString realname; QString delims; delims = search_delimiters.isNull() ? QString::fromLatin1("_.") : search_delimiters; for (;;) { QFileInfo fi; #ifdef Q_OS_SYMBIAN //search for translations on other drives, e.g. Qt may be in Z, while app is in C //note this uses symbian search rules, i.e. y:->a:, followed by z: TFindFile finder(qt_s60GetRFs()); QString fname2 = fname + (suffix.isNull() ? QString::fromLatin1(".qm") : suffix); TInt err = finder.FindByDir( qt_QString2TPtrC(fname2), qt_QString2TPtrC(nativePrefix)); if (err != KErrNone) err = finder.FindByDir(qt_QString2TPtrC(fname), qt_QString2TPtrC(nativePrefix)); if (err == KErrNone) { fi.setFile(qt_TDesC2QString(finder.File())); realname = fi.canonicalFilePath(); if (fi.isReadable() && fi.isFile()) break; } #endif realname = prefix + fname + (suffix.isNull() ? QString::fromLatin1(".qm") : suffix); fi.setFile(realname); if (fi.isReadable() && fi.isFile()) break; realname = prefix + fname; fi.setFile(realname); if (fi.isReadable() && fi.isFile()) break; int rightmost = 0; for (int i = 0; i < (int)delims.length(); i++) { int k = fname.lastIndexOf(delims[i]); if (k > rightmost) rightmost = k; } // no truncations? fail if (rightmost == 0) return false; fname.truncate(rightmost); } // realname is now the fully qualified name of a readable file. return d->do_load(realname); }