/** * @file Common/util.cpp * @brief Global utility functions for eVaf * @author Enar Vaikene * * Copyright (c) 2011-2019 Enar Vaikene * * This file is part of the eVaf C++ cross-platform application development framework. * * This file can be used under the terms of the GNU General Public License * version 3.0 as published by the Free Software Foundation and appearing in * the file LICENSE included in the packaging of this file. Please review the * the following information to ensure the GNU General Public License version * 3.0 requirements will be met: http://www.gnu.org/copyleft/gpl.html. * * Alternatively, this file may be used in accordance with the Commercial License * Agreement provided with the Software. */ #include "util.h" #include //------------------------------------------------------------------- QVariant eVaf::Common::toVariant(QString const & value, QVariant const & defaultValue) { // If the default value is not valid, return the string value without conversions if (!defaultValue.isValid()) return QVariant(value); // Convert to the expected type switch (defaultValue.type()) { case QVariant::UInt: { bool ok; uint const v = value.toUInt(&ok, 0); if (ok) return QVariant(v); else return defaultValue; } case QVariant::Int: { bool ok; int const v = value.toInt(&ok, 0); if (ok) return QVariant(v); else return defaultValue; } case QVariant::Double: { bool ok; double const v = value.toDouble(&ok); if (ok) return QVariant(v); else return defaultValue; } case QVariant::Bool: { if (eVaf::Common::isTrue(value)) return QVariant(true); else if (eVaf::Common::isFalse(value)) return QVariant(false); else { bool ok; uint const v = value.toUInt(&ok, 0); if (ok) return QVariant(v); else return defaultValue; } } case QVariant::Char: { if (value.size() > 0) { if (value.startsWith("\\0x")) { bool ok; char const c = static_cast(value.mid(1).toUInt(&ok, 16)); if (ok) return QVariant(c); } else if (value.startsWith("\\0")) { bool ok; char const c = static_cast(value.mid(1).toUInt(&ok, 8)); if (ok) return QVariant(c); } else if (value.startsWith('&')) { QString const c = strFromEscapedCharArray(value.toLatin1()); if (c.size() > 0) return QVariant(c.at(0)); } else return QVariant(value.at(0)); } return defaultValue; } default: return QVariant(value); } } QByteArray eVaf::Common::strToEscapedCharArray(QString const & str) { QByteArray rval; foreach (QChar c, str) { if (c.unicode() < 32 || c.unicode() >= 127) rval.append("&#x" + QByteArray::number(c.unicode(), 16) + ";"); else if (c == '\"') rval.append("""); else if (c == '&') rval.append("&"); else if (c == '\'') rval.append("'"); else if (c == '<') rval.append("<"); else if (c == '>') rval.append(">"); else rval.append(static_cast(c.unicode())); } return rval; } QString eVaf::Common::strFromEscapedCharArray(QByteArray const & str) { QString rval; bool e = false; QByteArray ref; foreach (char c, str) { if (!e) { if (c == '&') { e = true; ref = "&"; } else rval.append(QChar(static_cast(c))); } else { ref.append(c); if (c == ';') { e = false; ref = ref.toLower(); if (ref.startsWith("&#x")) { // Numeric character reference in the HEX format bool ok; ushort const ucode = static_cast(ref.mid(3, ref.size() - 4).toUInt(&ok, 16)); if (ok) rval.append(QChar(ucode)); else // Invalid numeric character reference; output as is rval.append(ref); } else if (ref.startsWith("&#")) { // Numeric character reference in the DEC format bool ok; ushort const ucode = static_cast(ref.mid(2, ref.size() - 3).toUInt(&ok, 10)); if (ok) rval.append(QChar(ucode)); else // Invalid numeric character reference; output as is rval.append(ref); } else if (ref == """) rval.append('\"'); else if (ref == "&") rval.append('&'); else if (ref == "'") rval.append('\''); else if (ref == "<") rval.append('<'); else if (ref == ">") rval.append('>'); else // Unknown reference, output as is rval.append(ref); } } } return rval; } QByteArray eVaf::Common::binToEscapedCharArray(QByteArray const & src) { QByteArray rval; foreach (char const c, src) { if (c < 32 || c >= 127) rval.append("&#x" + QByteArray::number(c, 16) + ";"); else if (c == '\"') rval.append("""); else if (c == '&') rval.append("&"); else if (c == '\'') rval.append("'"); else if (c == '<') rval.append("<"); else if (c == '>') rval.append(">"); else rval.append(c); } return rval; } QByteArray eVaf::Common::binFromEscapedCharArray(QByteArray const & str) { QByteArray rval; bool e = false; QByteArray ref; foreach (char c, str) { if (!e) { if (c == '&') { e = true; ref = "&"; } else rval.append(c); } else { ref.append(c); if (c == ';') { e = false; ref = ref.toLower(); if (ref.startsWith("&#x")) { // Numeric character reference in the HEX format bool ok; char const ucode = static_cast(ref.mid(3, ref.size() - 4).toUInt(&ok, 16)); if (ok) rval.append(ucode); else // Invalid numeric character reference; output as is rval.append(ref); } else if (ref.startsWith("&#")) { // Numeric character reference in the DEC format bool ok; char const ucode = static_cast(ref.mid(2, ref.size() - 3).toUInt(&ok, 10)); if (ok) rval.append(ucode); else // Invalid numeric character reference; output as is rval.append(ref); } else if (ref == """) rval.append('\"'); else if (ref == "&") rval.append('&'); else if (ref == "'") rval.append('\''); else if (ref == "<") rval.append('<'); else if (ref == ">") rval.append('>'); else // Unknown reference, output as is rval.append(ref); } } } return rval; }