1 // SPDX-License-Identifier: LGPL-2.1-or-later
2 //
3 // SPDX-FileCopyrightText: 2009 Bastian Holst <bastianholst@gmx.de>
4 //
5 
6 // Self
7 #include "StationListParser.h"
8 
9 // Marble
10 #include "MarbleGlobal.h"
11 #include "BBCStation.h"
12 #include "GeoDataCoordinates.h"
13 #include "MarbleDebug.h"
14 
15 // Qt
16 #include <QFile>
17 #include <QString>
18 
19 using namespace Marble;
20 
StationListParser(QObject * parent)21 StationListParser::StationListParser( QObject *parent )
22     : QThread( parent ),
23       QXmlStreamReader()
24 {
25 }
26 
~StationListParser()27 StationListParser::~StationListParser()
28 {
29     wait( 1000 );
30 }
31 
read()32 void StationListParser::read()
33 {
34     m_list.clear();
35 
36     while ( !atEnd() ) {
37         readNext();
38 
39         if ( isStartElement() ) {
40             if (name() == QLatin1String("StationList"))
41                 readStationList();
42             else
43                 raiseError( QObject::tr("The file is not a valid file.") );
44         }
45     }
46 }
47 
stationList() const48 QList<BBCStation> StationListParser::stationList() const
49 {
50     return m_list;
51 }
52 
setPath(const QString & path)53 void StationListParser::setPath( const QString& path )
54 {
55     m_path = path;
56 }
57 
run()58 void StationListParser::run()
59 {
60     QFile file( m_path );
61 
62     if( !file.open( QIODevice::ReadOnly | QIODevice::Text ) ) {
63         return;
64     }
65 
66     setDevice( &file );
67     read();
68 }
69 
readUnknownElement()70 void StationListParser::readUnknownElement()
71 {
72     Q_ASSERT( isStartElement() );
73 
74     while ( !atEnd() ) {
75         readNext();
76 
77         if ( isEndElement() )
78             break;
79 
80         if ( isStartElement() )
81             readUnknownElement();
82     }
83 }
84 
readStationList()85 void StationListParser::readStationList()
86 {
87     Q_ASSERT( isStartElement()
88               && name() == QLatin1String("StationList"));
89 
90     while( !atEnd() ) {
91         readNext();
92 
93         if( isEndElement() )
94             break;
95 
96         if( isStartElement() ) {
97             if (name() == QLatin1String("Station"))
98                 readStation();
99             else
100                 readUnknownElement();
101         }
102     }
103 }
104 
readStation()105 void StationListParser::readStation()
106 {
107     Q_ASSERT( isStartElement()
108               && name() == QLatin1String("Station"));
109 
110     BBCStation station;
111 
112     while ( !atEnd() ) {
113         readNext();
114 
115         if( isEndElement() )
116             break;
117 
118         if( isStartElement() ) {
119             if (name() == QLatin1String("name"))
120                 station.setName( readCharacters() );
121             else if (name() == QLatin1String("id"))
122                 station.setBbcId( readCharacters().toLong() );
123             else if (name() == QLatin1String("priority"))
124                 station.setPriority( readCharacters().toInt() );
125             else if (name() == QLatin1String("Point"))
126                 readPoint( &station );
127             else
128                 readUnknownElement();
129         }
130     }
131 
132     // This find the right position in the sorted to insert the new item
133     QList<BBCStation>::iterator i = std::lower_bound( m_list.begin(),
134                                                  m_list.end(),
135                                                  station );
136     // Insert the item on the right position in the list
137     m_list.insert( i, station );
138 }
139 
readCharacters()140 QString StationListParser::readCharacters()
141 {
142     Q_ASSERT( isStartElement() );
143 
144     QString string;
145 
146     while ( !atEnd() ) {
147         readNext();
148 
149         if ( isEndElement() )
150             break;
151 
152         if ( isStartElement() ) {
153             readUnknownElement();
154         }
155 
156         if ( isCharacters() ) {
157             string = text().toString();
158         }
159     }
160 
161     return string;
162 }
163 
readPoint(BBCStation * station)164 void StationListParser::readPoint( BBCStation *station )
165 {
166     Q_ASSERT( isStartElement()
167               && name() == QLatin1String("Point"));
168 
169     while ( !atEnd() ) {
170         readNext();
171 
172         if ( isEndElement() )
173             break;
174 
175         if ( isStartElement() ) {
176             if (name() == QLatin1String("coordinates")) {
177                 QString coorString = readCharacters();
178                 QStringList coorList = coorString.split(QLatin1Char(','));
179 
180                 if ( coorList.size() >= 2 ) {
181                     GeoDataCoordinates coordinates( coorList.at( 0 ).toFloat() * DEG2RAD,
182                                                     coorList.at( 1 ).toFloat() * DEG2RAD );
183                     station->setCoordinate( coordinates );
184                 }
185             }
186             else
187                 readUnknownElement();
188         }
189     }
190 }
191 
192 #include "moc_StationListParser.cpp"
193