Пример #1
0
//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;
}
Пример #6
0
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;
}
Пример #8
0
/*!
    \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;
}
Пример #10
0
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();
        }
    }
Пример #11
0
//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;
        }

    }
Пример #13
0
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;
}
Пример #14
0
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;
}
Пример #15
0
//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;
}
Пример #16
0
//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);
}
Пример #17
0
/*!
    \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;
}
Пример #19
0
/*!
    \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;
}
Пример #20
0
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
}
Пример #21
0
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);
}