File indexing completed on 2024-05-05 17:39:48
0001 /* 0002 KSysGuard, the KDE System Guard 0003 0004 SPDX-FileCopyrightText: 1999, 2000 Chris Schlaeger <cs@kde.org> 0005 SPDX-FileCopyrightText: 2006 John Tapsell <tapsell@kde.org> 0006 0007 SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0008 0009 */ 0010 0011 #ifndef KSG_SENSORCLIENT_H 0012 #define KSG_SENSORCLIENT_H 0013 0014 #include <QByteArray> 0015 #include <QList> 0016 #include <QString> 0017 0018 namespace KSGRD 0019 { 0020 /** 0021 Every object that should act as a client to a sensor must inherit from 0022 this class. A pointer to the client object is passed as SensorClient* 0023 to the SensorAgent. When the requested information is available or a 0024 problem occurred one of the member functions is called. 0025 */ 0026 class SensorClient 0027 { 0028 public: 0029 explicit SensorClient() 0030 { 0031 } 0032 virtual ~SensorClient() 0033 { 0034 } 0035 0036 /** 0037 This function is called whenever the information from the sensor has 0038 been received by the sensor agent. This function must be reimplemented 0039 by the sensor client to receive and process this information. 0040 */ 0041 virtual void answerReceived(int id, const QList<QByteArray> &answer) 0042 { 0043 Q_UNUSED(id); 0044 Q_UNUSED(answer); 0045 } 0046 0047 /** 0048 In case of an unexpected fatal problem with the sensor the sensor 0049 agent will call this function to notify the client about it. 0050 */ 0051 virtual void sensorLost(int id) 0052 { 0053 Q_UNUSED(id); 0054 } 0055 }; 0056 0057 /** 0058 The following classes are utility classes that provide a 0059 convenient way to retrieve pieces of information from the sensor 0060 answers. For each type of answer there is a separate class. 0061 */ 0062 class SensorTokenizer 0063 { 0064 public: 0065 SensorTokenizer(const QByteArray &info, char separator) 0066 { 0067 if (separator == '/') { 0068 // This is a special case where we assume that info is a '\' escaped string 0069 0070 int i = 0; 0071 int lastTokenAt = -1; 0072 0073 for (; i < info.length(); ++i) { 0074 if (info[i] == '\\') { 0075 ++i; 0076 } else if (info[i] == separator) { 0077 mTokens.append(unEscapeString(info.mid(lastTokenAt + 1, i - lastTokenAt - 1))); 0078 lastTokenAt = i; 0079 } 0080 } 0081 0082 // Add everything after the last token 0083 mTokens.append(unEscapeString(info.mid(lastTokenAt + 1, i - lastTokenAt - 1))); 0084 } else { 0085 mTokens = info.split(separator); 0086 } 0087 } 0088 0089 ~SensorTokenizer() 0090 { 0091 } 0092 0093 const QByteArray &operator[](unsigned idx) 0094 { 0095 Q_ASSERT(idx < (unsigned)(mTokens.count())); 0096 return mTokens[idx]; 0097 } 0098 0099 uint count() 0100 { 0101 return mTokens.count(); 0102 } 0103 0104 private: 0105 QList<QByteArray> mTokens; 0106 0107 QByteArray unEscapeString(QByteArray string) 0108 { 0109 int i = 0; 0110 for (; i < string.length(); ++i) { 0111 if (string[i] == '\\') { 0112 string.remove(i, 1); 0113 ++i; 0114 } 0115 } 0116 0117 return string; 0118 } 0119 }; 0120 0121 /** 0122 An integer info contains 4 fields separated by TABS, a description 0123 (name), the minimum and the maximum values and the unit. 0124 e.g. Swap Memory 0 133885952 KB 0125 */ 0126 class SensorIntegerInfo : public SensorTokenizer 0127 { 0128 public: 0129 explicit SensorIntegerInfo(const QByteArray &info) 0130 : SensorTokenizer(info, '\t') 0131 { 0132 } 0133 0134 ~SensorIntegerInfo() 0135 { 0136 } 0137 0138 QString name() 0139 { 0140 if (count() > 0) 0141 return QString::fromUtf8((*this)[0]); 0142 return QString(); 0143 } 0144 0145 long long min() 0146 { 0147 if (count() > 1) 0148 return (*this)[1].toLongLong(); 0149 return -1; 0150 } 0151 0152 long long max() 0153 { 0154 if (count() > 2) 0155 return (*this)[2].toLongLong(); 0156 return -1; 0157 } 0158 0159 QString unit() 0160 { 0161 if (count() > 3) 0162 return QString::fromUtf8((*this)[3]); 0163 return QString(); 0164 } 0165 }; 0166 0167 /** 0168 An float info contains 4 fields separated by TABS, a description 0169 (name), the minimum and the maximum values and the unit. 0170 e.g. CPU Voltage 0.0 5.0 V 0171 */ 0172 class SensorFloatInfo : public SensorTokenizer 0173 { 0174 public: 0175 explicit SensorFloatInfo(const QByteArray &info) 0176 : SensorTokenizer(info, '\t') 0177 { 0178 } 0179 0180 ~SensorFloatInfo() 0181 { 0182 } 0183 0184 QString name() 0185 { 0186 if (count() > 0) 0187 return QString::fromUtf8((*this)[0]); 0188 return QString(); 0189 } 0190 0191 double min() 0192 { 0193 if (count() > 1) 0194 return (*this)[1].toDouble(); 0195 return -1; 0196 } 0197 0198 double max() 0199 { 0200 if (count() > 2) 0201 return (*this)[2].toDouble(); 0202 return -1; 0203 } 0204 0205 QString unit() 0206 { 0207 if (count() > 3) 0208 return QString::fromUtf8((*this)[3]); 0209 return QString(); 0210 } 0211 }; 0212 0213 } 0214 0215 #endif