1 /* 2 KSysGuard, the KDE System Guard 3 4 SPDX-FileCopyrightText: 1999, 2000 Chris Schlaeger <cs@kde.org> 5 SPDX-FileCopyrightText: 2006 John Tapsell <tapsell@kde.org> 6 7 SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 8 9 */ 10 11 #ifndef KSG_SENSORCLIENT_H 12 #define KSG_SENSORCLIENT_H 13 14 #include <QByteArray> 15 #include <QList> 16 #include <QString> 17 18 namespace KSGRD 19 { 20 /** 21 Every object that should act as a client to a sensor must inherit from 22 this class. A pointer to the client object is passed as SensorClient* 23 to the SensorAgent. When the requested information is available or a 24 problem occurred one of the member functions is called. 25 */ 26 class SensorClient 27 { 28 public: SensorClient()29 explicit SensorClient() 30 { 31 } ~SensorClient()32 virtual ~SensorClient() 33 { 34 } 35 36 /** 37 This function is called whenever the information from the sensor has 38 been received by the sensor agent. This function must be reimplemented 39 by the sensor client to receive and process this information. 40 */ answerReceived(int id,const QList<QByteArray> & answer)41 virtual void answerReceived(int id, const QList<QByteArray> &answer) 42 { 43 Q_UNUSED(id); 44 Q_UNUSED(answer); 45 } 46 47 /** 48 In case of an unexpected fatal problem with the sensor the sensor 49 agent will call this function to notify the client about it. 50 */ sensorLost(int id)51 virtual void sensorLost(int id) 52 { 53 Q_UNUSED(id); 54 } 55 }; 56 57 /** 58 The following classes are utility classes that provide a 59 convenient way to retrieve pieces of information from the sensor 60 answers. For each type of answer there is a separate class. 61 */ 62 class SensorTokenizer 63 { 64 public: SensorTokenizer(const QByteArray & info,char separator)65 SensorTokenizer(const QByteArray &info, char separator) 66 { 67 if (separator == '/') { 68 // This is a special case where we assume that info is a '\' escaped string 69 70 int i = 0; 71 int lastTokenAt = -1; 72 73 for (; i < info.length(); ++i) { 74 if (info[i] == '\\') { 75 ++i; 76 } else if (info[i] == separator) { 77 mTokens.append(unEscapeString(info.mid(lastTokenAt + 1, i - lastTokenAt - 1))); 78 lastTokenAt = i; 79 } 80 } 81 82 // Add everything after the last token 83 mTokens.append(unEscapeString(info.mid(lastTokenAt + 1, i - lastTokenAt - 1))); 84 } else { 85 mTokens = info.split(separator); 86 } 87 } 88 ~SensorTokenizer()89 ~SensorTokenizer() 90 { 91 } 92 93 const QByteArray &operator[](unsigned idx) 94 { 95 Q_ASSERT(idx < (unsigned)(mTokens.count())); 96 return mTokens[idx]; 97 } 98 count()99 uint count() 100 { 101 return mTokens.count(); 102 } 103 104 private: 105 QList<QByteArray> mTokens; 106 unEscapeString(QByteArray string)107 QByteArray unEscapeString(QByteArray string) 108 { 109 int i = 0; 110 for (; i < string.length(); ++i) { 111 if (string[i] == '\\') { 112 string.remove(i, 1); 113 ++i; 114 } 115 } 116 117 return string; 118 } 119 }; 120 121 /** 122 An integer info contains 4 fields separated by TABS, a description 123 (name), the minimum and the maximum values and the unit. 124 e.g. Swap Memory 0 133885952 KB 125 */ 126 class SensorIntegerInfo : public SensorTokenizer 127 { 128 public: SensorIntegerInfo(const QByteArray & info)129 explicit SensorIntegerInfo(const QByteArray &info) 130 : SensorTokenizer(info, '\t') 131 { 132 } 133 ~SensorIntegerInfo()134 ~SensorIntegerInfo() 135 { 136 } 137 name()138 QString name() 139 { 140 if (count() > 0) 141 return QString::fromUtf8((*this)[0]); 142 return QString(); 143 } 144 min()145 long long min() 146 { 147 if (count() > 1) 148 return (*this)[1].toLongLong(); 149 return -1; 150 } 151 max()152 long long max() 153 { 154 if (count() > 2) 155 return (*this)[2].toLongLong(); 156 return -1; 157 } 158 unit()159 QString unit() 160 { 161 if (count() > 3) 162 return QString::fromUtf8((*this)[3]); 163 return QString(); 164 } 165 }; 166 167 /** 168 An float info contains 4 fields separated by TABS, a description 169 (name), the minimum and the maximum values and the unit. 170 e.g. CPU Voltage 0.0 5.0 V 171 */ 172 class SensorFloatInfo : public SensorTokenizer 173 { 174 public: SensorFloatInfo(const QByteArray & info)175 explicit SensorFloatInfo(const QByteArray &info) 176 : SensorTokenizer(info, '\t') 177 { 178 } 179 ~SensorFloatInfo()180 ~SensorFloatInfo() 181 { 182 } 183 name()184 QString name() 185 { 186 if (count() > 0) 187 return QString::fromUtf8((*this)[0]); 188 return QString(); 189 } 190 min()191 double min() 192 { 193 if (count() > 1) 194 return (*this)[1].toDouble(); 195 return -1; 196 } 197 max()198 double max() 199 { 200 if (count() > 2) 201 return (*this)[2].toDouble(); 202 return -1; 203 } 204 unit()205 QString unit() 206 { 207 if (count() > 3) 208 return QString::fromUtf8((*this)[3]); 209 return QString(); 210 } 211 }; 212 213 } 214 215 #endif 216