Line data Source code
1 : /// IndiElement.hpp
2 : ///
3 : /// @author Paul Grenz
4 : ///
5 : /// This class represents one element in an INDI property. In its most basic
6 : /// form it is a name-value pair with other attributes associated with it.
7 : /// All access is protected by a read-write lock.
8 : ///
9 : ////////////////////////////////////////////////////////////////////////////////
10 :
11 : #ifndef INDI_ELEMENT_HPP
12 : #define INDI_ELEMENT_HPP
13 : #pragma once
14 :
15 : #include <stdint.h>
16 : #include <string>
17 : #include <sstream>
18 : #include <exception>
19 : #include "ReadWriteLock.hpp"
20 :
21 : namespace pcf
22 : {
23 : class IndiElement
24 : {
25 : public:
26 : // These are the possible types for streaming this element.
27 : enum Type
28 : {
29 : UnknownType = 0,
30 : // Define properties.
31 : DefBLOB,
32 : DefLight,
33 : DefNumber,
34 : DefSwitch,
35 : DefText,
36 : // Used to set or update.
37 : OneBLOB,
38 : OneLight,
39 : OneNumber,
40 : OneSwitch,
41 : OneText,
42 : };
43 :
44 : enum Error
45 : {
46 : ErrNone = 0,
47 : ErrAttributeIsNotAllowed = -1,
48 : ErrTypeNotDefined = -2,
49 : ErrIncorrectType = -3,
50 : ErrUndefined = -9999
51 : };
52 :
53 : enum LightStateType
54 : {
55 : UnknownLightState = 0,
56 : Idle = 1,
57 : Ok,
58 : Busy,
59 : Alert
60 : };
61 :
62 : enum SwitchStateType
63 : {
64 : UnknownSwitchState = 0,
65 : Off = 1,
66 : On
67 : };
68 :
69 : // Constructor/copy constructor/destructor.
70 : public:
71 : /// Constructor.
72 : IndiElement();
73 :
74 : /// Constructor with a name. This will be used often.
75 : IndiElement( const std::string &szName );
76 :
77 : /// Constructor with a name and a string value.
78 : IndiElement( const std::string &szName, const std::string &szValue );
79 :
80 : /// Constructor with a name and a char pointer value.
81 : IndiElement( const std::string &szName, const char *pcValue );
82 :
83 : /// Constructor with a name and a TT value.
84 : template <class TT> IndiElement( const std::string &szName, const TT &tValue );
85 :
86 : /// Constructor with a name and a LightStateType value.
87 : IndiElement( const std::string &szName, const LightStateType &tValue );
88 :
89 : /// Constructor with a name and a SwitchStateType value.
90 : IndiElement( const std::string &szName, const SwitchStateType &tValue );
91 :
92 : /// Copy constructor.
93 : IndiElement( const IndiElement &ieRhs );
94 :
95 : /// Destructor.
96 : virtual ~IndiElement();
97 :
98 : // Operators.
99 : public:
100 : /// Assigns the internal data of this object from an existing one.
101 : const IndiElement &operator= ( const IndiElement &ieRhs );
102 : /// This is an alternate way of calling 'setLightState'.
103 : const LightStateType &operator= ( const LightStateType &tValue );
104 : /// This is an alternate way of calling 'setSwitchState'.
105 : const SwitchStateType &operator= ( const SwitchStateType &tValue );
106 : /// Returns true if we have an exact match (value as well).
107 : bool operator==( const IndiElement &ieRhs ) const;
108 : /// This is an alternate way of calling 'setValue'.
109 : template <class TT> const TT &operator= ( const TT &tValue );
110 :
111 : // We want the value as a different things.
112 : operator LightStateType() const;
113 : operator SwitchStateType() const;
114 :
115 : // Methods.
116 : public:
117 : /// Reset this object.
118 : virtual void clear();
119 : /// Returns a string with each attribute & value enumerated.
120 : std::string createString() const;
121 :
122 : // All the different data this can store.
123 : const std::string &getFormat() const;
124 :
125 : const std::string &getLabel() const;
126 :
127 : const std::string &getMax() const;
128 :
129 : const std::string &getMin() const;
130 :
131 : const std::string &getName() const;
132 :
133 : const std::string &getSize() const;
134 :
135 : const std::string &getStep() const;
136 :
137 : /// Different ways of getting the data in this element.
138 : LightStateType getLightState() const;
139 : SwitchStateType getSwitchState() const;
140 : /// Return the value as type string.
141 : std::string get() const;
142 : /// Return the value as type string.
143 : std::string getValue() const;
144 : void getValue( char *pcValue, unsigned int &uiSize ) const;
145 : /// Return the value as type TT.
146 : template <class TT> TT getValue() const;
147 : /// Return the value as type TT.
148 : template <class TT> TT get() const;
149 :
150 : // Are the entries valid (non zero size)?
151 : bool hasValidFormat() const;
152 : bool hasValidLabel() const;
153 : bool hasValidLightState() const;
154 : bool hasValidMax() const;
155 : bool hasValidMin() const;
156 : bool hasValidName() const;
157 : bool hasValidSize() const;
158 : bool hasValidStep() const;
159 : bool hasValidSwitchState() const;
160 : bool hasValidValue() const;
161 :
162 : // Is the value (not LightState or SwitchState) a numeric?
163 : bool isNumeric() const;
164 :
165 : /// Returns the string type given the enumerated type.
166 : static std::string convertTypeToString( const Type &tType );
167 : /// Returns the enumerated type given the tag.
168 : static Type convertStringToType( const std::string &szTag );
169 : /// Returns the string type given the enumerated type.
170 : static std::string getLightStateString( const LightStateType &tType );
171 : /// Returns the enumerated type given the string type.
172 : static LightStateType getLightStateType( const std::string &szType );
173 : /// Returns the string type given the enumerated type.
174 : static std::string getSwitchStateString( const SwitchStateType &tType );
175 : /// Returns the enumerated type given the string type.
176 : static SwitchStateType getSwitchStateType( const std::string &szType );
177 :
178 : void setFormat( const std::string &szFormat );
179 : void setLabel( const std::string &szValue );
180 : void setMax( const std::string &szMax );
181 : void setMin( const std::string &szMin );
182 : void setName( const std::string &szName );
183 : void setSize( const std::string &szSize );
184 : void setStep( const std::string &szStep );
185 :
186 : template <class TT> void setMax( const TT &ttMax );
187 : template <class TT> void setMin( const TT &ttMin );
188 : template <class TT> void setSize( const TT &ttSize );
189 : template <class TT> void setStep( const TT &ttStep );
190 :
191 : /// Different ways of setting the data in this element.
192 : void setLightState( const LightStateType &tValue );
193 : void setSwitchState( const SwitchStateType &tValue );
194 : void setValue( const std::string &szValue );
195 : void setValue( const char *pcValue, const unsigned int &uiSize );
196 : template <class TT> void setValue( const TT &ttValue );
197 : template <class TT> void set( const TT &ttValue );
198 :
199 : // Members.
200 : private:
201 : /// If this is a number or BLOB, this is the 'printf' format.
202 : std::string m_szFormat {"%g"};
203 :
204 : /// A label, usually used in a GUI.
205 : std::string m_szLabel;
206 :
207 : /// If this is a number, this is its maximum value.
208 : std::string m_szMax {"0"};
209 :
210 : /// If this is a number, this is its minimum value.
211 : std::string m_szMin {"0"};
212 :
213 : /// The name of this element.
214 : std::string m_szName;
215 :
216 : /// If this is a BLOB, this is the number of bytes for it.
217 : std::string m_szSize {"0"};
218 :
219 : /// If this is a number, this is increment for it.
220 : std::string m_szStep {"0"};
221 :
222 : /// This is the value of the data.
223 : std::string m_szValue;
224 :
225 : /// This can also be the value.
226 : LightStateType m_lsValue {UnknownLightState};
227 :
228 : /// This can also be the value.
229 : SwitchStateType m_ssValue {UnknownSwitchState};
230 :
231 : // A read write lock to protect the internal data.
232 : mutable pcf::ReadWriteLock m_rwData;
233 :
234 : }; // class IndiElement
235 : } // namespace pcf
236 :
237 :
238 : ////////////////////////////////////////////////////////////////////////////////
239 : /// Constructor with a name and a TT value.
240 :
241 24 : template <class TT> pcf::IndiElement::IndiElement( const std::string &szName,
242 264 : const TT &ttValue ) : m_szName(szName)
243 : {
244 24 : std::stringstream ssValue;
245 24 : ssValue << std::boolalpha << ttValue;
246 24 : m_szValue = ssValue.str();
247 24 : }
248 :
249 : ////////////////////////////////////////////////////////////////////////////////
250 : /// Get the value as type TT.
251 :
252 38 : template <class TT> TT pcf::IndiElement::get() const
253 : {
254 38 : pcf::ReadWriteLock::AutoRLock rwAuto( &m_rwData );
255 :
256 18 : TT tValue;
257 : // stream the data into the variable.
258 38 : std::stringstream ssValue( m_szValue );
259 38 : ssValue >> std::boolalpha >> tValue;
260 56 : return tValue;
261 38 : }
262 :
263 : ////////////////////////////////////////////////////////////////////////////////
264 : /// Get an value of type TT from the element.
265 :
266 : template <class TT> TT pcf::IndiElement::getValue() const
267 : {
268 : pcf::ReadWriteLock::AutoRLock rwAuto( &m_rwData );
269 :
270 : TT tValue;
271 : // stream the data into the variable.
272 : std::stringstream ssValue( m_szValue );
273 : ssValue >> std::boolalpha >> tValue;
274 : return tValue;
275 : }
276 :
277 :
278 : ////////////////////////////////////////////////////////////////////////////////
279 : /// set an value of type TT in the element using the "=" operator.
280 :
281 58 : template <class TT> const TT &pcf::IndiElement::operator= ( const TT &ttValue )
282 : {
283 58 : pcf::ReadWriteLock::AutoWLock rwAuto( &m_rwData );
284 :
285 58 : std::stringstream ssValue;
286 58 : ssValue.precision( 15 );
287 58 : ssValue << std::boolalpha << ttValue;
288 58 : m_szValue = ssValue.str();
289 58 : return ttValue;
290 58 : }
291 :
292 : ////////////////////////////////////////////////////////////////////////////////
293 : /// set the value from type TT.
294 :
295 16 : template <class TT> void pcf::IndiElement::set( const TT &ttValue )
296 : {
297 16 : pcf::ReadWriteLock::AutoWLock rwAuto( &m_rwData );
298 :
299 16 : std::stringstream ssValue;
300 16 : ssValue.precision( 15 );
301 16 : ssValue << std::boolalpha << ttValue;
302 16 : m_szValue = ssValue.str();
303 16 : }
304 :
305 : ////////////////////////////////////////////////////////////////////////////////
306 : /// set an value of type TT in the element.
307 :
308 28 : template <class TT> void pcf::IndiElement::setValue( const TT &ttValue )
309 : {
310 28 : pcf::ReadWriteLock::AutoWLock rwAuto( &m_rwData );
311 :
312 28 : std::stringstream ssValue;
313 28 : ssValue.precision( 15 );
314 28 : ssValue << std::boolalpha << ttValue;
315 28 : m_szValue = ssValue.str();
316 28 : }
317 :
318 : ////////////////////////////////////////////////////////////////////////////////
319 : /// set a max of type TT in the element.
320 :
321 2 : template <class TT> void pcf::IndiElement::setMax( const TT &ttMax )
322 : {
323 2 : pcf::ReadWriteLock::AutoWLock rwAuto( &m_rwData );
324 :
325 2 : std::stringstream ssValue;
326 2 : ssValue.precision( 15 );
327 2 : ssValue << std::boolalpha << ttMax;
328 2 : m_szMax = ssValue.str();
329 2 : }
330 :
331 : ////////////////////////////////////////////////////////////////////////////////
332 : /// set a max of type TT in the element.
333 :
334 2 : template <class TT> void pcf::IndiElement::setMin( const TT &ttMin )
335 : {
336 2 : pcf::ReadWriteLock::AutoWLock rwAuto( &m_rwData );
337 :
338 2 : std::stringstream ssValue;
339 2 : ssValue.precision( 15 );
340 2 : ssValue << std::boolalpha << ttMin;
341 2 : m_szMin = ssValue.str();
342 2 : }
343 :
344 : ////////////////////////////////////////////////////////////////////////////////
345 : /// set a size of type TT in the element.
346 :
347 : template <class TT> void pcf::IndiElement::setSize( const TT &ttSize )
348 : {
349 : pcf::ReadWriteLock::AutoWLock rwAuto( &m_rwData );
350 :
351 : std::stringstream ssValue;
352 : ssValue.precision( 15 );
353 : ssValue << std::boolalpha << ttSize;
354 : m_szSize = ssValue.str();
355 : }
356 :
357 : /*
358 : ////////////////////////////////////////////////////////////////////////////////
359 : /// Get the size as an arbitrary type.
360 : template <class TT> typename std::remove_reference<TT>::type pcf::IndiElement::getSize() const
361 : {
362 : pcf::ReadWriteLock::AutoRLock rwAuto( &m_rwData );
363 :
364 : typename std::remove_reference<TT>::type tValue;
365 : // stream the size into the variable.
366 : std::stringstream ssValue( m_szSize );
367 : ssValue >> std::boolalpha >> tValue;
368 : return tValue;
369 : }*/
370 :
371 :
372 : ////////////////////////////////////////////////////////////////////////////////
373 : /// set a step of type TT in the element.
374 :
375 2 : template <class TT> void pcf::IndiElement::setStep( const TT &ttStep )
376 : {
377 2 : pcf::ReadWriteLock::AutoWLock rwAuto( &m_rwData );
378 :
379 2 : std::stringstream ssValue;
380 2 : ssValue.precision( 15 );
381 2 : ssValue << std::boolalpha << ttStep;
382 2 : m_szStep = ssValue.str();
383 2 : }
384 :
385 : ////////////////////////////////////////////////////////////////////////////////
386 :
387 : #endif // INDI_ELEMENT_HPP
|