⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qsettings.cpp

📁 qt-x11-opensource-src-4.1.4.tar.gz源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    if (readOnly) {        QFileInfo fileInfo(confFile->name);        if (confFile->size == fileInfo.size() && confFile->timeStamp == fileInfo.lastModified())            return;    }    /*        Open the configuration file and try to use it using a named        semaphore on Windows and an advisory lock on Unix-based        systems. This protect us against other QSettings instances        trying to access the same file from other threads or        processes.        As it stands now, the locking mechanism doesn't work for        .plist files.    */    QFile file(confFile->name);    bool createFile = !file.exists();    if (!readOnly)        file.open(QFile::ReadWrite);    if (!file.isOpen())        file.open(QFile::ReadOnly);#ifdef Q_OS_WIN    HANDLE semaphore = 0;    static const int FileLockSemMax = 50;    int numLocks = readOnly ? 1 : FileLockSemMax;    if (file.isOpen()) {        QString semName = QLatin1String("QSettings semaphore ");        semName.append(file.fileName());        QT_WA( {            semaphore = CreateSemaphoreW(0, FileLockSemMax, FileLockSemMax, reinterpret_cast<const wchar_t *>(semName.utf16()));        } , {            semaphore = CreateSemaphoreA(0, FileLockSemMax, FileLockSemMax, semName.toLocal8Bit());        } );        if (semaphore) {            for (int i = 0; i < numLocks; ++i)                WaitForSingleObject(semaphore, INFINITE);        } else {            setStatus(QSettings::AccessError);            return;        }    }#else    if (file.isOpen())        unixLock(file.handle(), readOnly ? F_RDLCK : F_WRLCK);#endif    // If we have created the file, apply the file perms    if (file.isOpen()) {        if (createFile) {            QFile::Permissions perms = QFile::ReadOwner|QFile::WriteOwner;            if (!confFile->userPerms)                perms |= QFile::ReadGroup|QFile::ReadOther;            file.setPermissions(perms);        }    }    /*        We hold the lock. Let's reread the file if it has changed        since last time we read it.    */    QFileInfo fileInfo(confFile->name);    bool mustReadFile = true;    if (!readOnly) {        mustReadFile = (confFile->size != fileInfo.size()                        || (confFile->size != 0 && confFile->timeStamp != fileInfo.lastModified()));    }    if (mustReadFile) {        InternalSettingsMap newKeys;        /*            Files that we can't read (because of permissions or            because they don't exist) are treated as empty files.        */        if (file.isReadable() && fileInfo.size() != 0) {#ifdef Q_OS_MAC            if (format == QSettings::NativeFormat) {                ok = readPlistFile(confFile->name, &newKeys);            } else#endif            {                if (format <= QSettings::IniFormat) {                    ok = readIniFile(file, &newKeys);                } else {                    if (readFunc) {                        QSettings::SettingsMap tempNewKeys;                        ok = readFunc(file, tempNewKeys);                        if (ok) {                            QSettings::SettingsMap::const_iterator i = tempNewKeys.constBegin();                            while (i != tempNewKeys.constEnd()) {                                newKeys.insert(QSettingsKey(i.key(), caseSensitivity), i.value());                                ++i;                            }                        }                    } else {                        ok = false;                    }                }            }            if (!ok)                setStatus(QSettings::FormatError);        }        confFile->originalKeys = newKeys;        confFile->size = fileInfo.size();        confFile->timeStamp = fileInfo.lastModified();    }    /*        We also need to save the file. We still hold the file lock,        so everything is under control.    */    if (!readOnly) {        InternalSettingsMap mergedKeys = confFile->mergedKeyMap();        if (file.isWritable()) {#ifdef Q_OS_MAC            if (format == QSettings::NativeFormat) {                ok = writePlistFile(confFile->name, mergedKeys);            } else#endif            {                file.seek(0); // shouldn't be necessary                file.resize(0);                if (format <= QSettings::IniFormat) {                    ok = writeIniFile(file, mergedKeys);                } else {                    if (writeFunc) {                        QSettings::SettingsMap tempOriginalKeys;                        InternalSettingsMap::const_iterator i = mergedKeys.constBegin();                        while (i != mergedKeys.constEnd()) {                            tempOriginalKeys.insert(i.key(), i.value());                            ++i;                        }                        ok = writeFunc(file, tempOriginalKeys);                    } else {                        ok = false;                    }                }            }        } else {            ok = false;        }        if (ok) {            confFile->originalKeys = mergedKeys;            confFile->addedKeys.clear();            confFile->removedKeys.clear();            QFileInfo fileInfo(confFile->name);            confFile->size = fileInfo.size();            confFile->timeStamp = fileInfo.lastModified();        } else {            setStatus(QSettings::AccessError);        }    }    /*        Release the file lock.    */#ifdef Q_OS_WIN    if (semaphore != 0) {        ReleaseSemaphore(semaphore, numLocks, 0);        CloseHandle(semaphore);    }#endif}bool QConfFileSettingsPrivate::readIniLine(QIODevice &device, QByteArray &line, int &len,                                           int &equalsCharPos){#define MAYBE_GROW() \    if (pos + 4 > line.size()) { \        line.resize(pos << 1); \        data = line.data(); \    }    char *data = line.data();    char ch, ch2;    int pos = 0;    equalsCharPos = -1;    while (device.getChar(&ch)) {    process_ch:        MAYBE_GROW();        switch (ch) {        case '"':            data[pos++] = '"';            while (device.getChar(&ch) && ch != '"') {                MAYBE_GROW();                if (static_cast<signed char>(ch) == -1)                    goto end;                if (ch == '\\') {                    data[pos++] = '\\';                    if (!device.getChar(&ch))                        goto end;                }                data[pos++] = ch;            }            data[pos++] = '"';            break;        case ' ':        case '\t':            if (pos > 0)                data[pos++] = ch;            break;        case '\n':        case '\r':        process_newline:            /*                According to the specs, a line ends with CF, LF,                CR+LF, or LF+CR. In practice, this is irrelevant and                the ungetch() call is expensive, so let's not do it.            */#if 0            if (!device.getChar(&ch2))                goto end;            if ((ch2 != '\n' && ch2 != '\r') || ch == ch2)                device.ungetChar(ch2);#endif            if (pos > 0)                goto end;            break;        case '\\':            if (!device.getChar(&ch))                goto end;            if (ch == '\n' || ch == '\r') {                if (device.getChar(&ch2)) {                    if ((ch2 != '\n' && ch2 != '\r') || ch == ch2) {                        ch = ch2;                        goto process_ch;                    }                }            } else {                data[pos++] = '\\';                data[pos++] = ch;            }            break;        case ';':            while (device.getChar(&ch)) {                if (ch == '\n' || ch == '\r')                    goto process_newline;            }            break;        case '=':            if (equalsCharPos == -1) {                while (pos > 0 && (ch = data[pos - 1]) == ' ' || ch == '\t')                    --pos;                equalsCharPos = pos;            }            data[pos++] = '=';            break;        default:            data[pos++] = ch;        }    }end:    data[pos] = '\0';    len = pos;    return pos > 0;}/*    Returns false on parse error. However, as many keys are read as    possible, so if the user doesn't check the status he will get the    most out of the file anyway.*/bool QConfFileSettingsPrivate::readIniFile(QIODevice &device, InternalSettingsMap *map){    QString currentSection;    bool currentSectionIsLowercase = true;    QByteArray line;    line.resize(512);    int equalsCharPos;    int len;    bool ok = true;    while (readIniLine(device, line, len, equalsCharPos)) {        if (line.at(0) == '[') {            // this is a section            QByteArray iniSection;            int idx = line.indexOf(']');            if (idx == -1) {                ok = false;                iniSection = line.mid(1);            } else {                iniSection = line.mid(1, idx - 1);            }            iniSection = iniSection.trimmed();            if (qstricmp(iniSection, "general") == 0) {                currentSection.clear();            } else if (qstricmp(iniSection, "%general") == 0) {                currentSection = QLatin1String("general");                currentSection += QLatin1Char('/');            } else {                currentSection.clear();                currentSectionIsLowercase = iniUnescapedKey(iniSection, 0, iniSection.size(),                                                            currentSection);                currentSection += QLatin1Char('/');            }        } else {            if (equalsCharPos < 1) {                ok = false;                continue;            }            QString key = currentSection;            bool keyIsLowercase = (iniUnescapedKey(line, 0, equalsCharPos, key)                                   && currentSectionIsLowercase);            QString strValue;            strValue.reserve(len - equalsCharPos);            QStringList *strListValue = iniUnescapedStringList(line, equalsCharPos + 1, len,                                                               strValue);            QVariant variant;            if (strListValue) {                variant = stringListToVariantList(*strListValue);                delete strListValue;            } else {                variant = stringToVariant(strValue);            }            /*                We try to avoid the expensive toLower() call in                QSettingsKey by passing Qt::CaseSensitive when the                key is already in lowercase.            */            map->insert(QSettingsKey(key, keyIsLowercase ? Qt::CaseSensitive : Qt::CaseInsensitive),                        variant);        }    }    return ok;}bool QConfFileSettingsPrivate::writeIniFile(QIODevice &device, const InternalSettingsMap &map){    typedef QMap<QString, QVariantMap> IniMap;    IniMap iniMap;    IniMap::const_iterator i;#ifdef Q_OS_WIN    const char * const eol = "\r\n";#else    const char eol = '\n';#endif    for (InternalSettingsMap::const_iterator j = map.constBegin(); j != map.constEnd(); ++j) {        QString section;        QString key = j.key().realKey();        int slashPos;        if ((slashPos = key.indexOf(QLatin1Char('/'))) != -1) {            section = key.left(slashPos);            key.remove(0, slashPos + 1);        }        iniMap[section][key] = j.value();    }    bool writeError = false;    for (i = iniMap.constBegin(); !writeError && i != iniMap.constEnd(); ++i) {        QByteArray realSection;        iniEscapedKey(i.key(), realSection);        if (realSection.isEmpty()) {            realSection = "[General]";        } else if (qstricmp(realSection, "general") == 0) {            realSection = "[%General]";        } else {            realSection.prepend('[');            realSection.append(']');        }        if (i != iniMap.constBegin())            realSection.prepend(eol);        realSection += eol;        device.write(realSection);        const QVariantMap &ents = i.value();        for (QVariantMap::const_iterator j = ents.constBegin(); j != ents.constEnd(); ++j) {            QByteArray block;            iniEscapedKey(j.key(), block);            block += '=';            const QVariant &value = j.value();            /*                The size() != 1 trick is necessary because                QVariant(QString("foo")).toList() returns an empty                list, not a list containing "foo".            */            if (value.type() == QVariant::StringList                    || (value.type() == QVariant::List && value.toList().size() != 1)) {                iniEscapedStringList(variantListToStringList(value.toList()), block);            } else {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -