A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita
audio
rust
zig
deno
mpris
rockbox
mpd
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2010 Robert Bieber
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#include "targetdata.h"
23
24#include <QStringList>
25#include <QSettings>
26
27const QString TargetData::reserved = "{}:#\n";
28
29TargetData::TargetData()
30{
31 QSettings settings;
32 settings.beginGroup("TargetData");
33 QString file = settings.value("targetDbPath", "").toString();
34 settings.endGroup();
35
36 if(!QFile::exists(file))
37 file = ":/targets/targetdb";
38
39 QFile fin(file);
40 fin.open(QFile::ReadOnly | QFile::Text);
41
42 /* Reading the database */
43 QString data = QString(fin.readAll());
44
45 fin.close();
46
47 int cursor = 0;
48 int index = 0;
49 while(cursor < data.length())
50 {
51 QString id = scanString(data, cursor);
52 QString name = "";
53 QRect size(0, 0, 0, 0);
54 ScreenDepth depth = None;
55 QRect rSize(0, 0, 0, 0);
56 ScreenDepth rDepth = None;
57 bool fm = false;
58 bool record = false;
59
60 if(id == "")
61 break;
62
63 if(!require('{', data, cursor))
64 break;
65
66 /* Now we have to parse each of the arguments */
67 while(cursor < data.length())
68 {
69 QString key = scanString(data, cursor);
70 if(key == "")
71 {
72 break;
73 }
74 else
75 {
76 if(!require(':', data, cursor))
77 break;
78
79 if(key.toLower() == "name")
80 {
81 name = scanString(data, cursor);
82 }
83 else if(key.toLower() == "screen")
84 {
85 QString s = scanString(data, cursor);
86 if(s[0].toLower() != 'n')
87 {
88 int subCursor = 0;
89 int width = scanInt(s, subCursor);
90
91 if(!require('x', s, subCursor))
92 break;
93
94 int height = scanInt(s, subCursor);
95
96 if(!require('@', s, subCursor))
97 break;
98
99 size = QRect(0, 0, width, height);
100 depth = scanDepth(s, subCursor);
101 }
102 }
103 else if(key.toLower() == "remote")
104 {
105 QString s = scanString(data, cursor);
106 if(s[0].toLower() != 'n')
107 {
108 int subCursor = 0;
109 int width = scanInt(s, subCursor);
110
111 if(!require('x', s, subCursor))
112 break;
113
114 int height = scanInt(s, subCursor);
115
116 if(!require('@', s, subCursor))
117 break;
118
119 rSize = QRect(0, 0, width, height);
120 rDepth = scanDepth(s, subCursor);
121 }
122 }
123 else if(key.toLower() == "fm")
124 {
125 QString s = scanString(data, cursor);
126 if(s.toLower() == "yes")
127 fm = true;
128 }
129 else if(key.toLower() == "record")
130 {
131 QString s = scanString(data, cursor);
132 if(s.toLower() == "yes")
133 record = true;
134 }
135 }
136 }
137
138 /* Checking for the closing '}' and adding the entry */
139 if(require('}', data, cursor))
140 {
141 entries.append(Entry(id, name, size, depth, rSize, rDepth,
142 fm, record));
143 indices.insert(id, index);
144 index++;
145 }
146 else
147 {
148 break;
149 }
150 }
151}
152
153TargetData::~TargetData()
154{
155}
156
157QString TargetData::scanString(QString data, int &index)
158{
159 QString retval;
160
161 /* Skipping whitespace and comments */
162 while(index < data.length() && (data[index].isSpace() || data[index] == '#'))
163 {
164 if(data[index] == '#')
165 skipComment(data, index);
166 else
167 index++;
168 }
169
170 while(index < data.length() && !reserved.contains(data[index]))
171 {
172 if(data[index] == '%')
173 {
174 retval.append(data[index + 1]);
175 index += 2;
176 }
177 else
178 {
179 retval.append(data[index]);
180 index++;
181 }
182 }
183
184 return retval.trimmed();
185}
186
187int TargetData::scanInt(QString data, int &index)
188{
189 /* Skipping whitespace and comments */
190 while(index < data.length() && (data[index].isSpace() || data[index] == '#'))
191 {
192 if(data[index] == '#')
193 skipComment(data, index);
194 else
195 index++;
196 }
197
198 QString number;
199 while(index < data.length() && data[index].isDigit())
200 number.append(data[index++]);
201
202 return number.toInt();
203}
204
205TargetData::ScreenDepth TargetData::scanDepth(QString data, int &index)
206{
207 QString depth = scanString(data, index);
208
209 if(depth.toLower() == "grey")
210 return Grey;
211 else if(depth.toLower() == "rgb")
212 return RGB;
213 else if(depth.toLower() == "mono")
214 return Mono;
215 else
216 return None;
217}
218
219void TargetData::skipComment(QString data, int &index)
220{
221 if(data[index] != '#')
222 return;
223
224 while(index < data.length() && data[index] != '\n')
225 index++;
226
227 if(index < data.length())
228 index++;
229}
230
231bool TargetData::require(QChar required, QString data, int &index)
232{
233 /* Skipping whitespace and comments */
234 while(index < data.length() && (data[index].isSpace() || data[index] == '#'))
235 {
236 if(data[index] == '#')
237 skipComment(data, index);
238 else
239 index++;
240 }
241
242 if(index == data.length())
243 {
244 return false;
245 }
246 else
247 {
248 if(data[index] == required)
249 {
250 index++;
251 return true;
252 }
253 else
254 {
255 return false;
256 }
257 }
258
259}