1
1
/*
2
2
* Bittorrent Client using Qt and libtorrent.
3
- * Copyright (C) 2018-2023 Vladimir Golovnev <[email protected] >
3
+ * Copyright (C) 2018-2024 Vladimir Golovnev <[email protected] >
4
4
*
5
5
* This program is free software; you can redistribute it and/or
6
6
* modify it under the terms of the GNU General Public License
28
28
29
29
#include " synccontroller.h"
30
30
31
- #include < algorithm>
32
-
33
31
#include < QJsonArray>
34
32
#include < QJsonObject>
35
33
#include < QMetaObject>
@@ -119,9 +117,9 @@ namespace
119
117
const QString KEY_FULL_UPDATE = u" full_update" _s;
120
118
const QString KEY_RESPONSE_ID = u" rid" _s;
121
119
122
- void processMap (const QVariantMap &prevData, const QVariantMap &data, QVariantMap &syncData );
123
- void processHash (QVariantHash prevData, const QVariantHash &data, QVariantMap &syncData, QVariantList &removedItems );
124
- void processList (QVariantList prevData, const QVariantList &data, QVariantList &syncData, QVariantList &removedItems );
120
+ QVariantMap processMap (const QVariantMap &prevData, const QVariantMap &data);
121
+ std::pair<QVariantMap, QVariantList> processHash (QVariantHash prevData, const QVariantHash &data);
122
+ std::pair<QVariantList, QVariantList> processList (QVariantList prevData, const QVariantList &data);
125
123
QJsonObject generateSyncData (int acceptedResponseId, const QVariantMap &data, QVariantMap &lastAcceptedData, QVariantMap &lastData);
126
124
127
125
QVariantMap getTransferInfo ()
@@ -171,31 +169,28 @@ namespace
171
169
172
170
// Compare two structures (prevData, data) and calculate difference (syncData).
173
171
// Structures encoded as map.
174
- void processMap (const QVariantMap &prevData, const QVariantMap &data, QVariantMap &syncData )
172
+ QVariantMap processMap (const QVariantMap &prevData, const QVariantMap &data)
175
173
{
176
174
// initialize output variable
177
- syncData. clear () ;
175
+ QVariantMap syncData;
178
176
179
177
for (auto i = data.cbegin (); i != data.cend (); ++i)
180
178
{
181
179
const QString &key = i.key ();
182
180
const QVariant &value = i.value ();
183
- QVariantList removedItems;
184
181
185
182
switch (value.userType ())
186
183
{
187
184
case QMetaType::QVariantMap:
188
185
{
189
- QVariantMap map;
190
- processMap (prevData[key].toMap (), value.toMap (), map);
186
+ const QVariantMap map = processMap (prevData[key].toMap (), value.toMap ());
191
187
if (!map.isEmpty ())
192
188
syncData[key] = map;
193
189
}
194
190
break ;
195
191
case QMetaType::QVariantHash:
196
192
{
197
- QVariantMap map;
198
- processHash (prevData[key].toHash (), value.toHash (), map, removedItems);
193
+ const auto [map, removedItems] = processHash (prevData[key].toHash (), value.toHash ());
199
194
if (!map.isEmpty ())
200
195
syncData[key] = map;
201
196
if (!removedItems.isEmpty ())
@@ -204,8 +199,7 @@ namespace
204
199
break ;
205
200
case QMetaType::QVariantList:
206
201
{
207
- QVariantList list;
208
- processList (prevData[key].toList (), value.toList (), list, removedItems);
202
+ const auto [list, removedItems] = processList (prevData[key].toList (), value.toList ());
209
203
if (!list.isEmpty ())
210
204
syncData[key] = list;
211
205
if (!removedItems.isEmpty ())
@@ -228,21 +222,22 @@ namespace
228
222
break ;
229
223
default :
230
224
Q_ASSERT_X (false , " processMap"
231
- , u" Unexpected type: %1" _s
232
- .arg (QString::fromLatin1 (value.metaType ().name ()))
233
- .toUtf8 ().constData ());
225
+ , u" Unexpected type: %1" _s.arg (QString::fromLatin1 (value.metaType ().name ()))
226
+ .toUtf8 ().constData ());
234
227
}
235
228
}
229
+
230
+ return syncData;
236
231
}
237
232
238
233
// Compare two lists of structures (prevData, data) and calculate difference (syncData, removedItems).
239
234
// Structures encoded as map.
240
235
// Lists are encoded as hash table (indexed by structure key value) to improve ease of searching for removed items.
241
- void processHash (QVariantHash prevData, const QVariantHash &data, QVariantMap &syncData, QVariantList &removedItems )
236
+ std::pair<QVariantMap, QVariantList> processHash (QVariantHash prevData, const QVariantHash &data)
242
237
{
243
238
// initialize output variables
244
- syncData. clear () ;
245
- removedItems. clear () ;
239
+ std::pair<QVariantMap, QVariantList> result ;
240
+ auto &[syncData, removedItems] = result ;
246
241
247
242
if (prevData.isEmpty ())
248
243
{
@@ -264,8 +259,7 @@ namespace
264
259
}
265
260
else
266
261
{
267
- QVariantMap map;
268
- processMap (prevData[i.key ()].toMap (), i.value ().toMap (), map);
262
+ const QVariantMap map = processMap (prevData[i.key ()].toMap (), i.value ().toMap ());
269
263
// existing list item found - remove it from prevData
270
264
prevData.remove (i.key ());
271
265
if (!map.isEmpty ())
@@ -283,9 +277,7 @@ namespace
283
277
}
284
278
else
285
279
{
286
- QVariantList list;
287
- QVariantList removedList;
288
- processList (prevData[i.key ()].toList (), i.value ().toList (), list, removedList);
280
+ const auto [list, removedList] = processList (prevData[i.key ()].toList (), i.value ().toList ());
289
281
// existing list item found - remove it from prevData
290
282
prevData.remove (i.key ());
291
283
if (!list.isEmpty () || !removedList.isEmpty ())
@@ -309,14 +301,16 @@ namespace
309
301
removedItems << i.key ();
310
302
}
311
303
}
304
+
305
+ return result;
312
306
}
313
307
314
308
// Compare two lists of simple value (prevData, data) and calculate difference (syncData, removedItems).
315
- void processList (QVariantList prevData, const QVariantList &data, QVariantList &syncData, QVariantList &removedItems )
309
+ std::pair<QVariantList, QVariantList> processList (QVariantList prevData, const QVariantList &data)
316
310
{
317
311
// initialize output variables
318
- syncData. clear () ;
319
- removedItems. clear () ;
312
+ std::pair<QVariantList, QVariantList> result ;
313
+ auto &[syncData, removedItems] = result ;
320
314
321
315
if (prevData.isEmpty ())
322
316
{
@@ -346,6 +340,8 @@ namespace
346
340
removedItems = prevData;
347
341
}
348
342
}
343
+
344
+ return result;
349
345
}
350
346
351
347
QJsonObject generateSyncData (int acceptedResponseId, const QVariantMap &data, QVariantMap &lastAcceptedData, QVariantMap &lastData)
@@ -373,7 +369,7 @@ namespace
373
369
}
374
370
else
375
371
{
376
- processMap (lastAcceptedData, data, syncData );
372
+ syncData = processMap (lastAcceptedData, data);
377
373
}
378
374
379
375
const int responseId = (lastResponseId % 1000000 ) + 1 ; // cycle between 1 and 1000000
@@ -595,8 +591,11 @@ QJsonObject SyncController::generateMaindataSyncData(const int id, const bool fu
595
591
category.insert (u" name" _s, categoryName);
596
592
597
593
auto &categorySnapshot = m_maindataSnapshot.categories [categoryName];
598
- processMap (categorySnapshot, category, m_maindataSyncBuf.categories [categoryName]);
599
- categorySnapshot = category;
594
+ if (const QVariantMap syncData = processMap (categorySnapshot, category); !syncData.isEmpty ())
595
+ {
596
+ m_maindataSyncBuf.categories [categoryName] = syncData;
597
+ categorySnapshot = category;
598
+ }
600
599
}
601
600
m_updatedCategories.clear ();
602
601
@@ -630,8 +629,12 @@ QJsonObject SyncController::generateMaindataSyncData(const int id, const bool fu
630
629
serializedTorrent.remove (KEY_TORRENT_ID);
631
630
632
631
auto &torrentSnapshot = m_maindataSnapshot.torrents [torrentID.toString ()];
633
- processMap (torrentSnapshot, serializedTorrent, m_maindataSyncBuf.torrents [torrentID.toString ()]);
634
- torrentSnapshot = serializedTorrent;
632
+
633
+ if (const QVariantMap syncData = processMap (torrentSnapshot, serializedTorrent); !syncData.isEmpty ())
634
+ {
635
+ m_maindataSyncBuf.torrents [torrentID.toString ()] = syncData;
636
+ torrentSnapshot = serializedTorrent;
637
+ }
635
638
}
636
639
m_updatedTorrents.clear ();
637
640
@@ -668,8 +671,11 @@ QJsonObject SyncController::generateMaindataSyncData(const int id, const bool fu
668
671
serverState[KEY_SYNC_MAINDATA_USE_ALT_SPEED_LIMITS] = session->isAltGlobalSpeedLimitEnabled ();
669
672
serverState[KEY_SYNC_MAINDATA_REFRESH_INTERVAL] = session->refreshInterval ();
670
673
serverState[KEY_SYNC_MAINDATA_USE_SUBCATEGORIES] = session->isSubcategoriesEnabled ();
671
- processMap (m_maindataSnapshot.serverState , serverState, m_maindataSyncBuf.serverState );
672
- m_maindataSnapshot.serverState = serverState;
674
+ if (const QVariantMap syncData = processMap (m_maindataSnapshot.serverState , serverState); !syncData.isEmpty ())
675
+ {
676
+ m_maindataSyncBuf.serverState = syncData;
677
+ m_maindataSnapshot.serverState = serverState;
678
+ }
673
679
674
680
QJsonObject syncData;
675
681
syncData[KEY_RESPONSE_ID] = id;
0 commit comments