Instrument Neutral Distributed Interface INDI  2.0.2
indiproperty.cpp
Go to the documentation of this file.
1 /*******************************************************************************
2  Copyright(c) 2011 Jasem Mutlaq. All rights reserved.
3  2022 Pawel Soja <kernel32.pl@gmail.com>
4 
5  This library is free software; you can redistribute it and/or
6  modify it under the terms of the GNU Library General Public
7  License version 2 as published by the Free Software Foundation.
8 
9  This library is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  Library General Public License for more details.
13 
14  You should have received a copy of the GNU Library General Public License
15  along with this library; see the file COPYING.LIB. If not, write to
16  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17  Boston, MA 02110-1301, USA.
18 *******************************************************************************/
19 
20 #include "indiproperty.h"
21 #include "indiproperty_p.h"
22 
23 #include "basedevice.h"
24 
25 #include "indipropertytext.h"
26 #include "indipropertyswitch.h"
27 #include "indipropertynumber.h"
28 #include "indipropertylight.h"
29 #include "indipropertyblob.h"
30 
31 #include "indipropertytext_p.h"
32 #include "indipropertyswitch_p.h"
33 #include "indipropertynumber_p.h"
34 #include "indipropertylight_p.h"
35 #include "indipropertyblob_p.h"
36 
37 #include <cstdlib>
38 #include <cstring>
39 
40 namespace INDI
41 {
42 
44  : property(property)
45  , type(property ? type : INDI_UNKNOWN)
46  , registered(property != nullptr)
47 { }
48 
50  : property(property)
51  , type(property ? INDI_TEXT : INDI_UNKNOWN)
52  , registered(property != nullptr)
53 { }
54 
56  : property(property)
57  , type(property ? INDI_NUMBER : INDI_UNKNOWN)
58  , registered(property != nullptr)
59 { }
60 
62  : property(property)
63  , type(property ? INDI_SWITCH : INDI_UNKNOWN)
64  , registered(property != nullptr)
65 { }
66 
68  : property(property)
69  , type(property ? INDI_LIGHT : INDI_UNKNOWN)
70  , registered(property != nullptr)
71 { }
72 
74  : property(property)
75  , type(property ? INDI_BLOB : INDI_UNKNOWN)
76  , registered(property != nullptr)
77 { }
78 
79 #ifdef INDI_PROPERTY_BACKWARD_COMPATIBILE
81 {
82  return this;
83 }
84 
86 {
87  return this;
88 }
89 
90 Property::operator INDI::Property *()
91 {
92  D_PTR(Property);
93  return isValid() ? &d->self : nullptr;
94 }
95 
96 Property::operator const INDI::Property *() const
97 {
98  D_PTR(const Property);
99  return isValid() ? &d->self : nullptr;
100 }
101 #endif
102 
104 {
105  D_PTR(Property);
106  return isValid() ? &d->self : nullptr;
107 }
108 
109 #define PROPERTY_CASE(CODE) \
110  switch (d->property != nullptr ? d->type : INDI_UNKNOWN) \
111  { \
112  case INDI_NUMBER: { auto property = static_cast<PropertyViewNumber *>(d->property); CODE } break; \
113  case INDI_TEXT: { auto property = static_cast<PropertyViewText *>(d->property); CODE } break; \
114  case INDI_SWITCH: { auto property = static_cast<PropertyViewSwitch *>(d->property); CODE } break; \
115  case INDI_LIGHT: { auto property = static_cast<PropertyViewLight *>(d->property); CODE } break; \
116  case INDI_BLOB: { auto property = static_cast<PropertyViewBlob *>(d->property); CODE } break; \
117  default:; \
118  }
119 
121 {
122  // Only delete properties if they were created dynamically via the buildSkeleton
123  // function. Other drivers are responsible for their own memory allocation.
124  if (property == nullptr || !dynamic)
125  return;
126 
127  auto d = this;
128  PROPERTY_CASE( delete property; )
129 }
130 
132  : d_ptr(new PropertyPrivate(nullptr, INDI_UNKNOWN))
133 { }
134 
136  : d_ptr(property.d_ptr)
137 { }
138 
140  : d_ptr(property.d_ptr)
141 { }
142 
144  : d_ptr(property.d_ptr)
145 { }
146 
148  : d_ptr(property.d_ptr)
149 { }
150 
152  : d_ptr(property.d_ptr)
153 { }
154 
155 #ifdef INDI_PROPERTY_BACKWARD_COMPATIBILE
156 
158  : d_ptr(new PropertyNumberPrivate(property))
159 { }
160 
162  : d_ptr(new PropertyTextPrivate(property))
163 { }
164 
166  : d_ptr(new PropertySwitchPrivate(property))
167 { }
168 
170  : d_ptr(new PropertyLightPrivate(property))
171 { }
172 
174  : d_ptr(new PropertyBlobPrivate(property))
175 { }
176 
178  : d_ptr(new PropertyNumberPrivate(property))
179 { }
180 
182  : d_ptr(new PropertyTextPrivate(property))
183 { }
184 
186  : d_ptr(new PropertySwitchPrivate(property))
187 { }
188 
190  : d_ptr(new PropertyLightPrivate(property))
191 { }
192 
194  : d_ptr(new PropertyBlobPrivate(property))
195 { }
196 #endif
197 
199 { }
200 
202  : d_ptr(&dd)
203 { }
204 
205 Property::Property(const std::shared_ptr<PropertyPrivate> &dd)
206  : d_ptr(dd)
207 { }
208 
210 {
211  D_PTR(Property);
212  d->type = p ? d->type : INDI_UNKNOWN;
213  d->registered = p != nullptr;
214  d->property = p;
215 }
216 
218 {
219  D_PTR(Property);
220  d->type = t;
221 }
222 
224 {
225  D_PTR(Property);
226  d->registered = r;
227 }
228 
229 void Property::setDynamic(bool dyn)
230 {
231  D_PTR(Property);
232  d->dynamic = dyn;
233 }
234 
236 {
237  D_PTR(Property);
238  d->baseDevice = (idp == nullptr ? BaseDevice() : *idp);
239 }
240 
242 {
243  D_PTR(Property);
244  d->baseDevice = baseDevice;
245 }
246 
248 {
249  D_PTR(const Property);
250  return d->property;
251 }
252 
254 {
255  D_PTR(const Property);
256  return d->property != nullptr ? d->type : INDI_UNKNOWN;
257 }
258 
259 const char *Property::getTypeAsString() const
260 {
261  switch (getType())
262  {
263  case INDI_NUMBER:
264  return "INDI_NUMBER";
265  case INDI_SWITCH:
266  return "INDI_SWITCH";
267  case INDI_TEXT:
268  return "INDI_TEXT";
269  case INDI_LIGHT:
270  return "INDI_LIGHT";
271  case INDI_BLOB:
272  return "INDI_BLOB";
273  case INDI_UNKNOWN:
274  return "INDI_UNKNOWN";
275  }
276  return "INDI_UNKNOWN";
277 }
278 
280 {
281  D_PTR(const Property);
282  return d->registered;
283 }
284 
286 {
287  D_PTR(const Property);
288  return d->dynamic;
289 }
290 
292 {
293  D_PTR(const Property);
294  return d->baseDevice;
295 }
296 
297 void Property::setName(const char *name)
298 {
299  D_PTR(Property);
300  PROPERTY_CASE( property->setName(name); )
301 }
302 
303 void Property::setLabel(const char *label)
304 {
305  D_PTR(Property);
306  PROPERTY_CASE( property->setLabel(label); )
307 }
308 
309 void Property::setGroupName(const char *group)
310 {
311  D_PTR(Property);
312  PROPERTY_CASE( property->setGroupName(group); )
313 }
314 
316 {
317  D_PTR(Property);
318  PROPERTY_CASE( property->setDeviceName(device); )
319 }
320 
321 void Property::setTimestamp(const char *timestamp)
322 {
323  D_PTR(Property);
324  PROPERTY_CASE( property->setTimestamp(timestamp); )
325 }
326 
328 {
329  D_PTR(Property);
330  PROPERTY_CASE( property->setState(state); )
331 }
332 
334 {
335  D_PTR(Property);
336  PROPERTY_CASE( property->setPermission(permission); )
337 }
338 
339 void Property::setTimeout(double timeout)
340 {
341  D_PTR(Property);
342  PROPERTY_CASE( property->setTimeout(timeout); )
343 }
344 
345 const char *Property::getName() const
346 {
347  D_PTR(const Property);
348  PROPERTY_CASE( return property->getName(); )
349  return nullptr;
350 }
351 
352 const char *Property::getLabel() const
353 {
354  D_PTR(const Property);
355  PROPERTY_CASE( return property->getLabel(); )
356  return nullptr;
357 }
358 
359 const char *Property::getGroupName() const
360 {
361  D_PTR(const Property);
362  PROPERTY_CASE( return property->getGroupName(); )
363  return nullptr;
364 }
365 
366 const char *Property::getDeviceName() const
367 {
368  D_PTR(const Property);
369  PROPERTY_CASE( return property->getDeviceName(); )
370  return nullptr;
371 }
372 
373 const char *Property::getTimestamp() const
374 {
375  D_PTR(const Property);
376  PROPERTY_CASE( return property->getTimestamp(); )
377  return nullptr;
378 }
379 
381 {
382  D_PTR(const Property);
383  PROPERTY_CASE( return property->getState(); )
384  return IPS_ALERT;
385 }
386 
387 const char *Property::getStateAsString() const
388 {
389  return pstateStr(getState());
390 }
391 
393 {
394  D_PTR(const Property);
395  PROPERTY_CASE( return property->getPermission(); )
396  return IP_RO;
397 }
398 
399 bool Property::isEmpty() const
400 {
401  D_PTR(const Property);
402  PROPERTY_CASE( return property->isEmpty(); )
403  return true;
404 }
405 
406 bool Property::isValid() const
407 {
408  D_PTR(const Property);
409  return d->type != INDI_UNKNOWN;
410 }
411 
412 bool Property::isNameMatch(const char *otherName) const
413 {
414  D_PTR(const Property);
415  PROPERTY_CASE( return property->isNameMatch(otherName); )
416  return false;
417 }
418 
419 bool Property::isNameMatch(const std::string &otherName) const
420 {
421  D_PTR(const Property);
422  PROPERTY_CASE( return property->isNameMatch(otherName); )
423  return false;
424 }
425 
426 bool Property::isLabelMatch(const char *otherLabel) const
427 {
428  D_PTR(const Property);
429  PROPERTY_CASE( return property->isLabelMatch(otherLabel); )
430  return false;
431 }
432 
433 bool Property::isLabelMatch(const std::string &otherLabel) const
434 {
435  D_PTR(const Property);
436  PROPERTY_CASE( return property->isLabelMatch(otherLabel); )
437  return false;
438 }
439 
440 bool Property::isDeviceNameMatch(const char *otherDeviceName) const
441 {
442  return isDeviceNameMatch(std::string(otherDeviceName));
443 }
444 
445 bool Property::isDeviceNameMatch(const std::string &otherDeviceName) const
446 {
447  return getDeviceName() == otherDeviceName;
448 }
449 
451 {
452  return getType() == otherType;
453 }
454 
456 {
457  D_PTR(const Property);
458  if (d->type == INDI_NUMBER)
459  return static_cast<PropertyViewNumber*>(d->property);
460 
461  return nullptr;
462 }
463 
465 {
466  D_PTR(const Property);
467  if (d->type == INDI_TEXT)
468  return static_cast<PropertyViewText*>(d->property);
469 
470  return nullptr;
471 }
472 
474 {
475  D_PTR(const Property);
476  if (d->type == INDI_LIGHT)
477  return static_cast<PropertyViewLight*>(d->property);
478 
479  return nullptr;
480 }
481 
483 {
484  D_PTR(const Property);
485  if (d->type == INDI_SWITCH)
486  return static_cast<PropertyViewSwitch*>(d->property);
487 
488  return nullptr;
489 }
490 
492 {
493  D_PTR(const Property);
494  if (d->type == INDI_BLOB)
495  return static_cast<PropertyViewBlob*>(d->property);
496 
497  return nullptr;
498 }
499 
500 void Property::save(FILE *fp) const
501 {
502  D_PTR(const Property);
503  PROPERTY_CASE( property->save(fp); )
504 }
505 
506 void Property::apply(const char *format, ...) const
507 {
508  D_PTR(const Property);
509  va_list ap;
510  va_start(ap, format);
511  PROPERTY_CASE( property->vapply(format, ap); )
512  va_end(ap);
513 }
514 
515 void Property::define(const char *format, ...) const
516 {
517  D_PTR(const Property);
518  va_list ap;
519  va_start(ap, format);
520  PROPERTY_CASE( property->vdefine(format, ap); )
521  va_end(ap);
522 }
523 
524 void Property::onUpdate(const std::function<void()> &callback)
525 {
526  D_PTR(Property);
527  d->onUpdateCallback = callback;
528 }
529 
531 {
532  D_PTR(Property);
533  if (d->onUpdateCallback)
534  d->onUpdateCallback();
535 }
536 
538 {
539  D_PTR(const Property);
540  return d->onUpdateCallback != nullptr;
541 }
542 
543 }
hid_device * device
Class to provide basic INDI device functionality.
Definition: basedevice.h:52
PropertyPrivate(void *property, INDI_PROPERTY_TYPE type)
Provides generic container for INDI properties.
Definition: indiproperty.h:48
bool isDeviceNameMatch(const char *otherDeviceName) const
void onUpdate(const std::function< void()> &callback)
INDI::PropertyViewSwitch * getSwitch() const
const char * getGroupName() const
INDI::PropertyViewBlob * getBLOB() const
INDI::PropertyViewText * getText() const
void void void apply() const
Definition: indiproperty.h:145
const char * getDeviceName() const
void setTimestamp(const char *timestamp)
bool isValid() const
INDI::Property * operator->()
void setLabel(const char *label)
INDI::Property * self()
void save(FILE *fp) const
void setDynamic(bool d)
bool isEmpty() const
const char * getStateAsString() const
INDI::PropertyViewNumber * getNumber() const
const char * getName() const
INDI::PropertyViewLight * getLight() const
IPerm getPermission() const
void setType(INDI_PROPERTY_TYPE t)
void setGroupName(const char *groupName)
void * getProperty() const
bool hasUpdateCallback() const
bool isDynamic() const
void setTimeout(double timeout)
void setDeviceName(const char *deviceName)
bool isNameMatch(const char *otherName) const
const char * getTypeAsString() const
BaseDevice getBaseDevice() const
const char * getLabel() const
void define() const
Definition: indiproperty.h:149
IPState getState() const
void setBaseDevice(BaseDevice *idp)
bool getRegistered() const
void setName(const char *name)
INDI_PROPERTY_TYPE getType() const
bool isLabelMatch(const char *otherLabel) const
void setRegistered(bool r)
void setProperty(void *)
const char * getTimestamp() const
bool isTypeMatch(INDI_PROPERTY_TYPE otherType) const
void setState(IPState state)
void setPermission(IPerm permission)
IPerm
Permission hint, with respect to client.
Definition: indiapi.h:183
@ IP_RO
Definition: indiapi.h:184
IPState
Property state.
Definition: indiapi.h:160
@ IPS_ALERT
Definition: indiapi.h:164
INDI_PROPERTY_TYPE
Definition: indibasetypes.h:23
const char * pstateStr(IPState s)
Definition: indidevapi.c:628
@ INDI_LIGHT
Definition: indidriver.c:60
@ INDI_TEXT
Definition: indidriver.c:59
@ INDI_UNKNOWN
Definition: indidriver.c:62
@ INDI_NUMBER
Definition: indidriver.c:57
@ INDI_SWITCH
Definition: indidriver.c:58
@ INDI_BLOB
Definition: indidriver.c:61
#define PROPERTY_CASE(CODE)
Namespace to encapsulate INDI client, drivers, and mediator classes.
__le16 type
Definition: pwc-ioctl.h:0
Provides decorator for Low-Level IXXXVectorProperty/IXXX.
BLOB (Binary Large Object) vector property descriptor.
Definition: indiapi.h:471
Light vector property descriptor.
Definition: indiapi.h:417
Number vector property descriptor.
Definition: indiapi.h:319
Switch vector property descriptor.
Definition: indiapi.h:367
Text vector property descriptor.
Definition: indiapi.h:246