return d->errorString();
}
-QVariant IniFile::getValue(QString const & paramName, QVariant const & defaultValue)
+QVariant IniFile::getValue(QByteArray const & paramName, QVariant const & defaultValue)
{
return d->getValue(paramName, defaultValue);
}
-bool IniFile::setValue(QString const & paramName, QVariant const & value)
+bool IniFile::setValue(QByteArray const & paramName, QVariant const & value)
{
return d->setValue(paramName, value);
}
void IniFileImpl::updateCache(quint64 pos, qint64 diff)
{
// Walk through all the sections in the cache
- QHash<QString, QExplicitlySharedDataPointer<IniFileSection> >::const_iterator it;
+ QHash<QByteArray, QExplicitlySharedDataPointer<IniFileSection> >::const_iterator it;
for (it = mCache.constBegin(); it != mCache.constEnd(); ++it) {
QExplicitlySharedDataPointer<IniFileSection> sectionObject = *it;
sectionObject->filePos += diff;
// Update individual values in the section that come after the current file offset
- QHash<QString, QExplicitlySharedDataPointer<IniFileValue> >::const_iterator it1;
+ QHash<QByteArray, QExplicitlySharedDataPointer<IniFileValue> >::const_iterator it1;
for (it1 = sectionObject->values.constBegin(); it1 != sectionObject->values.constEnd(); ++it1) {
QExplicitlySharedDataPointer<IniFileValue> valueObject = *it1;
if (valueObject->filePos > pos)
}
}
-QExplicitlySharedDataPointer<IniFileSection> IniFileImpl::getSection(QFile & file, QString const & sectionName)
+QExplicitlySharedDataPointer<IniFileSection> IniFileImpl::getSection(QFile & file, QByteArray const & sectionName)
{
// Check for external modifications
QFileInfo fi(file);
}
// Look for the section in the cache first
- QHash<QString, QExplicitlySharedDataPointer<IniFileSection> >::const_iterator it = mCache.constFind(sectionName.toLower());
+ QHash<QByteArray, QExplicitlySharedDataPointer<IniFileSection> >::const_iterator it = mCache.constFind(sectionName.toLower());
if (it != mCache.constEnd()) {
// Found in the cache
if (mValid)
// Read the INI file and look for the section
while (mValid && !file.atEnd()) {
- QString line = file.readLine().trimmed();
+ QByteArray line = file.readLine().trimmed();
// Ignore the line if it is empty, a comment or not a section name
if (line.isEmpty() || line.startsWith(';') || line.startsWith('#') || !line.startsWith('['))
continue;
// Is this the section that we are looking for?
- if (line.mid(1, idx - 1).compare(sectionName, Qt::CaseInsensitive) == 0) {
+ if (qstricmp(line.mid(1, idx - 1).constData(), sectionName.constData()) == 0) {
// Create the section object and add to the cache
QExplicitlySharedDataPointer<IniFileSection> sectionObject(new IniFileSection(file.pos()));
sectionObject->name = sectionName.toLower();
return QExplicitlySharedDataPointer<IniFileSection>();
}
-QExplicitlySharedDataPointer<IniFileValue> IniFileImpl::getParameter(QFile & file, IniFileSection & section, QString const & paramName)
+QExplicitlySharedDataPointer<IniFileValue> IniFileImpl::getParameter(QFile & file, IniFileSection & section, QByteArray const & paramName)
{
// Look for the parameter in the cache first
- QHash<QString, QExplicitlySharedDataPointer<IniFileValue> >::const_iterator it = section.values.constFind(paramName.toLower());
+ QHash<QByteArray, QExplicitlySharedDataPointer<IniFileValue> >::const_iterator it = section.values.constFind(paramName.toLower());
if (it != section.values.constEnd()) {
// Found it in the cache
if (mValid)
// Current file position
quint64 currentPos = file.pos();
- QString line = file.readLine().trimmed();
+ QByteArray line = file.readLine().trimmed();
// Ignore the line if it is empty or a comment
if (line.isEmpty() || line.startsWith(';') || line.startsWith('#'))
if (idx == -1)
continue;
- QString name = line.mid(0, idx).trimmed().toLower();
- QString value = line.mid(idx + 1).trimmed();
+ QByteArray name = line.mid(0, idx).trimmed().toLower();
+ QByteArray value = line.mid(idx + 1).trimmed();
// Check for the 'windows:' or 'linux:' prefix in the parameter name
bool thisOsOnly = false;
// If the parameter value is not in the cache, add it to the cache
QExplicitlySharedDataPointer<IniFileValue> valueObject;
- QHash<QString, QExplicitlySharedDataPointer<IniFileValue> >::const_iterator it = section.values.constFind(name);
+ QHash<QByteArray, QExplicitlySharedDataPointer<IniFileValue> >::const_iterator it = section.values.constFind(name);
if (it == section.values.constEnd()) {
valueObject = new IniFileValue(currentPos);
valueObject->name = name;
}
// Is this the parameter vwe are looking for?
- if (name.compare(paramName, Qt::CaseInsensitive) == 0) {
+ if (qstricmp(name.constData(), paramName.constData()) == 0) {
// Rewind to the beginning of the line
file.seek(currentPos);
return QExplicitlySharedDataPointer<IniFileValue>();
}
-QVariant IniFileImpl::getValue(QString const & paramName, QVariant const & defaultValue)
+QVariant IniFileImpl::getValue(QByteArray const & paramName, QVariant const & defaultValue)
{
// Locate the '/' character that separates section names from key names
int idx = paramName.lastIndexOf('/');
return defaultValue;
// Separate section and key names
- QString section = paramName.left(idx);
- QString key = paramName.mid(idx + 1);
+ QByteArray section = paramName.left(idx);
+ QByteArray key = paramName.mid(idx + 1);
// Open the file
QFile f(mFileName);
if (f.isOpen())
f.close();
- return toVariant(valueObject->paramValue, defaultValue);
+ // Return the cached value if it is already set and the type is the same than the default value type
+ if (valueObject->value.isValid() && (!defaultValue.isValid() || valueObject->value.type() == defaultValue.type()))
+ return valueObject->value;
+
+ // Convert to the proper type
+ if (defaultValue.type() == QVariant::ByteArray || defaultValue.type() == QVariant::String) {
+ // Remove single and double quotes
+ QByteArray v = valueObject->paramValue;
+ if (v.startsWith('\"')) {
+ v.remove(0, 1);
+ if (v.endsWith('\"'))
+ v.remove(v.size() - 1, 1);
+ }
+ else if (v.startsWith('\'')) {
+ v.remove(0, 1);
+ if (v.endsWith('\''))
+ v.remove(v.size() - 1, 1);
+ }
+
+ // Convert from the escaped character array
+ if (defaultValue.type() == QVariant::String)
+ valueObject->value = QVariant(strFromEscapedCharArray(v));
+ else
+ valueObject->value = QVariant(binFromEscapedCharArray(v));
+ }
+ else
+ valueObject->value = toVariant(valueObject->paramValue, defaultValue);
+
+ return valueObject->value;
}
-bool IniFileImpl::setValue(QString const & paramName, QVariant const & value)
+bool IniFileImpl::setValue(QByteArray const & paramName, QVariant const & value)
{
// Locate the '/' character that separates section names from key names
int idx = paramName.lastIndexOf('/', -1);
return false;
// Separate section and key names
- QString section = paramName.left(idx).toLower();
- QString key = paramName.mid(idx + 1).toLower();
+ QByteArray section = paramName.left(idx).toLower();
+ QByteArray key = paramName.mid(idx + 1).toLower();
// Format the value depending on the type
- QString valueString;
+ QByteArray valueString;
switch (value.type()) {
case QVariant::UInt:
- valueString = "0x" + QString::number(value.toUInt(), 16);
+ valueString = QByteArray("0x").append(QByteArray::number(value.toUInt(), 16));
break;
case QVariant::Int:
- valueString = QString::number(value.toInt());
+ valueString = QByteArray::number(value.toInt());
break;
case QVariant::Double:
- valueString = QString::number(value.toDouble(), 'f');
+ valueString = QByteArray::number(value.toDouble(), 'f');
break;
case QVariant::Bool:
valueString = value.toBool() ? "true" : "false";
break;
- case QVariant::Char:
- valueString = value.toChar();
+ case QVariant::Char: {
+ QChar c = value.toChar();
+ printf("c.unicode() = %u\n", c.unicode());
+ if (c.unicode() < 32 || c.unicode() >= 127)
+ valueString = QByteArray("\\0x").append(QByteArray::number(c.unicode(), 16));
+ else
+ valueString = QByteArray(1, (char const)c.unicode());
+ break;
+ }
+ case QVariant::ByteArray:
+ valueString = binToEscapedCharArray(value.toByteArray());
+ if (valueString.startsWith(' ') || valueString.endsWith(' ')) {
+ valueString.insert(0, '\"');
+ valueString.append('\"');
+ }
+ break;
+ case QVariant::String:
+ valueString = strToEscapedCharArray(value.toString());
+ if (valueString.startsWith(' ') || valueString.endsWith(' ')) {
+ valueString.insert(0, '\"');
+ valueString.append('\"');
+ }
break;
default:
- valueString = value.toString();
+ valueString = value.toString().toLatin1();
}
// Open the file
if (!sectionObject) {
// Write the new section to the INI file (the file is already positioned at the end)
- if (f.write(QString("[%1]" EOL).arg(section).toLocal8Bit()) == -1) {
+ if (f.write(QString("[%1]" EOL).arg(section.constData()).toLatin1()) == -1) {
mErrorString = f.errorString();
mValid = false;
EVAF_ERROR("Failed to write to the INI file %s : %s", qPrintable(mFileName), qPrintable(mErrorString));
mCache.insert(section.toLower(), sectionObject);
// Write the parameter value to the INI file
- if (f.write(QString("%1 = %2" EOL).arg(key).arg(valueString).toLocal8Bit()) == -1) {
+ if (f.write(QString("%1 = %2" EOL).arg(key.constData()).arg(valueString.constData()).toLatin1()) == -1) {
mErrorString = f.errorString();
mValid = false;
EVAF_ERROR("Failed to write to the INI file %s : %s", qPrintable(mFileName), qPrintable(mErrorString));
QExplicitlySharedDataPointer<IniFileValue> valueObject(new IniFileValue(currentPos));
valueObject->name = key;
valueObject->paramValue = valueString;
+ valueObject->value = value;
sectionObject->values.insert(key, valueObject);
}
// Rewind to the original position and write the new parameter value
f.seek(currentPos);
- if (f.write(QString("%1%2 = %3" EOL).arg(prefix).arg(key).arg(valueString).toLocal8Bit()) == -1) {
+ if (f.write(QString("%1%2 = %3" EOL).arg(prefix).arg(key.constData()).arg(valueString.constData()).toLatin1()) == -1) {
mErrorString = f.errorString();
mValid = false;
EVAF_ERROR("Failed to write to the INI file %s : %s", qPrintable(mFileName), qPrintable(mErrorString));
// Update the parameter value in the internal cache
valueObject->paramValue = valueString;
+ valueObject->value = value;
}