File indexing completed on 2024-05-05 05:34:26
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 } 0143 return QString(); 0144 } 0145 0146 long long min() 0147 { 0148 if (count() > 1) { 0149 return (*this)[1].toLongLong(); 0150 } 0151 return -1; 0152 } 0153 0154 long long max() 0155 { 0156 if (count() > 2) { 0157 return (*this)[2].toLongLong(); 0158 } 0159 return -1; 0160 } 0161 0162 QString unit() 0163 { 0164 if (count() > 3) { 0165 return QString::fromUtf8((*this)[3]); 0166 } 0167 return QString(); 0168 } 0169 }; 0170 0171 /** 0172 An float info contains 4 fields separated by TABS, a description 0173 (name), the minimum and the maximum values and the unit. 0174 e.g. CPU Voltage 0.0 5.0 V 0175 */ 0176 class SensorFloatInfo : public SensorTokenizer 0177 { 0178 public: 0179 explicit SensorFloatInfo(const QByteArray &info) 0180 : SensorTokenizer(info, '\t') 0181 { 0182 } 0183 0184 ~SensorFloatInfo() 0185 { 0186 } 0187 0188 QString name() 0189 { 0190 if (count() > 0) { 0191 return QString::fromUtf8((*this)[0]); 0192 } 0193 return QString(); 0194 } 0195 0196 double min() 0197 { 0198 if (count() > 1) { 0199 return (*this)[1].toDouble(); 0200 } 0201 return -1; 0202 } 0203 0204 double max() 0205 { 0206 if (count() > 2) { 0207 return (*this)[2].toDouble(); 0208 } 0209 return -1; 0210 } 0211 0212 QString unit() 0213 { 0214 if (count() > 3) { 0215 return QString::fromUtf8((*this)[3]); 0216 } 0217 return QString(); 0218 } 0219 }; 0220 0221 } 0222 0223 #endif