File indexing completed on 2024-12-08 12:56:12
0001 /* This file is part of the KDE project 0002 0003 Copyright (C) 2013 Inge Wallin <inge@lysator.liu.se> 0004 0005 This library is free software; you can redistribute it and/or 0006 modify it under the terms of the GNU Library General Public 0007 License as published by the Free Software Foundation; either 0008 version 2 of the License, or (at your option) any later version. 0009 0010 This library is distributed in the hope that it will be useful, 0011 but WITHOUT ANY WARRANTY; without even the implied warranty of 0012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0013 Library General Public License for more details. 0014 0015 You should have received a copy of the GNU Library General Public License 0016 along with this library; see the file COPYING.LIB. If not, write to 0017 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0018 * Boston, MA 02110-1301, USA. 0019 */ 0020 0021 #ifndef KOXMLSTREAMREADER_H 0022 #define KOXMLSTREAMREADER_H 0023 0024 0025 #include "KoXmlStreamReader.h" 0026 0027 #include <QXmlStreamReader> 0028 #include <QStringRef> 0029 #include <QVector> 0030 #include <QSharedData> 0031 0032 #include "koodf2_export.h" 0033 0034 0035 class QByteArray; 0036 class QString; 0037 class QIODevice; 0038 0039 class KoXmlStreamAttributes; 0040 0041 0042 /** 0043 * @brief An XML stream reader based on QXmlStreamReader and with namespace handling better suited to use for ODF in Calligra. 0044 * 0045 * Opendocument uses an XML encoding which makes heavy use of 0046 * namespaces. So normally you would want to compare the qualified 0047 * name when accessing tagnames and attributes. 0048 * 0049 * However, in QXmlStreamReader you have to either make an explicit 0050 * comparison with the namespace URI for every element and attribute 0051 * or risk that documents that use the correct namespaces but not the 0052 * normal namespace prefixes are wrongly interpreted. This is because 0053 * the prefix (e.g. "fo" in "fo:border-width") is declared at the 0054 * beginning of the document using a namespace declaration attribute 0055 * such as: xmlns:fo="http://www.w3.org/1999/XSL/Format". In this case 0056 * xmlns:fo could just as well be xmlns:xxx which makes the expected 0057 * fo:border-width become xxx:border-width in the rest of this 0058 * document. 0059 * 0060 * However, it is extremely rare to find document that uses such 0061 * non-standard namespace prefixes. This gives us the opportunity to 0062 * optimize for the common case, which is exactly what 0063 * KoXmlStreamReader does. 0064 * 0065 * The way to use this class is to tell it which namespaces and 0066 * prefixes that you expect before you open the XML stream. Then it 0067 * checks if the namespaces and prefixes in the document are the same 0068 * as the expected ones. If they are in fact the same, the document 0069 * is pronounced "sound", and for the rest of the processing you can 0070 * use the qualified name with the expected prefix ("fo:border-width") 0071 * with the maximum performance. 0072 * 0073 * If the namespace(s) in the document are the expected ones but the 0074 * prefix(es) are not, you can still compare the qualified name to 0075 * your expected ones. But in this case the document is deemed 0076 * "unsound" and for every access to attributes or calls to 0077 * qualifiedName(), KoXmlStreamReader will rewrite the actual name in 0078 * the document to become what you expect. The functions 0079 * namespaceUri() and name() are not affected, only the prefixes. 0080 */ 0081 class KOODF2_EXPORT KoXmlStreamReader : public QXmlStreamReader 0082 { 0083 friend class KoXmlStreamAttribute; 0084 friend class KoXmlStreamAttributes; 0085 0086 public: 0087 KoXmlStreamReader(); 0088 explicit KoXmlStreamReader(QIODevice *device); 0089 explicit KoXmlStreamReader(const QByteArray &data); 0090 explicit KoXmlStreamReader(const QString &data); 0091 explicit KoXmlStreamReader(const char *data); 0092 0093 ~KoXmlStreamReader(); 0094 0095 void clear(); 0096 0097 void addExpectedNamespace(const QString &prefix, const QString &namespaceUri); 0098 void addExtraNamespace(const QString &prefix, const QString &namespaceUri); 0099 0100 // -------------------------------- 0101 // Reimplemented from QXmlStreamReader 0102 0103 QStringRef prefix() const; 0104 QStringRef qualifiedName() const; 0105 void setDevice(QIODevice *device); 0106 KoXmlStreamAttributes attributes() const; 0107 0108 private: 0109 // No copying 0110 KoXmlStreamReader(const KoXmlStreamReader &other); 0111 KoXmlStreamReader &operator=(const KoXmlStreamReader &other); 0112 0113 // Only for friend classes KoXmlStreamAttributes and KoXmlStreamAttribute. 0114 bool isSound() const; 0115 0116 class Private; 0117 Private * const d; 0118 }; 0119 0120 0121 /** 0122 * @brief KoXmlStreamAttribute is a source-compatible replacement for QXmlStreamAttribute. 0123 * 0124 * In addition to the API from QXmlStreamAttribute, it offers the same 0125 * advantages that KoXmlStreamReader does over QXmlStreamReader: when 0126 * asked for the qualified name of an attribute it will return the 0127 * expected one even if the prefix declared in the namespace 0128 * declaration of the document is different. 0129 * 0130 * @see KoXmlStreamReader 0131 */ 0132 class KOODF2_EXPORT KoXmlStreamAttribute 0133 { 0134 friend class QVector<KoXmlStreamAttribute>; // For the default constructor 0135 friend class KoXmlStreamAttributes; // For the normal constructor 0136 friend class KoXmlStreamReader; 0137 public: 0138 ~KoXmlStreamAttribute(); 0139 0140 // API taken from QXmlStreamAttribute 0141 bool isDefault() const; 0142 QStringRef name() const; 0143 QStringRef namespaceUri() const; 0144 QStringRef prefix() const; 0145 QStringRef qualifiedName() const; 0146 QStringRef value() const; 0147 0148 bool operator==(const KoXmlStreamAttribute &other) const; 0149 bool operator!=(const KoXmlStreamAttribute &other) const; 0150 KoXmlStreamAttribute &operator=(const KoXmlStreamAttribute &other); 0151 0152 private: 0153 // Only for friend classes. 0154 KoXmlStreamAttribute(); 0155 KoXmlStreamAttribute(const KoXmlStreamAttribute &other); 0156 KoXmlStreamAttribute(const QXmlStreamAttribute *attr, const KoXmlStreamReader *reader); 0157 0158 class Private; 0159 Private * const d; 0160 }; 0161 0162 0163 /** 0164 * @brief KoXmlStreamAttributes is a mostly source-compatible replacement for QXmlStreamAttributes. 0165 * 0166 * All the convenience functions of KoXmlStreamAttributes work exactly 0167 * like the counterparts of QXmlStreamAttributes but they give the 0168 * expected prefix for the registered expected namespaces. 0169 * 0170 * Not all functions from QVector are implemented but the ones that 0171 * make sense for this read-only class are. This class can only be 0172 * used in connection with KoXmlStreamReader. 0173 * 0174 * @see KoXmlStreamReader 0175 */ 0176 class KOODF2_EXPORT KoXmlStreamAttributes 0177 { 0178 friend class KoXmlStreamReader; 0179 0180 public: 0181 typedef const KoXmlStreamAttribute *const_iterator; 0182 0183 KoXmlStreamAttributes(const KoXmlStreamAttributes &other); 0184 ~KoXmlStreamAttributes(); 0185 0186 KoXmlStreamAttributes &operator=(const KoXmlStreamAttributes &other); 0187 0188 // Relevant parts of the QVector API 0189 const KoXmlStreamAttribute &at(int i) const; 0190 int size() const; 0191 KoXmlStreamAttribute value(int i) const; 0192 const KoXmlStreamAttribute &operator[](int i) const; 0193 const_iterator begin() const; 0194 const_iterator end() const; 0195 0196 // Convenience functions taken from QXmlStreamAttributes API 0197 void append(const QString &namespaceUri, const QString &name, const QString &value); 0198 void append(const QXmlStreamAttribute &attribute); 0199 void append(const QString &qualifiedName, const QString &value); 0200 bool hasAttribute(const QString &qualifiedName) const; 0201 bool hasAttribute(const QLatin1String &qualifiedName) const; 0202 bool hasAttribute ( const QString & namespaceUri, const QString & name ) const; 0203 QStringRef value ( const QString & namespaceUri, const QString & name ) const; 0204 QStringRef value ( const QString & namespaceUri, const QLatin1String & name ) const; 0205 QStringRef value ( const QLatin1String & namespaceUri, const QLatin1String & name ) const; 0206 QStringRef value(const QString &qualifiedName) const; 0207 QStringRef value(const QLatin1String &qualifiedName) const; 0208 0209 private: 0210 // Only available from friend class KoXmlStreamReader. 0211 KoXmlStreamAttributes(const KoXmlStreamReader *r, const QXmlStreamAttributes &qAttrs); 0212 0213 // This class is implicitly shared. 0214 class Private; 0215 QSharedDataPointer<Private> d; 0216 }; 0217 0218 0219 void KOODF2_EXPORT prepareForOdf(KoXmlStreamReader &reader); 0220 0221 0222 #endif /* KOXMLSTREAMREADER_H */