File indexing completed on 2024-05-12 15:27:01
0001 /*************************************************************************** 0002 File : XmlStreamReader.cpp 0003 Project : LabPlot 0004 Description : XML stream parser that supports errors and warnings 0005 -------------------------------------------------------------------- 0006 Copyright : (C) 2009 Tilman Benkert (thzs@gmx.net) 0007 Copyright : (C) 2015-2016 Alexander Semke (alexander.semke@web.de) 0008 ***************************************************************************/ 0009 0010 /*************************************************************************** 0011 * * 0012 * This program is free software; you can redistribute it and/or modify * 0013 * it under the terms of the GNU General Public License as published by * 0014 * the Free Software Foundation; either version 2 of the License, or * 0015 * (at your option) any later version. * 0016 * * 0017 * This program is distributed in the hope that it will be useful, * 0018 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 0019 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 0020 * GNU General Public License for more details. * 0021 * * 0022 * You should have received a copy of the GNU General Public License * 0023 * along with this program; if not, write to the Free Software * 0024 * Foundation, Inc., 51 Franklin Street, Fifth Floor, * 0025 * Boston, MA 02110-1301 USA * 0026 * * 0027 ***************************************************************************/ 0028 0029 #include "backend/lib/XmlStreamReader.h" 0030 #include <KLocalizedString> 0031 0032 /** 0033 * \class XmlStreamReader 0034 * \brief XML stream parser that supports errors as well as warnings. 0035 * This class also adds line and column numbers to the error message. 0036 */ 0037 XmlStreamReader::XmlStreamReader() = default; 0038 0039 XmlStreamReader::XmlStreamReader(QIODevice* device) : QXmlStreamReader(device) { 0040 } 0041 0042 XmlStreamReader::XmlStreamReader(const QByteArray& data) : QXmlStreamReader(data) { 0043 } 0044 0045 XmlStreamReader::XmlStreamReader(const QString& data) : QXmlStreamReader(data) { 0046 } 0047 0048 XmlStreamReader::XmlStreamReader(const char* data) : QXmlStreamReader(data) { 0049 } 0050 0051 const QStringList& XmlStreamReader::warningStrings() const { 0052 return m_warnings; 0053 } 0054 0055 /* 0056 * returns the human readable string for the missing CAS plugins in case 0057 * the project has some CAS content but the application was either not compiled with 0058 * CAS/Cantor support or the correspongind plugins for the required backends are missing. 0059 * 0060 * The returned text is in the form "Octave" or "Octave and Maxima" or "Octave, Maxima and Python", etc. 0061 */ 0062 QString XmlStreamReader::missingCASWarning() const { 0063 const int count = m_missingCASPlugins.count(); 0064 if (count == 1) 0065 return m_missingCASPlugins.constFirst(); 0066 else { 0067 QString msg; 0068 for (int i = 0; i < count; ++ i) { 0069 if (!msg.isEmpty()) { 0070 if (i == count - 1) 0071 msg += QLatin1Char(' ') + i18n("and") + QLatin1Char(' '); 0072 else 0073 msg += QLatin1String(", "); 0074 } 0075 msg += m_missingCASPlugins.at(i); 0076 } 0077 return msg; 0078 } 0079 } 0080 0081 bool XmlStreamReader::hasWarnings() const { 0082 return !m_warnings.isEmpty(); 0083 } 0084 0085 bool XmlStreamReader::hasMissingCASWarnings() const { 0086 return !m_missingCASPlugins.isEmpty(); 0087 } 0088 0089 void XmlStreamReader::setFailedCASMissing(bool value) { 0090 m_failedCASMissing = value; 0091 } 0092 0093 /*! 0094 * returns \c true if the loading of an project object failed because 0095 * of the missing CAS functionality (no CAS support or missing CAS plugin). 0096 * returns \c false if the loadign failed because of other reasons 0097 * like broken XML or missing important and required attributes. 0098 */ 0099 bool XmlStreamReader::failedCASMissing() const { 0100 return m_failedCASMissing; 0101 } 0102 0103 void XmlStreamReader::raiseError(const QString & message) { 0104 QXmlStreamReader::raiseError(i18n("line %1, column %2: %3", lineNumber(), columnNumber(), message)); 0105 } 0106 0107 void XmlStreamReader::raiseWarning(const QString & message) { 0108 m_warnings.append(i18n("line %1, column %2: %3", lineNumber(), columnNumber(), message)); 0109 } 0110 0111 void XmlStreamReader::raiseMissingCASWarning(const QString& name) { 0112 m_missingCASPlugins.append(name); 0113 } 0114 0115 /*! 0116 * Go to the next start or end element tag 0117 * If the end of the document is reached, an error is raised. 0118 * \return false if end of document reached, otherwise true 0119 */ 0120 bool XmlStreamReader::skipToNextTag() { 0121 if (atEnd()) { 0122 raiseError(i18n("unexpected end of document")); 0123 return false; 0124 } 0125 0126 do { 0127 readNext(); 0128 } while (!(isStartElement() || isEndElement() || atEnd())); 0129 0130 if (atEnd()) { 0131 raiseError(i18n("unexpected end of document")); 0132 return false; 0133 } 0134 0135 return true; 0136 } 0137 0138 /*! 0139 * Go to the end element tag of the current element 0140 * If the end of the document is reached, an error is raised. 0141 * \return false if end of document reached, otherwise true 0142 */ 0143 bool XmlStreamReader::skipToEndElement() { 0144 int depth = 1; 0145 if (atEnd()) { 0146 raiseError(i18n("unexpected end of document")); 0147 return false; 0148 } 0149 0150 do { 0151 readNext(); 0152 if (isEndElement()) depth--; 0153 if (isStartElement()) depth++; 0154 } while (!((isEndElement() && depth == 0) || atEnd())); 0155 0156 if (atEnd()) { 0157 raiseError(i18n("unexpected end of document")); 0158 return false; 0159 } 0160 0161 return true; 0162 } 0163 0164 /*! 0165 * Read an XML attribute and convert it to int 0166 * \param name attribute name 0167 * \param ok pointer to report back whether the attribute value could be determined (may be NULL) 0168 * \return the attribute value if found and converted, otherwise zero (in this case *ok is false) 0169 */ 0170 int XmlStreamReader::readAttributeInt(const QString& name, bool* ok) { 0171 QString str = attributes().value(namespaceUri().toString(), name).toString(); 0172 if (str.isEmpty()) { 0173 if (ok) *ok = false; 0174 return 0; 0175 } 0176 0177 return str.toInt(ok); 0178 }