1 // Copyright (C) 2012-2019 The VPaint Developers. 2 // See the COPYRIGHT file at the top-level directory of this distribution 3 // and at https://github.com/dalboris/vpaint/blob/master/COPYRIGHT 4 // 5 // Licensed under the Apache License, Version 2.0 (the "License"); 6 // you may not use this file except in compliance with the License. 7 // You may obtain a copy of the License at 8 // 9 // http://www.apache.org/licenses/LICENSE-2.0 10 // 11 // Unless required by applicable law or agreed to in writing, software 12 // distributed under the License is distributed on an "AS IS" BASIS, 13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 // See the License for the specific language governing permissions and 15 // limitations under the License. 16 17 #ifndef XMLSTREAMWRITER_H 18 #define XMLSTREAMWRITER_H 19 20 #include <QXmlStreamWriter> 21 22 /// \class XmlStreamWriter 23 /// Writes an XML document to a file. 24 /// 25 /// This class overrides Qt default behaviour to achieve desired indenting style, 26 /// for better human-readability in our use-case. 27 /// 28 /// For instance, instead of: 29 /// 30 /// <tag attr1="value1" attr2="value2"/> 31 /// 32 /// We want: 33 /// 34 /// <tag 35 /// attr1="value1" 36 /// attr2="value2"/> 37 /// 38 /// Also, we want to allow writing multiline attribute values without escaping '\n', 39 /// such that instead of: 40 /// 41 /// <tag 42 /// attr="a long attribute spanning three different lines"/> 43 /// 44 /// We get: 45 /// 46 /// <tag 47 /// attr="a long attribute 48 /// spanning three 49 /// different lines"/> 50 /// 51 /// This is XML compliant but one should be aware that newlines characters will be 52 /// replaced by whitespaces by any compliant XML parser, i.e. it will be interpreted as: 53 /// 54 /// "a long attribute spanning three different lines" 55 /// 56 /// This is OK because in the specification of the VEC file formats, newlines in attributes 57 /// are never significant, and consecutive whitespaces are equivalent to single whitespaces. 58 59 class XmlStreamWriter : public QXmlStreamWriter 60 { 61 public: 62 XmlStreamWriter(QIODevice * device); 63 ~XmlStreamWriter(); 64 65 // Writes a start element 66 void writeStartElement(const QString & qualifiedName); 67 void writeEndElement(); 68 69 // Writes an element attributes 70 void writeAttribute(const QString & qualifiedName, const QString & value); 71 void writeAttribute(const QXmlStreamAttribute & attribute); 72 void writeAttributes(const QXmlStreamAttributes & attributes); 73 74 private: 75 int indentLevel_; 76 77 // Raw-write to device, without escaping XML characters 78 void write(const QString & string) const; 79 80 // Escape special characters 81 static QString escaped(const QString & s); 82 83 // Escape special characters except newlines 84 static QString escapedExceptNewlines(const QString & s); 85 86 }; 87 88 89 #endif // XMLSTREAMWRITER_H 90