• Skip to content
  • Skip to link menu
Brand

API Documentation

  1. KDE API Reference
  2. The KDE Frameworks
  3. KContacts
  • KDE Home
  • Contact Us

Quick Links

Skip menu "KContacts"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • File List
  • Dependencies
  • Related Pages

Class Picker

About

Address book API for KDE

Maintainer
Laurent Montel
Supported platforms
Android, FreeBSD, iOS, Linux, MacOSX, Windows
Community
IRC: #kde-devel on Freenode
Mailing list: kde-frameworks-devel
Use with CMake
find_package(KF5Contacts)
target_link_libraries(yourapp KF5::Contacts)
Use with QMake
QT += KContacts 
Clone
git clone git://anongit.kde.org/kcontacts.git
Browse source
KContacts on cgit.kde.org

KContacts

  • frameworks
  • frameworks
  • kcontacts
  • src
ldif.cpp
1 /*
2  A temporary copy to break dependency to KLDAP
3 
4  This file is part of libkldap.
5  Copyright (c) 2004-2006 Szombathelyi György <[email protected]>
6 
7  This library is free software; you can redistribute it and/or
8  modify it under the terms of the GNU Library General Public
9  License as published by the Free Software Foundation; either
10  version 2 of the License, or (at your option) any later version.
11 
12  This library is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  Library General Public License for more details.
16 
17  You should have received a copy of the GNU Library General Public License
18  along with this library; see the file COPYING.LIB. If not, write to
19  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20  Boston, MA 02110-1301, USA.
21 */
22 
23 #include "ldif_p.h"
24 
25 #include "kcontacts_debug.h"
26 
27 class Q_DECL_HIDDEN Ldif::LdifPrivate
28 {
29 public:
30  int mModType;
31  bool mDelOldRdn, mUrl;
32  QByteArray mDn;
33  QString mAttr, mNewRdn, mNewSuperior, mOid;
34  QByteArray mLdif, mValue;
35  EntryType mEntryType;
36 
37  bool mIsNewLine, mIsComment, mCritical;
38  ParseValue mLastParseValue;
39  uint mPos, mLineNumber;
40  QByteArray mLine;
41 };
42 
43 Ldif::Ldif() : d(new LdifPrivate)
44 {
45  startParsing();
46 }
47 
48 Ldif::Ldif(const Ldif &that) : d(new LdifPrivate)
49 {
50  *d = *that.d;
51 
52  startParsing();
53 }
54 
55 Ldif &Ldif::operator=(const Ldif &that)
56 {
57  if (this == &that) {
58  return *this;
59  }
60 
61  *d = *that.d;
62 
63  return *this;
64 }
65 
66 Ldif::~Ldif()
67 {
68  delete d;
69 }
70 
71 QByteArray Ldif::assembleLine(const QString &fieldname, const QByteArray &value, uint linelen, bool url)
72 {
73  QByteArray result;
74 
75  if (url) {
76  result = fieldname.toUtf8() + ":< " + value;
77  } else {
78  bool safe = false;
79  bool isDn = fieldname.toLower() == QLatin1String("dn");
80  //SAFE-INIT-CHAR
81  if (value.size() > 0 && value[0] > 0 && value[0] != '\n'
82  && value[0] != '\r' && value[0] != ':' && value[0] != '<') {
83  safe = true;
84  }
85 
86  //SAFE-CHAR
87  if (safe) {
88  for (int i = 1; i < value.size(); ++i) {
89  //allow utf-8 in Distinguished Names
90  if ((isDn && value[i] == 0)
91  || (!isDn && value[i] <= 0)
92  || value[i] == '\r' || value[i] == '\n') {
93  safe = false;
94  break;
95  }
96  }
97  }
98 
99  if (value.isEmpty()) {
100  safe = true;
101  }
102 
103  if (safe) {
104  result = fieldname.toUtf8() + ": " + value;
105  } else {
106  result = fieldname.toUtf8() + ":: " + value.toBase64();
107  }
108 
109  if (linelen > 0) {
110  int i = (uint)(fieldname.length() + 2) > linelen ? fieldname.length() + 2 : linelen;
111  while (i < result.length()) {
112  result.insert(i, "\n ");
113  i += linelen + 2;
114  }
115  }
116  }
117  return result;
118 }
119 
120 QByteArray Ldif::assembleLine(const QString &fieldname, const QString &value, uint linelen, bool url)
121 {
122  return assembleLine(fieldname, value.toUtf8(), linelen, url);
123 }
124 
125 bool Ldif::splitLine(const QByteArray &line, QString &fieldname, QByteArray &value)
126 {
127  int position;
128  int linelen;
129 
130 // qCDebug(KCONTACTS_LOG) << "line:" << QString::fromUtf8(line);
131 
132  position = line.indexOf(":");
133  if (position == -1) {
134  // strange: we did not find a fieldname
135  fieldname = QLatin1String("");
136  value = line.trimmed();
137 // qCDebug(KCONTACTS_LOG) << "value :" << value[0];
138  return false;
139  }
140 
141  linelen = line.size();
142  fieldname = QString::fromUtf8(line.left(position).trimmed());
143 
144  if (linelen > (position + 1) && line[ position + 1 ] == ':') {
145  // String is BASE64 encoded -> decode it now.
146  if (linelen <= (position + 3)) {
147  value.resize(0);
148  return false;
149  }
150  value = QByteArray::fromBase64(line.mid(position + 3));
151  return false;
152  }
153 
154  if (linelen > (position + 1) && line[ position + 1 ] == '<') {
155  // String is an URL.
156  if (linelen <= (position + 3)) {
157  value.resize(0);
158  return false;
159  }
160  value = QByteArray::fromBase64(line.mid(position + 3));
161  return true;
162  }
163 
164  if (linelen <= (position + 2)) {
165  value.resize(0);
166  return false;
167  }
168  value = line.mid(position + 2);
169  return false;
170 }
171 
172 bool Ldif::splitControl(const QByteArray &line, QString &oid, bool &critical, QByteArray &value)
173 {
174  QString tmp;
175  critical = false;
176  bool url = splitLine(line, tmp, value);
177 
178  qCDebug(KCONTACTS_LOG) << "value:" << QString::fromUtf8(value);
179  if (tmp.isEmpty()) {
180  tmp = QString::fromUtf8(value);
181  value.resize(0);
182  }
183  if (tmp.endsWith(QLatin1String("true"))) {
184  critical = true;
185  tmp.chop(5);
186  } else if (tmp.endsWith(QLatin1String("false"))) {
187  critical = false;
188  tmp.chop(6);
189  }
190  oid = tmp;
191  return url;
192 }
193 
194 Ldif::ParseValue Ldif::processLine()
195 {
196  if (d->mIsComment) {
197  return None;
198  }
199 
200  ParseValue retval = None;
201  if (d->mLastParseValue == EndEntry) {
202  d->mEntryType = Entry_None;
203  }
204 
205  d->mUrl = splitLine(d->mLine, d->mAttr, d->mValue);
206 
207  QString attrLower = d->mAttr.toLower();
208 
209  switch (d->mEntryType) {
210  case Entry_None:
211  if (attrLower == QLatin1String("version")) {
212  if (!d->mDn.isEmpty()) {
213  retval = Err;
214  }
215  } else if (attrLower == QLatin1String("dn")) {
216  qCDebug(KCONTACTS_LOG) << "ldapentry dn:" << QString::fromUtf8(d->mValue);
217  d->mDn = d->mValue;
218  d->mModType = Mod_None;
219  retval = NewEntry;
220  } else if (attrLower == QLatin1String("changetype")) {
221  if (d->mDn.isEmpty()) {
222  retval = Err;
223  } else {
224  QString tmpval = QString::fromUtf8(d->mValue);
225  qCDebug(KCONTACTS_LOG) << "changetype:" << tmpval;
226  if (tmpval == QLatin1String("add")) {
227  d->mEntryType = Entry_Add;
228  } else if (tmpval == QLatin1String("delete")) {
229  d->mEntryType = Entry_Del;
230  } else if (tmpval == QLatin1String("modrdn") || tmpval == QLatin1String("moddn")) {
231  d->mNewRdn = QLatin1String("");
232  d->mNewSuperior = QLatin1String("");
233  d->mDelOldRdn = true;
234  d->mEntryType = Entry_Modrdn;
235  } else if (tmpval == QLatin1String("modify")) {
236  d->mEntryType = Entry_Mod;
237  } else {
238  retval = Err;
239  }
240  }
241  } else if (attrLower == QLatin1String("control")) {
242  d->mUrl = splitControl(d->mValue, d->mOid, d->mCritical, d->mValue);
243  retval = Control;
244  } else if (!d->mAttr.isEmpty() && !d->mValue.isEmpty()) {
245  d->mEntryType = Entry_Add;
246  retval = Item;
247  }
248  break;
249  case Entry_Add:
250  if (d->mAttr.isEmpty() && d->mValue.isEmpty()) {
251  retval = EndEntry;
252  } else {
253  retval = Item;
254  }
255  break;
256  case Entry_Del:
257  if (d->mAttr.isEmpty() && d->mValue.isEmpty()) {
258  retval = EndEntry;
259  } else {
260  retval = Err;
261  }
262  break;
263  case Entry_Mod:
264  if (d->mModType == Mod_None) {
265  qCDebug(KCONTACTS_LOG) << "new modtype" << d->mAttr;
266  if (d->mAttr.isEmpty() && d->mValue.isEmpty()) {
267  retval = EndEntry;
268  } else if (attrLower == QLatin1String("add")) {
269  d->mModType = Mod_Add;
270  } else if (attrLower == QLatin1String("replace")) {
271  d->mModType = Mod_Replace;
272  d->mAttr = QString::fromUtf8(d->mValue);
273  d->mValue = QByteArray();
274  retval = Item;
275  } else if (attrLower == QLatin1String("delete")) {
276  d->mModType = Mod_Del;
277  d->mAttr = QString::fromUtf8(d->mValue);
278  d->mValue = QByteArray();
279  retval = Item;
280  } else {
281  retval = Err;
282  }
283  } else {
284  if (d->mAttr.isEmpty()) {
285  if (QString::fromUtf8(d->mValue) == QLatin1String("-")) {
286  d->mModType = Mod_None;
287  } else if (d->mValue.isEmpty()) {
288  retval = EndEntry;
289  } else {
290  retval = Err;
291  }
292  } else {
293  retval = Item;
294  }
295  }
296  break;
297  case Entry_Modrdn:
298  if (d->mAttr.isEmpty() && d->mValue.isEmpty()) {
299  retval = EndEntry;
300  } else if (attrLower == QLatin1String("newrdn")) {
301  d->mNewRdn = QString::fromUtf8(d->mValue);
302  } else if (attrLower == QLatin1String("newsuperior")) {
303  d->mNewSuperior = QString::fromUtf8(d->mValue);
304  } else if (attrLower == QLatin1String("deleteoldrdn")) {
305  if (d->mValue.size() > 0 && d->mValue[0] == '0') {
306  d->mDelOldRdn = false;
307  } else if (d->mValue.size() > 0 && d->mValue[0] == '1') {
308  d->mDelOldRdn = true;
309  } else {
310  retval = Err;
311  }
312  } else {
313  retval = Err;
314  }
315  break;
316  }
317  return retval;
318 }
319 
320 Ldif::ParseValue Ldif::nextItem()
321 {
322  ParseValue retval = None;
323  char c = 0;
324 
325  while (retval == None) {
326  if (d->mPos < (uint)d->mLdif.size()) {
327  c = d->mLdif[d->mPos];
328  d->mPos++;
329  if (d->mIsNewLine && c == '\r') {
330  continue; //handle \n\r line end
331  }
332  if (d->mIsNewLine && (c == ' ' || c == '\t')) { //line folding
333  d->mIsNewLine = false;
334  continue;
335  }
336  if (d->mIsNewLine) {
337  d->mIsNewLine = false;
338  retval = processLine();
339  d->mLastParseValue = retval;
340  d->mLine.resize(0);
341  d->mIsComment = (c == '#');
342  }
343  if (c == '\n' || c == '\r') {
344  d->mLineNumber++;
345  d->mIsNewLine = true;
346  continue;
347  }
348  } else {
349  retval = MoreData;
350  break;
351  }
352 
353  if (!d->mIsComment) {
354  d->mLine += c;
355  }
356  }
357  return retval;
358 }
359 
360 void Ldif::endLdif()
361 {
362  QByteArray tmp(3, '\n');
363  d->mLdif = tmp;
364  d->mPos = 0;
365 }
366 
367 void Ldif::startParsing()
368 {
369  d->mPos = d->mLineNumber = 0;
370  d->mDelOldRdn = false;
371  d->mEntryType = Entry_None;
372  d->mModType = Mod_None;
373  d->mNewRdn.clear();
374  d->mNewSuperior.clear();
375  d->mLine = QByteArray();
376  d->mIsNewLine = false;
377  d->mIsComment = false;
378  d->mLastParseValue = None;
379 }
380 
381 void Ldif::setLdif(const QByteArray &ldif)
382 {
383  d->mLdif = ldif;
384  d->mPos = 0;
385 }
386 
387 Ldif::EntryType Ldif::entryType() const
388 {
389  return d->mEntryType;
390 }
391 
392 int Ldif::modType() const
393 {
394  return d->mModType;
395 }
396 
397 QString Ldif::newRdn() const
398 {
399  return d->mNewRdn;
400 }
401 
402 QString Ldif::newSuperior() const
403 {
404  return d->mNewSuperior;
405 }
406 
407 bool Ldif::delOldRdn() const
408 {
409  return d->mDelOldRdn;
410 }
411 
412 QString Ldif::attr() const
413 {
414  return d->mAttr;
415 }
416 
417 QByteArray Ldif::value() const
418 {
419  return d->mValue;
420 }
421 
422 bool Ldif::isUrl() const
423 {
424  return d->mUrl;
425 }
426 
427 bool Ldif::isCritical() const
428 {
429  return d->mCritical;
430 }
431 
432 QString Ldif::oid() const
433 {
434  return d->mOid;
435 }
436 
437 uint Ldif::lineNumber() const
438 {
439  return d->mLineNumber;
440 }
QByteArray::trimmed
QByteArray trimmed() const
QByteArray
QByteArray::isEmpty
bool isEmpty() const
QByteArray::fromBase64
QByteArray fromBase64(const QByteArray &base64, QFlags< QByteArray::Base64Option > options)
QByteArray::insert
QByteArray & insert(int i, char ch)
QByteArray::length
int length() const
QString::chop
void chop(int n)
QByteArray::resize
void resize(int size)
QByteArray::indexOf
int indexOf(char ch, int from) const
QString::fromUtf8
QString fromUtf8(const char *str, int size)
QString::isEmpty
bool isEmpty() const
QString::endsWith
bool endsWith(const QString &s, Qt::CaseSensitivity cs) const
QString
QByteArray::mid
QByteArray mid(int pos, int len) const
QString::toLower
QString toLower() const
QByteArray::left
QByteArray left(int len) const
Ldif
QLatin1String
QString::length
int length() const
QByteArray::size
int size() const
QByteArray::toBase64
QByteArray toBase64(QFlags< QByteArray::Base64Option > options) const
KCModuleLoader::None
None
QString::toUtf8
QByteArray toUtf8() const
This file is part of the KDE documentation.
Documentation copyright © 1996-2019 The KDE developers.
Generated on Sun Dec 8 2019 03:29:32 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal