File indexing completed on 2024-04-28 12:37:49

0001 /* AUDEX CDDA EXTRACTOR
0002  * SPDX-FileCopyrightText: Copyright (C) 2007 Marco Nelles
0003  * <https://userbase.kde.org/Audex>
0004  *
0005  * SPDX-License-Identifier: GPL-3.0-or-later
0006  */
0007 
0008 #include "parameters.h"
0009 
0010 Parameters::Parameters()
0011 {
0012 }
0013 
0014 Parameters::Parameters(const Parameters &other)
0015 {
0016     p_parameters = other.p_parameters;
0017 }
0018 
0019 Parameters::Parameters(const QString &string, const QChar &sep)
0020 {
0021     fromString(string, sep);
0022 }
0023 
0024 Parameters &Parameters::operator=(const Parameters &other)
0025 {
0026     p_parameters = other.p_parameters;
0027     return *this;
0028 }
0029 
0030 Parameters::~Parameters()
0031 {
0032 }
0033 
0034 void Parameters::fromString(const QString &string, const QChar &sep)
0035 {
0036     p_error_string.clear();
0037 
0038     if (string.isEmpty())
0039         return;
0040 
0041     p_parameters.clear();
0042 
0043     QString key, value;
0044     bool value_is_quoted = false;
0045     bool is_in_key = false;
0046     bool is_in_value = false;
0047     bool is_in_value_quote = false;
0048     int i = 0;
0049     while (i < string.length()) {
0050 
0051         QChar c = string.at(i);
0052 
0053         if (is_in_key) {
0054 
0055             if (c.isLetterOrNumber() || c == QChar('_')) {
0056                 key.append(c);
0057             } else if (c == QChar('=')) {
0058                 is_in_key = false;
0059                 is_in_value = true;
0060             } else {
0061                 p_error_string = i18n("Illegal character found at index %1: '%2'").arg(i).arg(c);
0062                 return;
0063             }
0064 
0065         } else if (is_in_value) {
0066 
0067             if (is_in_value_quote) {
0068 
0069                 if (c == QChar('\'') || c == QChar('"')) {
0070                     is_in_value_quote = false;
0071                     is_in_value = false;
0072                 } else {
0073                     value.append(c);
0074                 }
0075 
0076             } else {
0077 
0078                 if (c == QChar('\'') || c == QChar('"')) {
0079                     if (value.isEmpty()) {
0080                         is_in_value_quote = true;
0081                         value_is_quoted = true;
0082                     } else {
0083                         p_error_string = i18n("Illegal character found at index %1: '%2'").arg(i).arg(c);
0084                         return;
0085                     }
0086                 } else if (c == sep) {
0087                     is_in_key = false;
0088                     is_in_value = false;
0089                     continue;
0090                 } else if (c.isSpace()) {
0091                     p_error_string = i18n("Illegal character found at index %1: '%2'").arg(i).arg(c);
0092                     return;
0093                 } else {
0094                     value.append(c);
0095                 }
0096 
0097             }
0098 
0099         } else {
0100 
0101             if (c == sep) {
0102                 p_insert_value(key, value, value_is_quoted);
0103                 key.clear();
0104                 value.clear();
0105                 value_is_quoted = false;
0106             } else if ((c.isLetterOrNumber() || c == QChar('_')) && value.isEmpty()) {
0107                 is_in_key = true;
0108                 key.append(c);
0109             } else {
0110                 p_error_string = i18n("Illegal character found at index %1: '%2'").arg(i).arg(c);
0111                 return;
0112             }
0113 
0114         }
0115 
0116         ++i;
0117 
0118     }
0119 
0120     if (is_in_value_quote) {
0121         p_error_string = i18n("Unclosed quote found");
0122         return;
0123     }
0124 
0125     p_insert_value(key, value, value_is_quoted);
0126 
0127 }
0128 
0129 const QString Parameters::toString(const QChar &sep)
0130 {
0131     QString string;
0132 
0133     for (auto i = p_parameters.cbegin(), end = p_parameters.cend(); i != end; ++i) {
0134         QVariant value = i.value();
0135         if (i != p_parameters.cbegin())
0136             string.append(sep);
0137         //qt6: if (value.metaType() == QMetaType::QString || value.metaType() == QMetaType::QDateTime || value.metaType() == QMetaType::QDate || value.metaType() == QMetaType::QTime)
0138         if (value.type() == QVariant::String || value.type() == QVariant::DateTime || value.type() == QVariant::Date || value.type() == QVariant::Time)
0139             string.append(i.key() + "='" + value.toString() + "'");
0140         else
0141             string.append(i.key() + "=" + value.toString());
0142     }
0143 
0144     return string;
0145 }
0146 
0147 void Parameters::fromBase64(const QByteArray &bytearray)
0148 {
0149     QByteArray ba = QByteArray::fromBase64(bytearray);
0150     fromString(QString::fromUtf8(ba.data()));
0151 }
0152 
0153 const QByteArray Parameters::toBase64()
0154 {
0155     QString s = toString();
0156     return s.toUtf8().toBase64();
0157 }
0158 
0159 bool Parameters::contains(const QString &key) const
0160 {
0161     return p_parameters.contains(key);
0162 }
0163 
0164 const KeyList Parameters::keys() const
0165 {
0166     return p_parameters.keys();
0167 }
0168 
0169 bool Parameters::isEmpty() const
0170 {
0171     return p_parameters.isEmpty();
0172 }
0173 
0174 void Parameters::p_insert_value(const QString& key, const QString& value, const bool is_quoted) {
0175 
0176     if (key.isEmpty())
0177         return;
0178 
0179     // an quoted value is expected to be alway a string
0180     if (is_quoted) {
0181 
0182         p_parameters.insert(key, QVariant(value));
0183 
0184     } else { // not quoted -> the case is more complicated
0185 
0186         bool ok;
0187         int number_int = value.toInt(&ok);
0188         if (ok) {
0189             p_parameters.insert(key, QVariant(number_int));
0190         } else {
0191             double number_double = value.toDouble(&ok);
0192             if (ok) {
0193                 p_parameters.insert(key, QVariant(number_double));
0194             } else {
0195 
0196                 if (value.toLower() == "false")
0197                     p_parameters.insert(key, QVariant(false));
0198                 else if (value.toLower() == "true")
0199                     p_parameters.insert(key, QVariant(true));
0200                 else
0201                     p_parameters.insert(key, QVariant(value));
0202 
0203             }
0204         }
0205 
0206     }
0207 
0208 }