LCOV - code coverage report
Current view: top level - src/engraving/rw - xmlreader.cpp Coverage Total Hit
Test: filtered_coverage.info Lines: 70.4 % 125 88
Test Date: 2026-11-05 04:07:02

            Line data    Source code
       1              : /*
       2              :  * SPDX-License-Identifier: GPL-3.0-only
       3              :  * MuseScore-Studio-CLA-applies
       4              :  *
       5              :  * MuseScore Studio
       6              :  * Music Composition & Notation
       7              :  *
       8              :  * Copyright (C) 2021 MuseScore Limited and others
       9              :  *
      10              :  * This program is free software: you can redistribute it and/or modify
      11              :  * it under the terms of the GNU General Public License version 3 as
      12              :  * published by the Free Software Foundation.
      13              :  *
      14              :  * This program is distributed in the hope that it will be useful,
      15              :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      16              :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      17              :  * GNU General Public License for more details.
      18              :  *
      19              :  * You should have received a copy of the GNU General Public License
      20              :  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
      21              :  */
      22              : 
      23              : #include "xmlreader.h"
      24              : 
      25              : #include "log.h"
      26              : 
      27              : using namespace mu;
      28              : using namespace muse::draw;
      29              : 
      30              : namespace mu::engraving {
      31         3968 : XmlReader::~XmlReader()
      32              : {
      33         3968 : }
      34              : 
      35          999 : PointF XmlReader::readPoint()
      36              : {
      37          999 :     assert(tokenType() == XmlStreamReader::StartElement);
      38              : #ifndef NDEBUG
      39          999 :     if (!hasAttribute("x")) {
      40            0 :         LOGD("XmlReader::readPoint: x attribute missing: %s", name().ascii());
      41            0 :         unknown();
      42              :     }
      43          999 :     if (!hasAttribute("y")) {
      44            0 :         LOGD("XmlReader::readPoint: y attribute missing: %s", name().ascii());
      45            0 :         unknown();
      46              :     }
      47              : #endif
      48          999 :     double x = doubleAttribute("x", 0.0);
      49          999 :     double y = doubleAttribute("y", 0.0);
      50          999 :     readNext();
      51          999 :     return PointF(x, y);
      52              : }
      53              : 
      54              : //---------------------------------------------------------
      55              : //   readColor
      56              : //---------------------------------------------------------
      57              : 
      58          306 : Color XmlReader::readColor()
      59              : {
      60          306 :     assert(tokenType() == XmlStreamReader::StartElement);
      61          306 :     Color c;
      62          306 :     c.setRed(intAttribute("r"));
      63          306 :     c.setGreen(intAttribute("g"));
      64          306 :     c.setBlue(intAttribute("b"));
      65          306 :     c.setAlpha(intAttribute("a", 255));
      66          306 :     skipCurrentElement();
      67          306 :     return c;
      68              : }
      69              : 
      70              : //---------------------------------------------------------
      71              : //   readSize
      72              : //---------------------------------------------------------
      73              : 
      74           14 : SizeF XmlReader::readSize()
      75              : {
      76           14 :     assert(tokenType() == XmlStreamReader::StartElement);
      77           14 :     SizeF p;
      78           14 :     p.setWidth(doubleAttribute("w", 0.0));
      79           14 :     p.setHeight(doubleAttribute("h", 0.0));
      80           14 :     skipCurrentElement();
      81           14 :     return p;
      82              : }
      83              : 
      84            0 : ScaleF XmlReader::readScale()
      85              : {
      86            0 :     assert(tokenType() == XmlStreamReader::StartElement);
      87            0 :     ScaleF p;
      88            0 :     p.setWidth(doubleAttribute("w", 0.0));
      89            0 :     p.setHeight(doubleAttribute("h", 0.0));
      90            0 :     skipCurrentElement();
      91            0 :     return p;
      92              : }
      93              : 
      94              : //---------------------------------------------------------
      95              : //   readRect
      96              : //---------------------------------------------------------
      97              : 
      98            0 : RectF XmlReader::readRect()
      99              : {
     100            0 :     assert(tokenType() == XmlStreamReader::StartElement);
     101            0 :     RectF p;
     102            0 :     p.setLeft(doubleAttribute("x", 0.0));
     103            0 :     p.setTop(doubleAttribute("y", 0.0));
     104            0 :     p.setWidth(doubleAttribute("w", 0.0));
     105            0 :     p.setHeight(doubleAttribute("h", 0.0));
     106            0 :     skipCurrentElement();
     107            0 :     return p;
     108              : }
     109              : 
     110              : //---------------------------------------------------------
     111              : //   readFraction
     112              : //    recognizes this two styles:
     113              : //    <move z="2" n="4"/>     (old style)
     114              : //    <move>2/4</move>        (new style)
     115              : //---------------------------------------------------------
     116              : 
     117        14368 : Fraction XmlReader::readFraction()
     118              : {
     119        14368 :     assert(tokenType() == XmlStreamReader::StartElement);
     120        14368 :     int z = intAttribute("z", 0);
     121        14368 :     int n = intAttribute("n", 1);
     122        14368 :     AsciiStringView s = readAsciiText();
     123        14368 :     if (!s.empty()) {
     124        14181 :         size_t i = s.indexOf('/');
     125        14181 :         if (i == muse::nidx) {
     126           62 :             return Fraction::fromTicks(s.toInt());
     127              :         } else {
     128        14119 :             String str = String::fromAscii(s.ascii());
     129        14119 :             z = str.left(i).toInt();
     130        14119 :             n = str.mid(i + 1).toInt();
     131        14119 :         }
     132              :     }
     133        14306 :     return Fraction(z, n);
     134              : }
     135              : 
     136              : //---------------------------------------------------------
     137              : //   unknown
     138              : //    unknown tag read
     139              : //---------------------------------------------------------
     140              : 
     141         2722 : void XmlReader::unknown()
     142              : {
     143         2722 :     if (XmlStreamReader::error()) {
     144            0 :         LOGD("%s ", muPrintable(errorString()));
     145              :     }
     146         2722 :     if (!m_docName.isEmpty()) {
     147         2587 :         LOGD() << "tag in <" << m_docName << "> byte offset " << byteOffset() + m_byteOffsetAdjustment << ": " << name();
     148              :     } else {
     149          135 :         LOGD() << "byte offset " << byteOffset() + m_byteOffsetAdjustment << ": " << name();
     150              :     }
     151         2722 :     skipCurrentElement();
     152         2722 : }
     153              : 
     154            1 : double XmlReader::readDouble(double min, double max)
     155              : {
     156            1 :     double val = readDouble();
     157            1 :     if (val < min) {
     158            0 :         val = min;
     159            1 :     } else if (val > max) {
     160            0 :         val = max;
     161              :     }
     162            1 :     return val;
     163              : }
     164              : 
     165              : //---------------------------------------------------------
     166              : //   htmlToString
     167              : //---------------------------------------------------------
     168              : 
     169         1572 : void XmlReader::htmlToString(int level, String* s)
     170              : {
     171         1572 :     bool selfClosing = noChildren();
     172         1572 :     *s += u'<' + String::fromAscii(name().ascii());
     173         2445 :     for (const Attribute& a : attributes()) {
     174          873 :         *s += u' ' + String::fromAscii(a.name.ascii()) + u"=\"" + a.value + u'\"';
     175         1572 :     }
     176         1572 :     *s += selfClosing ? u"/>" : u">";
     177         1572 :     ++level;
     178              :     for (;;) {
     179         2864 :         XmlStreamReader::TokenType t = readNext();
     180         2864 :         switch (t) {
     181          533 :         case XmlStreamReader::StartElement:
     182          533 :             htmlToString(level, s);
     183          533 :             break;
     184         1572 :         case XmlStreamReader::EndElement:
     185         1572 :             if (!selfClosing) {
     186         1002 :                 *s += u"</" + String::fromAscii(name().ascii()) + u'>';
     187              :             }
     188         1572 :             --level;
     189         1572 :             return;
     190          759 :         case XmlStreamReader::Characters:
     191          759 :             if (!s->empty() || !isWhitespace()) {
     192          759 :                 *s += text().toXmlEscaped();
     193              :             } else {
     194            0 :                 LOGD() << "ignoring whitespace";
     195              :             }
     196          759 :             break;
     197            0 :         case XmlStreamReader::Comment:
     198            0 :             break;
     199              : 
     200            0 :         default:
     201            0 :             LOGD() << "htmlToString: read token: " << tokenString();
     202            0 :             return;
     203              :         }
     204         1292 :     }
     205              : }
     206              : 
     207              : //-------------------------------------------------------------------
     208              : //   readXml
     209              : //    read verbatim until end tag of current level is reached
     210              : //-------------------------------------------------------------------
     211              : 
     212         7376 : String XmlReader::readXml()
     213              : {
     214         7376 :     String s;
     215         7376 :     int level = 1;
     216        15471 :     for (XmlStreamReader::TokenType t = readNext(); t != XmlStreamReader::EndElement; t = readNext()) {
     217         8095 :         switch (t) {
     218         1039 :         case XmlStreamReader::StartElement:
     219         1039 :             htmlToString(level, &s);
     220         1039 :             break;
     221            0 :         case XmlStreamReader::EndElement:
     222            0 :             break;
     223         7056 :         case XmlStreamReader::Characters:
     224         7056 :             if (!isWhitespace()) {
     225         7056 :                 s += text().toXmlEscaped();
     226              :             }
     227         7056 :             break;
     228            0 :         case XmlStreamReader::Comment:
     229            0 :             break;
     230              : 
     231            0 :         default:
     232            0 :             LOGD() << "read token: " << tokenString();
     233            0 :             return s;
     234              :         }
     235              :     }
     236         7376 :     return s;
     237            0 : }
     238              : }
        

Generated by: LCOV version 2.0-1