Libksieve

response.cpp
1 /*
2  SPDX-FileCopyrightText: 2010 Klarälvdalens Datakonsult AB, a KDAB Group company <[email protected]>
3  SPDX-FileContributor: Volker Krause <[email protected]>
4 
5  SPDX-License-Identifier: LGPL-2.0-or-later
6 */
7 
8 #include "response.h"
9 #include "kmanagersieve_debug.h"
10 
11 void KManageSieve::Response::clear()
12 {
13  m_type = None;
14  m_key.clear();
15  m_value.clear();
16  m_extra.clear();
17  m_quantity = 0;
18 }
19 
20 QByteArray KManageSieve::Response::action() const
21 {
22  return m_key;
23 }
24 
25 QByteArray KManageSieve::Response::extra() const
26 {
27  return m_extra;
28 }
29 
30 QByteArray KManageSieve::Response::key() const
31 {
32  return m_key;
33 }
34 
35 QByteArray KManageSieve::Response::value() const
36 {
37  return m_value;
38 }
39 
40 uint KManageSieve::Response::quantity() const
41 {
42  return m_quantity;
43 }
44 
45 KManageSieve::Response::Type KManageSieve::Response::type() const
46 {
47  return m_type;
48 }
49 
50 static uint parseQuantity(const QByteArray &line, int start, bool *ok = nullptr)
51 {
52  // expecting {quantity} at start
53  int end = line.indexOf("+}", start + 1);
54  // some older versions of Cyrus enclose the literal size just in { } instead of { +}
55  if (end == -1) {
56  end = line.indexOf('}', start + 1);
57  }
58 
59  return line.mid(start + 1, end - start - 1).toUInt(ok);
60 }
61 
62 bool KManageSieve::Response::parseResponse(const QByteArray &line)
63 {
64  clear();
65 
66  switch (line.at(0)) {
67  case '{': {
68  m_type = Quantity;
69  bool ok = false;
70  m_quantity = parseQuantity(line, 0, &ok);
71  return ok;
72  }
73  case '"':
74  // expecting "key" "value" pairs
75  m_type = KeyValuePair;
76  break;
77  default: {
78  // expecting single string
79  m_type = Action;
80  m_key = line;
81 
82  // Sometimes NO is followed by a quantity (multiline error message). Ex:
83  // S: "NO {62}"
84  // S: "script errors:"
85  // S: line 17: syntax error, unexpected $undefined
86  const int bracePos = line.indexOf('{');
87  if (bracePos > 0) {
88  m_quantity = parseQuantity(line, bracePos);
89  }
90  return true;
91  }
92  }
93 
94  int start = 0;
95  int end = line.indexOf('"', start + 1);
96  if (end == -1) {
97  qCDebug(KMANAGERSIEVE_LOG) << "Invalid protocol in:" << line;
98  m_key = line.right(line.length() - start);
99  return true;
100  }
101  m_key = line.mid(start + 1, end - start - 1);
102 
103  start = line.indexOf('"', end + 1);
104  if (start == -1) {
105  if (line.length() > end) {
106  // skip " and space
107  m_extra = line.right(line.length() - end - 2);
108  }
109  return true;
110  }
111 
112  end = line.indexOf('"', start + 1);
113  if (end == -1) {
114  qCDebug(KMANAGERSIEVE_LOG) << "Invalid protocol in:" << line;
115  m_value = line.right(line.length() - start);
116  return true;
117  }
118 
119  m_value = line.mid(start + 1, end - start - 1);
120  return true;
121 }
122 
123 KManageSieve::Response::Result KManageSieve::Response::operationResult() const
124 {
125  if (m_type == Action) {
126  const QByteArray response = m_key.left(2);
127  if (response == "OK") {
128  return Ok;
129  } else if (response == "NO") {
130  return No;
131  } else if (response == "BY" /*E*/) {
132  return Bye;
133  }
134  }
135  return Other;
136 }
137 
138 bool KManageSieve::Response::operationSuccessful() const
139 {
140  return operationResult() == Ok;
141 }
uint toUInt(bool *ok, int base) const const
void clear()
char at(int i) const const
int length() const const
int indexOf(char ch, int from) const const
QByteArray right(int len) const const
QByteArray mid(int pos, int len) const const
const QList< QKeySequence > & end()
QByteArray left(int len) const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Sun Dec 5 2021 23:01:02 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.