Akonadi

scope.cpp
1 /*
2  * SPDX-FileCopyrightText: 2009 Volker Krause <[email protected]>
3  * SPDX-FileCopyrightText: 2015 Daniel Vrátil <[email protected]>
4  *
5  * SPDX-License-Identifier: LGPL-2.0-or-later
6  */
7 
8 #include "scope_p.h"
9 #include "datastream_p_p.h"
10 
11 #include <QJsonArray>
12 #include <QJsonObject>
13 #include <QStringList>
14 
15 #include "imapset_p.h"
16 
17 namespace Akonadi
18 {
19 
20 class ScopePrivate : public QSharedData
21 {
22 public:
23  ImapSet uidSet;
24  QStringList ridSet;
25  QVector<Scope::HRID> hridChain;
26  QStringList gidSet;
27  Scope::SelectionScope scope = Scope::Invalid;
28 };
29 
30 Scope::HRID::HRID()
31  : id(-1)
32 {}
33 
34 Scope::HRID::HRID(qint64 id, const QString &remoteId)
35  : id(id)
36  , remoteId(remoteId)
37 {}
38 
39 Scope::HRID::HRID(const HRID &other)
40  : id(other.id)
41  , remoteId(other.remoteId)
42 {}
43 
44 Scope::HRID::HRID(HRID &&other) noexcept
45  : id(other.id)
46 {
47  remoteId.swap(other.remoteId);
48 }
49 
50 Scope::HRID &Scope::HRID::operator=(const HRID &other)
51 {
52  if (*this == other) {
53  return *this;
54  }
55 
56  id = other.id;
57  remoteId = other.remoteId;
58  return *this;
59 }
60 
61 Scope::HRID &Scope::HRID::operator=(HRID &&other) noexcept
62 {
63  if (*this == other) {
64  return *this;
65  }
66 
67  id = other.id;
68  remoteId.swap(other.remoteId);
69  return *this;
70 }
71 
72 bool Scope::HRID::isEmpty() const
73 {
74  return id <= 0 && remoteId.isEmpty();
75 }
76 
77 bool Scope::HRID::operator==(const HRID &other) const
78 {
79  return id == other.id && remoteId == other.remoteId;
80 }
81 
82 void Scope::HRID::toJson(QJsonObject &json) const
83 {
84  json[QStringLiteral("ID")] = id;
85  json[QStringLiteral("RemoteID")] = remoteId;
86 }
87 
88 Scope::Scope()
89  : d(new ScopePrivate)
90 {
91 }
92 
93 Scope::Scope(qint64 id)
94  : d(new ScopePrivate)
95 {
96  setUidSet(id);
97 }
98 
99 Scope::Scope(const ImapSet &set)
100  : d(new ScopePrivate)
101 {
102  setUidSet(set);
103 }
104 
105 Scope::Scope(const ImapInterval &interval)
106  : d(new ScopePrivate)
107 {
108  setUidSet(interval);
109 }
110 
111 Scope::Scope(const QVector<qint64> &interval)
112  : d(new ScopePrivate)
113 {
114  setUidSet(interval);
115 }
116 
117 Scope::Scope(SelectionScope scope, const QStringList &ids)
118  : d(new ScopePrivate)
119 {
120  Q_ASSERT(scope == Rid || scope == Gid);
121  if (scope == Rid) {
122  d->scope = scope;
123  d->ridSet = ids;
124  } else if (scope == Gid) {
125  d->scope = scope;
126  d->gidSet = ids;
127  }
128 }
129 
130 Scope::Scope(const QVector<HRID> &hrid)
131  : d(new ScopePrivate)
132 {
133  d->scope = HierarchicalRid;
134  d->hridChain = hrid;
135 }
136 
137 Scope::Scope(const Scope &other)
138  : d(other.d)
139 {
140 }
141 
142 Scope::Scope(Scope &&other) noexcept
143 {
144  d.swap(other.d);
145 }
146 
147 Scope::~Scope()
148 {
149 }
150 
151 Scope &Scope::operator=(const Scope &other)
152 {
153  d = other.d;
154  return *this;
155 }
156 
157 Scope &Scope::operator=(Scope &&other) noexcept
158 {
159  d.swap(other.d);
160  return *this;
161 }
162 
163 bool Scope::operator==(const Scope &other) const
164 {
165  if (d->scope != other.d->scope) {
166  return false;
167  }
168 
169  switch (d->scope) {
170  case Uid:
171  return d->uidSet == other.d->uidSet;
172  case Gid:
173  return d->gidSet == other.d->gidSet;
174  case Rid:
175  return d->ridSet == other.d->ridSet;
176  case HierarchicalRid:
177  return d->hridChain == other.d->hridChain;
178  case Invalid:
179  return true;
180  }
181 
182  Q_ASSERT(false);
183  return false;
184 }
185 
186 bool Scope::operator!=(const Scope &other) const
187 {
188  return !(*this == other);
189 }
190 
191 Scope::SelectionScope Scope::scope() const
192 {
193  return d->scope;
194 }
195 
196 bool Scope::isEmpty() const
197 {
198  switch (d->scope) {
199  case Invalid:
200  return true;
201  case Uid:
202  return d->uidSet.isEmpty();
203  case Rid:
204  return d->ridSet.isEmpty();
205  case HierarchicalRid:
206  return d->hridChain.isEmpty();
207  case Gid:
208  return d->gidSet.isEmpty();
209  }
210 
211  Q_ASSERT(false);
212  return true;
213 }
214 
215 void Scope::setUidSet(const ImapSet &uidSet)
216 {
217  d->scope = Uid;
218  d->uidSet = uidSet;
219 }
220 
221 ImapSet Scope::uidSet() const
222 {
223  return d->uidSet;
224 }
225 
226 void Scope::setRidSet(const QStringList &ridSet)
227 {
228  d->scope = Rid;
229  d->ridSet = ridSet;
230 }
231 
232 QStringList Scope::ridSet() const
233 {
234  return d->ridSet;
235 }
236 
237 void Scope::setHRidChain(const QVector<HRID> &hridChain)
238 {
239  d->scope = HierarchicalRid;
240  d->hridChain = hridChain;
241 }
242 
243 QVector<Scope::HRID> Scope::hridChain() const
244 {
245  return d->hridChain;
246 }
247 
248 void Scope::setGidSet(const QStringList &gidSet)
249 {
250  d->scope = Gid;
251  d->gidSet = gidSet;
252 }
253 
254 QStringList Scope::gidSet() const
255 {
256  return d->gidSet;
257 }
258 
259 qint64 Scope::uid() const
260 {
261  if (d->uidSet.intervals().size() == 1 &&
262  d->uidSet.intervals().at(0).size() == 1) {
263  return d->uidSet.intervals().at(0).begin();
264  }
265 
266  // TODO: Error handling!
267  return -1;
268 }
269 
270 QString Scope::rid() const
271 {
272  if (d->ridSet.size() != 1) {
273  // TODO: Error handling!
274  Q_ASSERT(d->ridSet.size() == 1);
275  return QString();
276  }
277  return d->ridSet.at(0);
278 }
279 
280 QString Scope::gid() const
281 {
282  if (d->gidSet.size() != 1) {
283  // TODO: Error handling!
284  Q_ASSERT(d->gidSet.size() == 1);
285  return QString();
286  }
287  return d->gidSet.at(0);
288 }
289 
290 void Scope::toJson(QJsonObject &json) const
291 {
292  switch (scope()) {
293  case Scope::Uid:
294  json[QStringLiteral("type")] = QStringLiteral("UID");
295  json[QStringLiteral("value")] = QString::fromUtf8(uidSet().toImapSequenceSet());
296  break;
297  case Scope::Rid:
298  json[QStringLiteral("type")] = QStringLiteral("RID");
299  json[QStringLiteral("value")] = QJsonArray::fromStringList(ridSet());
300  break;
301  case Scope::Gid:
302  json[QStringLiteral("type")] = QStringLiteral("GID");
303  json[QStringLiteral("value")] = QJsonArray::fromStringList(gidSet());
304  break;
305  case Scope::HierarchicalRid:
306  {
307  const auto &chain = hridChain();
308  QJsonArray hridArray;
309  for (const auto &hrid : chain) {
310  QJsonObject obj;
311  hrid.toJson(obj);
312  hridArray.append(obj);
313  }
314  json[QStringLiteral("type")] = QStringLiteral("HRID");
315  json[QStringLiteral("value")] = hridArray;
316  }
317  break;
318  default:
319  json[QStringLiteral("type")] = QStringLiteral("invalid");
320  json[QStringLiteral("value")] = QJsonValue(static_cast<int>(scope()));
321  }
322 }
323 
324 Protocol::DataStream &operator<<(Protocol::DataStream &stream, const Akonadi::Scope &scope)
325 {
326  stream << static_cast<quint8>(scope.d->scope);
327  switch (scope.d->scope) {
328  case Scope::Invalid:
329  return stream;
330  case Scope::Uid:
331  stream << scope.d->uidSet;
332  return stream;
333  case Scope::Rid:
334  stream << scope.d->ridSet;
335  return stream;
336  case Scope::HierarchicalRid:
337  stream << scope.d->hridChain;
338  return stream;
339  case Scope::Gid:
340  stream << scope.d->gidSet;
341  return stream;
342  }
343 
344  return stream;
345 }
346 
347 Protocol::DataStream &operator<<(Protocol::DataStream &stream, const Akonadi::Scope::HRID &hrid)
348 {
349  return stream << hrid.id << hrid.remoteId;
350 }
351 
352 Protocol::DataStream &operator>>(Protocol::DataStream &stream, Akonadi::Scope::HRID &hrid)
353 {
354  return stream >> hrid.id >> hrid.remoteId;
355 }
356 
357 Protocol::DataStream &operator>>(Protocol::DataStream &stream, Akonadi::Scope &scope)
358 {
359  scope.d->uidSet = ImapSet();
360  scope.d->ridSet.clear();
361  scope.d->hridChain.clear();
362  scope.d->gidSet.clear();
363 
364  stream >> reinterpret_cast<quint8 &>(scope.d->scope);
365  switch (scope.d->scope) {
366  case Scope::Invalid:
367  return stream;
368  case Scope::Uid:
369  stream >> scope.d->uidSet;
370  return stream;
371  case Scope::Rid:
372  stream >> scope.d->ridSet;
373  return stream;
374  case Scope::HierarchicalRid:
375  stream >> scope.d->hridChain;
376  return stream;
377  case Scope::Gid:
378  stream >> scope.d->gidSet;
379  return stream;
380  }
381 
382  return stream;
383 }
384 
385 } // namespace Akonadi
386 
387 using namespace Akonadi;
388 
389 QDebug operator<<(QDebug dbg, const Akonadi::Scope::HRID &hrid)
390 {
391  return dbg.nospace() << "(ID: " << hrid.id << ", RemoteID: " << hrid.remoteId << ")";
392 }
393 
394 QDebug operator<<(QDebug dbg, const Akonadi::Scope &scope)
395 {
396  switch (scope.scope()) {
397  case Scope::Uid:
398  return dbg.nospace() << "UID " << scope.uidSet();
399  case Scope::Rid:
400  return dbg.nospace() << "RID " << scope.ridSet();
401  case Scope::Gid:
402  return dbg.nospace() << "GID " << scope.gidSet();
403  case Scope::HierarchicalRid:
404  return dbg.nospace() << "HRID " << scope.hridChain();
405  default:
406  return dbg.nospace() << "Invalid scope";
407  }
408 }
QDataStream & operator>>(QDataStream &in, KDateTime::Spec &spec)
const T & at(int i) const const
QDebug & nospace()
QString fromUtf8(const char *str, int size)
void append(const QJsonValue &value)
QDataStream & operator<<(QDataStream &out, const KDateTime::Spec &spec)
Helper integration between Akonadi and Qt.
QJsonArray fromStringList(const QStringList &list)
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Sat Jul 4 2020 23:16:52 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.