Solid

cfhelper.cpp
1/*
2 SPDX-FileCopyrightText: 2009 Harald Fernengel <harry@kdevelop.org>
3 SPDX-FileCopyrightText: 2017 René J.V. Bertin <rjvbertin@gmail.com>
4
5 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
6*/
7
8#include <qdatetime.h>
9#include <qdebug.h>
10#include <qstring.h>
11#include <qstringlist.h>
12#include <qvariant.h>
13#include <qvarlengtharray.h>
14
15#include <CoreFoundation/CoreFoundation.h>
16
17#include <sys/sysctl.h>
18
19/* helper classes to convert from CF types to Qt */
20
21static QString q_toString(const CFStringRef &str)
22{
23 CFIndex length = CFStringGetLength(str);
24 QVarLengthArray<UniChar> buffer(length);
25
26 CFRange range = {0, length};
27 CFStringGetCharacters(str, range, buffer.data());
28 return QString(reinterpret_cast<const QChar *>(buffer.data()), length);
29}
30
31template<typename T>
32static inline T convertCFNumber(const CFNumberRef &num, CFNumberType type)
33{
34 T n;
35 CFNumberGetValue(num, type, &n);
36 return n;
37}
38
39static QVariant q_toVariant(const CFTypeRef &obj)
40{
41 const CFTypeID typeId = CFGetTypeID(obj);
42
43 if (typeId == CFStringGetTypeID()) {
44 return QVariant(q_toString(static_cast<const CFStringRef>(obj)));
45 }
46
47 if (typeId == CFNumberGetTypeID()) {
48 const CFNumberRef num = static_cast<const CFNumberRef>(obj);
49 const CFNumberType type = CFNumberGetType(num);
50 switch (type) {
51 case kCFNumberSInt8Type:
52 return QVariant::fromValue(convertCFNumber<char>(num, type));
53 case kCFNumberSInt16Type:
54 return QVariant::fromValue(convertCFNumber<qint16>(num, type));
55 case kCFNumberSInt32Type:
56 return QVariant::fromValue(convertCFNumber<qint32>(num, type));
57 case kCFNumberSInt64Type:
58 return QVariant::fromValue(convertCFNumber<qint64>(num, type));
59 case kCFNumberCharType:
60 return QVariant::fromValue(convertCFNumber<uchar>(num, type));
61 case kCFNumberShortType:
62 return QVariant::fromValue(convertCFNumber<short>(num, type));
63 case kCFNumberIntType:
64 return QVariant::fromValue(convertCFNumber<int>(num, type));
65 case kCFNumberLongType:
66 return QVariant::fromValue(convertCFNumber<long>(num, type));
67 case kCFNumberLongLongType:
68 return QVariant::fromValue(convertCFNumber<long long>(num, type));
69 case kCFNumberFloatType:
70 return QVariant::fromValue(convertCFNumber<float>(num, type));
71 case kCFNumberDoubleType:
72 return QVariant::fromValue(convertCFNumber<double>(num, type));
73 default:
74 if (CFNumberIsFloatType(num)) {
75 return QVariant::fromValue(convertCFNumber<double>(num, kCFNumberDoubleType));
76 }
77 return QVariant::fromValue(convertCFNumber<quint64>(num, kCFNumberLongLongType));
78 }
79 }
80
81 if (typeId == CFDateGetTypeID()) {
82 QDateTime dt;
83 dt.setSecsSinceEpoch(qint64(kCFAbsoluteTimeIntervalSince1970));
84 return dt.addSecs(int(CFDateGetAbsoluteTime(static_cast<const CFDateRef>(obj))));
85 }
86
87 if (typeId == CFDataGetTypeID()) {
88 const CFDataRef cfdata = static_cast<const CFDataRef>(obj);
89 return QByteArray(reinterpret_cast<const char *>(CFDataGetBytePtr(cfdata)), CFDataGetLength(cfdata));
90 }
91
92 if (typeId == CFBooleanGetTypeID()) {
93 return QVariant(bool(CFBooleanGetValue(static_cast<const CFBooleanRef>(obj))));
94 }
95
96 if (typeId == CFArrayGetTypeID()) {
97 const CFArrayRef cfarray = static_cast<const CFArrayRef>(obj);
99 CFIndex size = CFArrayGetCount(cfarray);
100 bool metNonString = false;
101 for (CFIndex i = 0; i < size; ++i) {
102 QVariant value = q_toVariant(CFArrayGetValueAtIndex(cfarray, i));
103 if (value.userType() != QMetaType::QString) {
104 metNonString = true;
105 }
106 list << value;
107 }
108 if (metNonString) {
109 return list;
110 } else {
111 return QVariant(list).toStringList();
112 }
113 }
114
115 if (typeId == CFDictionaryGetTypeID()) {
116 const CFDictionaryRef cfdict = static_cast<const CFDictionaryRef>(obj);
117 const CFTypeID arrayTypeId = CFArrayGetTypeID();
118 int size = int(CFDictionaryGetCount(cfdict));
121 CFDictionaryGetKeysAndValues(cfdict, keys.data(), values.data());
122
124 for (int i = 0; i < size; ++i) {
125 QString key = q_toString(static_cast<const CFStringRef>(keys[i]));
126
127 if (CFGetTypeID(values[i]) == arrayTypeId) {
128 const CFArrayRef cfarray = static_cast<const CFArrayRef>(values[i]);
129 CFIndex arraySize = CFArrayGetCount(cfarray);
130 for (CFIndex j = arraySize - 1; j >= 0; --j) {
131 map.insert(key, q_toVariant(CFArrayGetValueAtIndex(cfarray, j)));
132 }
133 } else {
134 map.insert(key, q_toVariant(values[i]));
135 }
136 }
137 return QVariant::fromValue(map);
138 }
139
140 return QVariant();
141}
142
143QMap<QString, QVariant> q_toVariantMap(const CFMutableDictionaryRef &dict)
144{
145 Q_ASSERT(dict);
146
148
149 const int count = CFDictionaryGetCount(dict);
150 QVarLengthArray<void *> keys(count);
151 QVarLengthArray<void *> values(count);
152
153 CFDictionaryGetKeysAndValues(dict, const_cast<const void **>(keys.data()), const_cast<const void **>(values.data()));
154
155 for (int i = 0; i < count; ++i) {
156 const QString key = q_toString((CFStringRef)keys[i]);
157 const QVariant value = q_toVariant((CFTypeRef)values[i]);
158 result[key] = value;
159 }
160
161 return result;
162}
163
164bool q_sysctlbyname(const char *name, QString &result)
165{
166 char *property = nullptr;
167 size_t size = 0;
168 int error = 0;
169 if (name && sysctlbyname(name, nullptr, &size, nullptr, 0) == 0 && size > 0) {
170 property = new char[size];
171 error = sysctlbyname(name, property, &size, nullptr, 0);
172 if (!error) {
173 result = QLatin1String(property);
174 }
175 delete[] property;
176 }
177 return !error;
178}
Type type(const QSqlDatabase &db)
void error(QWidget *parent, const QString &text, const QString &title, const KGuiItem &buttonOk, Options options=Notify)
KIOCORE_EXPORT QStringList list(const QString &fileClass)
QDateTime addSecs(qint64 s) const const
void setSecsSinceEpoch(qint64 secs)
QFuture< void > map(Iterator begin, Iterator end, MapFunctor &&function)
QVariant fromValue(T &&value)
QStringList toStringList() const const
int userType() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:17:12 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.